From 11fe3b3eee82e7b020aeb48b7f90ec7d6f2943d6 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 15 Jun 2022 11:24:00 -0500 Subject: [PATCH 001/116] descriptor v2 spike initial commit next up: handle background retirement --- .../contracts/NounsAuctionHouse.sol | 2 +- .../contracts/NounsDescriptor.sol | 349 ++++--- .../nouns-contracts/contracts/NounsSeeder.sol | 10 +- .../nouns-contracts/contracts/NounsToken.sol | 2 +- .../nouns-contracts/contracts/SVGRenderer.sol | 238 +++++ .../contracts/interfaces/INounsDescriptor.sol | 82 +- .../contracts/interfaces/ISVGRenderer.sol | 39 + .../contracts/libs/Inflate.sol | 924 ++++++++++++++++++ .../contracts/libs/NFTDescriptor.sol | 16 +- .../contracts/libs/SSTORE2.sol | 100 ++ .../proxies/NounsAuctionHouseProxy.sol | 2 +- .../proxies/NounsAuctionHouseProxyAdmin.sol | 2 +- packages/nouns-contracts/hardhat.config.ts | 2 +- .../tasks/populate-descriptor.ts | 65 +- 14 files changed, 1667 insertions(+), 166 deletions(-) create mode 100644 packages/nouns-contracts/contracts/SVGRenderer.sol create mode 100644 packages/nouns-contracts/contracts/interfaces/ISVGRenderer.sol create mode 100644 packages/nouns-contracts/contracts/libs/Inflate.sol create mode 100644 packages/nouns-contracts/contracts/libs/SSTORE2.sol diff --git a/packages/nouns-contracts/contracts/NounsAuctionHouse.sol b/packages/nouns-contracts/contracts/NounsAuctionHouse.sol index ccb78a64c6..cfba98fa4b 100644 --- a/packages/nouns-contracts/contracts/NounsAuctionHouse.sol +++ b/packages/nouns-contracts/contracts/NounsAuctionHouse.sol @@ -22,7 +22,7 @@ // AuctionHouse.sol source code Copyright Zora licensed under the GPL-3.0 license. // With modifications by Nounders DAO. -pragma solidity ^0.8.6; +pragma solidity ^0.8.12; import { PausableUpgradeable } from '@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol'; import { ReentrancyGuardUpgradeable } from '@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol'; diff --git a/packages/nouns-contracts/contracts/NounsDescriptor.sol b/packages/nouns-contracts/contracts/NounsDescriptor.sol index b3210c40da..17b80bb791 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptor.sol @@ -15,13 +15,16 @@ * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ -pragma solidity ^0.8.6; +pragma solidity ^0.8.12; import { Ownable } from '@openzeppelin/contracts/access/Ownable.sol'; import { Strings } from '@openzeppelin/contracts/utils/Strings.sol'; import { INounsDescriptor } from './interfaces/INounsDescriptor.sol'; import { INounsSeeder } from './interfaces/INounsSeeder.sol'; import { NFTDescriptor } from './libs/NFTDescriptor.sol'; +import { ISVGRenderer } from './interfaces/ISVGRenderer.sol'; +import { SSTORE2 } from './libs/SSTORE2.sol'; +import { Inflate } from './libs/Inflate.sol'; import { MultiPartRLEToSVG } from './libs/MultiPartRLEToSVG.sol'; contract NounsDescriptor is INounsDescriptor, Ownable { @@ -31,6 +34,9 @@ contract NounsDescriptor is INounsDescriptor, Ownable { // https://creativecommons.org/publicdomain/zero/1.0/legalcode.txt bytes32 constant COPYRIGHT_CC0_1_0_UNIVERSAL_LICENSE = 0xa2010f343487d3f7618affe54f789f5487602331c0a8d03f49e9a7c547cf0499; + // The contract responsible for constructing SVGs + ISVGRenderer public renderer; + // Whether or not new Noun parts can be added bool public override arePartsLocked; @@ -41,22 +47,22 @@ contract NounsDescriptor is INounsDescriptor, Ownable { string public override baseURI; // Noun Color Palettes (Index => Hex Colors) - mapping(uint8 => string[]) public override palettes; + mapping(uint8 => address) public override palettes; // Noun Backgrounds (Hex Colors) string[] public override backgrounds; // Noun Bodies (Custom RLE) - bytes[] public override bodies; + Trait private _bodies; // Noun Accessories (Custom RLE) - bytes[] public override accessories; + Trait private _accessories; // Noun Heads (Custom RLE) - bytes[] public override heads; + Trait private _heads; // Noun Glasses (Custom RLE) - bytes[] public override glasses; + Trait private _glasses; /** * @notice Require that the parts have not been locked. @@ -66,6 +72,20 @@ contract NounsDescriptor is INounsDescriptor, Ownable { _; } + constructor(ISVGRenderer _renderer) { + renderer = _renderer; + } + + /** + * @notice Set the SVG renderer. + * @dev Only callable by the owner. + */ + function setRenderer(ISVGRenderer _renderer) external onlyOwner { + renderer = _renderer; + + emit RendererUpdated(_renderer); + } + /** * @notice Get the number of available Noun `backgrounds`. */ @@ -77,39 +97,28 @@ contract NounsDescriptor is INounsDescriptor, Ownable { * @notice Get the number of available Noun `bodies`. */ function bodyCount() external view override returns (uint256) { - return bodies.length; + return _bodies.virtualIndexToStorageIndex.length; } /** * @notice Get the number of available Noun `accessories`. */ function accessoryCount() external view override returns (uint256) { - return accessories.length; + return _accessories.virtualIndexToStorageIndex.length; } /** * @notice Get the number of available Noun `heads`. */ function headCount() external view override returns (uint256) { - return heads.length; + return _heads.virtualIndexToStorageIndex.length; } /** * @notice Get the number of available Noun `glasses`. */ function glassesCount() external view override returns (uint256) { - return glasses.length; - } - - /** - * @notice Add colors to a color palette. - * @dev This function can only be called by the owner. - */ - function addManyColorsToPalette(uint8 paletteIndex, string[] calldata newColors) external override onlyOwner { - require(palettes[paletteIndex].length + newColors.length <= 256, 'Palettes can only hold 256 colors'); - for (uint256 i = 0; i < newColors.length; i++) { - _addColorToPalette(paletteIndex, newColors[i]); - } + return _glasses.virtualIndexToStorageIndex.length; } /** @@ -123,92 +132,149 @@ contract NounsDescriptor is INounsDescriptor, Ownable { } /** - * @notice Batch add Noun bodies. + * @notice Add a Noun background. * @dev This function can only be called by the owner when not locked. */ - function addManyBodies(bytes[] calldata _bodies) external override onlyOwner whenPartsNotLocked { - for (uint256 i = 0; i < _bodies.length; i++) { - _addBody(_bodies[i]); - } + function addBackground(string calldata _background) external override onlyOwner whenPartsNotLocked { + _addBackground(_background); } /** - * @notice Batch add Noun accessories. - * @dev This function can only be called by the owner when not locked. + * @notice Add a Noun background. */ - function addManyAccessories(bytes[] calldata _accessories) external override onlyOwner whenPartsNotLocked { - for (uint256 i = 0; i < _accessories.length; i++) { - _addAccessory(_accessories[i]); - } + function _addBackground(string calldata _background) internal { + backgrounds.push(_background); } /** - * @notice Batch add Noun heads. - * @dev This function can only be called by the owner when not locked. + * @notice Update a single color palette. This function can be used to + * add a new color palette or update an existing palette. + * @dev This function can only be called by the descriptor. */ - function addManyHeads(bytes[] calldata _heads) external override onlyOwner whenPartsNotLocked { - for (uint256 i = 0; i < _heads.length; i++) { - _addHead(_heads[i]); + function setPalette(uint8 paletteIndex, bytes calldata palette) external onlyOwner { + if (palette.length == 0) { + revert EmptyPalette(); } + if (palette.length % 3 != 0 || palette.length > 768) { + revert BadPaletteLength(); + } + palettes[paletteIndex] = SSTORE2.write(palette); } - /** - * @notice Batch add Noun glasses. - * @dev This function can only be called by the owner when not locked. - */ - function addManyGlasses(bytes[] calldata _glasses) external override onlyOwner whenPartsNotLocked { - for (uint256 i = 0; i < _glasses.length; i++) { - _addGlasses(_glasses[i]); - } + function addBodies( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external onlyOwner { + addToTrait(_bodies, encodedCompressed, decompressedLength, imageCount); } - /** - * @notice Add a single color to a color palette. - * @dev This function can only be called by the owner. - */ - function addColorToPalette(uint8 _paletteIndex, string calldata _color) external override onlyOwner { - require(palettes[_paletteIndex].length <= 255, 'Palettes can only hold 256 colors'); - _addColorToPalette(_paletteIndex, _color); + function addAccessories( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external onlyOwner { + addToTrait(_accessories, encodedCompressed, decompressedLength, imageCount); } - /** - * @notice Add a Noun background. - * @dev This function can only be called by the owner when not locked. - */ - function addBackground(string calldata _background) external override onlyOwner whenPartsNotLocked { - _addBackground(_background); + function addHeads( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external onlyOwner { + addToTrait(_heads, encodedCompressed, decompressedLength, imageCount); } - /** - * @notice Add a Noun body. - * @dev This function can only be called by the owner when not locked. - */ - function addBody(bytes calldata _body) external override onlyOwner whenPartsNotLocked { - _addBody(_body); + function addGlasses( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external onlyOwner { + addToTrait(_glasses, encodedCompressed, decompressedLength, imageCount); } - /** - * @notice Add a Noun accessory. - * @dev This function can only be called by the owner when not locked. - */ - function addAccessory(bytes calldata _accessory) external override onlyOwner whenPartsNotLocked { - _addAccessory(_accessory); + function retireBody(uint256 virtualIndex) external onlyOwner { + retireTraitImage(_bodies, virtualIndex); } - /** - * @notice Add a Noun head. - * @dev This function can only be called by the owner when not locked. - */ - function addHead(bytes calldata _head) external override onlyOwner whenPartsNotLocked { - _addHead(_head); + function retireAccessory(uint256 virtualIndex) external onlyOwner { + retireTraitImage(_accessories, virtualIndex); } - /** - * @notice Add Noun glasses. - * @dev This function can only be called by the owner when not locked. - */ - function addGlasses(bytes calldata _glasses) external override onlyOwner whenPartsNotLocked { - _addGlasses(_glasses); + function retireHead(uint256 virtualIndex) external onlyOwner { + retireTraitImage(_heads, virtualIndex); + } + + function retireGlasses(uint256 virtualIndex) external onlyOwner { + retireTraitImage(_glasses, virtualIndex); + } + + function bodyStorageIndex(uint256 virtualIndex) external view returns (uint256) { + return traitStorageIndex(_bodies, virtualIndex); + } + + function accessoryStorageIndex(uint256 virtualIndex) external view returns (uint256) { + return traitStorageIndex(_accessories, virtualIndex); + } + + function headStorageIndex(uint256 virtualIndex) external view returns (uint256) { + return traitStorageIndex(_heads, virtualIndex); + } + + function glassesStorageIndex(uint256 virtualIndex) external view returns (uint256) { + return traitStorageIndex(_glasses, virtualIndex); + } + + function traitStorageIndex(Trait storage trait, uint256 virtualIndex) internal view returns (uint256) { + return trait.virtualIndexToStorageIndex[virtualIndex]; + } + + function headsPageCount() public view returns (uint256) { + return _heads.storagePages.length; + } + + function bodiesPageCount() public view returns (uint256) { + return _bodies.storagePages.length; + } + + function accessoriesPageCount() public view returns (uint256) { + return _accessories.storagePages.length; + } + + function glassesPageCount() public view returns (uint256) { + return _glasses.storagePages.length; + } + + function headsPage(uint256 pageIndex) public view returns (NounArtStoragePage memory) { + return _heads.storagePages[pageIndex]; + } + + function bodiesPage(uint256 pageIndex) public view returns (NounArtStoragePage memory) { + return _bodies.storagePages[pageIndex]; + } + + function accessoriesPage(uint256 pageIndex) public view returns (NounArtStoragePage memory) { + return _accessories.storagePages[pageIndex]; + } + + function glassesPage(uint256 pageIndex) public view returns (NounArtStoragePage memory) { + return _glasses.storagePages[pageIndex]; + } + + function heads(uint256 storageIndex) public view returns (bytes memory) { + return imageByStorageIndex(_heads, storageIndex); + } + + function bodies(uint256 storageIndex) public view returns (bytes memory) { + return imageByStorageIndex(_bodies, storageIndex); + } + + function accessories(uint256 storageIndex) public view returns (bytes memory) { + return imageByStorageIndex(_accessories, storageIndex); + } + + function glasses(uint256 storageIndex) public view returns (bytes memory) { + return imageByStorageIndex(_glasses, storageIndex); } /** @@ -278,74 +344,111 @@ contract NounsDescriptor is INounsDescriptor, Ownable { NFTDescriptor.TokenURIParams memory params = NFTDescriptor.TokenURIParams({ name: name, description: description, - parts: _getPartsForSeed(seed), + parts: getPartsForSeed(seed), background: backgrounds[seed.background] }); - return NFTDescriptor.constructTokenURI(params, palettes); + return NFTDescriptor.constructTokenURI(renderer, params); } /** * @notice Given a seed, construct a base64 encoded SVG image. */ function generateSVGImage(INounsSeeder.Seed memory seed) external view override returns (string memory) { - MultiPartRLEToSVG.SVGParams memory params = MultiPartRLEToSVG.SVGParams({ - parts: _getPartsForSeed(seed), + ISVGRenderer.SVGParams memory params = ISVGRenderer.SVGParams({ + parts: getPartsForSeed(seed), background: backgrounds[seed.background] }); - return NFTDescriptor.generateSVGImage(params, palettes); + return NFTDescriptor.generateSVGImage(renderer, params); } /** - * @notice Add a single color to a color palette. + * @notice Get all Noun parts for the passed `seed`. */ - function _addColorToPalette(uint8 _paletteIndex, string calldata _color) internal { - palettes[_paletteIndex].push(_color); + function getPartsForSeed(INounsSeeder.Seed memory seed) public view returns (ISVGRenderer.Part[] memory) { + bytes memory _body = bodies(seed.body); + bytes memory _accessory = accessories(seed.accessory); + bytes memory _head = heads(seed.head); + bytes memory _glassesBytes = glasses(seed.glasses); + + ISVGRenderer.Part[] memory _parts = new ISVGRenderer.Part[](4); + _parts[0] = ISVGRenderer.Part({ image: _body, palette: _getPalette(_body) }); + _parts[1] = ISVGRenderer.Part({ image: _accessory, palette: _getPalette(_accessory) }); + _parts[2] = ISVGRenderer.Part({ image: _head, palette: _getPalette(_head) }); + _parts[3] = ISVGRenderer.Part({ image: _glassesBytes, palette: _getPalette(_glassesBytes) }); + return _parts; } /** - * @notice Add a Noun background. + * @notice Get the color palette pointer for the passed part. */ - function _addBackground(string calldata _background) internal { - backgrounds.push(_background); + function _getPalette(bytes memory part) private view returns (address) { + return palettes[uint8(part[0])]; } - /** - * @notice Add a Noun body. - */ - function _addBody(bytes calldata _body) internal { - bodies.push(_body); + function imageByStorageIndex(Trait storage trait, uint256 storageIndex) internal view returns (bytes memory) { + (NounArtStoragePage storage page, uint256 pageFirstImageIndex) = getPage(trait.storagePages, storageIndex); + bytes[] memory decompressedImages = decompressAndDecode(page); + return decompressedImages[storageIndex - pageFirstImageIndex]; } - /** - * @notice Add a Noun accessory. - */ - function _addAccessory(bytes calldata _accessory) internal { - accessories.push(_accessory); + function getPage(NounArtStoragePage[] storage pages, uint256 storageIndex) + internal + view + returns (NounArtStoragePage storage, uint256) + { + uint256 len = pages.length; + if (len == 0) { + revert NoPages(); + } + + uint256 pageFirstImageIndex = 0; + for (uint256 i = 0; i < len; i++) { + NounArtStoragePage storage page = pages[i]; + + if (storageIndex < pageFirstImageIndex + page.imageCount) { + return (page, pageFirstImageIndex); + } + + pageFirstImageIndex += page.imageCount; + } + + revert ImageNotFound(); } - /** - * @notice Add a Noun head. - */ - function _addHead(bytes calldata _head) internal { - heads.push(_head); + function decompressAndDecode(NounArtStoragePage storage page) internal view returns (bytes[] memory) { + bytes memory compressedData = SSTORE2.read(page.pointer); + (, bytes memory decompressedData) = Inflate.puff(compressedData, page.decompressedLength); + return abi.decode(decompressedData, (bytes[])); } - /** - * @notice Add Noun glasses. - */ - function _addGlasses(bytes calldata _glasses) internal { - glasses.push(_glasses); + function addToTrait( + Trait storage trait, + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) internal { + trait.storagePages.push( + NounArtStoragePage({ + pointer: SSTORE2.write(encodedCompressed), + decompressedLength: decompressedLength, + imageCount: imageCount + }) + ); + + uint256 storedImageCount = trait.storedImagesCount; + + for (uint256 i = 0; i < imageCount; i++) { + trait.virtualIndexToStorageIndex.push(storedImageCount + i); + } + + trait.storedImagesCount += imageCount; } - /** - * @notice Get all Noun parts for the passed `seed`. - */ - function _getPartsForSeed(INounsSeeder.Seed memory seed) internal view returns (bytes[] memory) { - bytes[] memory _parts = new bytes[](4); - _parts[0] = bodies[seed.body]; - _parts[1] = accessories[seed.accessory]; - _parts[2] = heads[seed.head]; - _parts[3] = glasses[seed.glasses]; - return _parts; + function retireTraitImage(Trait storage trait, uint256 virtualIndex) internal { + trait.virtualIndexToStorageIndex[virtualIndex] = trait.virtualIndexToStorageIndex[ + trait.virtualIndexToStorageIndex.length - 1 + ]; + + trait.virtualIndexToStorageIndex.pop(); } } diff --git a/packages/nouns-contracts/contracts/NounsSeeder.sol b/packages/nouns-contracts/contracts/NounsSeeder.sol index 099d8aca64..4f57ada5e5 100644 --- a/packages/nouns-contracts/contracts/NounsSeeder.sol +++ b/packages/nouns-contracts/contracts/NounsSeeder.sol @@ -15,7 +15,7 @@ * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ -pragma solidity ^0.8.6; +pragma solidity ^0.8.12; import { INounsSeeder } from './interfaces/INounsSeeder.sol'; import { INounsDescriptor } from './interfaces/INounsDescriptor.sol'; @@ -41,16 +41,16 @@ contract NounsSeeder is INounsSeeder { uint48(pseudorandomness) % backgroundCount ), body: uint48( - uint48(pseudorandomness >> 48) % bodyCount + descriptor.bodyStorageIndex(uint48(pseudorandomness >> 48) % bodyCount) ), accessory: uint48( - uint48(pseudorandomness >> 96) % accessoryCount + descriptor.accessoryStorageIndex(uint48(pseudorandomness >> 96) % accessoryCount) ), head: uint48( - uint48(pseudorandomness >> 144) % headCount + descriptor.headStorageIndex(uint48(pseudorandomness >> 144) % headCount) ), glasses: uint48( - uint48(pseudorandomness >> 192) % glassesCount + descriptor.glassesStorageIndex(uint48(pseudorandomness >> 192) % glassesCount) ) }); } diff --git a/packages/nouns-contracts/contracts/NounsToken.sol b/packages/nouns-contracts/contracts/NounsToken.sol index 19350477a1..efbaaa7e82 100644 --- a/packages/nouns-contracts/contracts/NounsToken.sol +++ b/packages/nouns-contracts/contracts/NounsToken.sol @@ -15,7 +15,7 @@ * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ -pragma solidity ^0.8.6; +pragma solidity ^0.8.12; import { Ownable } from '@openzeppelin/contracts/access/Ownable.sol'; import { ERC721Checkpointable } from './base/ERC721Checkpointable.sol'; diff --git a/packages/nouns-contracts/contracts/SVGRenderer.sol b/packages/nouns-contracts/contracts/SVGRenderer.sol new file mode 100644 index 0000000000..f7a400fc7b --- /dev/null +++ b/packages/nouns-contracts/contracts/SVGRenderer.sol @@ -0,0 +1,238 @@ +// SPDX-License-Identifier: GPL-3.0 + +/// @title A contract used to convert multi-part RLE compressed images to SVG + +/********************************* + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░██░░░████░░██░░░████░░░ * + * ░░██████░░░████████░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + *********************************/ + +pragma solidity ^0.8.12; + +import { ISVGRenderer } from './interfaces/ISVGRenderer.sol'; +import { SSTORE2 } from './libs/SSTORE2.sol'; + +contract SVGRenderer is ISVGRenderer { + bytes16 private constant _HEX_SYMBOLS = '0123456789abcdef'; + uint256 private constant _INDEX_TO_BYTES3_FACTOR = 3; + + // prettier-ignore + string private constant _SVG_START_TAG = ''; + string private constant _SVG_END_TAG = ''; + + struct ContentBounds { + uint8 top; + uint8 right; + uint8 bottom; + uint8 left; + } + + struct Draw { + uint8 length; + uint8 colorIndex; + } + + struct DecodedImage { + ContentBounds bounds; + Draw[] draws; + } + + /** + * @notice Given RLE image data and color palette pointers, merge to generate a single SVG image. + */ + function generateSVG(SVGParams calldata params) external view returns (string memory svg) { + if (bytes(params.background).length != 0) { + // prettier-ignore + return string( + abi.encodePacked( + _SVG_START_TAG, + '', + _generateSVGRects(params), + _SVG_END_TAG + ) + ); + } + return string(abi.encodePacked(_SVG_START_TAG, _generateSVGRects(params), _SVG_END_TAG)); + } + + /** + * @notice Given RLE image data and a color palette pointer, merge to generate a partial SVG image. + */ + function generateSVGPart(Part calldata part) external view returns (string memory partialSVG) { + Part[] memory parts = new Part[](1); + parts[0] = part; + + return _generateSVGRects(SVGParams({ parts: parts, background: '' })); + } + + /** + * @notice Given RLE image data and color palette pointers, merge to generate a partial SVG image. + */ + function generateSVGParts(Part[] calldata parts) external view returns (string memory partialSVG) { + return _generateSVGRects(SVGParams({ parts: parts, background: '' })); + } + + /** + * @notice Given RLE image parts and color palettes, generate SVG rects. + */ + // prettier-ignore + function _generateSVGRects(SVGParams memory params) + private + view + returns (string memory svg) + { + string[33] memory lookup = [ + '0', '10', '20', '30', '40', '50', '60', '70', + '80', '90', '100', '110', '120', '130', '140', '150', + '160', '170', '180', '190', '200', '210', '220', '230', + '240', '250', '260', '270', '280', '290', '300', '310', + '320' + ]; + string memory rects; + string[] memory cache; + for (uint8 p = 0; p < params.parts.length; p++) { + cache = new string[](256); // Initialize color cache + + DecodedImage memory image = _decodeRLEImage(params.parts[p].image); + bytes memory palette = _getPalette(params.parts[p].palette); + uint256 currentX = image.bounds.left; + uint256 currentY = image.bounds.top; + uint256 cursor; + string[16] memory buffer; + + string memory part; + for (uint256 i = 0; i < image.draws.length; i++) { + Draw memory draw = image.draws[i]; + + uint8 length = _getRectLength(currentX, draw.length, image.bounds.right); + while (length > 0) { + if (draw.colorIndex != 0) { + buffer[cursor] = lookup[length]; // width + buffer[cursor + 1] = lookup[currentX]; // x + buffer[cursor + 2] = lookup[currentY]; // y + buffer[cursor + 3] = _getColor(palette, draw.colorIndex, cache); // color + + cursor += 4; + + if (cursor >= 16) { + part = string(abi.encodePacked(part, _getChunk(cursor, buffer))); + cursor = 0; + } + } + + currentX += length; + if (currentX == image.bounds.right) { + currentX = image.bounds.left; + currentY++; + } + + draw.length -= length; + length = _getRectLength(currentX, draw.length, image.bounds.right); + } + } + + if (cursor != 0) { + part = string(abi.encodePacked(part, _getChunk(cursor, buffer))); + } + rects = string(abi.encodePacked(rects, part)); + } + return rects; + } + + /** + * @notice Given an x-coordinate, draw length, and right bound, return the draw + * length for a single SVG rectangle. + */ + function _getRectLength( + uint256 currentX, + uint8 drawLength, + uint8 rightBound + ) private pure returns (uint8) { + uint8 remainingPixelsInLine = rightBound - uint8(currentX); + return drawLength <= remainingPixelsInLine ? drawLength : remainingPixelsInLine; + } + + /** + * @notice Return a string that consists of all rects in the provided `buffer`. + */ + // prettier-ignore + function _getChunk(uint256 cursor, string[16] memory buffer) private pure returns (string memory) { + string memory chunk; + for (uint256 i = 0; i < cursor; i += 4) { + chunk = string( + abi.encodePacked( + chunk, + '' + ) + ); + } + return chunk; + } + + /** + * @notice Decode a single RLE compressed image into a `DecodedImage`. + */ + function _decodeRLEImage(bytes memory image) private pure returns (DecodedImage memory) { + ContentBounds memory bounds = ContentBounds({ + top: uint8(image[1]), + right: uint8(image[2]), + bottom: uint8(image[3]), + left: uint8(image[4]) + }); + + uint256 cursor; + Draw[] memory draws = new Draw[]((image.length - 5) / 2); + for (uint256 i = 5; i < image.length; i += 2) { + draws[cursor] = Draw({ length: uint8(image[i]), colorIndex: uint8(image[i + 1]) }); + cursor++; + } + return DecodedImage({ bounds: bounds, draws: draws }); + } + + /** + * @notice Fetch the color palette stored at the provided `pointer`. + */ + function _getPalette(address pointer) private view returns (bytes memory palette) { + palette = SSTORE2.read(pointer); + } + + /** + * @notice Get the target hex color code from the cache. Populate the cache if + * the color code does not yet exist. + */ + function _getColor( + bytes memory palette, + uint256 index, + string[] memory cache + ) private pure returns (string memory) { + if (bytes(cache[index]).length == 0) { + uint256 i = index * _INDEX_TO_BYTES3_FACTOR; + cache[index] = _toHexString(abi.encodePacked(palette[i], palette[i + 1], palette[i + 2])); + } + return cache[index]; + } + + /** + * @dev Convert `bytes` to a 6 character ASCII `string` hexadecimal representation. + */ + function _toHexString(bytes memory b) private pure returns (string memory) { + uint24 value = uint24(bytes3(b)); + + bytes memory buffer = new bytes(6); + buffer[5] = _HEX_SYMBOLS[value & 0xf]; + buffer[4] = _HEX_SYMBOLS[(value >> 4) & 0xf]; + buffer[3] = _HEX_SYMBOLS[(value >> 8) & 0xf]; + buffer[2] = _HEX_SYMBOLS[(value >> 12) & 0xf]; + buffer[1] = _HEX_SYMBOLS[(value >> 16) & 0xf]; + buffer[0] = _HEX_SYMBOLS[(value >> 20) & 0xf]; + return string(buffer); + } +} diff --git a/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol b/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol index 5cd1da52c6..a980310c36 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol @@ -18,6 +18,7 @@ pragma solidity ^0.8.6; import { INounsSeeder } from './INounsSeeder.sol'; +import { ISVGRenderer } from './ISVGRenderer.sol'; interface INounsDescriptor { event PartsLocked(); @@ -26,13 +27,32 @@ interface INounsDescriptor { event BaseURIUpdated(string baseURI); + event RendererUpdated(ISVGRenderer renderer); + + error EmptyPalette(); + error BadPaletteLength(); + error NoPages(); + error ImageNotFound(); + + struct NounArtStoragePage { + uint16 imageCount; + uint80 decompressedLength; + address pointer; + } + + struct Trait { + NounArtStoragePage[] storagePages; + uint256[] virtualIndexToStorageIndex; + uint256 storedImagesCount; + } + function arePartsLocked() external returns (bool); function isDataURIEnabled() external returns (bool); function baseURI() external returns (string memory); - function palettes(uint8 paletteIndex, uint256 colorIndex) external view returns (string memory); + function palettes(uint8 paletteIndex) external view returns (address); function backgrounds(uint256 index) external view returns (string memory); @@ -54,29 +74,67 @@ interface INounsDescriptor { function glassesCount() external view returns (uint256); - function addManyColorsToPalette(uint8 paletteIndex, string[] calldata newColors) external; + function headsPageCount() external view returns (uint256); - function addManyBackgrounds(string[] calldata backgrounds) external; + function bodiesPageCount() external view returns (uint256); - function addManyBodies(bytes[] calldata bodies) external; + function accessoriesPageCount() external view returns (uint256); - function addManyAccessories(bytes[] calldata accessories) external; + function glassesPageCount() external view returns (uint256); - function addManyHeads(bytes[] calldata heads) external; + function headsPage(uint256 pageIndex) external view returns (NounArtStoragePage memory); - function addManyGlasses(bytes[] calldata glasses) external; + function bodiesPage(uint256 pageIndex) external view returns (NounArtStoragePage memory); - function addColorToPalette(uint8 paletteIndex, string calldata color) external; + function accessoriesPage(uint256 pageIndex) external view returns (NounArtStoragePage memory); + + function glassesPage(uint256 pageIndex) external view returns (NounArtStoragePage memory); + + function addManyBackgrounds(string[] calldata backgrounds) external; function addBackground(string calldata background) external; - function addBody(bytes calldata body) external; + function setPalette(uint8 paletteIndex, bytes calldata palette) external; + + function addBodies( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function addAccessories( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function addHeads( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function addGlasses( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function retireBody(uint256 virtualIndex) external; + + function retireAccessory(uint256 virtualIndex) external; + + function retireHead(uint256 virtualIndex) external; + + function retireGlasses(uint256 virtualIndex) external; + + function bodyStorageIndex(uint256 virtualIndex) external view returns (uint256); - function addAccessory(bytes calldata accessory) external; + function accessoryStorageIndex(uint256 virtualIndex) external view returns (uint256); - function addHead(bytes calldata head) external; + function headStorageIndex(uint256 virtualIndex) external view returns (uint256); - function addGlasses(bytes calldata glasses) external; + function glassesStorageIndex(uint256 virtualIndex) external view returns (uint256); function lockParts() external; diff --git a/packages/nouns-contracts/contracts/interfaces/ISVGRenderer.sol b/packages/nouns-contracts/contracts/interfaces/ISVGRenderer.sol new file mode 100644 index 0000000000..9cab82ae36 --- /dev/null +++ b/packages/nouns-contracts/contracts/interfaces/ISVGRenderer.sol @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-3.0 + +/// @title Interface for SVGRenderer + +/********************************* + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░██░░░████░░██░░░████░░░ * + * ░░██████░░░████████░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + *********************************/ + +pragma solidity ^0.8.12; + +// TODO: Generalize to `IRenderer`? +// May be a day when we drop SVG support. + +interface ISVGRenderer { + struct Part { + bytes image; + address palette; + } + + struct SVGParams { + Part[] parts; + string background; + } + + function generateSVG(SVGParams memory params) external view returns (string memory svg); + + function generateSVGPart(Part memory part) external view returns (string memory partialSVG); + + function generateSVGParts(Part[] memory parts) external view returns (string memory partialSVG); +} diff --git a/packages/nouns-contracts/contracts/libs/Inflate.sol b/packages/nouns-contracts/contracts/libs/Inflate.sol new file mode 100644 index 0000000000..f65c31ff0e --- /dev/null +++ b/packages/nouns-contracts/contracts/libs/Inflate.sol @@ -0,0 +1,924 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.0 <0.9.0; + +/// @notice Based on https://github.com/madler/zlib/blob/master/contrib/puff +library Inflate { + // Maximum bits in a code + uint256 constant MAXBITS = 15; + // Maximum number of literal/length codes + uint256 constant MAXLCODES = 286; + // Maximum number of distance codes + uint256 constant MAXDCODES = 30; + // Maximum codes lengths to read + uint256 constant MAXCODES = (MAXLCODES + MAXDCODES); + // Number of fixed literal/length codes + uint256 constant FIXLCODES = 288; + + // Error codes + enum ErrorCode { + ERR_NONE, // 0 successful inflate + ERR_NOT_TERMINATED, // 1 available inflate data did not terminate + ERR_OUTPUT_EXHAUSTED, // 2 output space exhausted before completing inflate + ERR_INVALID_BLOCK_TYPE, // 3 invalid block type (type == 3) + ERR_STORED_LENGTH_NO_MATCH, // 4 stored block length did not match one's complement + ERR_TOO_MANY_LENGTH_OR_DISTANCE_CODES, // 5 dynamic block code description: too many length or distance codes + ERR_CODE_LENGTHS_CODES_INCOMPLETE, // 6 dynamic block code description: code lengths codes incomplete + ERR_REPEAT_NO_FIRST_LENGTH, // 7 dynamic block code description: repeat lengths with no first length + ERR_REPEAT_MORE, // 8 dynamic block code description: repeat more than specified lengths + ERR_INVALID_LITERAL_LENGTH_CODE_LENGTHS, // 9 dynamic block code description: invalid literal/length code lengths + ERR_INVALID_DISTANCE_CODE_LENGTHS, // 10 dynamic block code description: invalid distance code lengths + ERR_MISSING_END_OF_BLOCK, // 11 dynamic block code description: missing end-of-block code + ERR_INVALID_LENGTH_OR_DISTANCE_CODE, // 12 invalid literal/length or distance code in fixed or dynamic block + ERR_DISTANCE_TOO_FAR, // 13 distance is too far back in fixed or dynamic block + ERR_CONSTRUCT // 14 internal: error in construct() + } + + // Input and output state + struct State { + ////////////////// + // Output state // + ////////////////// + // Output buffer + bytes output; + // Bytes written to out so far + uint256 outcnt; + ///////////////// + // Input state // + ///////////////// + // Input buffer + bytes input; + // Bytes read so far + uint256 incnt; + //////////////// + // Temp state // + //////////////// + // Bit buffer + uint256 bitbuf; + // Number of bits in bit buffer + uint256 bitcnt; + ////////////////////////// + // Static Huffman codes // + ////////////////////////// + Huffman lencode; + Huffman distcode; + } + + // Huffman code decoding tables + struct Huffman { + uint256[] counts; + uint256[] symbols; + } + + function bits(State memory s, uint256 need) + private + pure + returns (ErrorCode, uint256) + { + unchecked { + // Bit accumulator (can use up to 20 bits) + uint256 val; + + // Load at least need bits into val + val = s.bitbuf; + while (s.bitcnt < need) { + if (s.incnt == s.input.length) { + // Out of input + return (ErrorCode.ERR_NOT_TERMINATED, 0); + } + + // Load eight bits + val |= uint256(uint8(s.input[s.incnt++])) << s.bitcnt; + s.bitcnt += 8; + } + + // Drop need bits and update buffer, always zero to seven bits left + s.bitbuf = val >> need; + s.bitcnt -= need; + + // Return need bits, zeroing the bits above that + uint256 ret = (val & ((1 << need) - 1)); + return (ErrorCode.ERR_NONE, ret); + } + } + + function _stored(State memory s) private pure returns (ErrorCode) { + unchecked { + // Length of stored block + uint256 len; + + // Discard leftover bits from current byte (assumes s.bitcnt < 8) + s.bitbuf = 0; + s.bitcnt = 0; + + // Get length and check against its one's complement + if (s.incnt + 4 > s.input.length) { + // Not enough input + return ErrorCode.ERR_NOT_TERMINATED; + } + len = uint256(uint8(s.input[s.incnt++])); + len |= uint256(uint8(s.input[s.incnt++])) << 8; + + if ( + uint8(s.input[s.incnt++]) != (~len & 0xFF) || + uint8(s.input[s.incnt++]) != ((~len >> 8) & 0xFF) + ) { + // Didn't match complement! + return ErrorCode.ERR_STORED_LENGTH_NO_MATCH; + } + + // Copy len bytes from in to out + if (s.incnt + len > s.input.length) { + // Not enough input + return ErrorCode.ERR_NOT_TERMINATED; + } + if (s.outcnt + len > s.output.length) { + // Not enough output space + return ErrorCode.ERR_OUTPUT_EXHAUSTED; + } + while (len != 0) { + // Note: Solidity reverts on underflow, so we decrement here + len -= 1; + s.output[s.outcnt++] = s.input[s.incnt++]; + } + + // Done with a valid stored block + return ErrorCode.ERR_NONE; + } + } + + function _decode(State memory s, Huffman memory h) + private + pure + returns (ErrorCode, uint256) + { + unchecked { + // Current number of bits in code + uint256 len; + // Len bits being decoded + uint256 code = 0; + // First code of length len + uint256 first = 0; + // Number of codes of length len + uint256 count; + // Index of first code of length len in symbol table + uint256 index = 0; + // Error code + ErrorCode err; + + uint256 tempCode; + for (len = 1; len <= MAXBITS; len += 5) { + // Get next bit + (err, tempCode) = bits(s, 1); + if (err != ErrorCode.ERR_NONE) { + return (err, 0); + } + code |= tempCode; + count = h.counts[len]; + + // If length len, return symbol + if (code < first + count) { + return (ErrorCode.ERR_NONE, h.symbols[index + (code - first)]); + } + // Else update for next length + index += count; + first += count; + first <<= 1; + code <<= 1; + + // Get next bit + (err, tempCode) = bits(s, 1); + if (err != ErrorCode.ERR_NONE) { + return (err, 0); + } + code |= tempCode; + count = h.counts[len + 1]; + + // If length len, return symbol + if (code < first + count) { + return (ErrorCode.ERR_NONE, h.symbols[index + (code - first)]); + } + // Else update for next length + index += count; + first += count; + first <<= 1; + code <<= 1; + + // Get next bit + (err, tempCode) = bits(s, 1); + if (err != ErrorCode.ERR_NONE) { + return (err, 0); + } + code |= tempCode; + count = h.counts[len + 2]; + + // If length len, return symbol + if (code < first + count) { + return (ErrorCode.ERR_NONE, h.symbols[index + (code - first)]); + } + // Else update for next length + index += count; + first += count; + first <<= 1; + code <<= 1; + + // Get next bit + (err, tempCode) = bits(s, 1); + if (err != ErrorCode.ERR_NONE) { + return (err, 0); + } + code |= tempCode; + count = h.counts[len + 3]; + + // If length len, return symbol + if (code < first + count) { + return (ErrorCode.ERR_NONE, h.symbols[index + (code - first)]); + } + // Else update for next length + index += count; + first += count; + first <<= 1; + code <<= 1; + + // Get next bit + (err, tempCode) = bits(s, 1); + if (err != ErrorCode.ERR_NONE) { + return (err, 0); + } + code |= tempCode; + count = h.counts[len + 4]; + + // If length len, return symbol + if (code < first + count) { + return (ErrorCode.ERR_NONE, h.symbols[index + (code - first)]); + } + // Else update for next length + index += count; + first += count; + first <<= 1; + code <<= 1; + } + + // Ran out of codes + return (ErrorCode.ERR_INVALID_LENGTH_OR_DISTANCE_CODE, 0); + } + } + + function _construct( + Huffman memory h, + uint256[] memory lengths, + uint256 n, + uint256 start + ) private pure returns (ErrorCode) { + unchecked { + // Current symbol when stepping through lengths[] + uint256 symbol; + // Current length when stepping through h.counts[] + uint256 len; + // Number of possible codes left of current length + uint256 left; + // Offsets in symbol table for each length + uint256[MAXBITS + 1] memory offs; + + // Count number of codes of each length + for (len = 0; len <= MAXBITS; ++len) { + h.counts[len] = 0; + } + for (symbol = 0; symbol < n; ++symbol) { + // Assumes lengths are within bounds + ++h.counts[lengths[start + symbol]]; + } + // No codes! + if (h.counts[0] == n) { + // Complete, but decode() will fail + return (ErrorCode.ERR_NONE); + } + + // Check for an over-subscribed or incomplete set of lengths + + // One possible code of zero length + left = 1; + + for (len = 1; len <= MAXBITS; len += 5) { + // One more bit, double codes left + left <<= 1; + if (left < h.counts[len]) { + // Over-subscribed--return error + return ErrorCode.ERR_CONSTRUCT; + } + // Deduct count from possible codes + left -= h.counts[len]; + + // One more bit, double codes left + left <<= 1; + if (left < h.counts[len + 1]) { + // Over-subscribed--return error + return ErrorCode.ERR_CONSTRUCT; + } + // Deduct count from possible codes + left -= h.counts[len + 1]; + + // One more bit, double codes left + left <<= 1; + if (left < h.counts[len + 2]) { + // Over-subscribed--return error + return ErrorCode.ERR_CONSTRUCT; + } + // Deduct count from possible codes + left -= h.counts[len + 2]; + + // One more bit, double codes left + left <<= 1; + if (left < h.counts[len + 3]) { + // Over-subscribed--return error + return ErrorCode.ERR_CONSTRUCT; + } + // Deduct count from possible codes + left -= h.counts[len + 3]; + + // One more bit, double codes left + left <<= 1; + if (left < h.counts[len + 4]) { + // Over-subscribed--return error + return ErrorCode.ERR_CONSTRUCT; + } + // Deduct count from possible codes + left -= h.counts[len + 4]; + } + + // Generate offsets into symbol table for each length for sorting + offs[1] = 0; + for (len = 1; len < MAXBITS; ++len) { + offs[len + 1] = offs[len] + h.counts[len]; + } + + // Put symbols in table sorted by length, by symbol order within each length + for (symbol = 0; symbol < n; ++symbol) { + if (lengths[start + symbol] != 0) { + h.symbols[offs[lengths[start + symbol]]++] = symbol; + } + } + + // Left > 0 means incomplete + return left > 0 ? ErrorCode.ERR_CONSTRUCT : ErrorCode.ERR_NONE; + } + } + + function _codes( + State memory s, + Huffman memory lencode, + Huffman memory distcode + ) private pure returns (ErrorCode) { + unchecked { + // Decoded symbol + uint256 symbol; + // Length for copy + uint256 len; + // Distance for copy + uint256 dist; + // TODO Solidity doesn't support constant arrays, but these are fixed at compile-time + // Size base for length codes 257..285 + uint16[29] memory lens = [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 13, + 15, + 17, + 19, + 23, + 27, + 31, + 35, + 43, + 51, + 59, + 67, + 83, + 99, + 115, + 131, + 163, + 195, + 227, + 258 + ]; + // Extra bits for length codes 257..285 + uint8[29] memory lext = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 2, + 2, + 2, + 2, + 3, + 3, + 3, + 3, + 4, + 4, + 4, + 4, + 5, + 5, + 5, + 5, + 0 + ]; + // Offset base for distance codes 0..29 + uint16[30] memory dists = [ + 1, + 2, + 3, + 4, + 5, + 7, + 9, + 13, + 17, + 25, + 33, + 49, + 65, + 97, + 129, + 193, + 257, + 385, + 513, + 769, + 1025, + 1537, + 2049, + 3073, + 4097, + 6145, + 8193, + 12289, + 16385, + 24577 + ]; + // Extra bits for distance codes 0..29 + uint8[30] memory dext = [ + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 2, + 3, + 3, + 4, + 4, + 5, + 5, + 6, + 6, + 7, + 7, + 8, + 8, + 9, + 9, + 10, + 10, + 11, + 11, + 12, + 12, + 13, + 13 + ]; + // Error code + ErrorCode err; + + // Decode literals and length/distance pairs + while (symbol != 256) { + (err, symbol) = _decode(s, lencode); + if (err != ErrorCode.ERR_NONE) { + // Invalid symbol + return err; + } + + if (symbol < 256) { + // Literal: symbol is the byte + // Write out the literal + if (s.outcnt == s.output.length) { + return ErrorCode.ERR_OUTPUT_EXHAUSTED; + } + s.output[s.outcnt] = bytes1(uint8(symbol)); + ++s.outcnt; + } else if (symbol > 256) { + uint256 tempBits; + // Length + // Get and compute length + symbol -= 257; + if (symbol >= 29) { + // Invalid fixed code + return ErrorCode.ERR_INVALID_LENGTH_OR_DISTANCE_CODE; + } + + (err, tempBits) = bits(s, lext[symbol]); + if (err != ErrorCode.ERR_NONE) { + return err; + } + len = lens[symbol] + tempBits; + + // Get and check distance + (err, symbol) = _decode(s, distcode); + if (err != ErrorCode.ERR_NONE) { + // Invalid symbol + return err; + } + (err, tempBits) = bits(s, dext[symbol]); + if (err != ErrorCode.ERR_NONE) { + return err; + } + dist = dists[symbol] + tempBits; + if (dist > s.outcnt) { + // Distance too far back + return ErrorCode.ERR_DISTANCE_TOO_FAR; + } + + // Copy length bytes from distance bytes back + if (s.outcnt + len > s.output.length) { + return ErrorCode.ERR_OUTPUT_EXHAUSTED; + } + while (len != 0) { + // Note: Solidity reverts on underflow, so we decrement here + len -= 1; + s.output[s.outcnt] = s.output[s.outcnt - dist]; + ++s.outcnt; + } + } else { + s.outcnt += len; + } + } + + // Done with a valid fixed or dynamic block + return ErrorCode.ERR_NONE; + } + } + + function _build_fixed(State memory s) private pure returns (ErrorCode) { + unchecked { + // Build fixed Huffman tables + // TODO this is all a compile-time constant + uint256 symbol; + uint256[] memory lengths = new uint256[](FIXLCODES); + + // Literal/length table + for (symbol = 0; symbol < 144; ++symbol) { + lengths[symbol] = 8; + } + for (; symbol < 256; ++symbol) { + lengths[symbol] = 9; + } + for (; symbol < 280; ++symbol) { + lengths[symbol] = 7; + } + for (; symbol < FIXLCODES; ++symbol) { + lengths[symbol] = 8; + } + + _construct(s.lencode, lengths, FIXLCODES, 0); + + // Distance table + for (symbol = 0; symbol < MAXDCODES; ++symbol) { + lengths[symbol] = 5; + } + + _construct(s.distcode, lengths, MAXDCODES, 0); + + return ErrorCode.ERR_NONE; + } + } + + function _fixed(State memory s) private pure returns (ErrorCode) { + unchecked { + // Decode data until end-of-block code + return _codes(s, s.lencode, s.distcode); + } + } + + function _build_dynamic_lengths(State memory s) + private + pure + returns (ErrorCode, uint256[] memory) + { + unchecked { + uint256 ncode; + // Index of lengths[] + uint256 index; + // Descriptor code lengths + uint256[] memory lengths = new uint256[](MAXCODES); + // Error code + ErrorCode err; + // Permutation of code length codes + uint8[19] memory order = [ + 16, + 17, + 18, + 0, + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15 + ]; + + (err, ncode) = bits(s, 4); + if (err != ErrorCode.ERR_NONE) { + return (err, lengths); + } + ncode += 4; + + // Read code length code lengths (really), missing lengths are zero + for (index = 0; index < ncode; ++index) { + (err, lengths[order[index]]) = bits(s, 3); + if (err != ErrorCode.ERR_NONE) { + return (err, lengths); + } + } + for (; index < 19; ++index) { + lengths[order[index]] = 0; + } + + return (ErrorCode.ERR_NONE, lengths); + } + } + + function _build_dynamic(State memory s) + private + pure + returns ( + ErrorCode, + Huffman memory, + Huffman memory + ) + { + unchecked { + // Number of lengths in descriptor + uint256 nlen; + uint256 ndist; + // Index of lengths[] + uint256 index; + // Error code + ErrorCode err; + // Descriptor code lengths + uint256[] memory lengths = new uint256[](MAXCODES); + // Length and distance codes + Huffman memory lencode = Huffman( + new uint256[](MAXBITS + 1), + new uint256[](MAXLCODES) + ); + Huffman memory distcode = Huffman( + new uint256[](MAXBITS + 1), + new uint256[](MAXDCODES) + ); + uint256 tempBits; + + // Get number of lengths in each table, check lengths + (err, nlen) = bits(s, 5); + if (err != ErrorCode.ERR_NONE) { + return (err, lencode, distcode); + } + nlen += 257; + (err, ndist) = bits(s, 5); + if (err != ErrorCode.ERR_NONE) { + return (err, lencode, distcode); + } + ndist += 1; + + if (nlen > MAXLCODES || ndist > MAXDCODES) { + // Bad counts + return ( + ErrorCode.ERR_TOO_MANY_LENGTH_OR_DISTANCE_CODES, + lencode, + distcode + ); + } + + (err, lengths) = _build_dynamic_lengths(s); + if (err != ErrorCode.ERR_NONE) { + return (err, lencode, distcode); + } + + // Build huffman table for code lengths codes (use lencode temporarily) + err = _construct(lencode, lengths, 19, 0); + if (err != ErrorCode.ERR_NONE) { + // Require complete code set here + return (ErrorCode.ERR_CODE_LENGTHS_CODES_INCOMPLETE, lencode, distcode); + } + + // Read length/literal and distance code length tables + index = 0; + while (index < nlen + ndist) { + // Decoded value + uint256 symbol; + // Last length to repeat + uint256 len; + + (err, symbol) = _decode(s, lencode); + if (err != ErrorCode.ERR_NONE) { + // Invalid symbol + return (err, lencode, distcode); + } + + if (symbol < 16) { + // Length in 0..15 + lengths[index++] = symbol; + } else { + // Repeat instruction + // Assume repeating zeros + len = 0; + if (symbol == 16) { + // Repeat last length 3..6 times + if (index == 0) { + // No last length! + return (ErrorCode.ERR_REPEAT_NO_FIRST_LENGTH, lencode, distcode); + } + // Last length + len = lengths[index - 1]; + (err, tempBits) = bits(s, 2); + if (err != ErrorCode.ERR_NONE) { + return (err, lencode, distcode); + } + symbol = 3 + tempBits; + } else if (symbol == 17) { + // Repeat zero 3..10 times + (err, tempBits) = bits(s, 3); + if (err != ErrorCode.ERR_NONE) { + return (err, lencode, distcode); + } + symbol = 3 + tempBits; + } else { + // == 18, repeat zero 11..138 times + (err, tempBits) = bits(s, 7); + if (err != ErrorCode.ERR_NONE) { + return (err, lencode, distcode); + } + symbol = 11 + tempBits; + } + + if (index + symbol > nlen + ndist) { + // Too many lengths! + return (ErrorCode.ERR_REPEAT_MORE, lencode, distcode); + } + while (symbol != 0) { + // Note: Solidity reverts on underflow, so we decrement here + symbol -= 1; + + // Repeat last or zero symbol times + lengths[index++] = len; + } + } + } + + // Check for end-of-block code -- there better be one! + if (lengths[256] == 0) { + return (ErrorCode.ERR_MISSING_END_OF_BLOCK, lencode, distcode); + } + + // Build huffman table for literal/length codes + err = _construct(lencode, lengths, nlen, 0); + if ( + err != ErrorCode.ERR_NONE && + (err == ErrorCode.ERR_NOT_TERMINATED || + err == ErrorCode.ERR_OUTPUT_EXHAUSTED || + nlen != lencode.counts[0] + lencode.counts[1]) + ) { + // Incomplete code ok only for single length 1 code + return ( + ErrorCode.ERR_INVALID_LITERAL_LENGTH_CODE_LENGTHS, + lencode, + distcode + ); + } + + // Build huffman table for distance codes + err = _construct(distcode, lengths, ndist, nlen); + if ( + err != ErrorCode.ERR_NONE && + (err == ErrorCode.ERR_NOT_TERMINATED || + err == ErrorCode.ERR_OUTPUT_EXHAUSTED || + ndist != distcode.counts[0] + distcode.counts[1]) + ) { + // Incomplete code ok only for single length 1 code + return (ErrorCode.ERR_INVALID_DISTANCE_CODE_LENGTHS, lencode, distcode); + } + + return (ErrorCode.ERR_NONE, lencode, distcode); + } + } + + function _dynamic(State memory s) private pure returns (ErrorCode) { + unchecked { + // Length and distance codes + Huffman memory lencode; + Huffman memory distcode; + // Error code + ErrorCode err; + + (err, lencode, distcode) = _build_dynamic(s); + if (err != ErrorCode.ERR_NONE) { + return err; + } + + // Decode data until end-of-block code + return _codes(s, lencode, distcode); + } + } + + function puff(bytes memory source, uint256 destlen) + internal + pure + returns (ErrorCode, bytes memory) + { + unchecked { + // Input/output state + State memory s = State( + new bytes(destlen), + 0, + source, + 0, + 0, + 0, + Huffman(new uint256[](MAXBITS + 1), new uint256[](FIXLCODES)), + Huffman(new uint256[](MAXBITS + 1), new uint256[](MAXDCODES)) + ); + // Temp: last bit + uint256 last; + // Temp: block type bit + uint256 t; + // Error code + ErrorCode err; + + // Build fixed Huffman tables + err = _build_fixed(s); + if (err != ErrorCode.ERR_NONE) { + return (err, s.output); + } + + // Process blocks until last block or error + while (last == 0) { + // One if last block + (err, last) = bits(s, 1); + if (err != ErrorCode.ERR_NONE) { + return (err, s.output); + } + + // Block type 0..3 + (err, t) = bits(s, 2); + if (err != ErrorCode.ERR_NONE) { + return (err, s.output); + } + + err = ( + t == 0 + ? _stored(s) + : ( + t == 1 + ? _fixed(s) + : (t == 2 ? _dynamic(s) : ErrorCode.ERR_INVALID_BLOCK_TYPE) + ) + ); + // type == 3, invalid + + if (err != ErrorCode.ERR_NONE) { + // Return with error + break; + } + } + + return (err, s.output); + } + } +} diff --git a/packages/nouns-contracts/contracts/libs/NFTDescriptor.sol b/packages/nouns-contracts/contracts/libs/NFTDescriptor.sol index 4b8e7b7985..fdc2c3a75f 100644 --- a/packages/nouns-contracts/contracts/libs/NFTDescriptor.sol +++ b/packages/nouns-contracts/contracts/libs/NFTDescriptor.sol @@ -15,30 +15,30 @@ * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ -pragma solidity ^0.8.6; +pragma solidity ^0.8.12; import { Base64 } from 'base64-sol/base64.sol'; -import { MultiPartRLEToSVG } from './MultiPartRLEToSVG.sol'; +import { ISVGRenderer } from '../interfaces/ISVGRenderer.sol'; library NFTDescriptor { struct TokenURIParams { string name; string description; - bytes[] parts; string background; + ISVGRenderer.Part[] parts; } /** * @notice Construct an ERC721 token URI. */ - function constructTokenURI(TokenURIParams memory params, mapping(uint8 => string[]) storage palettes) + function constructTokenURI(ISVGRenderer renderer, TokenURIParams memory params) public view returns (string memory) { string memory image = generateSVGImage( - MultiPartRLEToSVG.SVGParams({ parts: params.parts, background: params.background }), - palettes + renderer, + ISVGRenderer.SVGParams({ parts: params.parts, background: params.background }) ); // prettier-ignore @@ -57,11 +57,11 @@ library NFTDescriptor { /** * @notice Generate an SVG image for use in the ERC721 token URI. */ - function generateSVGImage(MultiPartRLEToSVG.SVGParams memory params, mapping(uint8 => string[]) storage palettes) + function generateSVGImage(ISVGRenderer renderer, ISVGRenderer.SVGParams memory params) public view returns (string memory svg) { - return Base64.encode(bytes(MultiPartRLEToSVG.generateSVG(params, palettes))); + return Base64.encode(bytes(renderer.generateSVG(params))); } } diff --git a/packages/nouns-contracts/contracts/libs/SSTORE2.sol b/packages/nouns-contracts/contracts/libs/SSTORE2.sol new file mode 100644 index 0000000000..a8912d2a09 --- /dev/null +++ b/packages/nouns-contracts/contracts/libs/SSTORE2.sol @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +pragma solidity ^0.8.12; + +/// @notice Read and write to persistent storage at a fraction of the cost. +/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SSTORE2.sol) +/// @author Modified from 0xSequence (https://github.com/0xSequence/sstore2/blob/master/contracts/SSTORE2.sol) +library SSTORE2 { + uint256 internal constant DATA_OFFSET = 1; // We skip the first byte as it's a STOP opcode to ensure the contract can't be called. + + /*/////////////////////////////////////////////////////////////// + WRITE LOGIC + //////////////////////////////////////////////////////////////*/ + + function write(bytes memory data) internal returns (address pointer) { + // Prefix the bytecode with a STOP opcode to ensure it cannot be called. + bytes memory runtimeCode = abi.encodePacked(hex'00', data); + + bytes memory creationCode = abi.encodePacked( + //---------------------------------------------------------------------------------------------------------------// + // Opcode | Opcode + Arguments | Description | Stack View // + //---------------------------------------------------------------------------------------------------------------// + // 0x60 | 0x600B | PUSH1 11 | codeOffset // + // 0x59 | 0x59 | MSIZE | 0 codeOffset // + // 0x81 | 0x81 | DUP2 | codeOffset 0 codeOffset // + // 0x38 | 0x38 | CODESIZE | codeSize codeOffset 0 codeOffset // + // 0x03 | 0x03 | SUB | (codeSize - codeOffset) 0 codeOffset // + // 0x80 | 0x80 | DUP | (codeSize - codeOffset) (codeSize - codeOffset) 0 codeOffset // + // 0x92 | 0x92 | SWAP3 | codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) // + // 0x59 | 0x59 | MSIZE | 0 codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) // + // 0x39 | 0x39 | CODECOPY | 0 (codeSize - codeOffset) // + // 0xf3 | 0xf3 | RETURN | // + //---------------------------------------------------------------------------------------------------------------// + hex'60_0B_59_81_38_03_80_92_59_39_F3', // Returns all code in the contract except for the first 11 (0B in hex) bytes. + runtimeCode // The bytecode we want the contract to have after deployment. Capped at 1 byte less than the code size limit. + ); + + assembly { + // Deploy a new contract with the generated creation code. + // We start 32 bytes into the code to avoid copying the byte length. + pointer := create(0, add(creationCode, 32), mload(creationCode)) + } + + require(pointer != address(0), 'DEPLOYMENT_FAILED'); + } + + /*/////////////////////////////////////////////////////////////// + READ LOGIC + //////////////////////////////////////////////////////////////*/ + + function read(address pointer) internal view returns (bytes memory) { + return readBytecode(pointer, DATA_OFFSET, pointer.code.length - DATA_OFFSET); + } + + function read(address pointer, uint256 start) internal view returns (bytes memory) { + start += DATA_OFFSET; + + return readBytecode(pointer, start, pointer.code.length - start); + } + + function read( + address pointer, + uint256 start, + uint256 end + ) internal view returns (bytes memory) { + start += DATA_OFFSET; + end += DATA_OFFSET; + + require(pointer.code.length >= end, 'OUT_OF_BOUNDS'); + + return readBytecode(pointer, start, end - start); + } + + /*/////////////////////////////////////////////////////////////// + INTERNAL HELPER LOGIC + //////////////////////////////////////////////////////////////*/ + + function readBytecode( + address pointer, + uint256 start, + uint256 size + ) private view returns (bytes memory data) { + assembly { + // Get a pointer to some free memory. + data := mload(0x40) + + // Update the free memory pointer to prevent overriding our data. + // We use and(x, not(31)) as a cheaper equivalent to sub(x, mod(x, 32)). + // Adding 31 to size and running the result through the logic above ensures + // the memory pointer remains word-aligned, following the Solidity convention. + mstore(0x40, add(data, and(add(add(size, 32), 31), not(31)))) + + // Store the size of the data in the first 32 byte chunk of free memory. + mstore(data, size) + + // Copy the code into memory right after the 32 bytes we used to store the size. + extcodecopy(pointer, add(data, 32), start, size) + } + } +} diff --git a/packages/nouns-contracts/contracts/proxies/NounsAuctionHouseProxy.sol b/packages/nouns-contracts/contracts/proxies/NounsAuctionHouseProxy.sol index afe885dcca..6c688f0ba4 100644 --- a/packages/nouns-contracts/contracts/proxies/NounsAuctionHouseProxy.sol +++ b/packages/nouns-contracts/contracts/proxies/NounsAuctionHouseProxy.sol @@ -15,7 +15,7 @@ * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ -pragma solidity ^0.8.6; +pragma solidity ^0.8.12; import { TransparentUpgradeableProxy } from '@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol'; diff --git a/packages/nouns-contracts/contracts/proxies/NounsAuctionHouseProxyAdmin.sol b/packages/nouns-contracts/contracts/proxies/NounsAuctionHouseProxyAdmin.sol index eb942caa59..767577401c 100644 --- a/packages/nouns-contracts/contracts/proxies/NounsAuctionHouseProxyAdmin.sol +++ b/packages/nouns-contracts/contracts/proxies/NounsAuctionHouseProxyAdmin.sol @@ -15,7 +15,7 @@ * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ -pragma solidity ^0.8.6; +pragma solidity ^0.8.12; import { ProxyAdmin } from '@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol'; diff --git a/packages/nouns-contracts/hardhat.config.ts b/packages/nouns-contracts/hardhat.config.ts index a95f899dff..eeb2efba3b 100644 --- a/packages/nouns-contracts/hardhat.config.ts +++ b/packages/nouns-contracts/hardhat.config.ts @@ -14,7 +14,7 @@ dotenv.config(); const config: HardhatUserConfig = { solidity: { - version: '0.8.6', + version: '0.8.12', settings: { optimizer: { enabled: true, diff --git a/packages/nouns-contracts/tasks/populate-descriptor.ts b/packages/nouns-contracts/tasks/populate-descriptor.ts index 58ed0dd390..3aad194512 100644 --- a/packages/nouns-contracts/tasks/populate-descriptor.ts +++ b/packages/nouns-contracts/tasks/populate-descriptor.ts @@ -1,6 +1,8 @@ import { task, types } from 'hardhat/config'; import ImageData from '../files/image-data.json'; import { chunkArray } from '../utils'; +import { deflateRawSync } from 'zlib'; +import { ethers } from 'ethers'; task('populate-descriptor', 'Populates the descriptor with color palettes and Noun parts') .addOptionalParam( @@ -26,22 +28,59 @@ task('populate-descriptor', 'Populates the descriptor with color palettes and No const { bgcolors, palette, images } = ImageData; const { bodies, accessories, heads, glasses } = images; + const { + encodedCompressed: bodiesCompressed, + originalLength: bodiesLength, + itemCount: bodiesCount, + } = dataToDescriptorInput(bodies.map(({ data }) => data)); + const { + encodedCompressed: accessoriesCompressed, + originalLength: accessoriesLength, + itemCount: accessoriesCount, + } = dataToDescriptorInput(accessories.map(({ data }) => data)); + const { + encodedCompressed: headsCompressed, + originalLength: headsLength, + itemCount: headsCount, + } = dataToDescriptorInput(heads.map(({ data }) => data)); + const { + encodedCompressed: glassesCompressed, + originalLength: glassesLength, + itemCount: glassesCount, + } = dataToDescriptorInput(glasses.map(({ data }) => data)); + // Chunk head and accessory population due to high gas usage await descriptorContract.addManyBackgrounds(bgcolors); - await descriptorContract.addManyColorsToPalette(0, palette); - await descriptorContract.addManyBodies(bodies.map(({ data }) => data)); - - const accessoryChunk = chunkArray(accessories, 10); - for (const chunk of accessoryChunk) { - await descriptorContract.addManyAccessories(chunk.map(({ data }) => data)); - } - - const headChunk = chunkArray(heads, 10); - for (const chunk of headChunk) { - await descriptorContract.addManyHeads(chunk.map(({ data }) => data)); - } + await descriptorContract.setPalette(0, `0x000000${palette.join('')}`); - await descriptorContract.addManyGlasses(glasses.map(({ data }) => data)); + await descriptorContract.addBodies(bodiesCompressed, bodiesLength, bodiesCount); + await descriptorContract.addAccessories( + accessoriesCompressed, + accessoriesLength, + accessoriesCount, + ); + await descriptorContract.addHeads(headsCompressed, headsLength, headsCount); + await descriptorContract.addGlasses(glassesCompressed, glassesLength, glassesCount); console.log('Descriptor populated with palettes and parts.'); }); + +function dataToDescriptorInput(data: string[]): { + encodedCompressed: string; + originalLength: number; + itemCount: number; +} { + const abiEncoded = ethers.utils.defaultAbiCoder.encode(['bytes[]'], [data]); + const encodedCompressed = `0x${deflateRawSync( + Buffer.from(abiEncoded.substring(2), 'hex'), + ).toString('hex')}`; + + const originalLength = abiEncoded.substring(2).length / 2; + const itemCount = data.length; + + return { + encodedCompressed, + originalLength, + itemCount, + }; +} From 44250432256c5fa9cae382e9386d4f62dce04e0a Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 15 Jun 2022 11:31:18 -0500 Subject: [PATCH 002/116] cleanup --- packages/nouns-contracts/contracts/NounsDescriptor.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsDescriptor.sol b/packages/nouns-contracts/contracts/NounsDescriptor.sol index 17b80bb791..8c0ab78e22 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptor.sol @@ -386,9 +386,9 @@ contract NounsDescriptor is INounsDescriptor, Ownable { } function imageByStorageIndex(Trait storage trait, uint256 storageIndex) internal view returns (bytes memory) { - (NounArtStoragePage storage page, uint256 pageFirstImageIndex) = getPage(trait.storagePages, storageIndex); + (NounArtStoragePage storage page, uint256 indexInPage) = getPage(trait.storagePages, storageIndex); bytes[] memory decompressedImages = decompressAndDecode(page); - return decompressedImages[storageIndex - pageFirstImageIndex]; + return decompressedImages[indexInPage]; } function getPage(NounArtStoragePage[] storage pages, uint256 storageIndex) @@ -406,7 +406,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { NounArtStoragePage storage page = pages[i]; if (storageIndex < pageFirstImageIndex + page.imageCount) { - return (page, pageFirstImageIndex); + return (page, storageIndex - pageFirstImageIndex); } pageFirstImageIndex += page.imageCount; From b2dc276ea7d6db2a01ff057e2173c80253a92605 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 15 Jun 2022 11:46:51 -0500 Subject: [PATCH 003/116] support retiring backgrounds --- .../contracts/NounsDescriptor.sol | 16 +++++++++++++++- .../nouns-contracts/contracts/NounsSeeder.sol | 2 +- .../contracts/interfaces/INounsDescriptor.sol | 4 ++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsDescriptor.sol b/packages/nouns-contracts/contracts/NounsDescriptor.sol index 8c0ab78e22..870123cfae 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptor.sol @@ -51,6 +51,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { // Noun Backgrounds (Hex Colors) string[] public override backgrounds; + uint256[] private backgroundsVirtualIndexToStorageIndex; // Noun Bodies (Custom RLE) Trait private _bodies; @@ -90,7 +91,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { * @notice Get the number of available Noun `backgrounds`. */ function backgroundCount() external view override returns (uint256) { - return backgrounds.length; + return backgroundsVirtualIndexToStorageIndex.length; } /** @@ -143,6 +144,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { * @notice Add a Noun background. */ function _addBackground(string calldata _background) internal { + backgroundsVirtualIndexToStorageIndex.push(backgrounds.length); backgrounds.push(_background); } @@ -193,6 +195,14 @@ contract NounsDescriptor is INounsDescriptor, Ownable { addToTrait(_glasses, encodedCompressed, decompressedLength, imageCount); } + function retireBackground(uint256 virtualIndex) external onlyOwner { + backgroundsVirtualIndexToStorageIndex[virtualIndex] = backgroundsVirtualIndexToStorageIndex[ + backgroundsVirtualIndexToStorageIndex.length - 1 + ]; + + backgroundsVirtualIndexToStorageIndex.pop(); + } + function retireBody(uint256 virtualIndex) external onlyOwner { retireTraitImage(_bodies, virtualIndex); } @@ -209,6 +219,10 @@ contract NounsDescriptor is INounsDescriptor, Ownable { retireTraitImage(_glasses, virtualIndex); } + function backgroundStorageIndex(uint256 virtualIndex) external view returns (uint256) { + return backgroundsVirtualIndexToStorageIndex[virtualIndex]; + } + function bodyStorageIndex(uint256 virtualIndex) external view returns (uint256) { return traitStorageIndex(_bodies, virtualIndex); } diff --git a/packages/nouns-contracts/contracts/NounsSeeder.sol b/packages/nouns-contracts/contracts/NounsSeeder.sol index 4f57ada5e5..afd3f6eea2 100644 --- a/packages/nouns-contracts/contracts/NounsSeeder.sol +++ b/packages/nouns-contracts/contracts/NounsSeeder.sol @@ -38,7 +38,7 @@ contract NounsSeeder is INounsSeeder { return Seed({ background: uint48( - uint48(pseudorandomness) % backgroundCount + descriptor.backgroundStorageIndex(uint48(pseudorandomness) % backgroundCount) ), body: uint48( descriptor.bodyStorageIndex(uint48(pseudorandomness >> 48) % bodyCount) diff --git a/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol b/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol index a980310c36..bade0c4163 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol @@ -120,6 +120,8 @@ interface INounsDescriptor { uint16 imageCount ) external; + function retireBackground(uint256 virtualIndex) external; + function retireBody(uint256 virtualIndex) external; function retireAccessory(uint256 virtualIndex) external; @@ -128,6 +130,8 @@ interface INounsDescriptor { function retireGlasses(uint256 virtualIndex) external; + function backgroundStorageIndex(uint256 virtualIndex) external view returns (uint256); + function bodyStorageIndex(uint256 virtualIndex) external view returns (uint256); function accessoryStorageIndex(uint256 virtualIndex) external view returns (uint256); From 36376cec25331dcbb4bf5dafadba40f2e0309056 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 15 Jun 2022 12:17:39 -0500 Subject: [PATCH 004/116] remove MultiPartRLEToSVG --- .../contracts/NounsDescriptor.sol | 1 - .../contracts/libs/MultiPartRLEToSVG.sol | 157 ------------------ 2 files changed, 158 deletions(-) delete mode 100644 packages/nouns-contracts/contracts/libs/MultiPartRLEToSVG.sol diff --git a/packages/nouns-contracts/contracts/NounsDescriptor.sol b/packages/nouns-contracts/contracts/NounsDescriptor.sol index 870123cfae..db9acc49a1 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptor.sol @@ -25,7 +25,6 @@ import { NFTDescriptor } from './libs/NFTDescriptor.sol'; import { ISVGRenderer } from './interfaces/ISVGRenderer.sol'; import { SSTORE2 } from './libs/SSTORE2.sol'; import { Inflate } from './libs/Inflate.sol'; -import { MultiPartRLEToSVG } from './libs/MultiPartRLEToSVG.sol'; contract NounsDescriptor is INounsDescriptor, Ownable { using Strings for uint256; diff --git a/packages/nouns-contracts/contracts/libs/MultiPartRLEToSVG.sol b/packages/nouns-contracts/contracts/libs/MultiPartRLEToSVG.sol deleted file mode 100644 index 720e727118..0000000000 --- a/packages/nouns-contracts/contracts/libs/MultiPartRLEToSVG.sol +++ /dev/null @@ -1,157 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 - -/// @title A library used to convert multi-part RLE compressed images to SVG - -/********************************* - * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * - * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * - * ░░░░░░█████████░░█████████░░░ * - * ░░░░░░██░░░████░░██░░░████░░░ * - * ░░██████░░░████████░░░████░░░ * - * ░░██░░██░░░████░░██░░░████░░░ * - * ░░██░░██░░░████░░██░░░████░░░ * - * ░░░░░░█████████░░█████████░░░ * - * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * - * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * - *********************************/ - -pragma solidity ^0.8.6; - -library MultiPartRLEToSVG { - struct SVGParams { - bytes[] parts; - string background; - } - - struct ContentBounds { - uint8 top; - uint8 right; - uint8 bottom; - uint8 left; - } - - struct Rect { - uint8 length; - uint8 colorIndex; - } - - struct DecodedImage { - uint8 paletteIndex; - ContentBounds bounds; - Rect[] rects; - } - - /** - * @notice Given RLE image parts and color palettes, merge to generate a single SVG image. - */ - function generateSVG(SVGParams memory params, mapping(uint8 => string[]) storage palettes) - internal - view - returns (string memory svg) - { - // prettier-ignore - return string( - abi.encodePacked( - '', - '', - _generateSVGRects(params, palettes), - '' - ) - ); - } - - /** - * @notice Given RLE image parts and color palettes, generate SVG rects. - */ - // prettier-ignore - function _generateSVGRects(SVGParams memory params, mapping(uint8 => string[]) storage palettes) - private - view - returns (string memory svg) - { - string[33] memory lookup = [ - '0', '10', '20', '30', '40', '50', '60', '70', - '80', '90', '100', '110', '120', '130', '140', '150', - '160', '170', '180', '190', '200', '210', '220', '230', - '240', '250', '260', '270', '280', '290', '300', '310', - '320' - ]; - string memory rects; - for (uint8 p = 0; p < params.parts.length; p++) { - DecodedImage memory image = _decodeRLEImage(params.parts[p]); - string[] storage palette = palettes[image.paletteIndex]; - uint256 currentX = image.bounds.left; - uint256 currentY = image.bounds.top; - uint256 cursor; - string[16] memory buffer; - - string memory part; - for (uint256 i = 0; i < image.rects.length; i++) { - Rect memory rect = image.rects[i]; - if (rect.colorIndex != 0) { - buffer[cursor] = lookup[rect.length]; // width - buffer[cursor + 1] = lookup[currentX]; // x - buffer[cursor + 2] = lookup[currentY]; // y - buffer[cursor + 3] = palette[rect.colorIndex]; // color - - cursor += 4; - - if (cursor >= 16) { - part = string(abi.encodePacked(part, _getChunk(cursor, buffer))); - cursor = 0; - } - } - - currentX += rect.length; - if (currentX == image.bounds.right) { - currentX = image.bounds.left; - currentY++; - } - } - - if (cursor != 0) { - part = string(abi.encodePacked(part, _getChunk(cursor, buffer))); - } - rects = string(abi.encodePacked(rects, part)); - } - return rects; - } - - /** - * @notice Return a string that consists of all rects in the provided `buffer`. - */ - // prettier-ignore - function _getChunk(uint256 cursor, string[16] memory buffer) private pure returns (string memory) { - string memory chunk; - for (uint256 i = 0; i < cursor; i += 4) { - chunk = string( - abi.encodePacked( - chunk, - '' - ) - ); - } - return chunk; - } - - /** - * @notice Decode a single RLE compressed image into a `DecodedImage`. - */ - function _decodeRLEImage(bytes memory image) private pure returns (DecodedImage memory) { - uint8 paletteIndex = uint8(image[0]); - ContentBounds memory bounds = ContentBounds({ - top: uint8(image[1]), - right: uint8(image[2]), - bottom: uint8(image[3]), - left: uint8(image[4]) - }); - - uint256 cursor; - Rect[] memory rects = new Rect[]((image.length - 5) / 2); - for (uint256 i = 5; i < image.length; i += 2) { - rects[cursor] = Rect({ length: uint8(image[i]), colorIndex: uint8(image[i + 1]) }); - cursor++; - } - return DecodedImage({ paletteIndex: paletteIndex, bounds: bounds, rects: rects }); - } -} From e0553af591df1299462c0ddfa44e530144064ee0 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 15 Jun 2022 12:18:35 -0500 Subject: [PATCH 005/116] add example fork renderer --- .../ExampleForkFastFoodSVGRenderer.sol | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 packages/nouns-contracts/contracts/ExampleForkFastFoodSVGRenderer.sol diff --git a/packages/nouns-contracts/contracts/ExampleForkFastFoodSVGRenderer.sol b/packages/nouns-contracts/contracts/ExampleForkFastFoodSVGRenderer.sol new file mode 100644 index 0000000000..944e00b3ba --- /dev/null +++ b/packages/nouns-contracts/contracts/ExampleForkFastFoodSVGRenderer.sol @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-3.0 + +/// @title A contract used to convert multi-part RLE compressed images to SVG + +/********************************* + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░██░░░████░░██░░░████░░░ * + * ░░██████░░░████████░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + *********************************/ + +pragma solidity ^0.8.12; + +import { ISVGRenderer } from './interfaces/ISVGRenderer.sol'; +import { SSTORE2 } from './libs/SSTORE2.sol'; + +contract ExampleForkFastFoodSVGRenderer is ISVGRenderer { + // prettier-ignore + string private constant _SVG_START_TAG = ''; + string private constant _SVG_END_TAG = ''; + string private constant _FAST_FOOD_HAT = + ''; + + ISVGRenderer private nounsRenderer; + + constructor(ISVGRenderer _nounsRenderer) { + nounsRenderer = _nounsRenderer; + } + + /** + * @notice Given RLE image data and color palette pointers, merge to generate a single SVG image. + */ + function generateSVG(SVGParams calldata params) external view returns (string memory svg) { + // prettier-ignore + return string( + abi.encodePacked( + _SVG_START_TAG, + '', + nounsRenderer.generateSVGParts(params.parts), + _FAST_FOOD_HAT, + _SVG_END_TAG + ) + ); + } + + // these functions can be removed from the interface in a real fork, they aren't used by the descriptor + + function generateSVGPart(Part memory part) external view returns (string memory partialSVG) { + return ''; + } + + function generateSVGParts(Part[] memory parts) external view returns (string memory partialSVG) { + return ''; + } +} From 658b4258929e69363f5e7f2ede635ac4dd22bbc6 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 15 Jun 2022 12:27:10 -0500 Subject: [PATCH 006/116] add functions that add images from a contract pointer --- .../contracts/NounsDescriptor.sol | 58 +++++++++++++++---- .../contracts/interfaces/INounsDescriptor.sol | 24 ++++++++ 2 files changed, 72 insertions(+), 10 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsDescriptor.sol b/packages/nouns-contracts/contracts/NounsDescriptor.sol index db9acc49a1..39ef750022 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptor.sol @@ -167,7 +167,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { uint80 decompressedLength, uint16 imageCount ) external onlyOwner { - addToTrait(_bodies, encodedCompressed, decompressedLength, imageCount); + addToTraitFromBytes(_bodies, encodedCompressed, decompressedLength, imageCount); } function addAccessories( @@ -175,7 +175,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { uint80 decompressedLength, uint16 imageCount ) external onlyOwner { - addToTrait(_accessories, encodedCompressed, decompressedLength, imageCount); + addToTraitFromBytes(_accessories, encodedCompressed, decompressedLength, imageCount); } function addHeads( @@ -183,7 +183,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { uint80 decompressedLength, uint16 imageCount ) external onlyOwner { - addToTrait(_heads, encodedCompressed, decompressedLength, imageCount); + addToTraitFromBytes(_heads, encodedCompressed, decompressedLength, imageCount); } function addGlasses( @@ -191,7 +191,39 @@ contract NounsDescriptor is INounsDescriptor, Ownable { uint80 decompressedLength, uint16 imageCount ) external onlyOwner { - addToTrait(_glasses, encodedCompressed, decompressedLength, imageCount); + addToTraitFromBytes(_glasses, encodedCompressed, decompressedLength, imageCount); + } + + function addBodiesFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external onlyOwner { + addToTraitFromPointer(_bodies, pointer, decompressedLength, imageCount); + } + + function addAccessoriesFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external onlyOwner { + addToTraitFromPointer(_accessories, pointer, decompressedLength, imageCount); + } + + function addHeadsFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external onlyOwner { + addToTraitFromPointer(_heads, pointer, decompressedLength, imageCount); + } + + function addGlassesFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external onlyOwner { + addToTraitFromPointer(_glasses, pointer, decompressedLength, imageCount); } function retireBackground(uint256 virtualIndex) external onlyOwner { @@ -434,18 +466,24 @@ contract NounsDescriptor is INounsDescriptor, Ownable { return abi.decode(decompressedData, (bytes[])); } - function addToTrait( + function addToTraitFromBytes( Trait storage trait, bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount + ) internal { + address pointer = SSTORE2.write(encodedCompressed); + addToTraitFromPointer(trait, pointer, decompressedLength, imageCount); + } + + function addToTraitFromPointer( + Trait storage trait, + address pointer, + uint80 decompressedLength, + uint16 imageCount ) internal { trait.storagePages.push( - NounArtStoragePage({ - pointer: SSTORE2.write(encodedCompressed), - decompressedLength: decompressedLength, - imageCount: imageCount - }) + NounArtStoragePage({ pointer: pointer, decompressedLength: decompressedLength, imageCount: imageCount }) ); uint256 storedImageCount = trait.storedImagesCount; diff --git a/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol b/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol index bade0c4163..4f96e8ac37 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol @@ -120,6 +120,30 @@ interface INounsDescriptor { uint16 imageCount ) external; + function addBodiesFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function addAccessoriesFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function addHeadsFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function addGlassesFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external; + function retireBackground(uint256 virtualIndex) external; function retireBody(uint256 virtualIndex) external; From 88b7c68bef7b66a2d690c8b7d21fc1ac57eeb10d Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 15 Jun 2022 13:56:25 -0500 Subject: [PATCH 007/116] make descriptor variables public --- packages/nouns-contracts/contracts/NounsDescriptor.sol | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsDescriptor.sol b/packages/nouns-contracts/contracts/NounsDescriptor.sol index 39ef750022..7f2b9fdc49 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptor.sol @@ -50,19 +50,19 @@ contract NounsDescriptor is INounsDescriptor, Ownable { // Noun Backgrounds (Hex Colors) string[] public override backgrounds; - uint256[] private backgroundsVirtualIndexToStorageIndex; + uint256[] public backgroundsVirtualIndexToStorageIndex; // Noun Bodies (Custom RLE) - Trait private _bodies; + Trait public _bodies; // Noun Accessories (Custom RLE) - Trait private _accessories; + Trait public _accessories; // Noun Heads (Custom RLE) - Trait private _heads; + Trait public _heads; // Noun Glasses (Custom RLE) - Trait private _glasses; + Trait public _glasses; /** * @notice Require that the parts have not been locked. From 1cfc89558906085f3702335b4eb32e63a25752f7 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 15 Jun 2022 14:12:04 -0500 Subject: [PATCH 008/116] add natspec to clarify inputs --- .../contracts/NounsDescriptor.sol | 61 ++++++++++++++++++- .../contracts/interfaces/INounsDescriptor.sol | 60 ++++++++++++++++++ 2 files changed, 120 insertions(+), 1 deletion(-) diff --git a/packages/nouns-contracts/contracts/NounsDescriptor.sol b/packages/nouns-contracts/contracts/NounsDescriptor.sol index 7f2b9fdc49..3d45ffdc39 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptor.sol @@ -150,7 +150,6 @@ contract NounsDescriptor is INounsDescriptor, Ownable { /** * @notice Update a single color palette. This function can be used to * add a new color palette or update an existing palette. - * @dev This function can only be called by the descriptor. */ function setPalette(uint8 paletteIndex, bytes calldata palette) external onlyOwner { if (palette.length == 0) { @@ -162,6 +161,13 @@ contract NounsDescriptor is INounsDescriptor, Ownable { palettes[paletteIndex] = SSTORE2.write(palette); } + /** + * @notice Add a batch of body images. + * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, + * and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ function addBodies( bytes calldata encodedCompressed, uint80 decompressedLength, @@ -170,6 +176,13 @@ contract NounsDescriptor is INounsDescriptor, Ownable { addToTraitFromBytes(_bodies, encodedCompressed, decompressedLength, imageCount); } + /** + * @notice Add a batch of accessory images. + * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, + * and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ function addAccessories( bytes calldata encodedCompressed, uint80 decompressedLength, @@ -178,6 +191,13 @@ contract NounsDescriptor is INounsDescriptor, Ownable { addToTraitFromBytes(_accessories, encodedCompressed, decompressedLength, imageCount); } + /** + * @notice Add a batch of head images. + * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, + * and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ function addHeads( bytes calldata encodedCompressed, uint80 decompressedLength, @@ -186,6 +206,13 @@ contract NounsDescriptor is INounsDescriptor, Ownable { addToTraitFromBytes(_heads, encodedCompressed, decompressedLength, imageCount); } + /** + * @notice Add a batch of glasses images. + * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, + * and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ function addGlasses( bytes calldata encodedCompressed, uint80 decompressedLength, @@ -194,6 +221,14 @@ contract NounsDescriptor is INounsDescriptor, Ownable { addToTraitFromBytes(_glasses, encodedCompressed, decompressedLength, imageCount); } + /** + * @notice Add a batch of body images from an existing storage contract. + * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data + * format is expected to be like {encodedCompressed}: bytes created by taking a string array of + * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ function addBodiesFromPointer( address pointer, uint80 decompressedLength, @@ -202,6 +237,14 @@ contract NounsDescriptor is INounsDescriptor, Ownable { addToTraitFromPointer(_bodies, pointer, decompressedLength, imageCount); } + /** + * @notice Add a batch of accessory images from an existing storage contract. + * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data + * format is expected to be like {encodedCompressed}: bytes created by taking a string array of + * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ function addAccessoriesFromPointer( address pointer, uint80 decompressedLength, @@ -210,6 +253,14 @@ contract NounsDescriptor is INounsDescriptor, Ownable { addToTraitFromPointer(_accessories, pointer, decompressedLength, imageCount); } + /** + * @notice Add a batch of head images from an existing storage contract. + * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data + * format is expected to be like {encodedCompressed}: bytes created by taking a string array of + * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ function addHeadsFromPointer( address pointer, uint80 decompressedLength, @@ -218,6 +269,14 @@ contract NounsDescriptor is INounsDescriptor, Ownable { addToTraitFromPointer(_heads, pointer, decompressedLength, imageCount); } + /** + * @notice Add a batch of glasses images from an existing storage contract. + * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data + * format is expected to be like {encodedCompressed}: bytes created by taking a string array of + * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ function addGlassesFromPointer( address pointer, uint80 decompressedLength, diff --git a/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol b/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol index 4f96e8ac37..a63e1fdf29 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol @@ -96,48 +96,108 @@ interface INounsDescriptor { function setPalette(uint8 paletteIndex, bytes calldata palette) external; + /** + * @notice Add a batch of body images. + * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, + * and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ function addBodies( bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount ) external; + /** + * @notice Add a batch of accessory images. + * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, + * and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ function addAccessories( bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount ) external; + /** + * @notice Add a batch of head images. + * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, + * and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ function addHeads( bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount ) external; + /** + * @notice Add a batch of glasses images. + * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, + * and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ function addGlasses( bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount ) external; + /** + * @notice Add a batch of body images from an existing storage contract. + * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data + * format is expected to be like {encodedCompressed}: bytes created by taking a string array of + * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ function addBodiesFromPointer( address pointer, uint80 decompressedLength, uint16 imageCount ) external; + /** + * @notice Add a batch of accessory images from an existing storage contract. + * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data + * format is expected to be like {encodedCompressed}: bytes created by taking a string array of + * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ function addAccessoriesFromPointer( address pointer, uint80 decompressedLength, uint16 imageCount ) external; + /** + * @notice Add a batch of head images from an existing storage contract. + * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data + * format is expected to be like {encodedCompressed}: bytes created by taking a string array of + * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ function addHeadsFromPointer( address pointer, uint80 decompressedLength, uint16 imageCount ) external; + /** + * @notice Add a batch of glasses images from an existing storage contract. + * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data + * format is expected to be like {encodedCompressed}: bytes created by taking a string array of + * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ function addGlassesFromPointer( address pointer, uint80 decompressedLength, From 8371af488c6a9f403cbb8f5b4f6462ff32694784 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 15 Jun 2022 14:15:59 -0500 Subject: [PATCH 009/116] refactor --- .../contracts/NounsDescriptor.sol | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsDescriptor.sol b/packages/nouns-contracts/contracts/NounsDescriptor.sol index 3d45ffdc39..ed73008ef1 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptor.sol @@ -286,27 +286,23 @@ contract NounsDescriptor is INounsDescriptor, Ownable { } function retireBackground(uint256 virtualIndex) external onlyOwner { - backgroundsVirtualIndexToStorageIndex[virtualIndex] = backgroundsVirtualIndexToStorageIndex[ - backgroundsVirtualIndexToStorageIndex.length - 1 - ]; - - backgroundsVirtualIndexToStorageIndex.pop(); + retireStorageIndexByVirtualIndex(backgroundsVirtualIndexToStorageIndex, virtualIndex); } function retireBody(uint256 virtualIndex) external onlyOwner { - retireTraitImage(_bodies, virtualIndex); + retireStorageIndexByVirtualIndex(_bodies.virtualIndexToStorageIndex, virtualIndex); } function retireAccessory(uint256 virtualIndex) external onlyOwner { - retireTraitImage(_accessories, virtualIndex); + retireStorageIndexByVirtualIndex(_accessories.virtualIndexToStorageIndex, virtualIndex); } function retireHead(uint256 virtualIndex) external onlyOwner { - retireTraitImage(_heads, virtualIndex); + retireStorageIndexByVirtualIndex(_heads.virtualIndexToStorageIndex, virtualIndex); } function retireGlasses(uint256 virtualIndex) external onlyOwner { - retireTraitImage(_glasses, virtualIndex); + retireStorageIndexByVirtualIndex(_glasses.virtualIndexToStorageIndex, virtualIndex); } function backgroundStorageIndex(uint256 virtualIndex) external view returns (uint256) { @@ -554,11 +550,8 @@ contract NounsDescriptor is INounsDescriptor, Ownable { trait.storedImagesCount += imageCount; } - function retireTraitImage(Trait storage trait, uint256 virtualIndex) internal { - trait.virtualIndexToStorageIndex[virtualIndex] = trait.virtualIndexToStorageIndex[ - trait.virtualIndexToStorageIndex.length - 1 - ]; - - trait.virtualIndexToStorageIndex.pop(); + function retireStorageIndexByVirtualIndex(uint256[] storage virtualToStorageArray, uint256 virtualIndex) internal { + virtualToStorageArray[virtualIndex] = virtualToStorageArray[virtualToStorageArray.length - 1]; + virtualToStorageArray.pop(); } } From 2bef4b2bad0d6f3e7856e5a5f9fb957e13ed1026 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 15 Jun 2022 14:30:40 -0500 Subject: [PATCH 010/116] add storage->virtual index mapping helper functions for image retirement. not expected to be used in transations --- .../contracts/NounsDescriptor.sol | 65 +++++++++++++++++++ .../contracts/interfaces/INounsDescriptor.sol | 41 ++++++++++++ 2 files changed, 106 insertions(+) diff --git a/packages/nouns-contracts/contracts/NounsDescriptor.sol b/packages/nouns-contracts/contracts/NounsDescriptor.sol index ed73008ef1..ca48b637a5 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptor.sol @@ -325,6 +325,56 @@ contract NounsDescriptor is INounsDescriptor, Ownable { return traitStorageIndex(_glasses, virtualIndex); } + /** + * @notice Get a background's virtual index from its storage index. Useful for image retirement, where virtual index is the + * input, and you might be holding the storage index. + * @param storageIndex the storage index to look up. + * @return uint256 virtual index. + */ + function backgroundVirtualIndex(uint256 storageIndex) external view returns (uint256) { + return storageIndexToVirtualIndex(backgroundsVirtualIndexToStorageIndex, storageIndex); + } + + /** + * @notice Get a body's virtual index from its storage index. Useful for image retirement, where virtual index is the + * input, and you might be holding the storage index. + * @param storageIndex the storage index to look up. + * @return uint256 virtual index. + */ + function bodyVirtualIndex(uint256 storageIndex) external view returns (uint256) { + return storageIndexToVirtualIndex(_bodies.virtualIndexToStorageIndex, storageIndex); + } + + /** + * @notice Get an accessory's virtual index from its storage index. Useful for image retirement, where virtual index is the + * input, and you might be holding the storage index. + * @param storageIndex the storage index to look up. + * @return uint256 virtual index. + */ + function accessoryVirtualIndex(uint256 storageIndex) external view returns (uint256) { + return storageIndexToVirtualIndex(_accessories.virtualIndexToStorageIndex, storageIndex); + } + + /** + * @notice Get a head's virtual index from its storage index. Useful for image retirement, where virtual index is the + * input, and you might be holding the storage index. + * @param storageIndex the storage index to look up. + * @return uint256 virtual index. + */ + function headVirtualIndex(uint256 storageIndex) external view returns (uint256) { + return storageIndexToVirtualIndex(_heads.virtualIndexToStorageIndex, storageIndex); + } + + /** + * @notice Get a glasses' virtual index from its storage index. Useful for image retirement, where virtual index is the + * input, and you might be holding the storage index. + * @param storageIndex the storage index to look up. + * @return uint256 virtual index. + */ + function glassesVirtualIndex(uint256 storageIndex) external view returns (uint256) { + return storageIndexToVirtualIndex(_glasses.virtualIndexToStorageIndex, storageIndex); + } + function traitStorageIndex(Trait storage trait, uint256 virtualIndex) internal view returns (uint256) { return trait.virtualIndexToStorageIndex[virtualIndex]; } @@ -554,4 +604,19 @@ contract NounsDescriptor is INounsDescriptor, Ownable { virtualToStorageArray[virtualIndex] = virtualToStorageArray[virtualToStorageArray.length - 1]; virtualToStorageArray.pop(); } + + function storageIndexToVirtualIndex(uint256[] storage mappingArray, uint256 storageIndex) + internal + view + returns (uint256) + { + uint256 len = mappingArray.length; + for (uint256 virtualIndex = 0; virtualIndex < len; virtualIndex++) { + if (mappingArray[virtualIndex] == storageIndex) { + return virtualIndex; + } + } + + revert IndexNotFound(); + } } diff --git a/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol b/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol index a63e1fdf29..7c2984f945 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol @@ -33,6 +33,7 @@ interface INounsDescriptor { error BadPaletteLength(); error NoPages(); error ImageNotFound(); + error IndexNotFound(); struct NounArtStoragePage { uint16 imageCount; @@ -224,6 +225,46 @@ interface INounsDescriptor { function glassesStorageIndex(uint256 virtualIndex) external view returns (uint256); + /** + * @notice Get a background's virtual index from its storage index. Useful for image retirement, where virtual index is the + * input, and you might be holding the storage index. + * @param storageIndex the storage index to look up. + * @return uint256 virtual index. + */ + function backgroundVirtualIndex(uint256 storageIndex) external view returns (uint256); + + /** + * @notice Get a body's virtual index from its storage index. Useful for image retirement, where virtual index is the + * input, and you might be holding the storage index. + * @param storageIndex the storage index to look up. + * @return uint256 virtual index. + */ + function bodyVirtualIndex(uint256 storageIndex) external view returns (uint256); + + /** + * @notice Get an accessory's virtual index from its storage index. Useful for image retirement, where virtual index is the + * input, and you might be holding the storage index. + * @param storageIndex the storage index to look up. + * @return uint256 virtual index. + */ + function accessoryVirtualIndex(uint256 storageIndex) external view returns (uint256); + + /** + * @notice Get a head's virtual index from its storage index. Useful for image retirement, where virtual index is the + * input, and you might be holding the storage index. + * @param storageIndex the storage index to look up. + * @return uint256 virtual index. + */ + function headVirtualIndex(uint256 storageIndex) external view returns (uint256); + + /** + * @notice Get a glasses' virtual index from its storage index. Useful for image retirement, where virtual index is the + * input, and you might be holding the storage index. + * @param storageIndex the storage index to look up. + * @return uint256 virtual index. + */ + function glassesVirtualIndex(uint256 storageIndex) external view returns (uint256); + function lockParts() external; function toggleDataURIEnabled() external; From 706fedb38961cc7a5f7a8e066de285743c6b3ed8 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 15 Jun 2022 16:00:20 -0500 Subject: [PATCH 011/116] refactor descriptor storage out to NounsArt --- .../nouns-contracts/contracts/NounsArt.sol | 301 ++++++++++++++++++ .../contracts/NounsDescriptor.sol | 275 ++++++---------- .../contracts/interfaces/INounsArt.sol | 145 +++++++++ .../contracts/interfaces/INounsDescriptor.sol | 33 +- 4 files changed, 549 insertions(+), 205 deletions(-) create mode 100644 packages/nouns-contracts/contracts/NounsArt.sol create mode 100644 packages/nouns-contracts/contracts/interfaces/INounsArt.sol diff --git a/packages/nouns-contracts/contracts/NounsArt.sol b/packages/nouns-contracts/contracts/NounsArt.sol new file mode 100644 index 0000000000..421340f5be --- /dev/null +++ b/packages/nouns-contracts/contracts/NounsArt.sol @@ -0,0 +1,301 @@ +// SPDX-License-Identifier: GPL-3.0 + +/// @title The Nouns art storage contract + +/********************************* + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░██░░░████░░██░░░████░░░ * + * ░░██████░░░████████░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + *********************************/ + +pragma solidity ^0.8.12; + +import { INounsArt } from './interfaces/INounsArt.sol'; +import { Inflate } from './libs/Inflate.sol'; +import { SSTORE2 } from './libs/SSTORE2.sol'; + +contract NounsArt is INounsArt { + // Current Nouns Descriptor address + address public descriptor; + + // Pending Nouns Descriptor address + address public pendingDescriptor; + + // Noun Backgrounds (Hex Colors) + string[] public backgrounds; + + // Noun Color Palettes (Index => Hex Colors) + mapping(uint8 => address) public override palettes; + + // Noun Bodies (Custom RLE) + Trait public _bodies; + + // Noun Accessories (Custom RLE) + Trait public _accessories; + + // Noun Heads (Custom RLE) + Trait public _heads; + + // Noun Glasses (Custom RLE) + Trait public _glasses; + + /** + * @notice Require that the sender is the descriptor. + */ + modifier onlyDescriptor() { + if (msg.sender != descriptor) { + revert SenderIsNotDescriptor(); + } + _; + } + + /** + * @notice Set the pending descriptor, which can be confirmed + * by calling `confirmDescriptor`. + * @dev This function can only be called by the current descriptor. + */ + function setDescriptor(address _pendingDescriptor) external onlyDescriptor { + pendingDescriptor = _pendingDescriptor; + } + + /** + * @notice Confirm the pending descriptor. + * @dev This function can only be called by the pending descriptor. + */ + function confirmDescriptor() external { + if (msg.sender != pendingDescriptor) { + revert SenderIsNotPendingDescriptor(); + } + + address oldDescriptor = descriptor; + descriptor = pendingDescriptor; + delete pendingDescriptor; + + emit DescriptorUpdated(oldDescriptor, descriptor); + } + + function bodiesTrait() external view returns (Trait memory) { + return _bodies; + } + + function accessoriesTrait() external view returns (Trait memory) { + return _accessories; + } + + function headsTrait() external view returns (Trait memory) { + return _heads; + } + + function glassesTrait() external view returns (Trait memory) { + return _glasses; + } + + function addManyBackgrounds(string[] calldata _backgrounds) external override onlyDescriptor { + for (uint256 i = 0; i < _backgrounds.length; i++) { + _addBackground(_backgrounds[i]); + } + } + + function addBackground(string calldata _background) external override onlyDescriptor { + _addBackground(_background); + } + + function _addBackground(string calldata _background) internal { + backgrounds.push(_background); + } + + function setPalette(uint8 paletteIndex, bytes calldata palette) external override onlyDescriptor { + if (palette.length == 0) { + revert EmptyPalette(); + } + if (palette.length % 3 != 0 || palette.length > 768) { + revert BadPaletteLength(); + } + palettes[paletteIndex] = SSTORE2.write(palette); + } + + function addBodies( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external override onlyDescriptor { + addToTraitFromBytes(_bodies, encodedCompressed, decompressedLength, imageCount); + } + + function addAccessories( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external override onlyDescriptor { + addToTraitFromBytes(_accessories, encodedCompressed, decompressedLength, imageCount); + } + + function addHeads( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external override onlyDescriptor { + addToTraitFromBytes(_heads, encodedCompressed, decompressedLength, imageCount); + } + + function addGlasses( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external override onlyDescriptor { + addToTraitFromBytes(_glasses, encodedCompressed, decompressedLength, imageCount); + } + + function addBodiesFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external override onlyDescriptor { + addToTraitFromPointer(_bodies, pointer, decompressedLength, imageCount); + } + + function addAccessoriesFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external override onlyDescriptor { + addToTraitFromPointer(_accessories, pointer, decompressedLength, imageCount); + } + + function addHeadsFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external override onlyDescriptor { + addToTraitFromPointer(_heads, pointer, decompressedLength, imageCount); + } + + function addGlassesFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external override onlyDescriptor { + addToTraitFromPointer(_glasses, pointer, decompressedLength, imageCount); + } + + function backgroundsCount() public view override returns (uint256) { + return backgrounds.length; + } + + function headsPageCount() public view override returns (uint256) { + return _heads.storagePages.length; + } + + function bodiesPageCount() public view override returns (uint256) { + return _bodies.storagePages.length; + } + + function accessoriesPageCount() public view override returns (uint256) { + return _accessories.storagePages.length; + } + + function glassesPageCount() public view override returns (uint256) { + return _glasses.storagePages.length; + } + + function headsPage(uint256 pageIndex) public view override returns (INounsArt.NounArtStoragePage memory) { + return _heads.storagePages[pageIndex]; + } + + function bodiesPage(uint256 pageIndex) public view override returns (INounsArt.NounArtStoragePage memory) { + return _bodies.storagePages[pageIndex]; + } + + function accessoriesPage(uint256 pageIndex) public view override returns (INounsArt.NounArtStoragePage memory) { + return _accessories.storagePages[pageIndex]; + } + + function glassesPage(uint256 pageIndex) public view override returns (INounsArt.NounArtStoragePage memory) { + return _glasses.storagePages[pageIndex]; + } + + function heads(uint256 storageIndex) public view override returns (bytes memory) { + return imageByStorageIndex(_heads, storageIndex); + } + + function bodies(uint256 storageIndex) public view override returns (bytes memory) { + return imageByStorageIndex(_bodies, storageIndex); + } + + function accessories(uint256 storageIndex) public view override returns (bytes memory) { + return imageByStorageIndex(_accessories, storageIndex); + } + + function glasses(uint256 storageIndex) public view override returns (bytes memory) { + return imageByStorageIndex(_glasses, storageIndex); + } + + function addToTraitFromBytes( + Trait storage trait, + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) internal { + address pointer = SSTORE2.write(encodedCompressed); + addToTraitFromPointer(trait, pointer, decompressedLength, imageCount); + } + + function addToTraitFromPointer( + Trait storage trait, + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) internal { + trait.storagePages.push( + NounArtStoragePage({ pointer: pointer, decompressedLength: decompressedLength, imageCount: imageCount }) + ); + trait.storedImagesCount += imageCount; + } + + function imageByStorageIndex(INounsArt.Trait storage trait, uint256 storageIndex) + internal + view + returns (bytes memory) + { + (INounsArt.NounArtStoragePage storage page, uint256 indexInPage) = getPage(trait.storagePages, storageIndex); + bytes[] memory decompressedImages = decompressAndDecode(page); + return decompressedImages[indexInPage]; + } + + function getPage(INounsArt.NounArtStoragePage[] storage pages, uint256 storageIndex) + internal + view + returns (INounsArt.NounArtStoragePage storage, uint256) + { + uint256 len = pages.length; + if (len == 0) { + revert NoPages(); + } + + uint256 pageFirstImageIndex = 0; + for (uint256 i = 0; i < len; i++) { + INounsArt.NounArtStoragePage storage page = pages[i]; + + if (storageIndex < pageFirstImageIndex + page.imageCount) { + return (page, storageIndex - pageFirstImageIndex); + } + + pageFirstImageIndex += page.imageCount; + } + + revert ImageNotFound(); + } + + function decompressAndDecode(INounsArt.NounArtStoragePage storage page) internal view returns (bytes[] memory) { + bytes memory compressedData = SSTORE2.read(page.pointer); + (, bytes memory decompressedData) = Inflate.puff(compressedData, page.decompressedLength); + return abi.decode(decompressedData, (bytes[])); + } +} diff --git a/packages/nouns-contracts/contracts/NounsDescriptor.sol b/packages/nouns-contracts/contracts/NounsDescriptor.sol index ca48b637a5..d4ddd3c78a 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptor.sol @@ -25,6 +25,7 @@ import { NFTDescriptor } from './libs/NFTDescriptor.sol'; import { ISVGRenderer } from './interfaces/ISVGRenderer.sol'; import { SSTORE2 } from './libs/SSTORE2.sol'; import { Inflate } from './libs/Inflate.sol'; +import { INounsArt } from './interfaces/INounsArt.sol'; contract NounsDescriptor is INounsDescriptor, Ownable { using Strings for uint256; @@ -33,6 +34,9 @@ contract NounsDescriptor is INounsDescriptor, Ownable { // https://creativecommons.org/publicdomain/zero/1.0/legalcode.txt bytes32 constant COPYRIGHT_CC0_1_0_UNIVERSAL_LICENSE = 0xa2010f343487d3f7618affe54f789f5487602331c0a8d03f49e9a7c547cf0499; + // The contract responsible for holding compressed Noun art + INounsArt public art; + // The contract responsible for constructing SVGs ISVGRenderer public renderer; @@ -45,24 +49,11 @@ contract NounsDescriptor is INounsDescriptor, Ownable { // Base URI string public override baseURI; - // Noun Color Palettes (Index => Hex Colors) - mapping(uint8 => address) public override palettes; - - // Noun Backgrounds (Hex Colors) - string[] public override backgrounds; uint256[] public backgroundsVirtualIndexToStorageIndex; - - // Noun Bodies (Custom RLE) - Trait public _bodies; - - // Noun Accessories (Custom RLE) - Trait public _accessories; - - // Noun Heads (Custom RLE) - Trait public _heads; - - // Noun Glasses (Custom RLE) - Trait public _glasses; + uint256[] public bodiesVirtualIndexToStorageIndex; + uint256[] public accessoriesVirtualIndexToStorageIndex; + uint256[] public headsVirtualIndexToStorageIndex; + uint256[] public glassesVirtualIndexToStorageIndex; /** * @notice Require that the parts have not been locked. @@ -72,10 +63,21 @@ contract NounsDescriptor is INounsDescriptor, Ownable { _; } - constructor(ISVGRenderer _renderer) { + constructor(INounsArt _art, ISVGRenderer _renderer) { + art = _art; renderer = _renderer; } + /** + * @notice Set the Noun's art contract. + * Only callable by the owner when not locked. + */ + function setArt(INounsArt _art) external onlyOwner whenPartsNotLocked { + art = _art; + + emit ArtUpdated(_art); + } + /** * @notice Set the SVG renderer. * @dev Only callable by the owner. @@ -97,28 +99,28 @@ contract NounsDescriptor is INounsDescriptor, Ownable { * @notice Get the number of available Noun `bodies`. */ function bodyCount() external view override returns (uint256) { - return _bodies.virtualIndexToStorageIndex.length; + return bodiesVirtualIndexToStorageIndex.length; } /** * @notice Get the number of available Noun `accessories`. */ function accessoryCount() external view override returns (uint256) { - return _accessories.virtualIndexToStorageIndex.length; + return accessoriesVirtualIndexToStorageIndex.length; } /** * @notice Get the number of available Noun `heads`. */ function headCount() external view override returns (uint256) { - return _heads.virtualIndexToStorageIndex.length; + return headsVirtualIndexToStorageIndex.length; } /** * @notice Get the number of available Noun `glasses`. */ function glassesCount() external view override returns (uint256) { - return _glasses.virtualIndexToStorageIndex.length; + return glassesVirtualIndexToStorageIndex.length; } /** @@ -126,9 +128,12 @@ contract NounsDescriptor is INounsDescriptor, Ownable { * @dev This function can only be called by the owner when not locked. */ function addManyBackgrounds(string[] calldata _backgrounds) external override onlyOwner whenPartsNotLocked { - for (uint256 i = 0; i < _backgrounds.length; i++) { - _addBackground(_backgrounds[i]); - } + appendToVirtualIndexArray( + backgroundsVirtualIndexToStorageIndex, + uint16(_backgrounds.length), + art.backgroundsCount() + ); + art.addManyBackgrounds(_backgrounds); } /** @@ -136,29 +141,16 @@ contract NounsDescriptor is INounsDescriptor, Ownable { * @dev This function can only be called by the owner when not locked. */ function addBackground(string calldata _background) external override onlyOwner whenPartsNotLocked { - _addBackground(_background); - } - - /** - * @notice Add a Noun background. - */ - function _addBackground(string calldata _background) internal { - backgroundsVirtualIndexToStorageIndex.push(backgrounds.length); - backgrounds.push(_background); + appendToVirtualIndexArray(backgroundsVirtualIndexToStorageIndex, 1, art.backgroundsCount()); + art.addBackground(_background); } /** * @notice Update a single color palette. This function can be used to * add a new color palette or update an existing palette. */ - function setPalette(uint8 paletteIndex, bytes calldata palette) external onlyOwner { - if (palette.length == 0) { - revert EmptyPalette(); - } - if (palette.length % 3 != 0 || palette.length > 768) { - revert BadPaletteLength(); - } - palettes[paletteIndex] = SSTORE2.write(palette); + function setPalette(uint8 paletteIndex, bytes calldata palette) external override onlyOwner { + art.setPalette(paletteIndex, palette); } /** @@ -172,8 +164,9 @@ contract NounsDescriptor is INounsDescriptor, Ownable { bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount - ) external onlyOwner { - addToTraitFromBytes(_bodies, encodedCompressed, decompressedLength, imageCount); + ) external override onlyOwner { + appendToVirtualIndexArray(bodiesVirtualIndexToStorageIndex, imageCount, art.bodiesTrait().storedImagesCount); + art.addBodies(encodedCompressed, decompressedLength, imageCount); } /** @@ -188,7 +181,12 @@ contract NounsDescriptor is INounsDescriptor, Ownable { uint80 decompressedLength, uint16 imageCount ) external onlyOwner { - addToTraitFromBytes(_accessories, encodedCompressed, decompressedLength, imageCount); + appendToVirtualIndexArray( + accessoriesVirtualIndexToStorageIndex, + imageCount, + art.accessoriesTrait().storedImagesCount + ); + art.addAccessories(encodedCompressed, decompressedLength, imageCount); } /** @@ -203,7 +201,8 @@ contract NounsDescriptor is INounsDescriptor, Ownable { uint80 decompressedLength, uint16 imageCount ) external onlyOwner { - addToTraitFromBytes(_heads, encodedCompressed, decompressedLength, imageCount); + appendToVirtualIndexArray(headsVirtualIndexToStorageIndex, imageCount, art.headsTrait().storedImagesCount); + art.addHeads(encodedCompressed, decompressedLength, imageCount); } /** @@ -218,7 +217,8 @@ contract NounsDescriptor is INounsDescriptor, Ownable { uint80 decompressedLength, uint16 imageCount ) external onlyOwner { - addToTraitFromBytes(_glasses, encodedCompressed, decompressedLength, imageCount); + appendToVirtualIndexArray(glassesVirtualIndexToStorageIndex, imageCount, art.glassesTrait().storedImagesCount); + art.addGlasses(encodedCompressed, decompressedLength, imageCount); } /** @@ -234,7 +234,8 @@ contract NounsDescriptor is INounsDescriptor, Ownable { uint80 decompressedLength, uint16 imageCount ) external onlyOwner { - addToTraitFromPointer(_bodies, pointer, decompressedLength, imageCount); + appendToVirtualIndexArray(bodiesVirtualIndexToStorageIndex, imageCount, art.bodiesTrait().storedImagesCount); + art.addBodiesFromPointer(pointer, decompressedLength, imageCount); } /** @@ -250,7 +251,12 @@ contract NounsDescriptor is INounsDescriptor, Ownable { uint80 decompressedLength, uint16 imageCount ) external onlyOwner { - addToTraitFromPointer(_accessories, pointer, decompressedLength, imageCount); + appendToVirtualIndexArray( + accessoriesVirtualIndexToStorageIndex, + imageCount, + art.accessoriesTrait().storedImagesCount + ); + art.addAccessoriesFromPointer(pointer, decompressedLength, imageCount); } /** @@ -266,7 +272,8 @@ contract NounsDescriptor is INounsDescriptor, Ownable { uint80 decompressedLength, uint16 imageCount ) external onlyOwner { - addToTraitFromPointer(_heads, pointer, decompressedLength, imageCount); + appendToVirtualIndexArray(headsVirtualIndexToStorageIndex, imageCount, art.headsTrait().storedImagesCount); + art.addHeadsFromPointer(pointer, decompressedLength, imageCount); } /** @@ -282,7 +289,8 @@ contract NounsDescriptor is INounsDescriptor, Ownable { uint80 decompressedLength, uint16 imageCount ) external onlyOwner { - addToTraitFromPointer(_glasses, pointer, decompressedLength, imageCount); + appendToVirtualIndexArray(glassesVirtualIndexToStorageIndex, imageCount, art.glassesTrait().storedImagesCount); + art.addGlassesFromPointer(pointer, decompressedLength, imageCount); } function retireBackground(uint256 virtualIndex) external onlyOwner { @@ -290,19 +298,19 @@ contract NounsDescriptor is INounsDescriptor, Ownable { } function retireBody(uint256 virtualIndex) external onlyOwner { - retireStorageIndexByVirtualIndex(_bodies.virtualIndexToStorageIndex, virtualIndex); + retireStorageIndexByVirtualIndex(bodiesVirtualIndexToStorageIndex, virtualIndex); } function retireAccessory(uint256 virtualIndex) external onlyOwner { - retireStorageIndexByVirtualIndex(_accessories.virtualIndexToStorageIndex, virtualIndex); + retireStorageIndexByVirtualIndex(accessoriesVirtualIndexToStorageIndex, virtualIndex); } function retireHead(uint256 virtualIndex) external onlyOwner { - retireStorageIndexByVirtualIndex(_heads.virtualIndexToStorageIndex, virtualIndex); + retireStorageIndexByVirtualIndex(headsVirtualIndexToStorageIndex, virtualIndex); } function retireGlasses(uint256 virtualIndex) external onlyOwner { - retireStorageIndexByVirtualIndex(_glasses.virtualIndexToStorageIndex, virtualIndex); + retireStorageIndexByVirtualIndex(glassesVirtualIndexToStorageIndex, virtualIndex); } function backgroundStorageIndex(uint256 virtualIndex) external view returns (uint256) { @@ -310,19 +318,19 @@ contract NounsDescriptor is INounsDescriptor, Ownable { } function bodyStorageIndex(uint256 virtualIndex) external view returns (uint256) { - return traitStorageIndex(_bodies, virtualIndex); + return bodiesVirtualIndexToStorageIndex[virtualIndex]; } function accessoryStorageIndex(uint256 virtualIndex) external view returns (uint256) { - return traitStorageIndex(_accessories, virtualIndex); + return accessoriesVirtualIndexToStorageIndex[virtualIndex]; } function headStorageIndex(uint256 virtualIndex) external view returns (uint256) { - return traitStorageIndex(_heads, virtualIndex); + return headsVirtualIndexToStorageIndex[virtualIndex]; } function glassesStorageIndex(uint256 virtualIndex) external view returns (uint256) { - return traitStorageIndex(_glasses, virtualIndex); + return glassesVirtualIndexToStorageIndex[virtualIndex]; } /** @@ -342,7 +350,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { * @return uint256 virtual index. */ function bodyVirtualIndex(uint256 storageIndex) external view returns (uint256) { - return storageIndexToVirtualIndex(_bodies.virtualIndexToStorageIndex, storageIndex); + return storageIndexToVirtualIndex(bodiesVirtualIndexToStorageIndex, storageIndex); } /** @@ -352,7 +360,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { * @return uint256 virtual index. */ function accessoryVirtualIndex(uint256 storageIndex) external view returns (uint256) { - return storageIndexToVirtualIndex(_accessories.virtualIndexToStorageIndex, storageIndex); + return storageIndexToVirtualIndex(accessoriesVirtualIndexToStorageIndex, storageIndex); } /** @@ -362,7 +370,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { * @return uint256 virtual index. */ function headVirtualIndex(uint256 storageIndex) external view returns (uint256) { - return storageIndexToVirtualIndex(_heads.virtualIndexToStorageIndex, storageIndex); + return storageIndexToVirtualIndex(headsVirtualIndexToStorageIndex, storageIndex); } /** @@ -372,59 +380,31 @@ contract NounsDescriptor is INounsDescriptor, Ownable { * @return uint256 virtual index. */ function glassesVirtualIndex(uint256 storageIndex) external view returns (uint256) { - return storageIndexToVirtualIndex(_glasses.virtualIndexToStorageIndex, storageIndex); - } - - function traitStorageIndex(Trait storage trait, uint256 virtualIndex) internal view returns (uint256) { - return trait.virtualIndexToStorageIndex[virtualIndex]; - } - - function headsPageCount() public view returns (uint256) { - return _heads.storagePages.length; - } - - function bodiesPageCount() public view returns (uint256) { - return _bodies.storagePages.length; + return storageIndexToVirtualIndex(glassesVirtualIndexToStorageIndex, storageIndex); } - function accessoriesPageCount() public view returns (uint256) { - return _accessories.storagePages.length; + function backgrounds(uint256 index) public view override returns (string memory) { + return art.backgrounds(index); } - function glassesPageCount() public view returns (uint256) { - return _glasses.storagePages.length; + function heads(uint256 storageIndex) public view override returns (bytes memory) { + return art.heads(storageIndex); } - function headsPage(uint256 pageIndex) public view returns (NounArtStoragePage memory) { - return _heads.storagePages[pageIndex]; + function bodies(uint256 storageIndex) public view override returns (bytes memory) { + return art.bodies(storageIndex); } - function bodiesPage(uint256 pageIndex) public view returns (NounArtStoragePage memory) { - return _bodies.storagePages[pageIndex]; + function accessories(uint256 storageIndex) public view override returns (bytes memory) { + return art.accessories(storageIndex); } - function accessoriesPage(uint256 pageIndex) public view returns (NounArtStoragePage memory) { - return _accessories.storagePages[pageIndex]; + function glasses(uint256 storageIndex) public view override returns (bytes memory) { + return art.glasses(storageIndex); } - function glassesPage(uint256 pageIndex) public view returns (NounArtStoragePage memory) { - return _glasses.storagePages[pageIndex]; - } - - function heads(uint256 storageIndex) public view returns (bytes memory) { - return imageByStorageIndex(_heads, storageIndex); - } - - function bodies(uint256 storageIndex) public view returns (bytes memory) { - return imageByStorageIndex(_bodies, storageIndex); - } - - function accessories(uint256 storageIndex) public view returns (bytes memory) { - return imageByStorageIndex(_accessories, storageIndex); - } - - function glasses(uint256 storageIndex) public view returns (bytes memory) { - return imageByStorageIndex(_glasses, storageIndex); + function palettes(uint8 paletteIndex) public view override returns (address) { + return art.palettes(paletteIndex); } /** @@ -495,7 +475,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { name: name, description: description, parts: getPartsForSeed(seed), - background: backgrounds[seed.background] + background: art.backgrounds(seed.background) }); return NFTDescriptor.constructTokenURI(renderer, params); } @@ -506,7 +486,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { function generateSVGImage(INounsSeeder.Seed memory seed) external view override returns (string memory) { ISVGRenderer.SVGParams memory params = ISVGRenderer.SVGParams({ parts: getPartsForSeed(seed), - background: backgrounds[seed.background] + background: art.backgrounds(seed.background) }); return NFTDescriptor.generateSVGImage(renderer, params); } @@ -515,10 +495,10 @@ contract NounsDescriptor is INounsDescriptor, Ownable { * @notice Get all Noun parts for the passed `seed`. */ function getPartsForSeed(INounsSeeder.Seed memory seed) public view returns (ISVGRenderer.Part[] memory) { - bytes memory _body = bodies(seed.body); - bytes memory _accessory = accessories(seed.accessory); - bytes memory _head = heads(seed.head); - bytes memory _glassesBytes = glasses(seed.glasses); + bytes memory _body = art.bodies(seed.body); + bytes memory _accessory = art.accessories(seed.accessory); + bytes memory _head = art.heads(seed.head); + bytes memory _glassesBytes = art.glasses(seed.glasses); ISVGRenderer.Part[] memory _parts = new ISVGRenderer.Part[](4); _parts[0] = ISVGRenderer.Part({ image: _body, palette: _getPalette(_body) }); @@ -532,72 +512,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { * @notice Get the color palette pointer for the passed part. */ function _getPalette(bytes memory part) private view returns (address) { - return palettes[uint8(part[0])]; - } - - function imageByStorageIndex(Trait storage trait, uint256 storageIndex) internal view returns (bytes memory) { - (NounArtStoragePage storage page, uint256 indexInPage) = getPage(trait.storagePages, storageIndex); - bytes[] memory decompressedImages = decompressAndDecode(page); - return decompressedImages[indexInPage]; - } - - function getPage(NounArtStoragePage[] storage pages, uint256 storageIndex) - internal - view - returns (NounArtStoragePage storage, uint256) - { - uint256 len = pages.length; - if (len == 0) { - revert NoPages(); - } - - uint256 pageFirstImageIndex = 0; - for (uint256 i = 0; i < len; i++) { - NounArtStoragePage storage page = pages[i]; - - if (storageIndex < pageFirstImageIndex + page.imageCount) { - return (page, storageIndex - pageFirstImageIndex); - } - - pageFirstImageIndex += page.imageCount; - } - - revert ImageNotFound(); - } - - function decompressAndDecode(NounArtStoragePage storage page) internal view returns (bytes[] memory) { - bytes memory compressedData = SSTORE2.read(page.pointer); - (, bytes memory decompressedData) = Inflate.puff(compressedData, page.decompressedLength); - return abi.decode(decompressedData, (bytes[])); - } - - function addToTraitFromBytes( - Trait storage trait, - bytes calldata encodedCompressed, - uint80 decompressedLength, - uint16 imageCount - ) internal { - address pointer = SSTORE2.write(encodedCompressed); - addToTraitFromPointer(trait, pointer, decompressedLength, imageCount); - } - - function addToTraitFromPointer( - Trait storage trait, - address pointer, - uint80 decompressedLength, - uint16 imageCount - ) internal { - trait.storagePages.push( - NounArtStoragePage({ pointer: pointer, decompressedLength: decompressedLength, imageCount: imageCount }) - ); - - uint256 storedImageCount = trait.storedImagesCount; - - for (uint256 i = 0; i < imageCount; i++) { - trait.virtualIndexToStorageIndex.push(storedImageCount + i); - } - - trait.storedImagesCount += imageCount; + return art.palettes(uint8(part[0])); } function retireStorageIndexByVirtualIndex(uint256[] storage virtualToStorageArray, uint256 virtualIndex) internal { @@ -619,4 +534,14 @@ contract NounsDescriptor is INounsDescriptor, Ownable { revert IndexNotFound(); } + + function appendToVirtualIndexArray( + uint256[] storage mappingArray, + uint16 imageCount, + uint256 storedImageCount + ) internal { + for (uint256 i = 0; i < imageCount; i++) { + mappingArray.push(storedImageCount + i); + } + } } diff --git a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol new file mode 100644 index 0000000000..1a6cc65333 --- /dev/null +++ b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: GPL-3.0 + +/// @title Interface for NounsArt + +/********************************* + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░██░░░████░░██░░░████░░░ * + * ░░██████░░░████████░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + *********************************/ + +pragma solidity ^0.8.12; + +interface INounsArt { + error SenderIsNotDescriptor(); + + error SenderIsNotPendingDescriptor(); + + error EmptyPalette(); + + error BadPaletteLength(); + + error NoPages(); + + error ImageNotFound(); + + event DescriptorUpdated(address oldDescriptor, address newDescriptor); + + struct NounArtStoragePage { + uint16 imageCount; + uint80 decompressedLength; + address pointer; + } + + struct Trait { + NounArtStoragePage[] storagePages; + uint256 storedImagesCount; + } + + function descriptor() external view returns (address); + + function pendingDescriptor() external view returns (address); + + function setDescriptor(address pendingDescriptor) external; + + function confirmDescriptor() external; + + function addManyBackgrounds(string[] calldata _backgrounds) external; + + function addBackground(string calldata _background) external; + + function palettes(uint8 paletteIndex) external view returns (address); + + function setPalette(uint8 paletteIndex, bytes calldata palette) external; + + function addBodies( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function addAccessories( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function addHeads( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function addGlasses( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function addBodiesFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function addAccessoriesFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function addHeadsFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function addGlassesFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function backgroundsCount() external view returns (uint256); + + function headsPageCount() external view returns (uint256); + + function bodiesPageCount() external view returns (uint256); + + function accessoriesPageCount() external view returns (uint256); + + function glassesPageCount() external view returns (uint256); + + function headsPage(uint256 pageIndex) external view returns (INounsArt.NounArtStoragePage memory); + + function bodiesPage(uint256 pageIndex) external view returns (INounsArt.NounArtStoragePage memory); + + function accessoriesPage(uint256 pageIndex) external view returns (INounsArt.NounArtStoragePage memory); + + function glassesPage(uint256 pageIndex) external view returns (INounsArt.NounArtStoragePage memory); + + function backgrounds(uint256 index) external view returns (string memory); + + function heads(uint256 storageIndex) external view returns (bytes memory); + + function bodies(uint256 storageIndex) external view returns (bytes memory); + + function accessories(uint256 storageIndex) external view returns (bytes memory); + + function glasses(uint256 storageIndex) external view returns (bytes memory); + + function bodiesTrait() external view returns (Trait memory); + + function accessoriesTrait() external view returns (Trait memory); + + function headsTrait() external view returns (Trait memory); + + function glassesTrait() external view returns (Trait memory); +} diff --git a/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol b/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol index 7c2984f945..9401cad5cd 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol @@ -19,6 +19,7 @@ pragma solidity ^0.8.6; import { INounsSeeder } from './INounsSeeder.sol'; import { ISVGRenderer } from './ISVGRenderer.sol'; +import { INounsArt } from './INounsArt.sol'; interface INounsDescriptor { event PartsLocked(); @@ -27,26 +28,14 @@ interface INounsDescriptor { event BaseURIUpdated(string baseURI); + event ArtUpdated(INounsArt art); + event RendererUpdated(ISVGRenderer renderer); error EmptyPalette(); error BadPaletteLength(); - error NoPages(); - error ImageNotFound(); error IndexNotFound(); - struct NounArtStoragePage { - uint16 imageCount; - uint80 decompressedLength; - address pointer; - } - - struct Trait { - NounArtStoragePage[] storagePages; - uint256[] virtualIndexToStorageIndex; - uint256 storedImagesCount; - } - function arePartsLocked() external returns (bool); function isDataURIEnabled() external returns (bool); @@ -75,22 +64,6 @@ interface INounsDescriptor { function glassesCount() external view returns (uint256); - function headsPageCount() external view returns (uint256); - - function bodiesPageCount() external view returns (uint256); - - function accessoriesPageCount() external view returns (uint256); - - function glassesPageCount() external view returns (uint256); - - function headsPage(uint256 pageIndex) external view returns (NounArtStoragePage memory); - - function bodiesPage(uint256 pageIndex) external view returns (NounArtStoragePage memory); - - function accessoriesPage(uint256 pageIndex) external view returns (NounArtStoragePage memory); - - function glassesPage(uint256 pageIndex) external view returns (NounArtStoragePage memory); - function addManyBackgrounds(string[] calldata backgrounds) external; function addBackground(string calldata background) external; From a18efa9db5e934802014be5de38a2ac7216434c7 Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Mon, 20 Jun 2022 09:41:42 +0200 Subject: [PATCH 012/116] palette is passed as bytes array param --- .../nouns-contracts/contracts/NounsArt.sol | 8 ++++++-- .../contracts/NounsDescriptor.sol | 4 ++-- .../nouns-contracts/contracts/SVGRenderer.sol | 18 +++++------------- .../contracts/interfaces/INounsArt.sol | 2 +- .../contracts/interfaces/INounsDescriptor.sol | 2 +- .../contracts/interfaces/ISVGRenderer.sol | 2 +- 6 files changed, 16 insertions(+), 20 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsArt.sol b/packages/nouns-contracts/contracts/NounsArt.sol index 421340f5be..53903e6fa8 100644 --- a/packages/nouns-contracts/contracts/NounsArt.sol +++ b/packages/nouns-contracts/contracts/NounsArt.sol @@ -32,7 +32,7 @@ contract NounsArt is INounsArt { string[] public backgrounds; // Noun Color Palettes (Index => Hex Colors) - mapping(uint8 => address) public override palettes; + mapping(uint8 => address) public palettesPointers; // Noun Bodies (Custom RLE) Trait public _bodies; @@ -118,7 +118,7 @@ contract NounsArt is INounsArt { if (palette.length % 3 != 0 || palette.length > 768) { revert BadPaletteLength(); } - palettes[paletteIndex] = SSTORE2.write(palette); + palettesPointers[paletteIndex] = SSTORE2.write(palette); } function addBodies( @@ -237,6 +237,10 @@ contract NounsArt is INounsArt { return imageByStorageIndex(_glasses, storageIndex); } + function palettes(uint8 paletteIndex) public view override returns (bytes memory) { + return SSTORE2.read(palettesPointers[paletteIndex]); + } + function addToTraitFromBytes( Trait storage trait, bytes calldata encodedCompressed, diff --git a/packages/nouns-contracts/contracts/NounsDescriptor.sol b/packages/nouns-contracts/contracts/NounsDescriptor.sol index d4ddd3c78a..ba95434597 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptor.sol @@ -403,7 +403,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { return art.glasses(storageIndex); } - function palettes(uint8 paletteIndex) public view override returns (address) { + function palettes(uint8 paletteIndex) public view override returns (bytes memory) { return art.palettes(paletteIndex); } @@ -511,7 +511,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { /** * @notice Get the color palette pointer for the passed part. */ - function _getPalette(bytes memory part) private view returns (address) { + function _getPalette(bytes memory part) private view returns (bytes memory) { return art.palettes(uint8(part[0])); } diff --git a/packages/nouns-contracts/contracts/SVGRenderer.sol b/packages/nouns-contracts/contracts/SVGRenderer.sol index f7a400fc7b..a343558fe2 100644 --- a/packages/nouns-contracts/contracts/SVGRenderer.sol +++ b/packages/nouns-contracts/contracts/SVGRenderer.sol @@ -18,7 +18,6 @@ pragma solidity ^0.8.12; import { ISVGRenderer } from './interfaces/ISVGRenderer.sol'; -import { SSTORE2 } from './libs/SSTORE2.sol'; contract SVGRenderer is ISVGRenderer { bytes16 private constant _HEX_SYMBOLS = '0123456789abcdef'; @@ -48,7 +47,7 @@ contract SVGRenderer is ISVGRenderer { /** * @notice Given RLE image data and color palette pointers, merge to generate a single SVG image. */ - function generateSVG(SVGParams calldata params) external view returns (string memory svg) { + function generateSVG(SVGParams calldata params) external pure returns (string memory svg) { if (bytes(params.background).length != 0) { // prettier-ignore return string( @@ -66,7 +65,7 @@ contract SVGRenderer is ISVGRenderer { /** * @notice Given RLE image data and a color palette pointer, merge to generate a partial SVG image. */ - function generateSVGPart(Part calldata part) external view returns (string memory partialSVG) { + function generateSVGPart(Part calldata part) external pure returns (string memory partialSVG) { Part[] memory parts = new Part[](1); parts[0] = part; @@ -76,7 +75,7 @@ contract SVGRenderer is ISVGRenderer { /** * @notice Given RLE image data and color palette pointers, merge to generate a partial SVG image. */ - function generateSVGParts(Part[] calldata parts) external view returns (string memory partialSVG) { + function generateSVGParts(Part[] calldata parts) external pure returns (string memory partialSVG) { return _generateSVGRects(SVGParams({ parts: parts, background: '' })); } @@ -86,7 +85,7 @@ contract SVGRenderer is ISVGRenderer { // prettier-ignore function _generateSVGRects(SVGParams memory params) private - view + pure returns (string memory svg) { string[33] memory lookup = [ @@ -102,7 +101,7 @@ contract SVGRenderer is ISVGRenderer { cache = new string[](256); // Initialize color cache DecodedImage memory image = _decodeRLEImage(params.parts[p].image); - bytes memory palette = _getPalette(params.parts[p].palette); + bytes memory palette = params.parts[p].palette; uint256 currentX = image.bounds.left; uint256 currentY = image.bounds.top; uint256 cursor; @@ -197,13 +196,6 @@ contract SVGRenderer is ISVGRenderer { return DecodedImage({ bounds: bounds, draws: draws }); } - /** - * @notice Fetch the color palette stored at the provided `pointer`. - */ - function _getPalette(address pointer) private view returns (bytes memory palette) { - palette = SSTORE2.read(pointer); - } - /** * @notice Get the target hex color code from the cache. Populate the cache if * the color code does not yet exist. diff --git a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol index 1a6cc65333..6c02d974f7 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol @@ -55,7 +55,7 @@ interface INounsArt { function addBackground(string calldata _background) external; - function palettes(uint8 paletteIndex) external view returns (address); + function palettes(uint8 paletteIndex) external view returns (bytes memory); function setPalette(uint8 paletteIndex, bytes calldata palette) external; diff --git a/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol b/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol index 9401cad5cd..90f5364789 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol @@ -42,7 +42,7 @@ interface INounsDescriptor { function baseURI() external returns (string memory); - function palettes(uint8 paletteIndex) external view returns (address); + function palettes(uint8 paletteIndex) external view returns (bytes memory); function backgrounds(uint256 index) external view returns (string memory); diff --git a/packages/nouns-contracts/contracts/interfaces/ISVGRenderer.sol b/packages/nouns-contracts/contracts/interfaces/ISVGRenderer.sol index 9cab82ae36..5bfb118f43 100644 --- a/packages/nouns-contracts/contracts/interfaces/ISVGRenderer.sol +++ b/packages/nouns-contracts/contracts/interfaces/ISVGRenderer.sol @@ -23,7 +23,7 @@ pragma solidity ^0.8.12; interface ISVGRenderer { struct Part { bytes image; - address palette; + bytes palette; } struct SVGParams { From 991ed789762158212338763b89b16c8e12697b68 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Mon, 27 Jun 2022 10:47:13 -0500 Subject: [PATCH 013/116] fix broken tests --- .../nouns-contracts/contracts/NounsArt.sol | 4 + .../nouns-contracts/test/descriptor.test.ts | 20 +-- .../NounsDAO/inflationHandling.test.ts | 53 +------- .../test/governance/NounsDAO/vetoing.test.ts | 45 +----- packages/nouns-contracts/test/utils.ts | 128 ++++++++++++++++-- 5 files changed, 149 insertions(+), 101 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsArt.sol b/packages/nouns-contracts/contracts/NounsArt.sol index 53903e6fa8..712509f24f 100644 --- a/packages/nouns-contracts/contracts/NounsArt.sol +++ b/packages/nouns-contracts/contracts/NounsArt.sol @@ -56,6 +56,10 @@ contract NounsArt is INounsArt { _; } + constructor(address _descriptor) { + descriptor = _descriptor; + } + /** * @notice Set the pending descriptor, which can be confirmed * by calling `confirmDescriptor`. diff --git a/packages/nouns-contracts/test/descriptor.test.ts b/packages/nouns-contracts/test/descriptor.test.ts index 85d339aa67..4142b10053 100644 --- a/packages/nouns-contracts/test/descriptor.test.ts +++ b/packages/nouns-contracts/test/descriptor.test.ts @@ -67,13 +67,17 @@ describe('NounsDescriptor', () => { }); it('should generate valid token uri metadata when data uris are enabled', async () => { - const tokenUri = await nounsDescriptor.tokenURI(0, { - background: 0, - body: longest.bodies.index, - accessory: longest.accessories.index, - head: longest.heads.index, - glasses: longest.glasses.index, - }); + const tokenUri = await nounsDescriptor.tokenURI( + 0, + { + background: 0, + body: longest.bodies.index, + accessory: longest.accessories.index, + head: longest.heads.index, + glasses: longest.glasses.index, + }, + { gasLimit: 200_000_000 }, + ); const { name, description, image } = JSON.parse( Buffer.from(tokenUri.replace('data:application/json;base64,', ''), 'base64').toString( 'ascii', @@ -82,7 +86,7 @@ describe('NounsDescriptor', () => { expect(name).to.equal('Noun 0'); expect(description).to.equal('Noun 0 is a member of the Nouns DAO'); expect(image).to.not.be.undefined; - }); + }).timeout(100_000); // Unskip this test to validate the encoding of all parts. It ensures that no parts revert when building the token URI. // This test also outputs a parts.html file, which can be visually inspected. diff --git a/packages/nouns-contracts/test/governance/NounsDAO/inflationHandling.test.ts b/packages/nouns-contracts/test/governance/NounsDAO/inflationHandling.test.ts index d17306d30c..1dde3ee858 100644 --- a/packages/nouns-contracts/test/governance/NounsDAO/inflationHandling.test.ts +++ b/packages/nouns-contracts/test/governance/NounsDAO/inflationHandling.test.ts @@ -12,6 +12,7 @@ import { TestSigners, setTotalSupply, populateDescriptor, + deployGovAndToken, } from '../../utils'; import { mineBlock, address, encodeParameters, advanceBlocks } from '../../utils'; @@ -29,51 +30,6 @@ import { chai.use(solidity); const { expect } = chai; -async function reset(): Promise { - // nonce 0: Deploy NounsDAOExecutor - // nonce 1: Deploy NounsDAOLogicV1 - // nonce 2: Deploy nftDescriptorLibraryFactory - // nonce 3: Deploy NounsDescriptor - // nonce 4: Deploy NounsSeeder - // nonce 5: Deploy NounsToken - // nonce 6: Deploy NounsDAOProxy - // nonce 7+: populate Descriptor - - const govDelegatorAddress = ethers.utils.getContractAddress({ - from: deployer.address, - nonce: (await deployer.getTransactionCount()) + 6, - }); - - // Deploy NounsDAOExecutor with pre-computed Delegator address - const { address: timelockAddress } = await new NounsDaoExecutorFactory(deployer).deploy( - govDelegatorAddress, - timelockDelay, - ); - - // Deploy Delegate - const { address: govDelegateAddress } = await new NounsDaoLogicV1Factory(deployer).deploy(); - // Deploy Nouns token - token = await deployNounsToken(deployer); - - // Deploy Delegator - await new NounsDaoProxyFactory(deployer).deploy( - timelockAddress, - token.address, - address(0), - timelockAddress, - govDelegateAddress, - 5760, - 1, - proposalThresholdBPS, - quorumVotesBPS, - ); - - // Cast Delegator as Delegate - gov = NounsDaoLogicV1Factory.connect(govDelegatorAddress, deployer); - - await populateDescriptor(NounsDescriptorFactory.connect(await token.descriptor(), deployer)); -} - async function propose(proposer: SignerWithAddress) { targets = [account0.address]; values = ['0']; @@ -116,7 +72,12 @@ describe('NounsDAO#inflationHandling', () => { signatures = ['getBalanceOf(address)']; callDatas = [encodeParameters(['address'], [account0.address])]; - await reset(); + ({ token, gov } = await deployGovAndToken( + deployer, + timelockDelay, + proposalThresholdBPS, + quorumVotesBPS, + )); }); it('set parameters correctly', async () => { diff --git a/packages/nouns-contracts/test/governance/NounsDAO/vetoing.test.ts b/packages/nouns-contracts/test/governance/NounsDAO/vetoing.test.ts index 77d4bba3a5..9abf25dbfc 100644 --- a/packages/nouns-contracts/test/governance/NounsDAO/vetoing.test.ts +++ b/packages/nouns-contracts/test/governance/NounsDAO/vetoing.test.ts @@ -12,6 +12,7 @@ import { TestSigners, setTotalSupply, populateDescriptor, + deployGovAndToken, } from '../../utils'; import { @@ -59,49 +60,15 @@ async function reset(): Promise { return; } - // nonce 0: Deploy NounsDAOExecutor - // nonce 1: Deploy NounsDAOLogicV1 - // nonce 2: Deploy nftDescriptorLibraryFactory - // nonce 3: Deploy NounsDescriptor - // nonce 4: Deploy NounsSeeder - // nonce 5: Deploy NounsToken - // nonce 6: Deploy NounsDAOProxy - // nonce 7+: populate Descriptor - vetoer = deployer; - const govDelegatorAddress = ethers.utils.getContractAddress({ - from: deployer.address, - nonce: (await deployer.getTransactionCount()) + 6, - }); - - // Deploy NounsDAOExecutor with pre-computed Delegator address - timelock = await new NounsDaoExecutorFactory(deployer).deploy(govDelegatorAddress, timelockDelay); - const timelockAddress = timelock.address; - - // Deploy Delegate - const { address: govDelegateAddress } = await new NounsDaoLogicV1Factory(deployer).deploy(); - - // Deploy Nouns token - token = await deployNounsToken(deployer); - - // Deploy Delegator - await new NounsDaoProxyFactory(deployer).deploy( - timelockAddress, - token.address, - vetoer.address, - timelockAddress, - govDelegateAddress, - 5760, - 1, + ({ token, gov, timelock } = await deployGovAndToken( + deployer, + timelockDelay, proposalThresholdBPS, quorumVotesBPS, - ); - - // Cast Delegator as Delegate - gov = NounsDaoLogicV1Factory.connect(govDelegatorAddress, deployer); - - await populateDescriptor(NounsDescriptorFactory.connect(await token.descriptor(), deployer)); + vetoer.address, + )); snapshotId = await ethers.provider.send('evm_snapshot', []); } diff --git a/packages/nouns-contracts/test/utils.ts b/packages/nouns-contracts/test/utils.ts index 3cf713ec25..f0538b120b 100644 --- a/packages/nouns-contracts/test/utils.ts +++ b/packages/nouns-contracts/test/utils.ts @@ -9,10 +9,18 @@ import { NounsSeeder__factory as NounsSeederFactory, WETH, WETH__factory as WethFactory, + NounsArt__factory as NounsArtFactory, + SVGRenderer__factory as SVGRendererFactory, + NounsDAOExecutor__factory as NounsDaoExecutorFactory, + NounsDAOLogicV1__factory as NounsDaoLogicV1Factory, + NounsDAOProxy__factory as NounsDaoProxyFactory, + NounsDAOLogicV1, + NounsDAOExecutor, } from '../typechain'; import ImageData from '../files/image-data.json'; import { Block } from '@ethersproject/abstract-provider'; import { chunkArray } from '../utils'; +import { deflateRawSync } from 'zlib'; export type TestSigners = { deployer: SignerWithAddress; @@ -44,7 +52,16 @@ export const deployNounsDescriptor = async ( signer, ); - return nounsDescriptorFactory.deploy(); + const renderer = await new SVGRendererFactory(signer).deploy(); + const descriptor = await nounsDescriptorFactory.deploy( + ethers.constants.AddressZero, + renderer.address, + ); + + const art = await new NounsArtFactory(signer).deploy(descriptor.address); + await descriptor.setArt(art.address); + + return descriptor; }; export const deployNounsSeeder = async (deployer?: SignerWithAddress): Promise => { @@ -83,19 +100,94 @@ export const populateDescriptor = async (nounsDescriptor: NounsDescriptor): Prom const { bgcolors, palette, images } = ImageData; const { bodies, accessories, heads, glasses } = images; + const { + encodedCompressed: bodiesCompressed, + originalLength: bodiesLength, + itemCount: bodiesCount, + } = dataToDescriptorInput(bodies.map(({ data }) => data)); + const { + encodedCompressed: accessoriesCompressed, + originalLength: accessoriesLength, + itemCount: accessoriesCount, + } = dataToDescriptorInput(accessories.map(({ data }) => data)); + const { + encodedCompressed: headsCompressed, + originalLength: headsLength, + itemCount: headsCount, + } = dataToDescriptorInput(heads.map(({ data }) => data)); + const { + encodedCompressed: glassesCompressed, + originalLength: glassesLength, + itemCount: glassesCount, + } = dataToDescriptorInput(glasses.map(({ data }) => data)); + // Split up head and accessory population due to high gas usage await Promise.all([ nounsDescriptor.addManyBackgrounds(bgcolors), - nounsDescriptor.addManyColorsToPalette(0, palette), - nounsDescriptor.addManyBodies(bodies.map(({ data }) => data)), - chunkArray(accessories, 10).map(chunk => - nounsDescriptor.addManyAccessories(chunk.map(({ data }) => data)), - ), - chunkArray(heads, 10).map(chunk => nounsDescriptor.addManyHeads(chunk.map(({ data }) => data))), - nounsDescriptor.addManyGlasses(glasses.map(({ data }) => data)), + nounsDescriptor.setPalette(0, `0x000000${palette.join('')}`), + nounsDescriptor.addBodies(bodiesCompressed, bodiesLength, bodiesCount), + nounsDescriptor.addAccessories(accessoriesCompressed, accessoriesLength, accessoriesCount), + nounsDescriptor.addHeads(headsCompressed, headsLength, headsCount), + nounsDescriptor.addGlasses(glassesCompressed, glassesLength, glassesCount), ]); }; +export const deployGovAndToken = async ( + deployer: SignerWithAddress, + timelockDelay: number, + proposalThresholdBPS: number, + quorumVotesBPS: number, + vetoer?: string, +): Promise<{ token: NounsToken; gov: NounsDAOLogicV1; timelock: NounsDAOExecutor }> => { + // nonce 0: Deploy NounsDAOExecutor + // nonce 1: Deploy NounsDAOLogicV1 + // nonce 2: Deploy nftDescriptorLibraryFactory + // nonce 3: Deploy SVGRenderer + // nonce 4: Deploy NounsDescriptor + // nonce 5: Deploy NounsArt + // nonce 6: NounsDescriptor.setArt + // nonce 7: Deploy NounsSeeder + // nonce 8: Deploy NounsToken + // nonce 9: Deploy NounsDAOProxy + // nonce 10+: populate Descriptor + + const govDelegatorAddress = ethers.utils.getContractAddress({ + from: deployer.address, + nonce: (await deployer.getTransactionCount()) + 9, + }); + + // Deploy NounsDAOExecutor with pre-computed Delegator address + const timelock = await new NounsDaoExecutorFactory(deployer).deploy( + govDelegatorAddress, + timelockDelay, + ); + + // Deploy Delegate + const { address: govDelegateAddress } = await new NounsDaoLogicV1Factory(deployer).deploy(); + // Deploy Nouns token + const token = await deployNounsToken(deployer); + + // Deploy Delegator + await new NounsDaoProxyFactory(deployer).deploy( + timelock.address, + token.address, + vetoer || address(0), + timelock.address, + govDelegateAddress, + 5760, + 1, + proposalThresholdBPS, + quorumVotesBPS, + ); + + // Cast Delegator as Delegate + const gov = NounsDaoLogicV1Factory.connect(govDelegatorAddress, deployer); + + await populateDescriptor(NounsDescriptorFactory.connect(await token.descriptor(), deployer)); + + return { token, gov, timelock }; +}; + /** * Return a function used to mint `amount` Nouns on the provided `token` * @param token The Nouns ERC721 token @@ -211,3 +303,23 @@ export const chainId = async (): Promise => { export const address = (n: number): string => { return `0x${n.toString(16).padStart(40, '0')}`; }; + +function dataToDescriptorInput(data: string[]): { + encodedCompressed: string; + originalLength: number; + itemCount: number; +} { + const abiEncoded = ethers.utils.defaultAbiCoder.encode(['bytes[]'], [data]); + const encodedCompressed = `0x${deflateRawSync( + Buffer.from(abiEncoded.substring(2), 'hex'), + ).toString('hex')}`; + + const originalLength = abiEncoded.substring(2).length / 2; + const itemCount = data.length; + + return { + encodedCompressed, + originalLength, + itemCount, + }; +} From 32f126fcb5cbb06985371e9a0a7fd4ffd41d24fd Mon Sep 17 00:00:00 2001 From: eladmallel Date: Mon, 27 Jun 2022 10:47:32 -0500 Subject: [PATCH 014/116] cleanup: remove example fork contract --- .../ExampleForkFastFoodSVGRenderer.sol | 61 ------------------- 1 file changed, 61 deletions(-) delete mode 100644 packages/nouns-contracts/contracts/ExampleForkFastFoodSVGRenderer.sol diff --git a/packages/nouns-contracts/contracts/ExampleForkFastFoodSVGRenderer.sol b/packages/nouns-contracts/contracts/ExampleForkFastFoodSVGRenderer.sol deleted file mode 100644 index 944e00b3ba..0000000000 --- a/packages/nouns-contracts/contracts/ExampleForkFastFoodSVGRenderer.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 - -/// @title A contract used to convert multi-part RLE compressed images to SVG - -/********************************* - * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * - * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * - * ░░░░░░█████████░░█████████░░░ * - * ░░░░░░██░░░████░░██░░░████░░░ * - * ░░██████░░░████████░░░████░░░ * - * ░░██░░██░░░████░░██░░░████░░░ * - * ░░██░░██░░░████░░██░░░████░░░ * - * ░░░░░░█████████░░█████████░░░ * - * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * - * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * - *********************************/ - -pragma solidity ^0.8.12; - -import { ISVGRenderer } from './interfaces/ISVGRenderer.sol'; -import { SSTORE2 } from './libs/SSTORE2.sol'; - -contract ExampleForkFastFoodSVGRenderer is ISVGRenderer { - // prettier-ignore - string private constant _SVG_START_TAG = ''; - string private constant _SVG_END_TAG = ''; - string private constant _FAST_FOOD_HAT = - ''; - - ISVGRenderer private nounsRenderer; - - constructor(ISVGRenderer _nounsRenderer) { - nounsRenderer = _nounsRenderer; - } - - /** - * @notice Given RLE image data and color palette pointers, merge to generate a single SVG image. - */ - function generateSVG(SVGParams calldata params) external view returns (string memory svg) { - // prettier-ignore - return string( - abi.encodePacked( - _SVG_START_TAG, - '', - nounsRenderer.generateSVGParts(params.parts), - _FAST_FOOD_HAT, - _SVG_END_TAG - ) - ); - } - - // these functions can be removed from the interface in a real fork, they aren't used by the descriptor - - function generateSVGPart(Part memory part) external view returns (string memory partialSVG) { - return ''; - } - - function generateSVGParts(Part[] memory parts) external view returns (string memory partialSVG) { - return ''; - } -} From f2063264ec3a17e6b15d518bea4633be3c7c30df Mon Sep 17 00:00:00 2001 From: eladmallel Date: Mon, 27 Jun 2022 11:21:00 -0500 Subject: [PATCH 015/116] cleanup image retirement code --- .../contracts/NounsDescriptor.sol | 194 ++++-------------- .../nouns-contracts/contracts/NounsSeeder.sol | 20 +- .../contracts/interfaces/INounsDescriptor.sol | 120 ----------- 3 files changed, 42 insertions(+), 292 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsDescriptor.sol b/packages/nouns-contracts/contracts/NounsDescriptor.sol index ba95434597..1380b6c288 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptor.sol @@ -23,8 +23,6 @@ import { INounsDescriptor } from './interfaces/INounsDescriptor.sol'; import { INounsSeeder } from './interfaces/INounsSeeder.sol'; import { NFTDescriptor } from './libs/NFTDescriptor.sol'; import { ISVGRenderer } from './interfaces/ISVGRenderer.sol'; -import { SSTORE2 } from './libs/SSTORE2.sol'; -import { Inflate } from './libs/Inflate.sol'; import { INounsArt } from './interfaces/INounsArt.sol'; contract NounsDescriptor is INounsDescriptor, Ownable { @@ -49,12 +47,6 @@ contract NounsDescriptor is INounsDescriptor, Ownable { // Base URI string public override baseURI; - uint256[] public backgroundsVirtualIndexToStorageIndex; - uint256[] public bodiesVirtualIndexToStorageIndex; - uint256[] public accessoriesVirtualIndexToStorageIndex; - uint256[] public headsVirtualIndexToStorageIndex; - uint256[] public glassesVirtualIndexToStorageIndex; - /** * @notice Require that the parts have not been locked. */ @@ -92,35 +84,35 @@ contract NounsDescriptor is INounsDescriptor, Ownable { * @notice Get the number of available Noun `backgrounds`. */ function backgroundCount() external view override returns (uint256) { - return backgroundsVirtualIndexToStorageIndex.length; + return art.backgroundsCount(); } /** * @notice Get the number of available Noun `bodies`. */ function bodyCount() external view override returns (uint256) { - return bodiesVirtualIndexToStorageIndex.length; + return art.bodiesTrait().storedImagesCount; } /** * @notice Get the number of available Noun `accessories`. */ function accessoryCount() external view override returns (uint256) { - return accessoriesVirtualIndexToStorageIndex.length; + return art.accessoriesTrait().storedImagesCount; } /** * @notice Get the number of available Noun `heads`. */ function headCount() external view override returns (uint256) { - return headsVirtualIndexToStorageIndex.length; + return art.headsTrait().storedImagesCount; } /** * @notice Get the number of available Noun `glasses`. */ function glassesCount() external view override returns (uint256) { - return glassesVirtualIndexToStorageIndex.length; + return art.glassesTrait().storedImagesCount; } /** @@ -128,11 +120,6 @@ contract NounsDescriptor is INounsDescriptor, Ownable { * @dev This function can only be called by the owner when not locked. */ function addManyBackgrounds(string[] calldata _backgrounds) external override onlyOwner whenPartsNotLocked { - appendToVirtualIndexArray( - backgroundsVirtualIndexToStorageIndex, - uint16(_backgrounds.length), - art.backgroundsCount() - ); art.addManyBackgrounds(_backgrounds); } @@ -141,7 +128,6 @@ contract NounsDescriptor is INounsDescriptor, Ownable { * @dev This function can only be called by the owner when not locked. */ function addBackground(string calldata _background) external override onlyOwner whenPartsNotLocked { - appendToVirtualIndexArray(backgroundsVirtualIndexToStorageIndex, 1, art.backgroundsCount()); art.addBackground(_background); } @@ -165,7 +151,6 @@ contract NounsDescriptor is INounsDescriptor, Ownable { uint80 decompressedLength, uint16 imageCount ) external override onlyOwner { - appendToVirtualIndexArray(bodiesVirtualIndexToStorageIndex, imageCount, art.bodiesTrait().storedImagesCount); art.addBodies(encodedCompressed, decompressedLength, imageCount); } @@ -181,11 +166,6 @@ contract NounsDescriptor is INounsDescriptor, Ownable { uint80 decompressedLength, uint16 imageCount ) external onlyOwner { - appendToVirtualIndexArray( - accessoriesVirtualIndexToStorageIndex, - imageCount, - art.accessoriesTrait().storedImagesCount - ); art.addAccessories(encodedCompressed, decompressedLength, imageCount); } @@ -201,7 +181,6 @@ contract NounsDescriptor is INounsDescriptor, Ownable { uint80 decompressedLength, uint16 imageCount ) external onlyOwner { - appendToVirtualIndexArray(headsVirtualIndexToStorageIndex, imageCount, art.headsTrait().storedImagesCount); art.addHeads(encodedCompressed, decompressedLength, imageCount); } @@ -217,7 +196,6 @@ contract NounsDescriptor is INounsDescriptor, Ownable { uint80 decompressedLength, uint16 imageCount ) external onlyOwner { - appendToVirtualIndexArray(glassesVirtualIndexToStorageIndex, imageCount, art.glassesTrait().storedImagesCount); art.addGlasses(encodedCompressed, decompressedLength, imageCount); } @@ -234,7 +212,6 @@ contract NounsDescriptor is INounsDescriptor, Ownable { uint80 decompressedLength, uint16 imageCount ) external onlyOwner { - appendToVirtualIndexArray(bodiesVirtualIndexToStorageIndex, imageCount, art.bodiesTrait().storedImagesCount); art.addBodiesFromPointer(pointer, decompressedLength, imageCount); } @@ -251,11 +228,6 @@ contract NounsDescriptor is INounsDescriptor, Ownable { uint80 decompressedLength, uint16 imageCount ) external onlyOwner { - appendToVirtualIndexArray( - accessoriesVirtualIndexToStorageIndex, - imageCount, - art.accessoriesTrait().storedImagesCount - ); art.addAccessoriesFromPointer(pointer, decompressedLength, imageCount); } @@ -272,7 +244,6 @@ contract NounsDescriptor is INounsDescriptor, Ownable { uint80 decompressedLength, uint16 imageCount ) external onlyOwner { - appendToVirtualIndexArray(headsVirtualIndexToStorageIndex, imageCount, art.headsTrait().storedImagesCount); art.addHeadsFromPointer(pointer, decompressedLength, imageCount); } @@ -289,122 +260,61 @@ contract NounsDescriptor is INounsDescriptor, Ownable { uint80 decompressedLength, uint16 imageCount ) external onlyOwner { - appendToVirtualIndexArray(glassesVirtualIndexToStorageIndex, imageCount, art.glassesTrait().storedImagesCount); art.addGlassesFromPointer(pointer, decompressedLength, imageCount); } - function retireBackground(uint256 virtualIndex) external onlyOwner { - retireStorageIndexByVirtualIndex(backgroundsVirtualIndexToStorageIndex, virtualIndex); - } - - function retireBody(uint256 virtualIndex) external onlyOwner { - retireStorageIndexByVirtualIndex(bodiesVirtualIndexToStorageIndex, virtualIndex); - } - - function retireAccessory(uint256 virtualIndex) external onlyOwner { - retireStorageIndexByVirtualIndex(accessoriesVirtualIndexToStorageIndex, virtualIndex); - } - - function retireHead(uint256 virtualIndex) external onlyOwner { - retireStorageIndexByVirtualIndex(headsVirtualIndexToStorageIndex, virtualIndex); - } - - function retireGlasses(uint256 virtualIndex) external onlyOwner { - retireStorageIndexByVirtualIndex(glassesVirtualIndexToStorageIndex, virtualIndex); - } - - function backgroundStorageIndex(uint256 virtualIndex) external view returns (uint256) { - return backgroundsVirtualIndexToStorageIndex[virtualIndex]; - } - - function bodyStorageIndex(uint256 virtualIndex) external view returns (uint256) { - return bodiesVirtualIndexToStorageIndex[virtualIndex]; - } - - function accessoryStorageIndex(uint256 virtualIndex) external view returns (uint256) { - return accessoriesVirtualIndexToStorageIndex[virtualIndex]; - } - - function headStorageIndex(uint256 virtualIndex) external view returns (uint256) { - return headsVirtualIndexToStorageIndex[virtualIndex]; - } - - function glassesStorageIndex(uint256 virtualIndex) external view returns (uint256) { - return glassesVirtualIndexToStorageIndex[virtualIndex]; - } - /** - * @notice Get a background's virtual index from its storage index. Useful for image retirement, where virtual index is the - * input, and you might be holding the storage index. - * @param storageIndex the storage index to look up. - * @return uint256 virtual index. + * @notice Get a background color by ID. + * @param index the index of the background. + * @return string the RGB hex value of the background. */ - function backgroundVirtualIndex(uint256 storageIndex) external view returns (uint256) { - return storageIndexToVirtualIndex(backgroundsVirtualIndexToStorageIndex, storageIndex); + function backgrounds(uint256 index) public view override returns (string memory) { + return art.backgrounds(index); } /** - * @notice Get a body's virtual index from its storage index. Useful for image retirement, where virtual index is the - * input, and you might be holding the storage index. - * @param storageIndex the storage index to look up. - * @return uint256 virtual index. + * @notice Get a head image by ID. + * @param index the index of the head. + * @return bytes the RLE-encoded bytes of the image. */ - function bodyVirtualIndex(uint256 storageIndex) external view returns (uint256) { - return storageIndexToVirtualIndex(bodiesVirtualIndexToStorageIndex, storageIndex); + function heads(uint256 index) public view override returns (bytes memory) { + return art.heads(index); } /** - * @notice Get an accessory's virtual index from its storage index. Useful for image retirement, where virtual index is the - * input, and you might be holding the storage index. - * @param storageIndex the storage index to look up. - * @return uint256 virtual index. + * @notice Get a body image by ID. + * @param index the index of the body. + * @return bytes the RLE-encoded bytes of the image. */ - function accessoryVirtualIndex(uint256 storageIndex) external view returns (uint256) { - return storageIndexToVirtualIndex(accessoriesVirtualIndexToStorageIndex, storageIndex); + function bodies(uint256 index) public view override returns (bytes memory) { + return art.bodies(index); } /** - * @notice Get a head's virtual index from its storage index. Useful for image retirement, where virtual index is the - * input, and you might be holding the storage index. - * @param storageIndex the storage index to look up. - * @return uint256 virtual index. + * @notice Get an accessory image by ID. + * @param index the index of the accessory. + * @return bytes the RLE-encoded bytes of the image. */ - function headVirtualIndex(uint256 storageIndex) external view returns (uint256) { - return storageIndexToVirtualIndex(headsVirtualIndexToStorageIndex, storageIndex); + function accessories(uint256 index) public view override returns (bytes memory) { + return art.accessories(index); } /** - * @notice Get a glasses' virtual index from its storage index. Useful for image retirement, where virtual index is the - * input, and you might be holding the storage index. - * @param storageIndex the storage index to look up. - * @return uint256 virtual index. + * @notice Get a glasses image by ID. + * @param index the index of the glasses. + * @return bytes the RLE-encoded bytes of the image. */ - function glassesVirtualIndex(uint256 storageIndex) external view returns (uint256) { - return storageIndexToVirtualIndex(glassesVirtualIndexToStorageIndex, storageIndex); + function glasses(uint256 index) public view override returns (bytes memory) { + return art.glasses(index); } - function backgrounds(uint256 index) public view override returns (string memory) { - return art.backgrounds(index); - } - - function heads(uint256 storageIndex) public view override returns (bytes memory) { - return art.heads(storageIndex); - } - - function bodies(uint256 storageIndex) public view override returns (bytes memory) { - return art.bodies(storageIndex); - } - - function accessories(uint256 storageIndex) public view override returns (bytes memory) { - return art.accessories(storageIndex); - } - - function glasses(uint256 storageIndex) public view override returns (bytes memory) { - return art.glasses(storageIndex); - } - - function palettes(uint8 paletteIndex) public view override returns (bytes memory) { - return art.palettes(paletteIndex); + /** + * @notice Get a color palette by ID. + * @param index the index of the palette. + * @return bytes the palette bytes, where every 3 consecutive bytes represent a color in RGB format. + */ + function palettes(uint8 index) public view override returns (bytes memory) { + return art.palettes(index); } /** @@ -514,34 +424,4 @@ contract NounsDescriptor is INounsDescriptor, Ownable { function _getPalette(bytes memory part) private view returns (bytes memory) { return art.palettes(uint8(part[0])); } - - function retireStorageIndexByVirtualIndex(uint256[] storage virtualToStorageArray, uint256 virtualIndex) internal { - virtualToStorageArray[virtualIndex] = virtualToStorageArray[virtualToStorageArray.length - 1]; - virtualToStorageArray.pop(); - } - - function storageIndexToVirtualIndex(uint256[] storage mappingArray, uint256 storageIndex) - internal - view - returns (uint256) - { - uint256 len = mappingArray.length; - for (uint256 virtualIndex = 0; virtualIndex < len; virtualIndex++) { - if (mappingArray[virtualIndex] == storageIndex) { - return virtualIndex; - } - } - - revert IndexNotFound(); - } - - function appendToVirtualIndexArray( - uint256[] storage mappingArray, - uint16 imageCount, - uint256 storedImageCount - ) internal { - for (uint256 i = 0; i < imageCount; i++) { - mappingArray.push(storedImageCount + i); - } - } } diff --git a/packages/nouns-contracts/contracts/NounsSeeder.sol b/packages/nouns-contracts/contracts/NounsSeeder.sol index afd3f6eea2..b0dcea341d 100644 --- a/packages/nouns-contracts/contracts/NounsSeeder.sol +++ b/packages/nouns-contracts/contracts/NounsSeeder.sol @@ -37,21 +37,11 @@ contract NounsSeeder is INounsSeeder { uint256 glassesCount = descriptor.glassesCount(); return Seed({ - background: uint48( - descriptor.backgroundStorageIndex(uint48(pseudorandomness) % backgroundCount) - ), - body: uint48( - descriptor.bodyStorageIndex(uint48(pseudorandomness >> 48) % bodyCount) - ), - accessory: uint48( - descriptor.accessoryStorageIndex(uint48(pseudorandomness >> 96) % accessoryCount) - ), - head: uint48( - descriptor.headStorageIndex(uint48(pseudorandomness >> 144) % headCount) - ), - glasses: uint48( - descriptor.glassesStorageIndex(uint48(pseudorandomness >> 192) % glassesCount) - ) + background: uint48(uint48(pseudorandomness) % backgroundCount), + body: uint48(uint48(pseudorandomness >> 48) % bodyCount), + accessory: uint48(uint48(pseudorandomness >> 96) % accessoryCount), + head: uint48(uint48(pseudorandomness >> 144) % headCount), + glasses: uint48(uint48(pseudorandomness >> 192) % glassesCount) }); } } diff --git a/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol b/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol index 90f5364789..59e40ddf68 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol @@ -70,174 +70,54 @@ interface INounsDescriptor { function setPalette(uint8 paletteIndex, bytes calldata palette) external; - /** - * @notice Add a batch of body images. - * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, - * and finally compressing it using deflate. - * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. - * @param imageCount the number of images in this batch; used when searching for images among batches. - */ function addBodies( bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount ) external; - /** - * @notice Add a batch of accessory images. - * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, - * and finally compressing it using deflate. - * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. - * @param imageCount the number of images in this batch; used when searching for images among batches. - */ function addAccessories( bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount ) external; - /** - * @notice Add a batch of head images. - * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, - * and finally compressing it using deflate. - * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. - * @param imageCount the number of images in this batch; used when searching for images among batches. - */ function addHeads( bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount ) external; - /** - * @notice Add a batch of glasses images. - * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, - * and finally compressing it using deflate. - * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. - * @param imageCount the number of images in this batch; used when searching for images among batches. - */ function addGlasses( bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount ) external; - /** - * @notice Add a batch of body images from an existing storage contract. - * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data - * format is expected to be like {encodedCompressed}: bytes created by taking a string array of - * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. - * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. - * @param imageCount the number of images in this batch; used when searching for images among batches. - */ function addBodiesFromPointer( address pointer, uint80 decompressedLength, uint16 imageCount ) external; - /** - * @notice Add a batch of accessory images from an existing storage contract. - * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data - * format is expected to be like {encodedCompressed}: bytes created by taking a string array of - * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. - * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. - * @param imageCount the number of images in this batch; used when searching for images among batches. - */ function addAccessoriesFromPointer( address pointer, uint80 decompressedLength, uint16 imageCount ) external; - /** - * @notice Add a batch of head images from an existing storage contract. - * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data - * format is expected to be like {encodedCompressed}: bytes created by taking a string array of - * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. - * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. - * @param imageCount the number of images in this batch; used when searching for images among batches. - */ function addHeadsFromPointer( address pointer, uint80 decompressedLength, uint16 imageCount ) external; - /** - * @notice Add a batch of glasses images from an existing storage contract. - * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data - * format is expected to be like {encodedCompressed}: bytes created by taking a string array of - * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. - * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. - * @param imageCount the number of images in this batch; used when searching for images among batches. - */ function addGlassesFromPointer( address pointer, uint80 decompressedLength, uint16 imageCount ) external; - function retireBackground(uint256 virtualIndex) external; - - function retireBody(uint256 virtualIndex) external; - - function retireAccessory(uint256 virtualIndex) external; - - function retireHead(uint256 virtualIndex) external; - - function retireGlasses(uint256 virtualIndex) external; - - function backgroundStorageIndex(uint256 virtualIndex) external view returns (uint256); - - function bodyStorageIndex(uint256 virtualIndex) external view returns (uint256); - - function accessoryStorageIndex(uint256 virtualIndex) external view returns (uint256); - - function headStorageIndex(uint256 virtualIndex) external view returns (uint256); - - function glassesStorageIndex(uint256 virtualIndex) external view returns (uint256); - - /** - * @notice Get a background's virtual index from its storage index. Useful for image retirement, where virtual index is the - * input, and you might be holding the storage index. - * @param storageIndex the storage index to look up. - * @return uint256 virtual index. - */ - function backgroundVirtualIndex(uint256 storageIndex) external view returns (uint256); - - /** - * @notice Get a body's virtual index from its storage index. Useful for image retirement, where virtual index is the - * input, and you might be holding the storage index. - * @param storageIndex the storage index to look up. - * @return uint256 virtual index. - */ - function bodyVirtualIndex(uint256 storageIndex) external view returns (uint256); - - /** - * @notice Get an accessory's virtual index from its storage index. Useful for image retirement, where virtual index is the - * input, and you might be holding the storage index. - * @param storageIndex the storage index to look up. - * @return uint256 virtual index. - */ - function accessoryVirtualIndex(uint256 storageIndex) external view returns (uint256); - - /** - * @notice Get a head's virtual index from its storage index. Useful for image retirement, where virtual index is the - * input, and you might be holding the storage index. - * @param storageIndex the storage index to look up. - * @return uint256 virtual index. - */ - function headVirtualIndex(uint256 storageIndex) external view returns (uint256); - - /** - * @notice Get a glasses' virtual index from its storage index. Useful for image retirement, where virtual index is the - * input, and you might be holding the storage index. - * @param storageIndex the storage index to look up. - * @return uint256 virtual index. - */ - function glassesVirtualIndex(uint256 storageIndex) external view returns (uint256); - function lockParts() external; function toggleDataURIEnabled() external; From 5754eb5dae9da0a511f262bf84a8d07e58180a65 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Mon, 27 Jun 2022 11:58:53 -0500 Subject: [PATCH 016/116] add natspec to NounsArt --- .../nouns-contracts/contracts/NounsArt.sol | 177 +++++++++++++++--- .../contracts/interfaces/INounsArt.sol | 8 +- 2 files changed, 160 insertions(+), 25 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsArt.sol b/packages/nouns-contracts/contracts/NounsArt.sol index 712509f24f..ab60d256f4 100644 --- a/packages/nouns-contracts/contracts/NounsArt.sol +++ b/packages/nouns-contracts/contracts/NounsArt.sol @@ -85,36 +85,61 @@ contract NounsArt is INounsArt { emit DescriptorUpdated(oldDescriptor, descriptor); } + /** + * @notice Get the Trait struct for bodies. + * @return Trait the struct, including a total image count, and an array of storage pages. + */ function bodiesTrait() external view returns (Trait memory) { return _bodies; } + /** + * @notice Get the Trait struct for accessories. + * @return Trait the struct, including a total image count, and an array of storage pages. + */ function accessoriesTrait() external view returns (Trait memory) { return _accessories; } + /** + * @notice Get the Trait struct for heads. + * @return Trait the struct, including a total image count, and an array of storage pages. + */ function headsTrait() external view returns (Trait memory) { return _heads; } + /** + * @notice Get the Trait struct for glasses. + * @return Trait the struct, including a total image count, and an array of storage pages. + */ function glassesTrait() external view returns (Trait memory) { return _glasses; } + /** + * @notice Batch add Noun backgrounds. + * @dev This function can only be called by the descriptor. + */ function addManyBackgrounds(string[] calldata _backgrounds) external override onlyDescriptor { for (uint256 i = 0; i < _backgrounds.length; i++) { _addBackground(_backgrounds[i]); } } + /** + * @notice Add a Noun background. + * @dev This function can only be called by the descriptor. + */ function addBackground(string calldata _background) external override onlyDescriptor { _addBackground(_background); } - function _addBackground(string calldata _background) internal { - backgrounds.push(_background); - } - + /** + * @notice Update a single color palette. This function can be used to + * add a new color palette or update an existing palette. + * @dev This function can only be called by the descriptor. + */ function setPalette(uint8 paletteIndex, bytes calldata palette) external override onlyDescriptor { if (palette.length == 0) { revert EmptyPalette(); @@ -125,6 +150,14 @@ contract NounsArt is INounsArt { palettesPointers[paletteIndex] = SSTORE2.write(palette); } + /** + * @notice Add a batch of body images. + * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, + * and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + * @dev This function can only be called by the descriptor. + */ function addBodies( bytes calldata encodedCompressed, uint80 decompressedLength, @@ -133,6 +166,14 @@ contract NounsArt is INounsArt { addToTraitFromBytes(_bodies, encodedCompressed, decompressedLength, imageCount); } + /** + * @notice Add a batch of accessory images. + * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, + * and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + * @dev This function can only be called by the descriptor. + */ function addAccessories( bytes calldata encodedCompressed, uint80 decompressedLength, @@ -141,6 +182,14 @@ contract NounsArt is INounsArt { addToTraitFromBytes(_accessories, encodedCompressed, decompressedLength, imageCount); } + /** + * @notice Add a batch of head images. + * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, + * and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + * @dev This function can only be called by the descriptor. + */ function addHeads( bytes calldata encodedCompressed, uint80 decompressedLength, @@ -149,6 +198,14 @@ contract NounsArt is INounsArt { addToTraitFromBytes(_heads, encodedCompressed, decompressedLength, imageCount); } + /** + * @notice Add a batch of glasses images. + * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, + * and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + * @dev This function can only be called by the descriptor. + */ function addGlasses( bytes calldata encodedCompressed, uint80 decompressedLength, @@ -157,6 +214,15 @@ contract NounsArt is INounsArt { addToTraitFromBytes(_glasses, encodedCompressed, decompressedLength, imageCount); } + /** + * @notice Add a batch of body images from an existing storage contract. + * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data + * format is expected to be like {encodedCompressed}: bytes created by taking a string array of + * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + * @dev This function can only be called by the descriptor. + */ function addBodiesFromPointer( address pointer, uint80 decompressedLength, @@ -165,6 +231,15 @@ contract NounsArt is INounsArt { addToTraitFromPointer(_bodies, pointer, decompressedLength, imageCount); } + /** + * @notice Add a batch of accessory images from an existing storage contract. + * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data + * format is expected to be like {encodedCompressed}: bytes created by taking a string array of + * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + * @dev This function can only be called by the descriptor. + */ function addAccessoriesFromPointer( address pointer, uint80 decompressedLength, @@ -173,6 +248,15 @@ contract NounsArt is INounsArt { addToTraitFromPointer(_accessories, pointer, decompressedLength, imageCount); } + /** + * @notice Add a batch of head images from an existing storage contract. + * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data + * format is expected to be like {encodedCompressed}: bytes created by taking a string array of + * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches + * @dev This function can only be called by the descriptor.. + */ function addHeadsFromPointer( address pointer, uint80 decompressedLength, @@ -181,6 +265,15 @@ contract NounsArt is INounsArt { addToTraitFromPointer(_heads, pointer, decompressedLength, imageCount); } + /** + * @notice Add a batch of glasses images from an existing storage contract. + * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data + * format is expected to be like {encodedCompressed}: bytes created by taking a string array of + * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + * @dev This function can only be called by the descriptor. + */ function addGlassesFromPointer( address pointer, uint80 decompressedLength, @@ -189,62 +282,108 @@ contract NounsArt is INounsArt { addToTraitFromPointer(_glasses, pointer, decompressedLength, imageCount); } + /** + * @notice Get the number of available Noun `backgrounds`. + */ function backgroundsCount() public view override returns (uint256) { return backgrounds.length; } + /** + * @notice Get the number of heads storage pages. + */ function headsPageCount() public view override returns (uint256) { return _heads.storagePages.length; } + /** + * @notice Get the number of bodies storage pages. + */ function bodiesPageCount() public view override returns (uint256) { return _bodies.storagePages.length; } + /** + * @notice Get the number of accessories storage pages. + */ function accessoriesPageCount() public view override returns (uint256) { return _accessories.storagePages.length; } + /** + * @notice Get the number of glasses storage pages. + */ function glassesPageCount() public view override returns (uint256) { return _glasses.storagePages.length; } + /** + * @notice Get a storage page of head images. + */ function headsPage(uint256 pageIndex) public view override returns (INounsArt.NounArtStoragePage memory) { return _heads.storagePages[pageIndex]; } + /** + * @notice Get a storage page of body images. + */ function bodiesPage(uint256 pageIndex) public view override returns (INounsArt.NounArtStoragePage memory) { return _bodies.storagePages[pageIndex]; } + /** + * @notice Get a storage page of accessory images. + */ function accessoriesPage(uint256 pageIndex) public view override returns (INounsArt.NounArtStoragePage memory) { return _accessories.storagePages[pageIndex]; } + /** + * @notice Get a storage page of glasses images. + */ function glassesPage(uint256 pageIndex) public view override returns (INounsArt.NounArtStoragePage memory) { return _glasses.storagePages[pageIndex]; } - function heads(uint256 storageIndex) public view override returns (bytes memory) { - return imageByStorageIndex(_heads, storageIndex); + /** + * @notice Get a head image bytes (RLE-encoded). + */ + function heads(uint256 index) public view override returns (bytes memory) { + return imageByIndex(_heads, index); } - function bodies(uint256 storageIndex) public view override returns (bytes memory) { - return imageByStorageIndex(_bodies, storageIndex); + /** + * @notice Get a body image bytes (RLE-encoded). + */ + function bodies(uint256 index) public view override returns (bytes memory) { + return imageByIndex(_bodies, index); } - function accessories(uint256 storageIndex) public view override returns (bytes memory) { - return imageByStorageIndex(_accessories, storageIndex); + /** + * @notice Get a accessory image bytes (RLE-encoded). + */ + function accessories(uint256 index) public view override returns (bytes memory) { + return imageByIndex(_accessories, index); } - function glasses(uint256 storageIndex) public view override returns (bytes memory) { - return imageByStorageIndex(_glasses, storageIndex); + /** + * @notice Get a glasses image bytes (RLE-encoded). + */ + function glasses(uint256 index) public view override returns (bytes memory) { + return imageByIndex(_glasses, index); } + /** + * @notice Get a color palette bytes. + */ function palettes(uint8 paletteIndex) public view override returns (bytes memory) { return SSTORE2.read(palettesPointers[paletteIndex]); } + function _addBackground(string calldata _background) internal { + backgrounds.push(_background); + } + function addToTraitFromBytes( Trait storage trait, bytes calldata encodedCompressed, @@ -267,17 +406,13 @@ contract NounsArt is INounsArt { trait.storedImagesCount += imageCount; } - function imageByStorageIndex(INounsArt.Trait storage trait, uint256 storageIndex) - internal - view - returns (bytes memory) - { - (INounsArt.NounArtStoragePage storage page, uint256 indexInPage) = getPage(trait.storagePages, storageIndex); + function imageByIndex(INounsArt.Trait storage trait, uint256 index) internal view returns (bytes memory) { + (INounsArt.NounArtStoragePage storage page, uint256 indexInPage) = getPage(trait.storagePages, index); bytes[] memory decompressedImages = decompressAndDecode(page); return decompressedImages[indexInPage]; } - function getPage(INounsArt.NounArtStoragePage[] storage pages, uint256 storageIndex) + function getPage(INounsArt.NounArtStoragePage[] storage pages, uint256 index) internal view returns (INounsArt.NounArtStoragePage storage, uint256) @@ -291,8 +426,8 @@ contract NounsArt is INounsArt { for (uint256 i = 0; i < len; i++) { INounsArt.NounArtStoragePage storage page = pages[i]; - if (storageIndex < pageFirstImageIndex + page.imageCount) { - return (page, storageIndex - pageFirstImageIndex); + if (index < pageFirstImageIndex + page.imageCount) { + return (page, index - pageFirstImageIndex); } pageFirstImageIndex += page.imageCount; diff --git a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol index 6c02d974f7..c7421ac05a 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol @@ -127,13 +127,13 @@ interface INounsArt { function backgrounds(uint256 index) external view returns (string memory); - function heads(uint256 storageIndex) external view returns (bytes memory); + function heads(uint256 index) external view returns (bytes memory); - function bodies(uint256 storageIndex) external view returns (bytes memory); + function bodies(uint256 index) external view returns (bytes memory); - function accessories(uint256 storageIndex) external view returns (bytes memory); + function accessories(uint256 index) external view returns (bytes memory); - function glasses(uint256 storageIndex) external view returns (bytes memory); + function glasses(uint256 index) external view returns (bytes memory); function bodiesTrait() external view returns (Trait memory); From 619faf732cb1cccd819791378e4ba90baca05feb Mon Sep 17 00:00:00 2001 From: eladmallel Date: Mon, 27 Jun 2022 12:12:21 -0500 Subject: [PATCH 017/116] back to solidity 0.8.6 --- .../nouns-contracts/contracts/NounsArt.sol | 20 +++++++++---------- .../contracts/NounsAuctionHouse.sol | 2 +- .../contracts/NounsDescriptor.sol | 16 +++++++-------- .../nouns-contracts/contracts/NounsSeeder.sol | 2 +- .../nouns-contracts/contracts/NounsToken.sol | 2 +- .../nouns-contracts/contracts/SVGRenderer.sol | 8 ++++---- .../contracts/interfaces/INounsArt.sol | 2 +- .../contracts/interfaces/ISVGRenderer.sol | 2 +- .../contracts/libs/NFTDescriptor.sol | 2 +- .../contracts/libs/SSTORE2.sol | 2 +- .../proxies/NounsAuctionHouseProxy.sol | 2 +- .../proxies/NounsAuctionHouseProxyAdmin.sol | 2 +- packages/nouns-contracts/hardhat.config.ts | 2 +- 13 files changed, 32 insertions(+), 32 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsArt.sol b/packages/nouns-contracts/contracts/NounsArt.sol index ab60d256f4..17dbe97035 100644 --- a/packages/nouns-contracts/contracts/NounsArt.sol +++ b/packages/nouns-contracts/contracts/NounsArt.sol @@ -15,7 +15,7 @@ * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ -pragma solidity ^0.8.12; +pragma solidity ^0.8.6; import { INounsArt } from './interfaces/INounsArt.sol'; import { Inflate } from './libs/Inflate.sol'; @@ -23,13 +23,13 @@ import { SSTORE2 } from './libs/SSTORE2.sol'; contract NounsArt is INounsArt { // Current Nouns Descriptor address - address public descriptor; + address public override descriptor; // Pending Nouns Descriptor address - address public pendingDescriptor; + address public override pendingDescriptor; // Noun Backgrounds (Hex Colors) - string[] public backgrounds; + string[] public override backgrounds; // Noun Color Palettes (Index => Hex Colors) mapping(uint8 => address) public palettesPointers; @@ -65,7 +65,7 @@ contract NounsArt is INounsArt { * by calling `confirmDescriptor`. * @dev This function can only be called by the current descriptor. */ - function setDescriptor(address _pendingDescriptor) external onlyDescriptor { + function setDescriptor(address _pendingDescriptor) external override onlyDescriptor { pendingDescriptor = _pendingDescriptor; } @@ -73,7 +73,7 @@ contract NounsArt is INounsArt { * @notice Confirm the pending descriptor. * @dev This function can only be called by the pending descriptor. */ - function confirmDescriptor() external { + function confirmDescriptor() external override { if (msg.sender != pendingDescriptor) { revert SenderIsNotPendingDescriptor(); } @@ -89,7 +89,7 @@ contract NounsArt is INounsArt { * @notice Get the Trait struct for bodies. * @return Trait the struct, including a total image count, and an array of storage pages. */ - function bodiesTrait() external view returns (Trait memory) { + function bodiesTrait() external view override returns (Trait memory) { return _bodies; } @@ -97,7 +97,7 @@ contract NounsArt is INounsArt { * @notice Get the Trait struct for accessories. * @return Trait the struct, including a total image count, and an array of storage pages. */ - function accessoriesTrait() external view returns (Trait memory) { + function accessoriesTrait() external view override returns (Trait memory) { return _accessories; } @@ -105,7 +105,7 @@ contract NounsArt is INounsArt { * @notice Get the Trait struct for heads. * @return Trait the struct, including a total image count, and an array of storage pages. */ - function headsTrait() external view returns (Trait memory) { + function headsTrait() external view override returns (Trait memory) { return _heads; } @@ -113,7 +113,7 @@ contract NounsArt is INounsArt { * @notice Get the Trait struct for glasses. * @return Trait the struct, including a total image count, and an array of storage pages. */ - function glassesTrait() external view returns (Trait memory) { + function glassesTrait() external view override returns (Trait memory) { return _glasses; } diff --git a/packages/nouns-contracts/contracts/NounsAuctionHouse.sol b/packages/nouns-contracts/contracts/NounsAuctionHouse.sol index cfba98fa4b..ccb78a64c6 100644 --- a/packages/nouns-contracts/contracts/NounsAuctionHouse.sol +++ b/packages/nouns-contracts/contracts/NounsAuctionHouse.sol @@ -22,7 +22,7 @@ // AuctionHouse.sol source code Copyright Zora licensed under the GPL-3.0 license. // With modifications by Nounders DAO. -pragma solidity ^0.8.12; +pragma solidity ^0.8.6; import { PausableUpgradeable } from '@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol'; import { ReentrancyGuardUpgradeable } from '@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol'; diff --git a/packages/nouns-contracts/contracts/NounsDescriptor.sol b/packages/nouns-contracts/contracts/NounsDescriptor.sol index 1380b6c288..5a364e19bf 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptor.sol @@ -15,7 +15,7 @@ * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ -pragma solidity ^0.8.12; +pragma solidity ^0.8.6; import { Ownable } from '@openzeppelin/contracts/access/Ownable.sol'; import { Strings } from '@openzeppelin/contracts/utils/Strings.sol'; @@ -165,7 +165,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount - ) external onlyOwner { + ) external override onlyOwner { art.addAccessories(encodedCompressed, decompressedLength, imageCount); } @@ -180,7 +180,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount - ) external onlyOwner { + ) external override onlyOwner { art.addHeads(encodedCompressed, decompressedLength, imageCount); } @@ -195,7 +195,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount - ) external onlyOwner { + ) external override onlyOwner { art.addGlasses(encodedCompressed, decompressedLength, imageCount); } @@ -211,7 +211,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { address pointer, uint80 decompressedLength, uint16 imageCount - ) external onlyOwner { + ) external override onlyOwner { art.addBodiesFromPointer(pointer, decompressedLength, imageCount); } @@ -227,7 +227,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { address pointer, uint80 decompressedLength, uint16 imageCount - ) external onlyOwner { + ) external override onlyOwner { art.addAccessoriesFromPointer(pointer, decompressedLength, imageCount); } @@ -243,7 +243,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { address pointer, uint80 decompressedLength, uint16 imageCount - ) external onlyOwner { + ) external override onlyOwner { art.addHeadsFromPointer(pointer, decompressedLength, imageCount); } @@ -259,7 +259,7 @@ contract NounsDescriptor is INounsDescriptor, Ownable { address pointer, uint80 decompressedLength, uint16 imageCount - ) external onlyOwner { + ) external override onlyOwner { art.addGlassesFromPointer(pointer, decompressedLength, imageCount); } diff --git a/packages/nouns-contracts/contracts/NounsSeeder.sol b/packages/nouns-contracts/contracts/NounsSeeder.sol index b0dcea341d..bcd79f43e1 100644 --- a/packages/nouns-contracts/contracts/NounsSeeder.sol +++ b/packages/nouns-contracts/contracts/NounsSeeder.sol @@ -15,7 +15,7 @@ * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ -pragma solidity ^0.8.12; +pragma solidity ^0.8.6; import { INounsSeeder } from './interfaces/INounsSeeder.sol'; import { INounsDescriptor } from './interfaces/INounsDescriptor.sol'; diff --git a/packages/nouns-contracts/contracts/NounsToken.sol b/packages/nouns-contracts/contracts/NounsToken.sol index efbaaa7e82..19350477a1 100644 --- a/packages/nouns-contracts/contracts/NounsToken.sol +++ b/packages/nouns-contracts/contracts/NounsToken.sol @@ -15,7 +15,7 @@ * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ -pragma solidity ^0.8.12; +pragma solidity ^0.8.6; import { Ownable } from '@openzeppelin/contracts/access/Ownable.sol'; import { ERC721Checkpointable } from './base/ERC721Checkpointable.sol'; diff --git a/packages/nouns-contracts/contracts/SVGRenderer.sol b/packages/nouns-contracts/contracts/SVGRenderer.sol index a343558fe2..f52355ff0d 100644 --- a/packages/nouns-contracts/contracts/SVGRenderer.sol +++ b/packages/nouns-contracts/contracts/SVGRenderer.sol @@ -15,7 +15,7 @@ * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ -pragma solidity ^0.8.12; +pragma solidity ^0.8.6; import { ISVGRenderer } from './interfaces/ISVGRenderer.sol'; @@ -47,7 +47,7 @@ contract SVGRenderer is ISVGRenderer { /** * @notice Given RLE image data and color palette pointers, merge to generate a single SVG image. */ - function generateSVG(SVGParams calldata params) external pure returns (string memory svg) { + function generateSVG(SVGParams calldata params) external pure override returns (string memory svg) { if (bytes(params.background).length != 0) { // prettier-ignore return string( @@ -65,7 +65,7 @@ contract SVGRenderer is ISVGRenderer { /** * @notice Given RLE image data and a color palette pointer, merge to generate a partial SVG image. */ - function generateSVGPart(Part calldata part) external pure returns (string memory partialSVG) { + function generateSVGPart(Part calldata part) external pure override returns (string memory partialSVG) { Part[] memory parts = new Part[](1); parts[0] = part; @@ -75,7 +75,7 @@ contract SVGRenderer is ISVGRenderer { /** * @notice Given RLE image data and color palette pointers, merge to generate a partial SVG image. */ - function generateSVGParts(Part[] calldata parts) external pure returns (string memory partialSVG) { + function generateSVGParts(Part[] calldata parts) external pure override returns (string memory partialSVG) { return _generateSVGRects(SVGParams({ parts: parts, background: '' })); } diff --git a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol index c7421ac05a..a0f736840e 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol @@ -15,7 +15,7 @@ * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ -pragma solidity ^0.8.12; +pragma solidity ^0.8.6; interface INounsArt { error SenderIsNotDescriptor(); diff --git a/packages/nouns-contracts/contracts/interfaces/ISVGRenderer.sol b/packages/nouns-contracts/contracts/interfaces/ISVGRenderer.sol index 5bfb118f43..1d6df0f4dc 100644 --- a/packages/nouns-contracts/contracts/interfaces/ISVGRenderer.sol +++ b/packages/nouns-contracts/contracts/interfaces/ISVGRenderer.sol @@ -15,7 +15,7 @@ * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ -pragma solidity ^0.8.12; +pragma solidity ^0.8.6; // TODO: Generalize to `IRenderer`? // May be a day when we drop SVG support. diff --git a/packages/nouns-contracts/contracts/libs/NFTDescriptor.sol b/packages/nouns-contracts/contracts/libs/NFTDescriptor.sol index fdc2c3a75f..5eacf2bf13 100644 --- a/packages/nouns-contracts/contracts/libs/NFTDescriptor.sol +++ b/packages/nouns-contracts/contracts/libs/NFTDescriptor.sol @@ -15,7 +15,7 @@ * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ -pragma solidity ^0.8.12; +pragma solidity ^0.8.6; import { Base64 } from 'base64-sol/base64.sol'; import { ISVGRenderer } from '../interfaces/ISVGRenderer.sol'; diff --git a/packages/nouns-contracts/contracts/libs/SSTORE2.sol b/packages/nouns-contracts/contracts/libs/SSTORE2.sol index a8912d2a09..7ff65f3991 100644 --- a/packages/nouns-contracts/contracts/libs/SSTORE2.sol +++ b/packages/nouns-contracts/contracts/libs/SSTORE2.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.12; +pragma solidity ^0.8.6; /// @notice Read and write to persistent storage at a fraction of the cost. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SSTORE2.sol) diff --git a/packages/nouns-contracts/contracts/proxies/NounsAuctionHouseProxy.sol b/packages/nouns-contracts/contracts/proxies/NounsAuctionHouseProxy.sol index 6c688f0ba4..afe885dcca 100644 --- a/packages/nouns-contracts/contracts/proxies/NounsAuctionHouseProxy.sol +++ b/packages/nouns-contracts/contracts/proxies/NounsAuctionHouseProxy.sol @@ -15,7 +15,7 @@ * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ -pragma solidity ^0.8.12; +pragma solidity ^0.8.6; import { TransparentUpgradeableProxy } from '@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol'; diff --git a/packages/nouns-contracts/contracts/proxies/NounsAuctionHouseProxyAdmin.sol b/packages/nouns-contracts/contracts/proxies/NounsAuctionHouseProxyAdmin.sol index 767577401c..eb942caa59 100644 --- a/packages/nouns-contracts/contracts/proxies/NounsAuctionHouseProxyAdmin.sol +++ b/packages/nouns-contracts/contracts/proxies/NounsAuctionHouseProxyAdmin.sol @@ -15,7 +15,7 @@ * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ -pragma solidity ^0.8.12; +pragma solidity ^0.8.6; import { ProxyAdmin } from '@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol'; diff --git a/packages/nouns-contracts/hardhat.config.ts b/packages/nouns-contracts/hardhat.config.ts index eeb2efba3b..a95f899dff 100644 --- a/packages/nouns-contracts/hardhat.config.ts +++ b/packages/nouns-contracts/hardhat.config.ts @@ -14,7 +14,7 @@ dotenv.config(); const config: HardhatUserConfig = { solidity: { - version: '0.8.12', + version: '0.8.6', settings: { optimizer: { enabled: true, From 9363783e4316a2917112b3ce65bb34a03c1394fd Mon Sep 17 00:00:00 2001 From: eladmallel Date: Mon, 27 Jun 2022 13:26:31 -0500 Subject: [PATCH 018/116] get NounsToken test working with descriptor v2 --- .../tasks/descriptor-art-to-console.ts | 88 +++++++++++++++++++ packages/nouns-contracts/tasks/index.ts | 1 + .../test/foundry/NounsToken.t.sol | 68 ++++++++++++-- 3 files changed, 151 insertions(+), 6 deletions(-) create mode 100644 packages/nouns-contracts/tasks/descriptor-art-to-console.ts diff --git a/packages/nouns-contracts/tasks/descriptor-art-to-console.ts b/packages/nouns-contracts/tasks/descriptor-art-to-console.ts new file mode 100644 index 0000000000..8c277fab37 --- /dev/null +++ b/packages/nouns-contracts/tasks/descriptor-art-to-console.ts @@ -0,0 +1,88 @@ +import { task, types } from 'hardhat/config'; +import ImageData from '../files/image-data.json'; +import { deflateRawSync } from 'zlib'; +import { ethers } from 'ethers'; + +task( + 'descriptor-art-to-console', + 'Prints the descriptor art config in the final format, to be used in foundry / manual tests.', +) + .addOptionalParam( + 'slice', + 'How many items to take from each of the image arrays', + undefined, + types.int, + ) + .setAction(async ({ slice }, { ethers }) => { + const { bgcolors, palette, images } = ImageData; + let { bodies, accessories, heads, glasses } = images; + + if (slice !== undefined) { + bodies = bodies.slice(0, slice); + accessories = accessories.slice(0, slice); + heads = heads.slice(0, slice); + glasses = glasses.slice(0, slice); + } + + const { + encodedCompressed: bodiesCompressed, + originalLength: bodiesLength, + itemCount: bodiesCount, + } = dataToDescriptorInput(bodies.map(({ data }) => data)); + const { + encodedCompressed: accessoriesCompressed, + originalLength: accessoriesLength, + itemCount: accessoriesCount, + } = dataToDescriptorInput(accessories.map(({ data }) => data)); + const { + encodedCompressed: headsCompressed, + originalLength: headsLength, + itemCount: headsCount, + } = dataToDescriptorInput(heads.map(({ data }) => data)); + const { + encodedCompressed: glassesCompressed, + originalLength: glassesLength, + itemCount: glassesCount, + } = dataToDescriptorInput(glasses.map(({ data }) => data)); + + const paletteValue = `0x000000${palette.join('')}`; + + console.log('=== PALETTE ===\n'); + console.log(`paletteValue: '${paletteValue}'\n`); + + console.log('=== BODIES ===\n'); + console.log(`bodiesCompressed: '${bodiesCompressed}'\n`); + console.log(`bodiesLength: ${bodiesLength}\n`); + + console.log('=== ACCESSORIES ===\n'); + console.log(`accessoriesCompressed: '${accessoriesCompressed}'\n`); + console.log(`accessoriesLength: ${accessoriesLength}\n`); + + console.log('=== HEADS ===\n'); + console.log(`headsCompressed: '${headsCompressed}'\n`); + console.log(`headsLength: ${headsLength}\n`); + + console.log('=== GLASSES ===\n'); + console.log(`glassesCompressed: '${glassesCompressed}'\n`); + console.log(`glassesLength: ${glassesLength}\n`); + }); + +function dataToDescriptorInput(data: string[]): { + encodedCompressed: string; + originalLength: number; + itemCount: number; +} { + const abiEncoded = ethers.utils.defaultAbiCoder.encode(['bytes[]'], [data]); + const encodedCompressed = `0x${deflateRawSync( + Buffer.from(abiEncoded.substring(2), 'hex'), + ).toString('hex')}`; + + const originalLength = abiEncoded.substring(2).length / 2; + const itemCount = data.length; + + return { + encodedCompressed, + originalLength, + itemCount, + }; +} diff --git a/packages/nouns-contracts/tasks/index.ts b/packages/nouns-contracts/tasks/index.ts index 9fb99135f6..f2276f2451 100644 --- a/packages/nouns-contracts/tasks/index.ts +++ b/packages/nouns-contracts/tasks/index.ts @@ -9,3 +9,4 @@ export * from './populate-descriptor'; export * from './run-local'; export * from './verify-etherscan'; export * from './update-configs'; +export * from './descriptor-art-to-console'; diff --git a/packages/nouns-contracts/test/foundry/NounsToken.t.sol b/packages/nouns-contracts/test/foundry/NounsToken.t.sol index 71c01ba71c..2c1abd1305 100644 --- a/packages/nouns-contracts/test/foundry/NounsToken.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsToken.t.sol @@ -6,6 +6,9 @@ import { NounsToken } from '../../contracts/NounsToken.sol'; import { NounsDescriptor } from '../../contracts/NounsDescriptor.sol'; import { NounsSeeder } from '../../contracts/NounsSeeder.sol'; import { IProxyRegistry } from '../../contracts/external/opensea/IProxyRegistry.sol'; +import { SVGRenderer } from '../../contracts/SVGRenderer.sol'; +import { NounsArt } from '../../contracts/NounsArt.sol'; +import { INounsArt } from '../../contracts/interfaces/INounsArt.sol'; contract NounsTokenTest is Test { NounsToken nounsToken; @@ -16,18 +19,46 @@ contract NounsTokenTest is Test { address minter = address(2); function setUp() public { - descriptor = new NounsDescriptor(); + SVGRenderer renderer = new SVGRenderer(); + descriptor = new NounsDescriptor(INounsArt(address(0)), renderer); + NounsArt art = new NounsArt(address(descriptor)); + descriptor.setArt(art); + _populateDescriptor(); seeder = new NounsSeeder(); nounsToken = new NounsToken(noundersDAO, minter, descriptor, seeder, proxyRegistry); } function _populateDescriptor() internal { - descriptor.addBackground('#000000'); - descriptor.addAccessory('aaa'); - descriptor.addBody('bbb'); - descriptor.addGlasses('ggg'); - descriptor.addHead('hhh'); + descriptor.addBackground('d5d7e1'); + descriptor.addAccessories( + fromHex( + '6360c00b14f04b3330129027a4df95415c448e979181519e95810988412c66206604b398c098192c066133c9c3c441340b94c6630100' + ), + 224, + 1 + ); + descriptor.addBodies(fromHex('6360c00b14f04b3330129027a4df9c41545c9e938f090299981819b88922e1060000'), 192, 1); + descriptor.addGlasses( + fromHex( + '6360c00b14f04b3330129027a43f9a815b5c809d99814d811188991918159818999419813c188b054c3363e501d560d101330d6c0100' + ), + 224, + 1 + ); + descriptor.addHeads( + fromHex( + '6360c00b14f04b3330129027a47f2203939c081b2b03a3391310f333b0303001594ce67c0ccc0ccc4016b3392f0313038b3908f3208921d421f4f29a73e3c06c0cacb52092b196b10e82b9cd3991d8bcb55ce6acca9c60169a0301' + ), + 288, + 1 + ); + descriptor.setPalette( + 0, + fromHex( + '000000ffffffc5b9a1cfc2ab63a0f9807f7ecaeff95648ed5a423fb9185cb87b11fffdf24b49493432351f1d29068940867c1dae32089f21a0f98f30fe500cd26451fd8b5b5a65fad22209e9265cc54e3880a72d4bea6934ac80eed81162616dff638d8bc0c5c4da53000000f3322cffae1affc110505a5cffef16fff671fff449db8323df2c39f938d85c25fb2a86fd45faff38dd56ff3a0ed32a099037076e3206552e05e8705bf38b7ce4a499667af9648df97cc4f297f2fba3efd087e4d971bde4ff1a0bf78a182b83f6d62149834398ffc925d9391fbd2d24ff7216254efbe5e5de00a556c5030eabf131fb4694e7a32cfff0ee009c590385eb00499ce1183326b1f3fff0bed8dadfd7d3cd1929f4eab1180b5027f9f5cbcfc9b8feb9d5f8d6895d606176858b757576ff0e0e0adc4dfdf8ff70e890f7913dff1ad2ff82ad535a15fa6fe2ffe939ab36beadc8cc604666f20422abaaa84b65f7a19c9a58565cda42cb027c92cec189909b0e74580d027ee6b2958defad817d635eeff2fa6f597ad4b7b2d18687cd916d6b3f394d271b85634ff9f4e6f8ddb0b92b3cd08b11257ceda3baed5fd4fbc16710a28ef43a085b67b1e31e3445ffd067962236769ca95a6b7b7e5243a86f608f785ecc059542ffb0d56333b8ced2b91b43f39713e8e8e2ec5b43235476b2a8a5d6c3be49b38bfccf25f59b34375dfc99e6de27a463554543b19e00d4a0159f4b27f9e8dd6b72129d8e6e4243f8fa5e20f82905555353876f69410d66552d1df71248fee3f3c169232b28340079fcd31e14f830018dd122fffdf4ffa21ee4afa3fbc311aa940ceedc00fff0069cb4b8a38654ae6c0a2bb26be2c8c0f89865f86100dcd8d3049d43d0aea9f39d44eeb78cf9f5e95d3500c3a199aaa6a4caa26afde7f5fdf008fdcef2f681e6018146d19a549eb5e1f5fcff3f932300fcff4a5358fbc800d596a6ffb913e9ba12767c0ef9f6d1d29607f8ce47395ed1ffc5f0cbc1bcd4cfc0' + ) + ); } function testSymbol() public { @@ -50,4 +81,29 @@ contract NounsTokenTest is Test { vm.expectRevert('Sender is not the minter'); nounsToken.mint(); } + + // Convert an hexadecimal string to raw bytes + function fromHex(string memory s) public pure returns (bytes memory) { + bytes memory ss = bytes(s); + require(ss.length % 2 == 0); // length must be even + bytes memory r = new bytes(ss.length / 2); + for (uint256 i = 0; i < ss.length / 2; ++i) { + r[i] = bytes1(fromHexChar(uint8(ss[2 * i])) * 16 + fromHexChar(uint8(ss[2 * i + 1]))); + } + return r; + } + + // Convert an hexadecimal character to their value + function fromHexChar(uint8 c) public pure returns (uint8) { + if (bytes1(c) >= bytes1('0') && bytes1(c) <= bytes1('9')) { + return c - uint8(bytes1('0')); + } + if (bytes1(c) >= bytes1('a') && bytes1(c) <= bytes1('f')) { + return 10 + c - uint8(bytes1('a')); + } + if (bytes1(c) >= bytes1('A') && bytes1(c) <= bytes1('F')) { + return 10 + c - uint8(bytes1('A')); + } + revert('fail'); + } } From ce466a454849c815b0a6da4360cbcb8eed25f499 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Mon, 27 Jun 2022 15:42:52 -0500 Subject: [PATCH 019/116] add descriptor v1 back * to enable an upgrade test * to enable web backwards compatibility --- .../contracts/NounsDescriptor.sol | 352 ++++++--------- .../contracts/NounsDescriptorV2.sol | 427 ++++++++++++++++++ .../nouns-contracts/contracts/NounsSeeder.sol | 4 +- .../nouns-contracts/contracts/NounsToken.sol | 8 +- .../contracts/interfaces/INounsDescriptor.sol | 97 ++-- .../interfaces/INounsDescriptorMinimal.sol | 44 ++ .../interfaces/INounsDescriptorV2.sol | 139 ++++++ .../contracts/interfaces/INounsSeeder.sol | 4 +- .../contracts/interfaces/INounsToken.sol | 6 +- .../contracts/libs/MultiPartRLEToSVG.sol | 158 +++++++ .../contracts/libs/NFTDescriptor.sol | 14 +- .../contracts/libs/NFTDescriptorV2.sol | 67 +++ .../nouns-contracts/tasks/deploy-local.ts | 22 +- packages/nouns-contracts/tasks/deploy.ts | 21 +- .../tasks/populate-descriptor.ts | 18 +- packages/nouns-contracts/tasks/run-local.ts | 4 +- packages/nouns-contracts/tasks/types/index.ts | 2 +- .../nouns-contracts/tasks/update-configs.ts | 4 +- packages/nouns-contracts/test/auction.test.ts | 6 +- .../nouns-contracts/test/descriptor.test.ts | 20 +- .../nouns-contracts/test/descriptorV2.test.ts | 127 ++++++ packages/nouns-contracts/test/end2end.test.ts | 12 +- .../test/foundry/NounsToken.t.sol | 6 +- .../test/governance/NounsDAO/castVote.test.ts | 8 +- .../NounsDAO/inflationHandling.test.ts | 2 +- .../test/governance/NounsDAO/state.test.ts | 8 +- .../test/governance/NounsDAO/vetoing.test.ts | 2 +- .../test/governance/nounsGovernance.test.ts | 11 +- packages/nouns-contracts/test/nouns.test.ts | 6 +- packages/nouns-contracts/test/utils.ts | 41 +- 30 files changed, 1273 insertions(+), 367 deletions(-) create mode 100644 packages/nouns-contracts/contracts/NounsDescriptorV2.sol create mode 100644 packages/nouns-contracts/contracts/interfaces/INounsDescriptorMinimal.sol create mode 100644 packages/nouns-contracts/contracts/interfaces/INounsDescriptorV2.sol create mode 100644 packages/nouns-contracts/contracts/libs/MultiPartRLEToSVG.sol create mode 100644 packages/nouns-contracts/contracts/libs/NFTDescriptorV2.sol create mode 100644 packages/nouns-contracts/test/descriptorV2.test.ts diff --git a/packages/nouns-contracts/contracts/NounsDescriptor.sol b/packages/nouns-contracts/contracts/NounsDescriptor.sol index 5a364e19bf..b3210c40da 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptor.sol @@ -22,8 +22,7 @@ import { Strings } from '@openzeppelin/contracts/utils/Strings.sol'; import { INounsDescriptor } from './interfaces/INounsDescriptor.sol'; import { INounsSeeder } from './interfaces/INounsSeeder.sol'; import { NFTDescriptor } from './libs/NFTDescriptor.sol'; -import { ISVGRenderer } from './interfaces/ISVGRenderer.sol'; -import { INounsArt } from './interfaces/INounsArt.sol'; +import { MultiPartRLEToSVG } from './libs/MultiPartRLEToSVG.sol'; contract NounsDescriptor is INounsDescriptor, Ownable { using Strings for uint256; @@ -32,12 +31,6 @@ contract NounsDescriptor is INounsDescriptor, Ownable { // https://creativecommons.org/publicdomain/zero/1.0/legalcode.txt bytes32 constant COPYRIGHT_CC0_1_0_UNIVERSAL_LICENSE = 0xa2010f343487d3f7618affe54f789f5487602331c0a8d03f49e9a7c547cf0499; - // The contract responsible for holding compressed Noun art - INounsArt public art; - - // The contract responsible for constructing SVGs - ISVGRenderer public renderer; - // Whether or not new Noun parts can be added bool public override arePartsLocked; @@ -47,274 +40,175 @@ contract NounsDescriptor is INounsDescriptor, Ownable { // Base URI string public override baseURI; - /** - * @notice Require that the parts have not been locked. - */ - modifier whenPartsNotLocked() { - require(!arePartsLocked, 'Parts are locked'); - _; - } + // Noun Color Palettes (Index => Hex Colors) + mapping(uint8 => string[]) public override palettes; - constructor(INounsArt _art, ISVGRenderer _renderer) { - art = _art; - renderer = _renderer; - } + // Noun Backgrounds (Hex Colors) + string[] public override backgrounds; - /** - * @notice Set the Noun's art contract. - * Only callable by the owner when not locked. - */ - function setArt(INounsArt _art) external onlyOwner whenPartsNotLocked { - art = _art; + // Noun Bodies (Custom RLE) + bytes[] public override bodies; - emit ArtUpdated(_art); - } + // Noun Accessories (Custom RLE) + bytes[] public override accessories; + + // Noun Heads (Custom RLE) + bytes[] public override heads; + + // Noun Glasses (Custom RLE) + bytes[] public override glasses; /** - * @notice Set the SVG renderer. - * @dev Only callable by the owner. + * @notice Require that the parts have not been locked. */ - function setRenderer(ISVGRenderer _renderer) external onlyOwner { - renderer = _renderer; - - emit RendererUpdated(_renderer); + modifier whenPartsNotLocked() { + require(!arePartsLocked, 'Parts are locked'); + _; } /** * @notice Get the number of available Noun `backgrounds`. */ function backgroundCount() external view override returns (uint256) { - return art.backgroundsCount(); + return backgrounds.length; } /** * @notice Get the number of available Noun `bodies`. */ function bodyCount() external view override returns (uint256) { - return art.bodiesTrait().storedImagesCount; + return bodies.length; } /** * @notice Get the number of available Noun `accessories`. */ function accessoryCount() external view override returns (uint256) { - return art.accessoriesTrait().storedImagesCount; + return accessories.length; } /** * @notice Get the number of available Noun `heads`. */ function headCount() external view override returns (uint256) { - return art.headsTrait().storedImagesCount; + return heads.length; } /** * @notice Get the number of available Noun `glasses`. */ function glassesCount() external view override returns (uint256) { - return art.glassesTrait().storedImagesCount; + return glasses.length; } /** - * @notice Batch add Noun backgrounds. - * @dev This function can only be called by the owner when not locked. + * @notice Add colors to a color palette. + * @dev This function can only be called by the owner. */ - function addManyBackgrounds(string[] calldata _backgrounds) external override onlyOwner whenPartsNotLocked { - art.addManyBackgrounds(_backgrounds); + function addManyColorsToPalette(uint8 paletteIndex, string[] calldata newColors) external override onlyOwner { + require(palettes[paletteIndex].length + newColors.length <= 256, 'Palettes can only hold 256 colors'); + for (uint256 i = 0; i < newColors.length; i++) { + _addColorToPalette(paletteIndex, newColors[i]); + } } /** - * @notice Add a Noun background. + * @notice Batch add Noun backgrounds. * @dev This function can only be called by the owner when not locked. */ - function addBackground(string calldata _background) external override onlyOwner whenPartsNotLocked { - art.addBackground(_background); - } - - /** - * @notice Update a single color palette. This function can be used to - * add a new color palette or update an existing palette. - */ - function setPalette(uint8 paletteIndex, bytes calldata palette) external override onlyOwner { - art.setPalette(paletteIndex, palette); - } - - /** - * @notice Add a batch of body images. - * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, - * and finally compressing it using deflate. - * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. - * @param imageCount the number of images in this batch; used when searching for images among batches. - */ - function addBodies( - bytes calldata encodedCompressed, - uint80 decompressedLength, - uint16 imageCount - ) external override onlyOwner { - art.addBodies(encodedCompressed, decompressedLength, imageCount); - } - - /** - * @notice Add a batch of accessory images. - * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, - * and finally compressing it using deflate. - * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. - * @param imageCount the number of images in this batch; used when searching for images among batches. - */ - function addAccessories( - bytes calldata encodedCompressed, - uint80 decompressedLength, - uint16 imageCount - ) external override onlyOwner { - art.addAccessories(encodedCompressed, decompressedLength, imageCount); - } - - /** - * @notice Add a batch of head images. - * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, - * and finally compressing it using deflate. - * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. - * @param imageCount the number of images in this batch; used when searching for images among batches. - */ - function addHeads( - bytes calldata encodedCompressed, - uint80 decompressedLength, - uint16 imageCount - ) external override onlyOwner { - art.addHeads(encodedCompressed, decompressedLength, imageCount); - } - - /** - * @notice Add a batch of glasses images. - * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, - * and finally compressing it using deflate. - * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. - * @param imageCount the number of images in this batch; used when searching for images among batches. - */ - function addGlasses( - bytes calldata encodedCompressed, - uint80 decompressedLength, - uint16 imageCount - ) external override onlyOwner { - art.addGlasses(encodedCompressed, decompressedLength, imageCount); + function addManyBackgrounds(string[] calldata _backgrounds) external override onlyOwner whenPartsNotLocked { + for (uint256 i = 0; i < _backgrounds.length; i++) { + _addBackground(_backgrounds[i]); + } } /** - * @notice Add a batch of body images from an existing storage contract. - * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data - * format is expected to be like {encodedCompressed}: bytes created by taking a string array of - * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. - * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. - * @param imageCount the number of images in this batch; used when searching for images among batches. + * @notice Batch add Noun bodies. + * @dev This function can only be called by the owner when not locked. */ - function addBodiesFromPointer( - address pointer, - uint80 decompressedLength, - uint16 imageCount - ) external override onlyOwner { - art.addBodiesFromPointer(pointer, decompressedLength, imageCount); + function addManyBodies(bytes[] calldata _bodies) external override onlyOwner whenPartsNotLocked { + for (uint256 i = 0; i < _bodies.length; i++) { + _addBody(_bodies[i]); + } } /** - * @notice Add a batch of accessory images from an existing storage contract. - * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data - * format is expected to be like {encodedCompressed}: bytes created by taking a string array of - * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. - * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. - * @param imageCount the number of images in this batch; used when searching for images among batches. + * @notice Batch add Noun accessories. + * @dev This function can only be called by the owner when not locked. */ - function addAccessoriesFromPointer( - address pointer, - uint80 decompressedLength, - uint16 imageCount - ) external override onlyOwner { - art.addAccessoriesFromPointer(pointer, decompressedLength, imageCount); + function addManyAccessories(bytes[] calldata _accessories) external override onlyOwner whenPartsNotLocked { + for (uint256 i = 0; i < _accessories.length; i++) { + _addAccessory(_accessories[i]); + } } /** - * @notice Add a batch of head images from an existing storage contract. - * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data - * format is expected to be like {encodedCompressed}: bytes created by taking a string array of - * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. - * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. - * @param imageCount the number of images in this batch; used when searching for images among batches. + * @notice Batch add Noun heads. + * @dev This function can only be called by the owner when not locked. */ - function addHeadsFromPointer( - address pointer, - uint80 decompressedLength, - uint16 imageCount - ) external override onlyOwner { - art.addHeadsFromPointer(pointer, decompressedLength, imageCount); + function addManyHeads(bytes[] calldata _heads) external override onlyOwner whenPartsNotLocked { + for (uint256 i = 0; i < _heads.length; i++) { + _addHead(_heads[i]); + } } /** - * @notice Add a batch of glasses images from an existing storage contract. - * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data - * format is expected to be like {encodedCompressed}: bytes created by taking a string array of - * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. - * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. - * @param imageCount the number of images in this batch; used when searching for images among batches. + * @notice Batch add Noun glasses. + * @dev This function can only be called by the owner when not locked. */ - function addGlassesFromPointer( - address pointer, - uint80 decompressedLength, - uint16 imageCount - ) external override onlyOwner { - art.addGlassesFromPointer(pointer, decompressedLength, imageCount); + function addManyGlasses(bytes[] calldata _glasses) external override onlyOwner whenPartsNotLocked { + for (uint256 i = 0; i < _glasses.length; i++) { + _addGlasses(_glasses[i]); + } } /** - * @notice Get a background color by ID. - * @param index the index of the background. - * @return string the RGB hex value of the background. + * @notice Add a single color to a color palette. + * @dev This function can only be called by the owner. */ - function backgrounds(uint256 index) public view override returns (string memory) { - return art.backgrounds(index); + function addColorToPalette(uint8 _paletteIndex, string calldata _color) external override onlyOwner { + require(palettes[_paletteIndex].length <= 255, 'Palettes can only hold 256 colors'); + _addColorToPalette(_paletteIndex, _color); } /** - * @notice Get a head image by ID. - * @param index the index of the head. - * @return bytes the RLE-encoded bytes of the image. + * @notice Add a Noun background. + * @dev This function can only be called by the owner when not locked. */ - function heads(uint256 index) public view override returns (bytes memory) { - return art.heads(index); + function addBackground(string calldata _background) external override onlyOwner whenPartsNotLocked { + _addBackground(_background); } /** - * @notice Get a body image by ID. - * @param index the index of the body. - * @return bytes the RLE-encoded bytes of the image. + * @notice Add a Noun body. + * @dev This function can only be called by the owner when not locked. */ - function bodies(uint256 index) public view override returns (bytes memory) { - return art.bodies(index); + function addBody(bytes calldata _body) external override onlyOwner whenPartsNotLocked { + _addBody(_body); } /** - * @notice Get an accessory image by ID. - * @param index the index of the accessory. - * @return bytes the RLE-encoded bytes of the image. + * @notice Add a Noun accessory. + * @dev This function can only be called by the owner when not locked. */ - function accessories(uint256 index) public view override returns (bytes memory) { - return art.accessories(index); + function addAccessory(bytes calldata _accessory) external override onlyOwner whenPartsNotLocked { + _addAccessory(_accessory); } /** - * @notice Get a glasses image by ID. - * @param index the index of the glasses. - * @return bytes the RLE-encoded bytes of the image. + * @notice Add a Noun head. + * @dev This function can only be called by the owner when not locked. */ - function glasses(uint256 index) public view override returns (bytes memory) { - return art.glasses(index); + function addHead(bytes calldata _head) external override onlyOwner whenPartsNotLocked { + _addHead(_head); } /** - * @notice Get a color palette by ID. - * @param index the index of the palette. - * @return bytes the palette bytes, where every 3 consecutive bytes represent a color in RGB format. + * @notice Add Noun glasses. + * @dev This function can only be called by the owner when not locked. */ - function palettes(uint8 index) public view override returns (bytes memory) { - return art.palettes(index); + function addGlasses(bytes calldata _glasses) external override onlyOwner whenPartsNotLocked { + _addGlasses(_glasses); } /** @@ -384,44 +278,74 @@ contract NounsDescriptor is INounsDescriptor, Ownable { NFTDescriptor.TokenURIParams memory params = NFTDescriptor.TokenURIParams({ name: name, description: description, - parts: getPartsForSeed(seed), - background: art.backgrounds(seed.background) + parts: _getPartsForSeed(seed), + background: backgrounds[seed.background] }); - return NFTDescriptor.constructTokenURI(renderer, params); + return NFTDescriptor.constructTokenURI(params, palettes); } /** * @notice Given a seed, construct a base64 encoded SVG image. */ function generateSVGImage(INounsSeeder.Seed memory seed) external view override returns (string memory) { - ISVGRenderer.SVGParams memory params = ISVGRenderer.SVGParams({ - parts: getPartsForSeed(seed), - background: art.backgrounds(seed.background) + MultiPartRLEToSVG.SVGParams memory params = MultiPartRLEToSVG.SVGParams({ + parts: _getPartsForSeed(seed), + background: backgrounds[seed.background] }); - return NFTDescriptor.generateSVGImage(renderer, params); + return NFTDescriptor.generateSVGImage(params, palettes); } /** - * @notice Get all Noun parts for the passed `seed`. + * @notice Add a single color to a color palette. */ - function getPartsForSeed(INounsSeeder.Seed memory seed) public view returns (ISVGRenderer.Part[] memory) { - bytes memory _body = art.bodies(seed.body); - bytes memory _accessory = art.accessories(seed.accessory); - bytes memory _head = art.heads(seed.head); - bytes memory _glassesBytes = art.glasses(seed.glasses); - - ISVGRenderer.Part[] memory _parts = new ISVGRenderer.Part[](4); - _parts[0] = ISVGRenderer.Part({ image: _body, palette: _getPalette(_body) }); - _parts[1] = ISVGRenderer.Part({ image: _accessory, palette: _getPalette(_accessory) }); - _parts[2] = ISVGRenderer.Part({ image: _head, palette: _getPalette(_head) }); - _parts[3] = ISVGRenderer.Part({ image: _glassesBytes, palette: _getPalette(_glassesBytes) }); - return _parts; + function _addColorToPalette(uint8 _paletteIndex, string calldata _color) internal { + palettes[_paletteIndex].push(_color); + } + + /** + * @notice Add a Noun background. + */ + function _addBackground(string calldata _background) internal { + backgrounds.push(_background); + } + + /** + * @notice Add a Noun body. + */ + function _addBody(bytes calldata _body) internal { + bodies.push(_body); + } + + /** + * @notice Add a Noun accessory. + */ + function _addAccessory(bytes calldata _accessory) internal { + accessories.push(_accessory); + } + + /** + * @notice Add a Noun head. + */ + function _addHead(bytes calldata _head) internal { + heads.push(_head); } /** - * @notice Get the color palette pointer for the passed part. + * @notice Add Noun glasses. */ - function _getPalette(bytes memory part) private view returns (bytes memory) { - return art.palettes(uint8(part[0])); + function _addGlasses(bytes calldata _glasses) internal { + glasses.push(_glasses); + } + + /** + * @notice Get all Noun parts for the passed `seed`. + */ + function _getPartsForSeed(INounsSeeder.Seed memory seed) internal view returns (bytes[] memory) { + bytes[] memory _parts = new bytes[](4); + _parts[0] = bodies[seed.body]; + _parts[1] = accessories[seed.accessory]; + _parts[2] = heads[seed.head]; + _parts[3] = glasses[seed.glasses]; + return _parts; } } diff --git a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol new file mode 100644 index 0000000000..a411ea261f --- /dev/null +++ b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol @@ -0,0 +1,427 @@ +// SPDX-License-Identifier: GPL-3.0 + +/// @title The Nouns NFT descriptor + +/********************************* + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░██░░░████░░██░░░████░░░ * + * ░░██████░░░████████░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + *********************************/ + +pragma solidity ^0.8.6; + +import { Ownable } from '@openzeppelin/contracts/access/Ownable.sol'; +import { Strings } from '@openzeppelin/contracts/utils/Strings.sol'; +import { INounsDescriptorV2 } from './interfaces/INounsDescriptorV2.sol'; +import { INounsSeeder } from './interfaces/INounsSeeder.sol'; +import { NFTDescriptorV2 } from './libs/NFTDescriptorV2.sol'; +import { ISVGRenderer } from './interfaces/ISVGRenderer.sol'; +import { INounsArt } from './interfaces/INounsArt.sol'; + +contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { + using Strings for uint256; + + // prettier-ignore + // https://creativecommons.org/publicdomain/zero/1.0/legalcode.txt + bytes32 constant COPYRIGHT_CC0_1_0_UNIVERSAL_LICENSE = 0xa2010f343487d3f7618affe54f789f5487602331c0a8d03f49e9a7c547cf0499; + + // The contract responsible for holding compressed Noun art + INounsArt public art; + + // The contract responsible for constructing SVGs + ISVGRenderer public renderer; + + // Whether or not new Noun parts can be added + bool public override arePartsLocked; + + // Whether or not `tokenURI` should be returned as a data URI (Default: true) + bool public override isDataURIEnabled = true; + + // Base URI + string public override baseURI; + + /** + * @notice Require that the parts have not been locked. + */ + modifier whenPartsNotLocked() { + require(!arePartsLocked, 'Parts are locked'); + _; + } + + constructor(INounsArt _art, ISVGRenderer _renderer) { + art = _art; + renderer = _renderer; + } + + /** + * @notice Set the Noun's art contract. + * Only callable by the owner when not locked. + */ + function setArt(INounsArt _art) external onlyOwner whenPartsNotLocked { + art = _art; + + emit ArtUpdated(_art); + } + + /** + * @notice Set the SVG renderer. + * @dev Only callable by the owner. + */ + function setRenderer(ISVGRenderer _renderer) external onlyOwner { + renderer = _renderer; + + emit RendererUpdated(_renderer); + } + + /** + * @notice Get the number of available Noun `backgrounds`. + */ + function backgroundCount() external view override returns (uint256) { + return art.backgroundsCount(); + } + + /** + * @notice Get the number of available Noun `bodies`. + */ + function bodyCount() external view override returns (uint256) { + return art.bodiesTrait().storedImagesCount; + } + + /** + * @notice Get the number of available Noun `accessories`. + */ + function accessoryCount() external view override returns (uint256) { + return art.accessoriesTrait().storedImagesCount; + } + + /** + * @notice Get the number of available Noun `heads`. + */ + function headCount() external view override returns (uint256) { + return art.headsTrait().storedImagesCount; + } + + /** + * @notice Get the number of available Noun `glasses`. + */ + function glassesCount() external view override returns (uint256) { + return art.glassesTrait().storedImagesCount; + } + + /** + * @notice Batch add Noun backgrounds. + * @dev This function can only be called by the owner when not locked. + */ + function addManyBackgrounds(string[] calldata _backgrounds) external override onlyOwner whenPartsNotLocked { + art.addManyBackgrounds(_backgrounds); + } + + /** + * @notice Add a Noun background. + * @dev This function can only be called by the owner when not locked. + */ + function addBackground(string calldata _background) external override onlyOwner whenPartsNotLocked { + art.addBackground(_background); + } + + /** + * @notice Update a single color palette. This function can be used to + * add a new color palette or update an existing palette. + */ + function setPalette(uint8 paletteIndex, bytes calldata palette) external override onlyOwner { + art.setPalette(paletteIndex, palette); + } + + /** + * @notice Add a batch of body images. + * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, + * and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ + function addBodies( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external override onlyOwner { + art.addBodies(encodedCompressed, decompressedLength, imageCount); + } + + /** + * @notice Add a batch of accessory images. + * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, + * and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ + function addAccessories( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external override onlyOwner { + art.addAccessories(encodedCompressed, decompressedLength, imageCount); + } + + /** + * @notice Add a batch of head images. + * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, + * and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ + function addHeads( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external override onlyOwner { + art.addHeads(encodedCompressed, decompressedLength, imageCount); + } + + /** + * @notice Add a batch of glasses images. + * @param encodedCompressed bytes created by taking a string array of RLE-encoded images, abi encoding it as a bytes array, + * and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ + function addGlasses( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external override onlyOwner { + art.addGlasses(encodedCompressed, decompressedLength, imageCount); + } + + /** + * @notice Add a batch of body images from an existing storage contract. + * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data + * format is expected to be like {encodedCompressed}: bytes created by taking a string array of + * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ + function addBodiesFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external override onlyOwner { + art.addBodiesFromPointer(pointer, decompressedLength, imageCount); + } + + /** + * @notice Add a batch of accessory images from an existing storage contract. + * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data + * format is expected to be like {encodedCompressed}: bytes created by taking a string array of + * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ + function addAccessoriesFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external override onlyOwner { + art.addAccessoriesFromPointer(pointer, decompressedLength, imageCount); + } + + /** + * @notice Add a batch of head images from an existing storage contract. + * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data + * format is expected to be like {encodedCompressed}: bytes created by taking a string array of + * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ + function addHeadsFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external override onlyOwner { + art.addHeadsFromPointer(pointer, decompressedLength, imageCount); + } + + /** + * @notice Add a batch of glasses images from an existing storage contract. + * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data + * format is expected to be like {encodedCompressed}: bytes created by taking a string array of + * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. + * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. + * @param imageCount the number of images in this batch; used when searching for images among batches. + */ + function addGlassesFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external override onlyOwner { + art.addGlassesFromPointer(pointer, decompressedLength, imageCount); + } + + /** + * @notice Get a background color by ID. + * @param index the index of the background. + * @return string the RGB hex value of the background. + */ + function backgrounds(uint256 index) public view override returns (string memory) { + return art.backgrounds(index); + } + + /** + * @notice Get a head image by ID. + * @param index the index of the head. + * @return bytes the RLE-encoded bytes of the image. + */ + function heads(uint256 index) public view override returns (bytes memory) { + return art.heads(index); + } + + /** + * @notice Get a body image by ID. + * @param index the index of the body. + * @return bytes the RLE-encoded bytes of the image. + */ + function bodies(uint256 index) public view override returns (bytes memory) { + return art.bodies(index); + } + + /** + * @notice Get an accessory image by ID. + * @param index the index of the accessory. + * @return bytes the RLE-encoded bytes of the image. + */ + function accessories(uint256 index) public view override returns (bytes memory) { + return art.accessories(index); + } + + /** + * @notice Get a glasses image by ID. + * @param index the index of the glasses. + * @return bytes the RLE-encoded bytes of the image. + */ + function glasses(uint256 index) public view override returns (bytes memory) { + return art.glasses(index); + } + + /** + * @notice Get a color palette by ID. + * @param index the index of the palette. + * @return bytes the palette bytes, where every 3 consecutive bytes represent a color in RGB format. + */ + function palettes(uint8 index) public view override returns (bytes memory) { + return art.palettes(index); + } + + /** + * @notice Lock all Noun parts. + * @dev This cannot be reversed and can only be called by the owner when not locked. + */ + function lockParts() external override onlyOwner whenPartsNotLocked { + arePartsLocked = true; + + emit PartsLocked(); + } + + /** + * @notice Toggle a boolean value which determines if `tokenURI` returns a data URI + * or an HTTP URL. + * @dev This can only be called by the owner. + */ + function toggleDataURIEnabled() external override onlyOwner { + bool enabled = !isDataURIEnabled; + + isDataURIEnabled = enabled; + emit DataURIToggled(enabled); + } + + /** + * @notice Set the base URI for all token IDs. It is automatically + * added as a prefix to the value returned in {tokenURI}, or to the + * token ID if {tokenURI} is empty. + * @dev This can only be called by the owner. + */ + function setBaseURI(string calldata _baseURI) external override onlyOwner { + baseURI = _baseURI; + + emit BaseURIUpdated(_baseURI); + } + + /** + * @notice Given a token ID and seed, construct a token URI for an official Nouns DAO noun. + * @dev The returned value may be a base64 encoded data URI or an API URL. + */ + function tokenURI(uint256 tokenId, INounsSeeder.Seed memory seed) external view override returns (string memory) { + if (isDataURIEnabled) { + return dataURI(tokenId, seed); + } + return string(abi.encodePacked(baseURI, tokenId.toString())); + } + + /** + * @notice Given a token ID and seed, construct a base64 encoded data URI for an official Nouns DAO noun. + */ + function dataURI(uint256 tokenId, INounsSeeder.Seed memory seed) public view override returns (string memory) { + string memory nounId = tokenId.toString(); + string memory name = string(abi.encodePacked('Noun ', nounId)); + string memory description = string(abi.encodePacked('Noun ', nounId, ' is a member of the Nouns DAO')); + + return genericDataURI(name, description, seed); + } + + /** + * @notice Given a name, description, and seed, construct a base64 encoded data URI. + */ + function genericDataURI( + string memory name, + string memory description, + INounsSeeder.Seed memory seed + ) public view override returns (string memory) { + NFTDescriptorV2.TokenURIParams memory params = NFTDescriptorV2.TokenURIParams({ + name: name, + description: description, + parts: getPartsForSeed(seed), + background: art.backgrounds(seed.background) + }); + return NFTDescriptorV2.constructTokenURI(renderer, params); + } + + /** + * @notice Given a seed, construct a base64 encoded SVG image. + */ + function generateSVGImage(INounsSeeder.Seed memory seed) external view override returns (string memory) { + ISVGRenderer.SVGParams memory params = ISVGRenderer.SVGParams({ + parts: getPartsForSeed(seed), + background: art.backgrounds(seed.background) + }); + return NFTDescriptorV2.generateSVGImage(renderer, params); + } + + /** + * @notice Get all Noun parts for the passed `seed`. + */ + function getPartsForSeed(INounsSeeder.Seed memory seed) public view returns (ISVGRenderer.Part[] memory) { + bytes memory _body = art.bodies(seed.body); + bytes memory _accessory = art.accessories(seed.accessory); + bytes memory _head = art.heads(seed.head); + bytes memory _glassesBytes = art.glasses(seed.glasses); + + ISVGRenderer.Part[] memory _parts = new ISVGRenderer.Part[](4); + _parts[0] = ISVGRenderer.Part({ image: _body, palette: _getPalette(_body) }); + _parts[1] = ISVGRenderer.Part({ image: _accessory, palette: _getPalette(_accessory) }); + _parts[2] = ISVGRenderer.Part({ image: _head, palette: _getPalette(_head) }); + _parts[3] = ISVGRenderer.Part({ image: _glassesBytes, palette: _getPalette(_glassesBytes) }); + return _parts; + } + + /** + * @notice Get the color palette pointer for the passed part. + */ + function _getPalette(bytes memory part) private view returns (bytes memory) { + return art.palettes(uint8(part[0])); + } +} diff --git a/packages/nouns-contracts/contracts/NounsSeeder.sol b/packages/nouns-contracts/contracts/NounsSeeder.sol index bcd79f43e1..07a385eeee 100644 --- a/packages/nouns-contracts/contracts/NounsSeeder.sol +++ b/packages/nouns-contracts/contracts/NounsSeeder.sol @@ -18,14 +18,14 @@ pragma solidity ^0.8.6; import { INounsSeeder } from './interfaces/INounsSeeder.sol'; -import { INounsDescriptor } from './interfaces/INounsDescriptor.sol'; +import { INounsDescriptorMinimal } from './interfaces/INounsDescriptorMinimal.sol'; contract NounsSeeder is INounsSeeder { /** * @notice Generate a pseudo-random Noun seed using the previous blockhash and noun ID. */ // prettier-ignore - function generateSeed(uint256 nounId, INounsDescriptor descriptor) external view override returns (Seed memory) { + function generateSeed(uint256 nounId, INounsDescriptorMinimal descriptor) external view override returns (Seed memory) { uint256 pseudorandomness = uint256( keccak256(abi.encodePacked(blockhash(block.number - 1), nounId)) ); diff --git a/packages/nouns-contracts/contracts/NounsToken.sol b/packages/nouns-contracts/contracts/NounsToken.sol index 19350477a1..db569d54e3 100644 --- a/packages/nouns-contracts/contracts/NounsToken.sol +++ b/packages/nouns-contracts/contracts/NounsToken.sol @@ -19,7 +19,7 @@ pragma solidity ^0.8.6; import { Ownable } from '@openzeppelin/contracts/access/Ownable.sol'; import { ERC721Checkpointable } from './base/ERC721Checkpointable.sol'; -import { INounsDescriptor } from './interfaces/INounsDescriptor.sol'; +import { INounsDescriptorMinimal } from './interfaces/INounsDescriptorMinimal.sol'; import { INounsSeeder } from './interfaces/INounsSeeder.sol'; import { INounsToken } from './interfaces/INounsToken.sol'; import { ERC721 } from './base/ERC721.sol'; @@ -34,7 +34,7 @@ contract NounsToken is INounsToken, Ownable, ERC721Checkpointable { address public minter; // The Nouns token URI descriptor - INounsDescriptor public descriptor; + INounsDescriptorMinimal public descriptor; // The Nouns token seeder INounsSeeder public seeder; @@ -103,7 +103,7 @@ contract NounsToken is INounsToken, Ownable, ERC721Checkpointable { constructor( address _noundersDAO, address _minter, - INounsDescriptor _descriptor, + INounsDescriptorMinimal _descriptor, INounsSeeder _seeder, IProxyRegistry _proxyRegistry ) ERC721('Nouns', 'NOUN') { @@ -213,7 +213,7 @@ contract NounsToken is INounsToken, Ownable, ERC721Checkpointable { * @notice Set the token URI descriptor. * @dev Only callable by the owner when not locked. */ - function setDescriptor(INounsDescriptor _descriptor) external override onlyOwner whenDescriptorNotLocked { + function setDescriptor(INounsDescriptorMinimal _descriptor) external override onlyOwner whenDescriptorNotLocked { descriptor = _descriptor; emit DescriptorUpdated(_descriptor); diff --git a/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol b/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol index 59e40ddf68..6c676f6abd 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsDescriptor.sol @@ -18,31 +18,22 @@ pragma solidity ^0.8.6; import { INounsSeeder } from './INounsSeeder.sol'; -import { ISVGRenderer } from './ISVGRenderer.sol'; -import { INounsArt } from './INounsArt.sol'; +import { INounsDescriptorMinimal } from './INounsDescriptorMinimal.sol'; -interface INounsDescriptor { +interface INounsDescriptor is INounsDescriptorMinimal { event PartsLocked(); event DataURIToggled(bool enabled); event BaseURIUpdated(string baseURI); - event ArtUpdated(INounsArt art); - - event RendererUpdated(ISVGRenderer renderer); - - error EmptyPalette(); - error BadPaletteLength(); - error IndexNotFound(); - function arePartsLocked() external returns (bool); function isDataURIEnabled() external returns (bool); function baseURI() external returns (string memory); - function palettes(uint8 paletteIndex) external view returns (bytes memory); + function palettes(uint8 paletteIndex, uint256 colorIndex) external view returns (string memory); function backgrounds(uint256 index) external view returns (string memory); @@ -54,69 +45,39 @@ interface INounsDescriptor { function glasses(uint256 index) external view returns (bytes memory); - function backgroundCount() external view returns (uint256); + function backgroundCount() external view override returns (uint256); - function bodyCount() external view returns (uint256); + function bodyCount() external view override returns (uint256); - function accessoryCount() external view returns (uint256); + function accessoryCount() external view override returns (uint256); - function headCount() external view returns (uint256); + function headCount() external view override returns (uint256); - function glassesCount() external view returns (uint256); + function glassesCount() external view override returns (uint256); + + function addManyColorsToPalette(uint8 paletteIndex, string[] calldata newColors) external; function addManyBackgrounds(string[] calldata backgrounds) external; + function addManyBodies(bytes[] calldata bodies) external; + + function addManyAccessories(bytes[] calldata accessories) external; + + function addManyHeads(bytes[] calldata heads) external; + + function addManyGlasses(bytes[] calldata glasses) external; + + function addColorToPalette(uint8 paletteIndex, string calldata color) external; + function addBackground(string calldata background) external; - function setPalette(uint8 paletteIndex, bytes calldata palette) external; - - function addBodies( - bytes calldata encodedCompressed, - uint80 decompressedLength, - uint16 imageCount - ) external; - - function addAccessories( - bytes calldata encodedCompressed, - uint80 decompressedLength, - uint16 imageCount - ) external; - - function addHeads( - bytes calldata encodedCompressed, - uint80 decompressedLength, - uint16 imageCount - ) external; - - function addGlasses( - bytes calldata encodedCompressed, - uint80 decompressedLength, - uint16 imageCount - ) external; - - function addBodiesFromPointer( - address pointer, - uint80 decompressedLength, - uint16 imageCount - ) external; - - function addAccessoriesFromPointer( - address pointer, - uint80 decompressedLength, - uint16 imageCount - ) external; - - function addHeadsFromPointer( - address pointer, - uint80 decompressedLength, - uint16 imageCount - ) external; - - function addGlassesFromPointer( - address pointer, - uint80 decompressedLength, - uint16 imageCount - ) external; + function addBody(bytes calldata body) external; + + function addAccessory(bytes calldata accessory) external; + + function addHead(bytes calldata head) external; + + function addGlasses(bytes calldata glasses) external; function lockParts() external; @@ -124,9 +85,9 @@ interface INounsDescriptor { function setBaseURI(string calldata baseURI) external; - function tokenURI(uint256 tokenId, INounsSeeder.Seed memory seed) external view returns (string memory); + function tokenURI(uint256 tokenId, INounsSeeder.Seed memory seed) external view override returns (string memory); - function dataURI(uint256 tokenId, INounsSeeder.Seed memory seed) external view returns (string memory); + function dataURI(uint256 tokenId, INounsSeeder.Seed memory seed) external view override returns (string memory); function genericDataURI( string calldata name, diff --git a/packages/nouns-contracts/contracts/interfaces/INounsDescriptorMinimal.sol b/packages/nouns-contracts/contracts/interfaces/INounsDescriptorMinimal.sol new file mode 100644 index 0000000000..c49d4c865d --- /dev/null +++ b/packages/nouns-contracts/contracts/interfaces/INounsDescriptorMinimal.sol @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-3.0 + +/// @title Common interface for NounsDescriptor versions, as used by NounsToken and NounsSeeder. + +/********************************* + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░██░░░████░░██░░░████░░░ * + * ░░██████░░░████████░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + *********************************/ + +pragma solidity ^0.8.6; + +import { INounsSeeder } from './INounsSeeder.sol'; + +interface INounsDescriptorMinimal { + /// + /// USED BY TOKEN + /// + + function tokenURI(uint256 tokenId, INounsSeeder.Seed memory seed) external view returns (string memory); + + function dataURI(uint256 tokenId, INounsSeeder.Seed memory seed) external view returns (string memory); + + /// + /// USED BY SEEDER + /// + + function backgroundCount() external view returns (uint256); + + function bodyCount() external view returns (uint256); + + function accessoryCount() external view returns (uint256); + + function headCount() external view returns (uint256); + + function glassesCount() external view returns (uint256); +} diff --git a/packages/nouns-contracts/contracts/interfaces/INounsDescriptorV2.sol b/packages/nouns-contracts/contracts/interfaces/INounsDescriptorV2.sol new file mode 100644 index 0000000000..f8c2269714 --- /dev/null +++ b/packages/nouns-contracts/contracts/interfaces/INounsDescriptorV2.sol @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-3.0 + +/// @title Interface for NounsDescriptorV2 + +/********************************* + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░██░░░████░░██░░░████░░░ * + * ░░██████░░░████████░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + *********************************/ + +pragma solidity ^0.8.6; + +import { INounsSeeder } from './INounsSeeder.sol'; +import { ISVGRenderer } from './ISVGRenderer.sol'; +import { INounsArt } from './INounsArt.sol'; +import { INounsDescriptorMinimal } from './INounsDescriptorMinimal.sol'; + +interface INounsDescriptorV2 is INounsDescriptorMinimal { + event PartsLocked(); + + event DataURIToggled(bool enabled); + + event BaseURIUpdated(string baseURI); + + event ArtUpdated(INounsArt art); + + event RendererUpdated(ISVGRenderer renderer); + + error EmptyPalette(); + error BadPaletteLength(); + error IndexNotFound(); + + function arePartsLocked() external returns (bool); + + function isDataURIEnabled() external returns (bool); + + function baseURI() external returns (string memory); + + function palettes(uint8 paletteIndex) external view returns (bytes memory); + + function backgrounds(uint256 index) external view returns (string memory); + + function bodies(uint256 index) external view returns (bytes memory); + + function accessories(uint256 index) external view returns (bytes memory); + + function heads(uint256 index) external view returns (bytes memory); + + function glasses(uint256 index) external view returns (bytes memory); + + function backgroundCount() external view override returns (uint256); + + function bodyCount() external view override returns (uint256); + + function accessoryCount() external view override returns (uint256); + + function headCount() external view override returns (uint256); + + function glassesCount() external view override returns (uint256); + + function addManyBackgrounds(string[] calldata backgrounds) external; + + function addBackground(string calldata background) external; + + function setPalette(uint8 paletteIndex, bytes calldata palette) external; + + function addBodies( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function addAccessories( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function addHeads( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function addGlasses( + bytes calldata encodedCompressed, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function addBodiesFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function addAccessoriesFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function addHeadsFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function addGlassesFromPointer( + address pointer, + uint80 decompressedLength, + uint16 imageCount + ) external; + + function lockParts() external; + + function toggleDataURIEnabled() external; + + function setBaseURI(string calldata baseURI) external; + + function tokenURI(uint256 tokenId, INounsSeeder.Seed memory seed) external view override returns (string memory); + + function dataURI(uint256 tokenId, INounsSeeder.Seed memory seed) external view override returns (string memory); + + function genericDataURI( + string calldata name, + string calldata description, + INounsSeeder.Seed memory seed + ) external view returns (string memory); + + function generateSVGImage(INounsSeeder.Seed memory seed) external view returns (string memory); +} diff --git a/packages/nouns-contracts/contracts/interfaces/INounsSeeder.sol b/packages/nouns-contracts/contracts/interfaces/INounsSeeder.sol index 25c15fa1c9..8b1b3f627e 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsSeeder.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsSeeder.sol @@ -17,7 +17,7 @@ pragma solidity ^0.8.6; -import { INounsDescriptor } from './INounsDescriptor.sol'; +import { INounsDescriptorMinimal } from './INounsDescriptorMinimal.sol'; interface INounsSeeder { struct Seed { @@ -28,5 +28,5 @@ interface INounsSeeder { uint48 glasses; } - function generateSeed(uint256 nounId, INounsDescriptor descriptor) external view returns (Seed memory); + function generateSeed(uint256 nounId, INounsDescriptorMinimal descriptor) external view returns (Seed memory); } diff --git a/packages/nouns-contracts/contracts/interfaces/INounsToken.sol b/packages/nouns-contracts/contracts/interfaces/INounsToken.sol index 70125c18d7..35a1de045c 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsToken.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsToken.sol @@ -18,7 +18,7 @@ pragma solidity ^0.8.6; import { IERC721 } from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; -import { INounsDescriptor } from './INounsDescriptor.sol'; +import { INounsDescriptorMinimal } from './INounsDescriptorMinimal.sol'; import { INounsSeeder } from './INounsSeeder.sol'; interface INounsToken is IERC721 { @@ -32,7 +32,7 @@ interface INounsToken is IERC721 { event MinterLocked(); - event DescriptorUpdated(INounsDescriptor descriptor); + event DescriptorUpdated(INounsDescriptorMinimal descriptor); event DescriptorLocked(); @@ -52,7 +52,7 @@ interface INounsToken is IERC721 { function lockMinter() external; - function setDescriptor(INounsDescriptor descriptor) external; + function setDescriptor(INounsDescriptorMinimal descriptor) external; function lockDescriptor() external; diff --git a/packages/nouns-contracts/contracts/libs/MultiPartRLEToSVG.sol b/packages/nouns-contracts/contracts/libs/MultiPartRLEToSVG.sol new file mode 100644 index 0000000000..cec68ecaf7 --- /dev/null +++ b/packages/nouns-contracts/contracts/libs/MultiPartRLEToSVG.sol @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-3.0 + +/// @title A library used to convert multi-part RLE compressed images to SVG +/// @dev Used in NFTDescriptor.sol. V2 uses SVGRenderer.sol. + +/********************************* + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░██░░░████░░██░░░████░░░ * + * ░░██████░░░████████░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + *********************************/ + +pragma solidity ^0.8.6; + +library MultiPartRLEToSVG { + struct SVGParams { + bytes[] parts; + string background; + } + + struct ContentBounds { + uint8 top; + uint8 right; + uint8 bottom; + uint8 left; + } + + struct Rect { + uint8 length; + uint8 colorIndex; + } + + struct DecodedImage { + uint8 paletteIndex; + ContentBounds bounds; + Rect[] rects; + } + + /** + * @notice Given RLE image parts and color palettes, merge to generate a single SVG image. + */ + function generateSVG(SVGParams memory params, mapping(uint8 => string[]) storage palettes) + internal + view + returns (string memory svg) + { + // prettier-ignore + return string( + abi.encodePacked( + '', + '', + _generateSVGRects(params, palettes), + '' + ) + ); + } + + /** + * @notice Given RLE image parts and color palettes, generate SVG rects. + */ + // prettier-ignore + function _generateSVGRects(SVGParams memory params, mapping(uint8 => string[]) storage palettes) + private + view + returns (string memory svg) + { + string[33] memory lookup = [ + '0', '10', '20', '30', '40', '50', '60', '70', + '80', '90', '100', '110', '120', '130', '140', '150', + '160', '170', '180', '190', '200', '210', '220', '230', + '240', '250', '260', '270', '280', '290', '300', '310', + '320' + ]; + string memory rects; + for (uint8 p = 0; p < params.parts.length; p++) { + DecodedImage memory image = _decodeRLEImage(params.parts[p]); + string[] storage palette = palettes[image.paletteIndex]; + uint256 currentX = image.bounds.left; + uint256 currentY = image.bounds.top; + uint256 cursor; + string[16] memory buffer; + + string memory part; + for (uint256 i = 0; i < image.rects.length; i++) { + Rect memory rect = image.rects[i]; + if (rect.colorIndex != 0) { + buffer[cursor] = lookup[rect.length]; // width + buffer[cursor + 1] = lookup[currentX]; // x + buffer[cursor + 2] = lookup[currentY]; // y + buffer[cursor + 3] = palette[rect.colorIndex]; // color + + cursor += 4; + + if (cursor >= 16) { + part = string(abi.encodePacked(part, _getChunk(cursor, buffer))); + cursor = 0; + } + } + + currentX += rect.length; + if (currentX == image.bounds.right) { + currentX = image.bounds.left; + currentY++; + } + } + + if (cursor != 0) { + part = string(abi.encodePacked(part, _getChunk(cursor, buffer))); + } + rects = string(abi.encodePacked(rects, part)); + } + return rects; + } + + /** + * @notice Return a string that consists of all rects in the provided `buffer`. + */ + // prettier-ignore + function _getChunk(uint256 cursor, string[16] memory buffer) private pure returns (string memory) { + string memory chunk; + for (uint256 i = 0; i < cursor; i += 4) { + chunk = string( + abi.encodePacked( + chunk, + '' + ) + ); + } + return chunk; + } + + /** + * @notice Decode a single RLE compressed image into a `DecodedImage`. + */ + function _decodeRLEImage(bytes memory image) private pure returns (DecodedImage memory) { + uint8 paletteIndex = uint8(image[0]); + ContentBounds memory bounds = ContentBounds({ + top: uint8(image[1]), + right: uint8(image[2]), + bottom: uint8(image[3]), + left: uint8(image[4]) + }); + + uint256 cursor; + Rect[] memory rects = new Rect[]((image.length - 5) / 2); + for (uint256 i = 5; i < image.length; i += 2) { + rects[cursor] = Rect({ length: uint8(image[i]), colorIndex: uint8(image[i + 1]) }); + cursor++; + } + return DecodedImage({ paletteIndex: paletteIndex, bounds: bounds, rects: rects }); + } +} diff --git a/packages/nouns-contracts/contracts/libs/NFTDescriptor.sol b/packages/nouns-contracts/contracts/libs/NFTDescriptor.sol index 5eacf2bf13..4b8e7b7985 100644 --- a/packages/nouns-contracts/contracts/libs/NFTDescriptor.sol +++ b/packages/nouns-contracts/contracts/libs/NFTDescriptor.sol @@ -18,27 +18,27 @@ pragma solidity ^0.8.6; import { Base64 } from 'base64-sol/base64.sol'; -import { ISVGRenderer } from '../interfaces/ISVGRenderer.sol'; +import { MultiPartRLEToSVG } from './MultiPartRLEToSVG.sol'; library NFTDescriptor { struct TokenURIParams { string name; string description; + bytes[] parts; string background; - ISVGRenderer.Part[] parts; } /** * @notice Construct an ERC721 token URI. */ - function constructTokenURI(ISVGRenderer renderer, TokenURIParams memory params) + function constructTokenURI(TokenURIParams memory params, mapping(uint8 => string[]) storage palettes) public view returns (string memory) { string memory image = generateSVGImage( - renderer, - ISVGRenderer.SVGParams({ parts: params.parts, background: params.background }) + MultiPartRLEToSVG.SVGParams({ parts: params.parts, background: params.background }), + palettes ); // prettier-ignore @@ -57,11 +57,11 @@ library NFTDescriptor { /** * @notice Generate an SVG image for use in the ERC721 token URI. */ - function generateSVGImage(ISVGRenderer renderer, ISVGRenderer.SVGParams memory params) + function generateSVGImage(MultiPartRLEToSVG.SVGParams memory params, mapping(uint8 => string[]) storage palettes) public view returns (string memory svg) { - return Base64.encode(bytes(renderer.generateSVG(params))); + return Base64.encode(bytes(MultiPartRLEToSVG.generateSVG(params, palettes))); } } diff --git a/packages/nouns-contracts/contracts/libs/NFTDescriptorV2.sol b/packages/nouns-contracts/contracts/libs/NFTDescriptorV2.sol new file mode 100644 index 0000000000..a69037dd47 --- /dev/null +++ b/packages/nouns-contracts/contracts/libs/NFTDescriptorV2.sol @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-3.0 + +/// @title A library used to construct ERC721 token URIs and SVG images + +/********************************* + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░██░░░████░░██░░░████░░░ * + * ░░██████░░░████████░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + *********************************/ + +pragma solidity ^0.8.6; + +import { Base64 } from 'base64-sol/base64.sol'; +import { ISVGRenderer } from '../interfaces/ISVGRenderer.sol'; + +library NFTDescriptorV2 { + struct TokenURIParams { + string name; + string description; + string background; + ISVGRenderer.Part[] parts; + } + + /** + * @notice Construct an ERC721 token URI. + */ + function constructTokenURI(ISVGRenderer renderer, TokenURIParams memory params) + public + view + returns (string memory) + { + string memory image = generateSVGImage( + renderer, + ISVGRenderer.SVGParams({ parts: params.parts, background: params.background }) + ); + + // prettier-ignore + return string( + abi.encodePacked( + 'data:application/json;base64,', + Base64.encode( + bytes( + abi.encodePacked('{"name":"', params.name, '", "description":"', params.description, '", "image": "', 'data:image/svg+xml;base64,', image, '"}') + ) + ) + ) + ); + } + + /** + * @notice Generate an SVG image for use in the ERC721 token URI. + */ + function generateSVGImage(ISVGRenderer renderer, ISVGRenderer.SVGParams memory params) + public + view + returns (string memory svg) + { + return Base64.encode(bytes(renderer.generateSVG(params))); + } +} diff --git a/packages/nouns-contracts/tasks/deploy-local.ts b/packages/nouns-contracts/tasks/deploy-local.ts index ef94d721b3..7386031dd7 100644 --- a/packages/nouns-contracts/tasks/deploy-local.ts +++ b/packages/nouns-contracts/tasks/deploy-local.ts @@ -38,11 +38,16 @@ task('deploy-local', 'Deploy contracts to hardhat') const proxyRegistryAddress = '0xa5409ec958c83c3f309868babaca7c86dcb077c1'; - const AUCTION_HOUSE_PROXY_NONCE_OFFSET = 7; - const GOVERNOR_N_DELEGATOR_NONCE_OFFSET = 10; + const NOUNS_ART_NONCE_OFFSET = 4; + const AUCTION_HOUSE_PROXY_NONCE_OFFSET = 9; + const GOVERNOR_N_DELEGATOR_NONCE_OFFSET = 12; const [deployer] = await ethers.getSigners(); const nonce = await deployer.getTransactionCount(); + const expectedNounsArtAddress = ethers.utils.getContractAddress({ + from: deployer.address, + nonce: nonce + NOUNS_ART_NONCE_OFFSET, + }); const expectedNounsDAOProxyAddress = ethers.utils.getContractAddress({ from: deployer.address, nonce: nonce + GOVERNOR_N_DELEGATOR_NONCE_OFFSET, @@ -53,18 +58,23 @@ task('deploy-local', 'Deploy contracts to hardhat') }); const contracts: Record = { WETH: {}, - NFTDescriptor: {}, - NounsDescriptor: { + NFTDescriptorV2: {}, + SVGRenderer: {}, + NounsDescriptorV2: { + args: [expectedNounsArtAddress, () => contracts.SVGRenderer.instance?.address], libraries: () => ({ - NFTDescriptor: contracts.NFTDescriptor.instance?.address as string, + NFTDescriptorV2: contracts.NFTDescriptorV2.instance?.address as string, }), }, + NounsArt: { + args: [() => contracts.NounsDescriptorV2.instance?.address], + }, NounsSeeder: {}, NounsToken: { args: [ args.noundersdao || deployer.address, expectedAuctionHouseProxyAddress, - () => contracts.NounsDescriptor.instance?.address, + () => contracts.NounsDescriptorV2.instance?.address, () => contracts.NounsSeeder.instance?.address, proxyRegistryAddress, ], diff --git a/packages/nouns-contracts/tasks/deploy.ts b/packages/nouns-contracts/tasks/deploy.ts index 1248179b3e..ceb7c47c4b 100644 --- a/packages/nouns-contracts/tasks/deploy.ts +++ b/packages/nouns-contracts/tasks/deploy.ts @@ -19,8 +19,9 @@ const wethContracts: Record = { [ChainId.Kovan]: '0xd0a1e359811322d97991e03f863a0c30c2cf029c', }; -const AUCTION_HOUSE_PROXY_NONCE_OFFSET = 6; -const GOVERNOR_N_DELEGATOR_NONCE_OFFSET = 9; +const NOUNS_ART_NONCE_OFFSET = 3; +const AUCTION_HOUSE_PROXY_NONCE_OFFSET = 8; +const GOVERNOR_N_DELEGATOR_NONCE_OFFSET = 11; task('deploy', 'Deploys NFTDescriptor, NounsDescriptor, NounsSeeder, and NounsToken') .addFlag('autoDeploy', 'Deploy all contracts without user interaction') @@ -104,6 +105,10 @@ task('deploy', 'Deploys NFTDescriptor, NounsDescriptor, NounsSeeder, and NounsTo } const nonce = await deployer.getTransactionCount(); + const expectedNounsArtAddress = ethers.utils.getContractAddress({ + from: deployer.address, + nonce: nonce + NOUNS_ART_NONCE_OFFSET, + }); const expectedAuctionHouseProxyAddress = ethers.utils.getContractAddress({ from: deployer.address, nonce: nonce + AUCTION_HOUSE_PROXY_NONCE_OFFSET, @@ -117,18 +122,22 @@ task('deploy', 'Deploys NFTDescriptor, NounsDescriptor, NounsSeeder, and NounsTo DeployedContract >; const contracts: Record = { - NFTDescriptor: {}, - NounsDescriptor: { + NFTDescriptorV2: {}, + SVGRenderer: {}, + NounsDescriptorV2: { libraries: () => ({ - NFTDescriptor: deployment.NFTDescriptor.address, + NFTDescriptorV2: deployment.NFTDescriptorV2.address, }), }, + NounsArt: { + args: [() => deployment.NounsDescriptorV2.address], + }, NounsSeeder: {}, NounsToken: { args: [ args.noundersdao, expectedAuctionHouseProxyAddress, - () => deployment.NounsDescriptor.address, + () => deployment.NounsDescriptorV2.address, () => deployment.NounsSeeder.address, proxyRegistryAddress, ], diff --git a/packages/nouns-contracts/tasks/populate-descriptor.ts b/packages/nouns-contracts/tasks/populate-descriptor.ts index 3aad194512..2db9489458 100644 --- a/packages/nouns-contracts/tasks/populate-descriptor.ts +++ b/packages/nouns-contracts/tasks/populate-descriptor.ts @@ -18,9 +18,9 @@ task('populate-descriptor', 'Populates the descriptor with color palettes and No types.string, ) .setAction(async ({ nftDescriptor, nounsDescriptor }, { ethers }) => { - const descriptorFactory = await ethers.getContractFactory('NounsDescriptor', { + const descriptorFactory = await ethers.getContractFactory('NounsDescriptorV2', { libraries: { - NFTDescriptor: nftDescriptor, + NFTDescriptorV2: nftDescriptor, }, }); const descriptorContract = descriptorFactory.attach(nounsDescriptor); @@ -49,18 +49,24 @@ task('populate-descriptor', 'Populates the descriptor with color palettes and No itemCount: glassesCount, } = dataToDescriptorInput(glasses.map(({ data }) => data)); - // Chunk head and accessory population due to high gas usage await descriptorContract.addManyBackgrounds(bgcolors); await descriptorContract.setPalette(0, `0x000000${palette.join('')}`); - await descriptorContract.addBodies(bodiesCompressed, bodiesLength, bodiesCount); + await descriptorContract.addBodies(bodiesCompressed, bodiesLength, bodiesCount, { + gasLimit: 30_000_000, + }); + await descriptorContract.addHeads(headsCompressed, headsLength, headsCount, { + gasLimit: 30_000_000, + }); + await descriptorContract.addGlasses(glassesCompressed, glassesLength, glassesCount, { + gasLimit: 30_000_000, + }); await descriptorContract.addAccessories( accessoriesCompressed, accessoriesLength, accessoriesCount, + { gasLimit: 30_000_000 }, ); - await descriptorContract.addHeads(headsCompressed, headsLength, headsCount); - await descriptorContract.addGlasses(glassesCompressed, glassesLength, glassesCount); console.log('Descriptor populated with palettes and parts.'); }); diff --git a/packages/nouns-contracts/tasks/run-local.ts b/packages/nouns-contracts/tasks/run-local.ts index 036e664ec4..226dadf3f3 100644 --- a/packages/nouns-contracts/tasks/run-local.ts +++ b/packages/nouns-contracts/tasks/run-local.ts @@ -12,8 +12,8 @@ task( const contracts = await run('deploy-local'); await run('populate-descriptor', { - nftDescriptor: contracts.NFTDescriptor.instance.address, - nounsDescriptor: contracts.NounsDescriptor.instance.address, + nftDescriptor: contracts.NFTDescriptorV2.instance.address, + nounsDescriptor: contracts.NounsDescriptorV2.instance.address, }); await contracts.NounsAuctionHouse.instance diff --git a/packages/nouns-contracts/tasks/types/index.ts b/packages/nouns-contracts/tasks/types/index.ts index 9dd05f46e2..867b6e047f 100644 --- a/packages/nouns-contracts/tasks/types/index.ts +++ b/packages/nouns-contracts/tasks/types/index.ts @@ -8,7 +8,7 @@ export enum ChainId { } // prettier-ignore -export type ContractName = 'NFTDescriptor' | 'NounsDescriptor' | 'NounsSeeder' | 'NounsToken' | 'NounsAuctionHouse' | 'NounsAuctionHouseProxyAdmin' | 'NounsAuctionHouseProxy' | 'NounsDAOExecutor' | 'NounsDAOLogicV1' | 'NounsDAOProxy'; +export type ContractName = 'NFTDescriptorV2' | 'NounsDescriptorV2' | 'SVGRenderer' | 'NounsArt' | 'NounsSeeder' | 'NounsToken' | 'NounsAuctionHouse' | 'NounsAuctionHouseProxyAdmin' | 'NounsAuctionHouseProxy' | 'NounsDAOExecutor' | 'NounsDAOLogicV1' | 'NounsDAOProxy'; export interface ContractDeployment { args?: (string | number | (() => string))[]; diff --git a/packages/nouns-contracts/tasks/update-configs.ts b/packages/nouns-contracts/tasks/update-configs.ts index a15d37c5f6..19b3335885 100644 --- a/packages/nouns-contracts/tasks/update-configs.ts +++ b/packages/nouns-contracts/tasks/update-configs.ts @@ -17,8 +17,8 @@ task('update-configs', 'Write the deployed addresses to the SDK and subgraph con addresses[chainId] = { nounsToken: contracts.NounsToken.address, nounsSeeder: contracts.NounsSeeder.address, - nounsDescriptor: contracts.NounsDescriptor.address, - nftDescriptor: contracts.NFTDescriptor.address, + nounsDescriptor: contracts.NounsDescriptorV2.address, + nftDescriptor: contracts.NFTDescriptorV2.address, nounsAuctionHouse: contracts.NounsAuctionHouse.address, nounsAuctionHouseProxy: contracts.NounsAuctionHouseProxy.address, nounsAuctionHouseProxyAdmin: contracts.NounsAuctionHouseProxyAdmin.address, diff --git a/packages/nouns-contracts/test/auction.test.ts b/packages/nouns-contracts/test/auction.test.ts index 0bbad0fb14..39af599567 100644 --- a/packages/nouns-contracts/test/auction.test.ts +++ b/packages/nouns-contracts/test/auction.test.ts @@ -6,11 +6,11 @@ import { ethers, upgrades } from 'hardhat'; import { MaliciousBidder__factory as MaliciousBidderFactory, NounsAuctionHouse, - NounsDescriptor__factory as NounsDescriptorFactory, + NounsDescriptorV2__factory as NounsDescriptorV2Factory, NounsToken, WETH, } from '../typechain'; -import { deployNounsToken, deployWeth, populateDescriptor } from './utils'; +import { deployNounsToken, deployWeth, populateDescriptorV2 } from './utils'; chai.use(solidity); const { expect } = chai; @@ -51,7 +51,7 @@ describe('NounsAuctionHouse', () => { const descriptor = await nounsToken.descriptor(); - await populateDescriptor(NounsDescriptorFactory.connect(descriptor, deployer)); + await populateDescriptorV2(NounsDescriptorV2Factory.connect(descriptor, deployer)); await nounsToken.setMinter(nounsAuctionHouse.address); }); diff --git a/packages/nouns-contracts/test/descriptor.test.ts b/packages/nouns-contracts/test/descriptor.test.ts index 4142b10053..85d339aa67 100644 --- a/packages/nouns-contracts/test/descriptor.test.ts +++ b/packages/nouns-contracts/test/descriptor.test.ts @@ -67,17 +67,13 @@ describe('NounsDescriptor', () => { }); it('should generate valid token uri metadata when data uris are enabled', async () => { - const tokenUri = await nounsDescriptor.tokenURI( - 0, - { - background: 0, - body: longest.bodies.index, - accessory: longest.accessories.index, - head: longest.heads.index, - glasses: longest.glasses.index, - }, - { gasLimit: 200_000_000 }, - ); + const tokenUri = await nounsDescriptor.tokenURI(0, { + background: 0, + body: longest.bodies.index, + accessory: longest.accessories.index, + head: longest.heads.index, + glasses: longest.glasses.index, + }); const { name, description, image } = JSON.parse( Buffer.from(tokenUri.replace('data:application/json;base64,', ''), 'base64').toString( 'ascii', @@ -86,7 +82,7 @@ describe('NounsDescriptor', () => { expect(name).to.equal('Noun 0'); expect(description).to.equal('Noun 0 is a member of the Nouns DAO'); expect(image).to.not.be.undefined; - }).timeout(100_000); + }); // Unskip this test to validate the encoding of all parts. It ensures that no parts revert when building the token URI. // This test also outputs a parts.html file, which can be visually inspected. diff --git a/packages/nouns-contracts/test/descriptorV2.test.ts b/packages/nouns-contracts/test/descriptorV2.test.ts new file mode 100644 index 0000000000..2ef897ac28 --- /dev/null +++ b/packages/nouns-contracts/test/descriptorV2.test.ts @@ -0,0 +1,127 @@ +import chai from 'chai'; +import { solidity } from 'ethereum-waffle'; +import { NounsDescriptorV2 } from '../typechain'; +import ImageData from '../files/image-data.json'; +import { LongestPart } from './types'; +import { deployNounsDescriptorV2, populateDescriptorV2 } from './utils'; +import { ethers } from 'hardhat'; +import { appendFileSync } from 'fs'; + +chai.use(solidity); +const { expect } = chai; + +describe('NounsDescriptorV2', () => { + let nounsDescriptor: NounsDescriptorV2; + let snapshotId: number; + + const part: LongestPart = { + length: 0, + index: 0, + }; + const longest: Record = { + bodies: part, + accessories: part, + heads: part, + glasses: part, + }; + + before(async () => { + nounsDescriptor = await deployNounsDescriptorV2(); + + for (const [l, layer] of Object.entries(ImageData.images)) { + for (const [i, item] of layer.entries()) { + if (item.data.length > longest[l].length) { + longest[l] = { + length: item.data.length, + index: i, + }; + } + } + } + + await populateDescriptorV2(nounsDescriptor); + }); + + beforeEach(async () => { + snapshotId = await ethers.provider.send('evm_snapshot', []); + }); + + afterEach(async () => { + await ethers.provider.send('evm_revert', [snapshotId]); + }); + + it('should generate valid token uri metadata when data uris are disabled', async () => { + const BASE_URI = 'https://api.nouns.wtf/metadata/'; + + await nounsDescriptor.setBaseURI(BASE_URI); + await nounsDescriptor.toggleDataURIEnabled(); + + const tokenUri = await nounsDescriptor.tokenURI(0, { + background: 0, + body: longest.bodies.index, + accessory: longest.accessories.index, + head: longest.heads.index, + glasses: longest.glasses.index, + }); + expect(tokenUri).to.equal(`${BASE_URI}0`); + }); + + it('should generate valid token uri metadata when data uris are enabled', async () => { + const tokenUri = await nounsDescriptor.tokenURI( + 0, + { + background: 0, + body: longest.bodies.index, + accessory: longest.accessories.index, + head: longest.heads.index, + glasses: longest.glasses.index, + }, + { gasLimit: 200_000_000 }, + ); + const { name, description, image } = JSON.parse( + Buffer.from(tokenUri.replace('data:application/json;base64,', ''), 'base64').toString( + 'ascii', + ), + ); + expect(name).to.equal('Noun 0'); + expect(description).to.equal('Noun 0 is a member of the Nouns DAO'); + expect(image).to.not.be.undefined; + }).timeout(100_000); + + // Unskip this test to validate the encoding of all parts. It ensures that no parts revert when building the token URI. + // This test also outputs a parts.html file, which can be visually inspected. + // Note that this test takes a long time to run. You must increase the mocha timeout to a large number. + it.skip('should generate valid token uri metadata for all supported parts when data uris are enabled', async () => { + console.log('Running... this may take a little while...'); + + const { bgcolors, images } = ImageData; + const { bodies, accessories, heads, glasses } = images; + const max = Math.max(bodies.length, accessories.length, heads.length, glasses.length); + for (let i = 0; i < max; i++) { + const tokenUri = await nounsDescriptor.tokenURI(i, { + background: Math.min(i, bgcolors.length - 1), + body: Math.min(i, bodies.length - 1), + accessory: Math.min(i, accessories.length - 1), + head: Math.min(i, heads.length - 1), + glasses: Math.min(i, glasses.length - 1), + }); + const { name, description, image } = JSON.parse( + Buffer.from(tokenUri.replace('data:application/json;base64,', ''), 'base64').toString( + 'ascii', + ), + ); + expect(name).to.equal(`Noun ${i}`); + expect(description).to.equal(`Noun ${i} is a member of the Nouns DAO`); + expect(image).to.not.be.undefined; + + appendFileSync( + 'parts.html', + Buffer.from(image.split(';base64,').pop(), 'base64').toString('ascii'), + ); + + if (i && i % Math.round(max / 10) === 0) { + console.log(`${Math.round((i / max) * 100)}% complete`); + } + } + }); +}); diff --git a/packages/nouns-contracts/test/end2end.test.ts b/packages/nouns-contracts/test/end2end.test.ts index 81f3c6bfae..7385e69a44 100644 --- a/packages/nouns-contracts/test/end2end.test.ts +++ b/packages/nouns-contracts/test/end2end.test.ts @@ -8,8 +8,8 @@ import { NounsToken, NounsAuctionHouse, NounsAuctionHouse__factory as NounsAuctionHouseFactory, - NounsDescriptor, - NounsDescriptor__factory as NounsDescriptorFactory, + NounsDescriptorV2, + NounsDescriptorV2__factory as NounsDescriptorV2Factory, NounsDAOProxy__factory as NounsDaoProxyFactory, NounsDAOLogicV1, NounsDAOLogicV1__factory as NounsDaoLogicV1Factory, @@ -20,7 +20,7 @@ import { import { deployNounsToken, deployWeth, - populateDescriptor, + populateDescriptorV2, address, encodeParameters, advanceBlocks, @@ -35,7 +35,7 @@ const { expect } = chai; let nounsToken: NounsToken; let nounsAuctionHouse: NounsAuctionHouse; -let descriptor: NounsDescriptor; +let descriptor: NounsDescriptorV2; let weth: WETH; let gov: NounsDAOLogicV1; let timelock: NounsDAOExecutor; @@ -109,9 +109,9 @@ async function deploy() { await nounsToken.setMinter(nounsAuctionHouse.address); // 4. POPULATE body parts - descriptor = NounsDescriptorFactory.connect(await nounsToken.descriptor(), deployer); + descriptor = NounsDescriptorV2Factory.connect(await nounsToken.descriptor(), deployer); - await populateDescriptor(descriptor); + await populateDescriptorV2(descriptor); // 5a. CALCULATE Gov Delegate, takes place after 2 transactions const calculatedGovDelegatorAddress = ethers.utils.getContractAddress({ diff --git a/packages/nouns-contracts/test/foundry/NounsToken.t.sol b/packages/nouns-contracts/test/foundry/NounsToken.t.sol index 2c1abd1305..1d675a8f1c 100644 --- a/packages/nouns-contracts/test/foundry/NounsToken.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsToken.t.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.6; import 'forge-std/Test.sol'; import { NounsToken } from '../../contracts/NounsToken.sol'; -import { NounsDescriptor } from '../../contracts/NounsDescriptor.sol'; +import { NounsDescriptorV2 } from '../../contracts/NounsDescriptorV2.sol'; import { NounsSeeder } from '../../contracts/NounsSeeder.sol'; import { IProxyRegistry } from '../../contracts/external/opensea/IProxyRegistry.sol'; import { SVGRenderer } from '../../contracts/SVGRenderer.sol'; @@ -12,7 +12,7 @@ import { INounsArt } from '../../contracts/interfaces/INounsArt.sol'; contract NounsTokenTest is Test { NounsToken nounsToken; - NounsDescriptor descriptor; + NounsDescriptorV2 descriptor; NounsSeeder seeder; IProxyRegistry proxyRegistry = IProxyRegistry(address(0)); address noundersDAO = address(1); @@ -20,7 +20,7 @@ contract NounsTokenTest is Test { function setUp() public { SVGRenderer renderer = new SVGRenderer(); - descriptor = new NounsDescriptor(INounsArt(address(0)), renderer); + descriptor = new NounsDescriptorV2(INounsArt(address(0)), renderer); NounsArt art = new NounsArt(address(descriptor)); descriptor.setArt(art); diff --git a/packages/nouns-contracts/test/governance/NounsDAO/castVote.test.ts b/packages/nouns-contracts/test/governance/NounsDAO/castVote.test.ts index 0a9e7f64d7..2ad0a98903 100644 --- a/packages/nouns-contracts/test/governance/NounsDAO/castVote.test.ts +++ b/packages/nouns-contracts/test/governance/NounsDAO/castVote.test.ts @@ -11,7 +11,7 @@ import { getSigners, TestSigners, setTotalSupply, - populateDescriptor, + populateDescriptorV2, } from '../../utils'; import { mineBlock, address, encodeParameters } from '../../utils'; @@ -19,7 +19,7 @@ import { mineBlock, address, encodeParameters } from '../../utils'; import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { NounsToken, - NounsDescriptor__factory as NounsDescriptorFactory, + NounsDescriptorV2__factory as NounsDescriptorV2Factory, NounsDAOLogicV1Harness, NounsDAOLogicV1Harness__factory as NounsDaoLogicV1HarnessFactory, NounsDAOProxy__factory as NounsDaoProxyFactory, @@ -78,8 +78,8 @@ async function reset() { } token = await deployNounsToken(signers.deployer); - await populateDescriptor( - NounsDescriptorFactory.connect(await token.descriptor(), signers.deployer), + await populateDescriptorV2( + NounsDescriptorV2Factory.connect(await token.descriptor(), signers.deployer), ); await setTotalSupply(token, 10); diff --git a/packages/nouns-contracts/test/governance/NounsDAO/inflationHandling.test.ts b/packages/nouns-contracts/test/governance/NounsDAO/inflationHandling.test.ts index 1dde3ee858..262a74d22d 100644 --- a/packages/nouns-contracts/test/governance/NounsDAO/inflationHandling.test.ts +++ b/packages/nouns-contracts/test/governance/NounsDAO/inflationHandling.test.ts @@ -11,7 +11,7 @@ import { getSigners, TestSigners, setTotalSupply, - populateDescriptor, + populateDescriptorV2, deployGovAndToken, } from '../../utils'; diff --git a/packages/nouns-contracts/test/governance/NounsDAO/state.test.ts b/packages/nouns-contracts/test/governance/NounsDAO/state.test.ts index 6db6e05149..5148848a2e 100644 --- a/packages/nouns-contracts/test/governance/NounsDAO/state.test.ts +++ b/packages/nouns-contracts/test/governance/NounsDAO/state.test.ts @@ -11,7 +11,7 @@ import { getSigners, TestSigners, setTotalSupply, - populateDescriptor, + populateDescriptorV2, } from '../../utils'; import { @@ -27,7 +27,7 @@ import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { NounsToken, - NounsDescriptor__factory as NounsDescriptorFactory, + NounsDescriptorV2__factory as NounsDescriptorV2Factory, NounsDAOExecutorHarness, NounsDAOExecutorHarness__factory as NounsDaoExecutorHarnessFactory, NounsDAOImmutable, @@ -121,8 +121,8 @@ describe('NounsDAO#state/1', () => { token = await deployNounsToken(signers.deployer); - await populateDescriptor( - NounsDescriptorFactory.connect(await token.descriptor(), signers.deployer), + await populateDescriptorV2( + NounsDescriptorV2Factory.connect(await token.descriptor(), signers.deployer), ); }); diff --git a/packages/nouns-contracts/test/governance/NounsDAO/vetoing.test.ts b/packages/nouns-contracts/test/governance/NounsDAO/vetoing.test.ts index 9abf25dbfc..1e1a86bfdd 100644 --- a/packages/nouns-contracts/test/governance/NounsDAO/vetoing.test.ts +++ b/packages/nouns-contracts/test/governance/NounsDAO/vetoing.test.ts @@ -11,7 +11,7 @@ import { getSigners, TestSigners, setTotalSupply, - populateDescriptor, + populateDescriptorV2, deployGovAndToken, } from '../../utils'; diff --git a/packages/nouns-contracts/test/governance/nounsGovernance.test.ts b/packages/nouns-contracts/test/governance/nounsGovernance.test.ts index f984414638..d571c76724 100644 --- a/packages/nouns-contracts/test/governance/nounsGovernance.test.ts +++ b/packages/nouns-contracts/test/governance/nounsGovernance.test.ts @@ -1,14 +1,17 @@ import chai from 'chai'; import { solidity } from 'ethereum-waffle'; import { ethers } from 'hardhat'; -import { NounsToken, NounsDescriptor__factory as NounsDescriptorFactory } from '../../typechain'; +import { + NounsToken, + NounsDescriptorV2__factory as NounsDescriptorV2Factory, +} from '../../typechain'; import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { deployNounsToken, getSigners, TestSigners, setTotalSupply, - populateDescriptor, + populateDescriptorV2, minerStart, minerStop, mineBlock, @@ -59,8 +62,8 @@ describe('Nouns Governance', () => { token = await deployNounsToken(signers.deployer); - await populateDescriptor( - NounsDescriptorFactory.connect(await token.descriptor(), signers.deployer), + await populateDescriptorV2( + NounsDescriptorV2Factory.connect(await token.descriptor(), signers.deployer), ); domain = Domain('Nouns', token.address, await chainId()); diff --git a/packages/nouns-contracts/test/nouns.test.ts b/packages/nouns-contracts/test/nouns.test.ts index 36342cae71..07424572e2 100644 --- a/packages/nouns-contracts/test/nouns.test.ts +++ b/packages/nouns-contracts/test/nouns.test.ts @@ -2,8 +2,8 @@ import chai from 'chai'; import { ethers } from 'hardhat'; import { BigNumber as EthersBN, constants } from 'ethers'; import { solidity } from 'ethereum-waffle'; -import { NounsDescriptor__factory as NounsDescriptorFactory, NounsToken } from '../typechain'; -import { deployNounsToken, populateDescriptor } from './utils'; +import { NounsDescriptorV2__factory as NounsDescriptorV2Factory, NounsToken } from '../typechain'; +import { deployNounsToken, populateDescriptorV2 } from './utils'; import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; chai.use(solidity); @@ -21,7 +21,7 @@ describe('NounsToken', () => { const descriptor = await nounsToken.descriptor(); - await populateDescriptor(NounsDescriptorFactory.connect(descriptor, deployer)); + await populateDescriptorV2(NounsDescriptorV2Factory.connect(descriptor, deployer)); }); beforeEach(async () => { diff --git a/packages/nouns-contracts/test/utils.ts b/packages/nouns-contracts/test/utils.ts index f0538b120b..36fabe1479 100644 --- a/packages/nouns-contracts/test/utils.ts +++ b/packages/nouns-contracts/test/utils.ts @@ -3,6 +3,8 @@ import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { NounsDescriptor, NounsDescriptor__factory as NounsDescriptorFactory, + NounsDescriptorV2, + NounsDescriptorV2__factory as NounsDescriptorV2Factory, NounsToken, NounsToken__factory as NounsTokenFactory, NounsSeeder, @@ -19,8 +21,8 @@ import { } from '../typechain'; import ImageData from '../files/image-data.json'; import { Block } from '@ethersproject/abstract-provider'; -import { chunkArray } from '../utils'; import { deflateRawSync } from 'zlib'; +import { chunkArray } from '../utils'; export type TestSigners = { deployer: SignerWithAddress; @@ -52,6 +54,22 @@ export const deployNounsDescriptor = async ( signer, ); + return nounsDescriptorFactory.deploy(); +}; + +export const deployNounsDescriptorV2 = async ( + deployer?: SignerWithAddress, +): Promise => { + const signer = deployer || (await getSigners()).deployer; + const nftDescriptorLibraryFactory = await ethers.getContractFactory('NFTDescriptorV2', signer); + const nftDescriptorLibrary = await nftDescriptorLibraryFactory.deploy(); + const nounsDescriptorFactory = new NounsDescriptorV2Factory( + { + 'contracts/libs/NFTDescriptorV2.sol:NFTDescriptorV2': nftDescriptorLibrary.address, + }, + signer, + ); + const renderer = await new SVGRendererFactory(signer).deploy(); const descriptor = await nounsDescriptorFactory.deploy( ethers.constants.AddressZero, @@ -84,7 +102,7 @@ export const deployNounsToken = async ( return factory.deploy( noundersDAO || signer.address, minter || signer.address, - descriptor || (await deployNounsDescriptor(signer)).address, + descriptor || (await deployNounsDescriptorV2(signer)).address, seeder || (await deployNounsSeeder(signer)).address, proxyRegistryAddress || address(0), ); @@ -100,6 +118,23 @@ export const populateDescriptor = async (nounsDescriptor: NounsDescriptor): Prom const { bgcolors, palette, images } = ImageData; const { bodies, accessories, heads, glasses } = images; + // Split up head and accessory population due to high gas usage + await Promise.all([ + nounsDescriptor.addManyBackgrounds(bgcolors), + nounsDescriptor.addManyColorsToPalette(0, palette), + nounsDescriptor.addManyBodies(bodies.map(({ data }) => data)), + chunkArray(accessories, 10).map(chunk => + nounsDescriptor.addManyAccessories(chunk.map(({ data }) => data)), + ), + chunkArray(heads, 10).map(chunk => nounsDescriptor.addManyHeads(chunk.map(({ data }) => data))), + nounsDescriptor.addManyGlasses(glasses.map(({ data }) => data)), + ]); +}; + +export const populateDescriptorV2 = async (nounsDescriptor: NounsDescriptorV2): Promise => { + const { bgcolors, palette, images } = ImageData; + const { bodies, accessories, heads, glasses } = images; + const { encodedCompressed: bodiesCompressed, originalLength: bodiesLength, @@ -183,7 +218,7 @@ export const deployGovAndToken = async ( // Cast Delegator as Delegate const gov = NounsDaoLogicV1Factory.connect(govDelegatorAddress, deployer); - await populateDescriptor(NounsDescriptorFactory.connect(await token.descriptor(), deployer)); + await populateDescriptorV2(NounsDescriptorV2Factory.connect(await token.descriptor(), deployer)); return { token, gov, timelock }; }; From c831476ebe65b1505e7551cf1aa0c43d7027d65f Mon Sep 17 00:00:00 2001 From: eladmallel Date: Mon, 27 Jun 2022 16:45:39 -0500 Subject: [PATCH 020/116] add descriptor upgrade test --- .../test/foundry/DescriptorUpgrade.t.sol | 41 +++ .../test/foundry/NounsToken.t.sol | 73 +----- .../test/foundry/helpers/Constants.sol | 247 ++++++++++++++++++ .../foundry/helpers/DescriptorHelpers.sol | 77 ++++++ .../test/foundry/helpers/Utils.sol | 29 ++ 5 files changed, 399 insertions(+), 68 deletions(-) create mode 100644 packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol create mode 100644 packages/nouns-contracts/test/foundry/helpers/Constants.sol create mode 100644 packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol create mode 100644 packages/nouns-contracts/test/foundry/helpers/Utils.sol diff --git a/packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol b/packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol new file mode 100644 index 0000000000..6e9ce9a93e --- /dev/null +++ b/packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.6; + +import 'forge-std/Test.sol'; +import { DescriptorHelpers } from './helpers/DescriptorHelpers.sol'; +import { NounsToken } from '../../contracts/NounsToken.sol'; +import { NounsDescriptor } from '../../contracts/NounsDescriptor.sol'; +import { NounsDescriptorV2 } from '../../contracts/NounsDescriptorV2.sol'; +import { NounsSeeder } from '../../contracts/NounsSeeder.sol'; +import { IProxyRegistry } from '../../contracts/external/opensea/IProxyRegistry.sol'; + +contract DescriptorUpgradeTest is Test, DescriptorHelpers { + NounsToken nounsToken; + + function setUp() public { + IProxyRegistry proxyRegistry = IProxyRegistry(address(0)); + address noundersDAO = address(1); + address minter = address(2); + + NounsDescriptor descriptor = new NounsDescriptor(); + _populateDescriptor(descriptor); + nounsToken = new NounsToken(noundersDAO, minter, descriptor, new NounsSeeder(), proxyRegistry); + + vm.prank(minter); + nounsToken.mint(); + } + + function testUpgradeToV2MaintainsTokenURI() public { + string memory tokenURIwithV1 = nounsToken.tokenURI(1); + + NounsDescriptorV2 descriptorV2 = _deployV2(); + _populateDescriptorV2(descriptorV2); + nounsToken.setDescriptor(descriptorV2); + + string memory tokenURIwithV2 = nounsToken.tokenURI(1); + + // both _populateDescriptor and _populateDescriptorV2 are hard-coded to populate + // with the first item of each type found in image-data.json. + assertEq(tokenURIwithV2, tokenURIwithV1); + } +} diff --git a/packages/nouns-contracts/test/foundry/NounsToken.t.sol b/packages/nouns-contracts/test/foundry/NounsToken.t.sol index 1d675a8f1c..7c8f16948f 100644 --- a/packages/nouns-contracts/test/foundry/NounsToken.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsToken.t.sol @@ -9,56 +9,18 @@ import { IProxyRegistry } from '../../contracts/external/opensea/IProxyRegistry. import { SVGRenderer } from '../../contracts/SVGRenderer.sol'; import { NounsArt } from '../../contracts/NounsArt.sol'; import { INounsArt } from '../../contracts/interfaces/INounsArt.sol'; +import { DescriptorHelpers } from './helpers/DescriptorHelpers.sol'; -contract NounsTokenTest is Test { +contract NounsTokenTest is Test, DescriptorHelpers { NounsToken nounsToken; - NounsDescriptorV2 descriptor; - NounsSeeder seeder; - IProxyRegistry proxyRegistry = IProxyRegistry(address(0)); address noundersDAO = address(1); address minter = address(2); function setUp() public { - SVGRenderer renderer = new SVGRenderer(); - descriptor = new NounsDescriptorV2(INounsArt(address(0)), renderer); - NounsArt art = new NounsArt(address(descriptor)); - descriptor.setArt(art); + NounsDescriptorV2 descriptor = _deployV2(); + _populateDescriptorV2(descriptor); - _populateDescriptor(); - seeder = new NounsSeeder(); - nounsToken = new NounsToken(noundersDAO, minter, descriptor, seeder, proxyRegistry); - } - - function _populateDescriptor() internal { - descriptor.addBackground('d5d7e1'); - descriptor.addAccessories( - fromHex( - '6360c00b14f04b3330129027a4df95415c448e979181519e95810988412c66206604b398c098192c066133c9c3c441340b94c6630100' - ), - 224, - 1 - ); - descriptor.addBodies(fromHex('6360c00b14f04b3330129027a4df9c41545c9e938f090299981819b88922e1060000'), 192, 1); - descriptor.addGlasses( - fromHex( - '6360c00b14f04b3330129027a43f9a815b5c809d99814d811188991918159818999419813c188b054c3363e501d560d101330d6c0100' - ), - 224, - 1 - ); - descriptor.addHeads( - fromHex( - '6360c00b14f04b3330129027a47f2203939c081b2b03a3391310f333b0303001594ce67c0ccc0ccc4016b3392f0313038b3908f3208921d421f4f29a73e3c06c0cacb52092b196b10e82b9cd3991d8bcb55ce6acca9c60169a0301' - ), - 288, - 1 - ); - descriptor.setPalette( - 0, - fromHex( - '000000ffffffc5b9a1cfc2ab63a0f9807f7ecaeff95648ed5a423fb9185cb87b11fffdf24b49493432351f1d29068940867c1dae32089f21a0f98f30fe500cd26451fd8b5b5a65fad22209e9265cc54e3880a72d4bea6934ac80eed81162616dff638d8bc0c5c4da53000000f3322cffae1affc110505a5cffef16fff671fff449db8323df2c39f938d85c25fb2a86fd45faff38dd56ff3a0ed32a099037076e3206552e05e8705bf38b7ce4a499667af9648df97cc4f297f2fba3efd087e4d971bde4ff1a0bf78a182b83f6d62149834398ffc925d9391fbd2d24ff7216254efbe5e5de00a556c5030eabf131fb4694e7a32cfff0ee009c590385eb00499ce1183326b1f3fff0bed8dadfd7d3cd1929f4eab1180b5027f9f5cbcfc9b8feb9d5f8d6895d606176858b757576ff0e0e0adc4dfdf8ff70e890f7913dff1ad2ff82ad535a15fa6fe2ffe939ab36beadc8cc604666f20422abaaa84b65f7a19c9a58565cda42cb027c92cec189909b0e74580d027ee6b2958defad817d635eeff2fa6f597ad4b7b2d18687cd916d6b3f394d271b85634ff9f4e6f8ddb0b92b3cd08b11257ceda3baed5fd4fbc16710a28ef43a085b67b1e31e3445ffd067962236769ca95a6b7b7e5243a86f608f785ecc059542ffb0d56333b8ced2b91b43f39713e8e8e2ec5b43235476b2a8a5d6c3be49b38bfccf25f59b34375dfc99e6de27a463554543b19e00d4a0159f4b27f9e8dd6b72129d8e6e4243f8fa5e20f82905555353876f69410d66552d1df71248fee3f3c169232b28340079fcd31e14f830018dd122fffdf4ffa21ee4afa3fbc311aa940ceedc00fff0069cb4b8a38654ae6c0a2bb26be2c8c0f89865f86100dcd8d3049d43d0aea9f39d44eeb78cf9f5e95d3500c3a199aaa6a4caa26afde7f5fdf008fdcef2f681e6018146d19a549eb5e1f5fcff3f932300fcff4a5358fbc800d596a6ffb913e9ba12767c0ef9f6d1d29607f8ce47395ed1ffc5f0cbc1bcd4cfc0' - ) - ); + nounsToken = new NounsToken(noundersDAO, minter, descriptor, new NounsSeeder(), IProxyRegistry(address(0))); } function testSymbol() public { @@ -81,29 +43,4 @@ contract NounsTokenTest is Test { vm.expectRevert('Sender is not the minter'); nounsToken.mint(); } - - // Convert an hexadecimal string to raw bytes - function fromHex(string memory s) public pure returns (bytes memory) { - bytes memory ss = bytes(s); - require(ss.length % 2 == 0); // length must be even - bytes memory r = new bytes(ss.length / 2); - for (uint256 i = 0; i < ss.length / 2; ++i) { - r[i] = bytes1(fromHexChar(uint8(ss[2 * i])) * 16 + fromHexChar(uint8(ss[2 * i + 1]))); - } - return r; - } - - // Convert an hexadecimal character to their value - function fromHexChar(uint8 c) public pure returns (uint8) { - if (bytes1(c) >= bytes1('0') && bytes1(c) <= bytes1('9')) { - return c - uint8(bytes1('0')); - } - if (bytes1(c) >= bytes1('a') && bytes1(c) <= bytes1('f')) { - return 10 + c - uint8(bytes1('a')); - } - if (bytes1(c) >= bytes1('A') && bytes1(c) <= bytes1('F')) { - return 10 + c - uint8(bytes1('A')); - } - revert('fail'); - } } diff --git a/packages/nouns-contracts/test/foundry/helpers/Constants.sol b/packages/nouns-contracts/test/foundry/helpers/Constants.sol new file mode 100644 index 0000000000..3a1c19af7f --- /dev/null +++ b/packages/nouns-contracts/test/foundry/helpers/Constants.sol @@ -0,0 +1,247 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.6; + +abstract contract Constants { + string[] paletteColors = [ + '', + 'ffffff', + 'c5b9a1', + 'cfc2ab', + '63a0f9', + '807f7e', + 'caeff9', + '5648ed', + '5a423f', + 'b9185c', + 'b87b11', + 'fffdf2', + '4b4949', + '343235', + '1f1d29', + '068940', + '867c1d', + 'ae3208', + '9f21a0', + 'f98f30', + 'fe500c', + 'd26451', + 'fd8b5b', + '5a65fa', + 'd22209', + 'e9265c', + 'c54e38', + '80a72d', + '4bea69', + '34ac80', + 'eed811', + '62616d', + 'ff638d', + '8bc0c5', + 'c4da53', + '000000', + 'f3322c', + 'ffae1a', + 'ffc110', + '505a5c', + 'ffef16', + 'fff671', + 'fff449', + 'db8323', + 'df2c39', + 'f938d8', + '5c25fb', + '2a86fd', + '45faff', + '38dd56', + 'ff3a0e', + 'd32a09', + '903707', + '6e3206', + '552e05', + 'e8705b', + 'f38b7c', + 'e4a499', + '667af9', + '648df9', + '7cc4f2', + '97f2fb', + 'a3efd0', + '87e4d9', + '71bde4', + 'ff1a0b', + 'f78a18', + '2b83f6', + 'd62149', + '834398', + 'ffc925', + 'd9391f', + 'bd2d24', + 'ff7216', + '254efb', + 'e5e5de', + '00a556', + 'c5030e', + 'abf131', + 'fb4694', + 'e7a32c', + 'fff0ee', + '009c59', + '0385eb', + '00499c', + 'e11833', + '26b1f3', + 'fff0be', + 'd8dadf', + 'd7d3cd', + '1929f4', + 'eab118', + '0b5027', + 'f9f5cb', + 'cfc9b8', + 'feb9d5', + 'f8d689', + '5d6061', + '76858b', + '757576', + 'ff0e0e', + '0adc4d', + 'fdf8ff', + '70e890', + 'f7913d', + 'ff1ad2', + 'ff82ad', + '535a15', + 'fa6fe2', + 'ffe939', + 'ab36be', + 'adc8cc', + '604666', + 'f20422', + 'abaaa8', + '4b65f7', + 'a19c9a', + '58565c', + 'da42cb', + '027c92', + 'cec189', + '909b0e', + '74580d', + '027ee6', + 'b2958d', + 'efad81', + '7d635e', + 'eff2fa', + '6f597a', + 'd4b7b2', + 'd18687', + 'cd916d', + '6b3f39', + '4d271b', + '85634f', + 'f9f4e6', + 'f8ddb0', + 'b92b3c', + 'd08b11', + '257ced', + 'a3baed', + '5fd4fb', + 'c16710', + 'a28ef4', + '3a085b', + '67b1e3', + '1e3445', + 'ffd067', + '962236', + '769ca9', + '5a6b7b', + '7e5243', + 'a86f60', + '8f785e', + 'cc0595', + '42ffb0', + 'd56333', + 'b8ced2', + 'b91b43', + 'f39713', + 'e8e8e2', + 'ec5b43', + '235476', + 'b2a8a5', + 'd6c3be', + '49b38b', + 'fccf25', + 'f59b34', + '375dfc', + '99e6de', + '27a463', + '554543', + 'b19e00', + 'd4a015', + '9f4b27', + 'f9e8dd', + '6b7212', + '9d8e6e', + '4243f8', + 'fa5e20', + 'f82905', + '555353', + '876f69', + '410d66', + '552d1d', + 'f71248', + 'fee3f3', + 'c16923', + '2b2834', + '0079fc', + 'd31e14', + 'f83001', + '8dd122', + 'fffdf4', + 'ffa21e', + 'e4afa3', + 'fbc311', + 'aa940c', + 'eedc00', + 'fff006', + '9cb4b8', + 'a38654', + 'ae6c0a', + '2bb26b', + 'e2c8c0', + 'f89865', + 'f86100', + 'dcd8d3', + '049d43', + 'd0aea9', + 'f39d44', + 'eeb78c', + 'f9f5e9', + '5d3500', + 'c3a199', + 'aaa6a4', + 'caa26a', + 'fde7f5', + 'fdf008', + 'fdcef2', + 'f681e6', + '018146', + 'd19a54', + '9eb5e1', + 'f5fcff', + '3f9323', + '00fcff', + '4a5358', + 'fbc800', + 'd596a6', + 'ffb913', + 'e9ba12', + '767c0e', + 'f9f6d1', + 'd29607', + 'f8ce47', + '395ed1', + 'ffc5f0', + 'cbc1bc', + 'd4cfc0' + ]; +} diff --git a/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol b/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol new file mode 100644 index 0000000000..fab7dd4760 --- /dev/null +++ b/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.6; + +import { NounsDescriptor } from '../../../contracts/NounsDescriptor.sol'; +import { NounsDescriptorV2 } from '../../../contracts/NounsDescriptorV2.sol'; +import { SVGRenderer } from '../../../contracts/SVGRenderer.sol'; +import { NounsArt } from '../../../contracts/NounsArt.sol'; +import { Utils } from './Utils.sol'; +import { Constants } from './Constants.sol'; + +abstract contract DescriptorHelpers is Utils, Constants { + function _deployV2() internal returns (NounsDescriptorV2) { + SVGRenderer renderer = new SVGRenderer(); + NounsDescriptorV2 descriptorV2 = new NounsDescriptorV2(NounsArt(address(0)), renderer); + NounsArt art = new NounsArt(address(descriptorV2)); + descriptorV2.setArt(art); + _populateDescriptorV2(descriptorV2); + return descriptorV2; + } + + function _populateDescriptor(NounsDescriptor descriptor) internal { + descriptor.addBackground('d5d7e1'); + descriptor.addAccessory( + fromHex( + '0017141e0d0100011f0500021f05000100011f0300011f01000100011f0200011f02000300011f03000200011f0200021f0100011f0200011f0100011f0400011f0100011f' + ) + ); + descriptor.addBody( + fromHex( + '0015171f090e020e020e020e02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02' + ) + ); + descriptor.addGlasses( + fromHex( + '000b1710070300062001000620030001200201022301200100012002010223012004200201022303200201022301200420020102230320020102230120012002000120020102230120010001200201022301200300062001000620' + ) + ); + descriptor.addHead( + fromHex( + '00021e140605000137020001370f0004000237020002370e0003000337020003370d0002000437020004370c0003000337020003370d0004000237020002370e0005000137020001370f000d370b000d370b000d370b000d370b000d370b000d370b000d370600057d0d370600017d017e017d017e017d0b37097d017e017d017e017d0b370d7d0a370523097d0b370d7d' + ) + ); + descriptor.addManyColorsToPalette(0, paletteColors); + } + + function _populateDescriptorV2(NounsDescriptorV2 descriptorV2) internal { + descriptorV2.addBackground('d5d7e1'); + descriptorV2.addAccessories( + fromHex( + '6360c00b14f04b3330129027a4df95415c448e979181519e95810988412c66206604b398c098192c066133c9c3c441340b94c6630100' + ), + 224, + 1 + ); + descriptorV2.addBodies(fromHex('6360c00b14f04b3330129027a4df9c41545c9e938f090299981819b88922e1060000'), 192, 1); + descriptorV2.addGlasses( + fromHex( + '6360c00b14f04b3330129027a43f9a815b5c809d99814d811188991918159818999419813c188b054c3363e501d560d101330d6c0100' + ), + 224, + 1 + ); + descriptorV2.addHeads( + fromHex( + '6360c00b14f04b3330129027a47f2203939c081b2b03a3391310f333b0303001594ce67c0ccc0ccc4016b3392f0313038b3908f3208921d421f4f29a73e3c06c0cacb52092b196b10e82b9cd3991d8bcb55ce6acca9c60169a0301' + ), + 288, + 1 + ); + descriptorV2.setPalette( + 0, + fromHex( + '000000ffffffc5b9a1cfc2ab63a0f9807f7ecaeff95648ed5a423fb9185cb87b11fffdf24b49493432351f1d29068940867c1dae32089f21a0f98f30fe500cd26451fd8b5b5a65fad22209e9265cc54e3880a72d4bea6934ac80eed81162616dff638d8bc0c5c4da53000000f3322cffae1affc110505a5cffef16fff671fff449db8323df2c39f938d85c25fb2a86fd45faff38dd56ff3a0ed32a099037076e3206552e05e8705bf38b7ce4a499667af9648df97cc4f297f2fba3efd087e4d971bde4ff1a0bf78a182b83f6d62149834398ffc925d9391fbd2d24ff7216254efbe5e5de00a556c5030eabf131fb4694e7a32cfff0ee009c590385eb00499ce1183326b1f3fff0bed8dadfd7d3cd1929f4eab1180b5027f9f5cbcfc9b8feb9d5f8d6895d606176858b757576ff0e0e0adc4dfdf8ff70e890f7913dff1ad2ff82ad535a15fa6fe2ffe939ab36beadc8cc604666f20422abaaa84b65f7a19c9a58565cda42cb027c92cec189909b0e74580d027ee6b2958defad817d635eeff2fa6f597ad4b7b2d18687cd916d6b3f394d271b85634ff9f4e6f8ddb0b92b3cd08b11257ceda3baed5fd4fbc16710a28ef43a085b67b1e31e3445ffd067962236769ca95a6b7b7e5243a86f608f785ecc059542ffb0d56333b8ced2b91b43f39713e8e8e2ec5b43235476b2a8a5d6c3be49b38bfccf25f59b34375dfc99e6de27a463554543b19e00d4a0159f4b27f9e8dd6b72129d8e6e4243f8fa5e20f82905555353876f69410d66552d1df71248fee3f3c169232b28340079fcd31e14f830018dd122fffdf4ffa21ee4afa3fbc311aa940ceedc00fff0069cb4b8a38654ae6c0a2bb26be2c8c0f89865f86100dcd8d3049d43d0aea9f39d44eeb78cf9f5e95d3500c3a199aaa6a4caa26afde7f5fdf008fdcef2f681e6018146d19a549eb5e1f5fcff3f932300fcff4a5358fbc800d596a6ffb913e9ba12767c0ef9f6d1d29607f8ce47395ed1ffc5f0cbc1bcd4cfc0' + ) + ); + } +} diff --git a/packages/nouns-contracts/test/foundry/helpers/Utils.sol b/packages/nouns-contracts/test/foundry/helpers/Utils.sol new file mode 100644 index 0000000000..972a71f180 --- /dev/null +++ b/packages/nouns-contracts/test/foundry/helpers/Utils.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.6; + +abstract contract Utils { + // Convert an hexadecimal string to raw bytes + function fromHex(string memory s) internal pure returns (bytes memory) { + bytes memory ss = bytes(s); + require(ss.length % 2 == 0); // length must be even + bytes memory r = new bytes(ss.length / 2); + for (uint256 i = 0; i < ss.length / 2; ++i) { + r[i] = bytes1(fromHexChar(uint8(ss[2 * i])) * 16 + fromHexChar(uint8(ss[2 * i + 1]))); + } + return r; + } + + // Convert an hexadecimal character to their value + function fromHexChar(uint8 c) internal pure returns (uint8) { + if (bytes1(c) >= bytes1('0') && bytes1(c) <= bytes1('9')) { + return c - uint8(bytes1('0')); + } + if (bytes1(c) >= bytes1('a') && bytes1(c) <= bytes1('f')) { + return 10 + c - uint8(bytes1('a')); + } + if (bytes1(c) >= bytes1('A') && bytes1(c) <= bytes1('F')) { + return 10 + c - uint8(bytes1('A')); + } + revert('fail'); + } +} From 988985b01b7d719ce924199b6eaff7a77ae67332 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Mon, 27 Jun 2022 16:55:43 -0500 Subject: [PATCH 021/116] add test natspec --- .../test/foundry/helpers/DescriptorHelpers.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol b/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol index fab7dd4760..e9a8ff8d53 100644 --- a/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol +++ b/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol @@ -43,6 +43,10 @@ abstract contract DescriptorHelpers is Utils, Constants { descriptor.addManyColorsToPalette(0, paletteColors); } + /** + * @dev the hard-coded values below were copied from running the hardhat task `descriptor-art-to-console` with + * the parameter `slice` set to 1. + */ function _populateDescriptorV2(NounsDescriptorV2 descriptorV2) internal { descriptorV2.addBackground('d5d7e1'); descriptorV2.addAccessories( From fc39a27bf06a39e7dfabeb7b7f6789edba8acb3e Mon Sep 17 00:00:00 2001 From: eladmallel Date: Mon, 27 Jun 2022 17:39:22 -0500 Subject: [PATCH 022/116] add some tests for NounsArt --- .../test/foundry/NounsArt.t.sol | 135 ++++++++++++++++++ .../test/foundry/NounsToken.t.sol | 1 - 2 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 packages/nouns-contracts/test/foundry/NounsArt.t.sol diff --git a/packages/nouns-contracts/test/foundry/NounsArt.t.sol b/packages/nouns-contracts/test/foundry/NounsArt.t.sol new file mode 100644 index 0000000000..db1e74ec08 --- /dev/null +++ b/packages/nouns-contracts/test/foundry/NounsArt.t.sol @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.6; + +import 'forge-std/Test.sol'; +import { NounsArt } from '../../contracts/NounsArt.sol'; +import { INounsArt } from '../../contracts/interfaces/INounsArt.sol'; +import { Utils } from './helpers/Utils.sol'; +import { SSTORE2 } from '../../contracts/libs/SSTORE2.sol'; + +contract NounsArtTest is Test, Utils { + NounsArt art; + address descriptor = address(1); + + function setUp() public { + art = new NounsArt(descriptor); + } + + /// + /// setDescriptor and confirmDescriptor + /// + + function testSetDescriptorRevertsIfSenderNotDescriptor() public { + vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); + art.setDescriptor(address(2)); + } + + function testSetDescriptorDoesntSetYet() public { + address newDescriptor = address(2); + + vm.prank(descriptor); + art.setDescriptor(newDescriptor); + + assertEq(art.descriptor(), descriptor); + } + + function testConfirmDescriptorRevertsIfSenderNotPendingDescriptor() public { + address newDescriptor = address(2); + + vm.prank(descriptor); + art.setDescriptor(newDescriptor); + + vm.expectRevert(INounsArt.SenderIsNotPendingDescriptor.selector); + art.confirmDescriptor(); + } + + function testConfirmDescriptorSetsDescriptor() public { + address newDescriptor = address(2); + + vm.prank(descriptor); + art.setDescriptor(newDescriptor); + + vm.prank(newDescriptor); + art.confirmDescriptor(); + + assertEq(art.descriptor(), newDescriptor); + } + + /// + /// addBackground, addManyBackgrounds, backgroundsCount, backgrounds + /// + + function testAddBackgroundRevertsIfSenderNotDescriptor() public { + vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); + art.addBackground('ffffff'); + } + + function testAddBackgroundWorks() public { + vm.prank(descriptor); + art.addBackground('ffffff'); + + assertEq(art.backgroundsCount(), 1); + assertEq(art.backgrounds(0), 'ffffff'); + } + + function testAddManyBackgroundsRevertsIfSenderNotDescriptor() public { + string[] memory bgs = new string[](2); + bgs[0] = 'ffffff'; + bgs[1] = '000000'; + + vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); + art.addManyBackgrounds(bgs); + } + + function testAddManyBackgroundsWorks() public { + string[] memory bgs = new string[](2); + bgs[0] = 'ffffff'; + bgs[1] = '000000'; + + vm.prank(descriptor); + art.addManyBackgrounds(bgs); + + assertEq(art.backgroundsCount(), 2); + assertEq(art.backgrounds(0), 'ffffff'); + assertEq(art.backgrounds(1), '000000'); + } + + /// + /// setPalette, palettes, palettesPointers + /// + + function testSetPaletteRevertsIfSenderNotDescriptor() public { + vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); + art.setPalette(0, fromHex('ffffff')); + } + + function testSetPaletteWorks() public { + bytes memory palette0 = fromHex('ffffffc5b9a1'); + bytes memory palette1 = fromHex('cfc2ab63a0f9'); + vm.startPrank(descriptor); + art.setPalette(0, palette0); + art.setPalette(1, palette1); + vm.stopPrank(); + + assertEq(art.palettes(0), palette0); + assertEq(art.palettes(1), palette1); + + assertEq(SSTORE2.read(art.palettesPointers(0)), palette0); + assertEq(SSTORE2.read(art.palettesPointers(1)), palette1); + } + + function testSetPaletteUpdatesAnExistingPalette() public { + bytes memory paletteV1 = fromHex('ffffffc5b9a1'); + bytes memory paletteV2 = fromHex('cfc2ab63a0f9'); + + vm.prank(descriptor); + art.setPalette(0, paletteV1); + assertEq(art.palettes(0), paletteV1); + assertEq(SSTORE2.read(art.palettesPointers(0)), paletteV1); + + vm.prank(descriptor); + art.setPalette(0, paletteV2); + assertEq(art.palettes(0), paletteV2); + assertEq(SSTORE2.read(art.palettesPointers(0)), paletteV2); + } +} diff --git a/packages/nouns-contracts/test/foundry/NounsToken.t.sol b/packages/nouns-contracts/test/foundry/NounsToken.t.sol index 7c8f16948f..aa67b0d5bb 100644 --- a/packages/nouns-contracts/test/foundry/NounsToken.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsToken.t.sol @@ -8,7 +8,6 @@ import { NounsSeeder } from '../../contracts/NounsSeeder.sol'; import { IProxyRegistry } from '../../contracts/external/opensea/IProxyRegistry.sol'; import { SVGRenderer } from '../../contracts/SVGRenderer.sol'; import { NounsArt } from '../../contracts/NounsArt.sol'; -import { INounsArt } from '../../contracts/interfaces/INounsArt.sol'; import { DescriptorHelpers } from './helpers/DescriptorHelpers.sol'; contract NounsTokenTest is Test, DescriptorHelpers { From d13163d6436fcbf9411b621af4a9621628b1dba3 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Mon, 27 Jun 2022 18:23:36 -0500 Subject: [PATCH 023/116] add NounsArt tests using body trait setters and getters --- .../tasks/descriptor-art-to-console.ts | 19 ++-- .../test/foundry/NounsArt.t.sol | 89 +++++++++++++++++++ 2 files changed, 100 insertions(+), 8 deletions(-) diff --git a/packages/nouns-contracts/tasks/descriptor-art-to-console.ts b/packages/nouns-contracts/tasks/descriptor-art-to-console.ts index 8c277fab37..9c111ab76e 100644 --- a/packages/nouns-contracts/tasks/descriptor-art-to-console.ts +++ b/packages/nouns-contracts/tasks/descriptor-art-to-console.ts @@ -8,20 +8,23 @@ task( 'Prints the descriptor art config in the final format, to be used in foundry / manual tests.', ) .addOptionalParam( - 'slice', - 'How many items to take from each of the image arrays', + 'count', + 'The length of the image slice to take from each of the image arrays', undefined, types.int, ) - .setAction(async ({ slice }, { ethers }) => { + .addOptionalParam('start', 'The index at which to start the image slice', undefined, types.int) + .setAction(async ({ count, start }, { ethers }) => { const { bgcolors, palette, images } = ImageData; let { bodies, accessories, heads, glasses } = images; - if (slice !== undefined) { - bodies = bodies.slice(0, slice); - accessories = accessories.slice(0, slice); - heads = heads.slice(0, slice); - glasses = glasses.slice(0, slice); + if (count !== undefined) { + start = start === undefined ? 0 : start; + + bodies = bodies.slice(start, count + start); + accessories = accessories.slice(start, count + start); + heads = heads.slice(start, count + start); + glasses = glasses.slice(start, count + start); } const { diff --git a/packages/nouns-contracts/test/foundry/NounsArt.t.sol b/packages/nouns-contracts/test/foundry/NounsArt.t.sol index db1e74ec08..a78932702a 100644 --- a/packages/nouns-contracts/test/foundry/NounsArt.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsArt.t.sol @@ -132,4 +132,93 @@ contract NounsArtTest is Test, Utils { assertEq(art.palettes(0), paletteV2); assertEq(SSTORE2.read(art.palettesPointers(0)), paletteV2); } + + /// + /// addBodies, addBodiesFromPointer, bodiesPageCount, bodiesPage, bodies + /// + + function testAddBodiesRevertsIfSenderNotDescriptor() public { + vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); + art.addBodies(fromHex('123456'), uint80(12), uint16(1)); + } + + function testAddBodiesWorksWithMultiplePages() public { + vm.startPrank(descriptor); + art.addBodies(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); + art.addBodies(fromHex(NEXT_TWO_IMAGES_COMPRESSED), NEXT_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); + vm.stopPrank(); + + _assertBodiesStoredOK(); + } + + function testAddBodiesFromPointerWorksWithMultiplePages() public { + vm.startPrank(descriptor); + art.addBodiesFromPointer( + SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)), + FIRST_TWO_IMAGES_DEFLATED_LENGTH, + uint16(2) + ); + art.addBodiesFromPointer( + SSTORE2.write(fromHex(NEXT_TWO_IMAGES_COMPRESSED)), + NEXT_TWO_IMAGES_DEFLATED_LENGTH, + uint16(2) + ); + vm.stopPrank(); + + _assertBodiesStoredOK(); + } + + function _assertBodiesStoredOK() internal { + assertEq(art.bodiesPageCount(), 2); + + INounsArt.NounArtStoragePage memory page = art.bodiesPage(0); + assertEq(page.imageCount, 2); + assertEq(page.decompressedLength, FIRST_TWO_IMAGES_DEFLATED_LENGTH); + assertEq(SSTORE2.read(page.pointer), fromHex(FIRST_TWO_IMAGES_COMPRESSED)); + + page = art.bodiesPage(1); + assertEq(page.imageCount, 2); + assertEq(page.decompressedLength, NEXT_TWO_IMAGES_DEFLATED_LENGTH); + assertEq(SSTORE2.read(page.pointer), fromHex(NEXT_TWO_IMAGES_COMPRESSED)); + + // These hard-coded values are copied from image-data.json -> images -> BODIES -> the first items + assertEq( + art.bodies(0), + fromHex( + '0015171f090e020e020e020e02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02' + ) + ); + assertEq( + art.bodies(1), + fromHex( + '0015171f090e030e030e030e03020301000b03020301000b03020301000b03020301000b03020301000b03020301000b03020301000b03' + ) + ); + + // These hard-coded values are copied from image-data.json -> images -> HEADS -> the first items + assertEq( + art.bodies(2), + fromHex( + '0005191406030004800c0002000980080001000e80040002000f80020001001080020002000f80020002000f800200020001800e810200020001800e810200020001800e810200020001800e81020003800e8102000180018101800f8101000180018103800d82018005800d81018002001180' + ) + ); + assertEq( + art.bodies(3), + fromHex( + '00031c140306000e3a050006000e3a05000400023a0e00023a03000400023a0e00023a03000400023a0e00023a030002000207023a0e07023a02070100020001070126023a040706260407023a01260107010001000126010702260607042606070226010701000100012608070626080701000100013a16070100013a0100013a15070100013a0100013a15070100013a0107013a1607013a0107013a1607010018070100070703760e0701001807020016070100' + ) + ); + } + + // the value below was copied from running the hardhat task `descriptor-art-to-console` with + // the parameter `count` set to 2, and taking the bodies values. + string constant FIRST_TWO_IMAGES_COMPRESSED = + '6360c00b14f04b33301190772020bf8080bc3983a8b83c271f130432313132701345123016dd7c6608646206ea258a841b0000'; + uint80 constant FIRST_TWO_IMAGES_DEFLATED_LENGTH = 320; + + // the value below was copied from running the hardhat task `descriptor-art-to-console` with + // the parameter `count` set to 2 and `start` set to 2, and taking the heads values. + string constant NEXT_TWO_IMAGES_COMPRESSED = + '858f410a02310c4593b4d38ee0548551145cb8ea21baf24e82eb8c77f23e1ec5df0e232a3a0dfcfcd7fc4253a2d93acdc72495fc5cc91f95fc42cda17786ac2ef1d6425b620a6ac12b15f01a7de4a9b386e1bf9bd25979605d0d5cc86877636db4c34c68a395953eea4ee6d81b4721353476ec9602647e1236f160483ce7ad3c4749d6bb6831e388337e955da2f31692d7acc5ad76e4b4cb9eb2b6dfe44b3a39ed21efcd351416cab3b77a02'; + uint80 constant NEXT_TWO_IMAGES_DEFLATED_LENGTH = 512; } From 21e7623c56f0332d08d7862c3012209844789ea7 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Tue, 28 Jun 2022 09:52:51 -0500 Subject: [PATCH 024/116] update local addresses --- .../nouns-sdk/src/contract/addresses.json | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/nouns-sdk/src/contract/addresses.json b/packages/nouns-sdk/src/contract/addresses.json index 188d23a82e..b42f6b68a0 100644 --- a/packages/nouns-sdk/src/contract/addresses.json +++ b/packages/nouns-sdk/src/contract/addresses.json @@ -24,15 +24,15 @@ "nounsDAOLogicV1": "0xdF05F2D3276F3F3fA00296702e4cf7190B78F6F9" }, "31337": { - "nounsToken": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", - "nounsSeeder": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9", - "nounsDescriptor": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", - "nftDescriptor": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", - "nounsAuctionHouse": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707", - "nounsAuctionHouseProxy": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", - "nounsAuctionHouseProxyAdmin": "0x0165878A594ca255338adfa4d48449f69242Eb8F", - "nounsDaoExecutor": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6", - "nounsDAOProxy": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788", - "nounsDAOLogicV1": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" + "nounsToken": "0x0165878a594ca255338adfa4d48449f69242eb8f", + "nounsSeeder": "0x5fc8d32690cc91d4c39d9d3abcbd16989f875707", + "nounsDescriptor": "0xcf7ed3acca5a467e9e704c703e8d87f634fb0fc9", + "nftDescriptor": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "nounsAuctionHouse": "0xa513e6e4b8f2a923d98304ec87f64353c4d5c853", + "nounsAuctionHouseProxy": "0x8a791620dd6260079bf849dc5567adc3f2fdc318", + "nounsAuctionHouseProxyAdmin": "0x2279b7a0a67db372996a5fab50d91eaa73d2ebe6", + "nounsDaoExecutor": "0x610178da211fef7d417bc0e6fed39f05609ad788", + "nounsDAOProxy": "0xa51c1fc2f0d1a1b8494ed1fe312d7c3a78ed91c0", + "nounsDAOLogicV1": "0xb7f8bc63bbcad18155201308c8f3540b07f84f5e" } } From ce4ee7f70a32a07ec97c514faaf11e47616698c6 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Tue, 28 Jun 2022 10:37:45 -0500 Subject: [PATCH 025/116] fix descriptorv2 missing args --- packages/nouns-contracts/tasks/deploy.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/nouns-contracts/tasks/deploy.ts b/packages/nouns-contracts/tasks/deploy.ts index ceb7c47c4b..04adfe83a0 100644 --- a/packages/nouns-contracts/tasks/deploy.ts +++ b/packages/nouns-contracts/tasks/deploy.ts @@ -125,6 +125,7 @@ task('deploy', 'Deploys NFTDescriptor, NounsDescriptor, NounsSeeder, and NounsTo NFTDescriptorV2: {}, SVGRenderer: {}, NounsDescriptorV2: { + args: [expectedNounsArtAddress, () => deployment.SVGRenderer.address], libraries: () => ({ NFTDescriptorV2: deployment.NFTDescriptorV2.address, }), From 6f721697007e331e116107a7ea071627c819cdc0 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Tue, 28 Jun 2022 10:38:01 -0500 Subject: [PATCH 026/116] fix deploy-and-configure param types --- .../nouns-contracts/tasks/deploy-and-configure.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/nouns-contracts/tasks/deploy-and-configure.ts b/packages/nouns-contracts/tasks/deploy-and-configure.ts index 2297677ba1..0b71200457 100644 --- a/packages/nouns-contracts/tasks/deploy-and-configure.ts +++ b/packages/nouns-contracts/tasks/deploy-and-configure.ts @@ -1,4 +1,4 @@ -import { task } from 'hardhat/config'; +import { task, types } from 'hardhat/config'; import { DeployedContract } from './types'; interface ContractRow { @@ -12,16 +12,21 @@ task('deploy-and-configure', 'Deploy and configure all contracts') .addFlag('updateConfigs', 'Write the deployed addresses to the SDK and subgraph configs') .addOptionalParam('weth', 'The WETH contract address') .addOptionalParam('noundersdao', 'The nounders DAO contract address') - .addOptionalParam('auctionTimeBuffer', 'The auction time buffer (seconds)') + .addOptionalParam( + 'auctionTimeBuffer', + 'The auction time buffer (seconds)', + 5 * 60 /* 5 minutes */, + types.int, + ) .addOptionalParam('auctionReservePrice', 'The auction reserve price (wei)') .addOptionalParam( 'auctionMinIncrementBidPercentage', 'The auction min increment bid percentage (out of 100)', ) - .addOptionalParam('auctionDuration', 'The auction duration (seconds)') + .addOptionalParam('auctionDuration', 'The auction duration (seconds)', 600, types.int) .addOptionalParam('timelockDelay', 'The timelock delay (seconds)') - .addOptionalParam('votingPeriod', 'The voting period (blocks)') - .addOptionalParam('votingDelay', 'The voting delay (blocks)') + .addOptionalParam('votingPeriod', 'The voting period (blocks)', 5760, types.int) + .addOptionalParam('votingDelay', 'The voting delay (blocks)', 1, types.int) .addOptionalParam('proposalThresholdBps', 'The proposal threshold (basis points)') .addOptionalParam('quorumVotesBps', 'Votes required for quorum (basis points)') .setAction(async (args, { run }) => { From a06c4e0b1d7f2b0f4f3ae08e75ab1fe901ebb46e Mon Sep 17 00:00:00 2001 From: eladmallel Date: Tue, 28 Jun 2022 12:52:06 -0500 Subject: [PATCH 027/116] fix deploy-and-configure descriptor name --- packages/nouns-contracts/tasks/deploy-and-configure.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/nouns-contracts/tasks/deploy-and-configure.ts b/packages/nouns-contracts/tasks/deploy-and-configure.ts index 0b71200457..1e3c7ce207 100644 --- a/packages/nouns-contracts/tasks/deploy-and-configure.ts +++ b/packages/nouns-contracts/tasks/deploy-and-configure.ts @@ -40,14 +40,14 @@ task('deploy-and-configure', 'Deploy and configure all contracts') // Populate the on-chain art await run('populate-descriptor', { - nftDescriptor: contracts.NFTDescriptor.address, - nounsDescriptor: contracts.NounsDescriptor.address, + nftDescriptor: contracts.NFTDescriptorV2.address, + nounsDescriptor: contracts.NounsDescriptorV2.address, }); // Transfer ownership of all contract except for the auction house. // We must maintain ownership of the auction house to kick off the first auction. const executorAddress = contracts.NounsDAOExecutor.address; - await contracts.NounsDescriptor.instance.transferOwnership(executorAddress); + await contracts.NounsDescriptorV2.instance.transferOwnership(executorAddress); await contracts.NounsToken.instance.transferOwnership(executorAddress); await contracts.NounsAuctionHouseProxyAdmin.instance.transferOwnership(executorAddress); console.log( From dfb1b5d1d0bf5a722162cfacdc8dde8066fa561b Mon Sep 17 00:00:00 2001 From: eladmallel Date: Tue, 28 Jun 2022 15:11:37 -0500 Subject: [PATCH 028/116] add NounsArt tests --- .../nouns-contracts/contracts/NounsArt.sol | 9 + .../contracts/interfaces/INounsArt.sol | 6 + .../test/foundry/NounsArt.t.sol | 413 ++++++++++++++++-- 3 files changed, 403 insertions(+), 25 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsArt.sol b/packages/nouns-contracts/contracts/NounsArt.sol index 17dbe97035..4411a3a40a 100644 --- a/packages/nouns-contracts/contracts/NounsArt.sol +++ b/packages/nouns-contracts/contracts/NounsArt.sol @@ -390,6 +390,9 @@ contract NounsArt is INounsArt { uint80 decompressedLength, uint16 imageCount ) internal { + if (encodedCompressed.length == 0) { + revert EmptyBytes(); + } address pointer = SSTORE2.write(encodedCompressed); addToTraitFromPointer(trait, pointer, decompressedLength, imageCount); } @@ -400,6 +403,12 @@ contract NounsArt is INounsArt { uint80 decompressedLength, uint16 imageCount ) internal { + if (decompressedLength == 0) { + revert BadDecompressedLength(); + } + if (imageCount == 0) { + revert BadImageCount(); + } trait.storagePages.push( NounArtStoragePage({ pointer: pointer, decompressedLength: decompressedLength, imageCount: imageCount }) ); diff --git a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol index a0f736840e..e54163f7f0 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol @@ -26,6 +26,12 @@ interface INounsArt { error BadPaletteLength(); + error EmptyBytes(); + + error BadDecompressedLength(); + + error BadImageCount(); + error NoPages(); error ImageNotFound(); diff --git a/packages/nouns-contracts/test/foundry/NounsArt.t.sol b/packages/nouns-contracts/test/foundry/NounsArt.t.sol index a78932702a..581923f409 100644 --- a/packages/nouns-contracts/test/foundry/NounsArt.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsArt.t.sol @@ -133,8 +133,47 @@ contract NounsArtTest is Test, Utils { assertEq(SSTORE2.read(art.palettesPointers(0)), paletteV2); } + function testCannotSetEmptyPalette() public { + vm.prank(descriptor); + vm.expectRevert(INounsArt.EmptyPalette.selector); + art.setPalette(0, new bytes(0)); + } + + function testCannotSetPaletteWithLengthNotAMultipleOf3() public { + vm.startPrank(descriptor); + + vm.expectRevert(INounsArt.BadPaletteLength.selector); + art.setPalette(0, new bytes(1)); + + vm.expectRevert(INounsArt.BadPaletteLength.selector); + art.setPalette(0, new bytes(2)); + + // expected to work + art.setPalette(0, new bytes(3)); + + vm.expectRevert(INounsArt.BadPaletteLength.selector); + art.setPalette(0, new bytes(4)); + + vm.expectRevert(INounsArt.BadPaletteLength.selector); + art.setPalette(0, new bytes(5)); + + // expected to work + art.setPalette(0, new bytes(6)); + + vm.expectRevert(INounsArt.BadPaletteLength.selector); + art.setPalette(0, new bytes(7)); + + vm.stopPrank(); + } + + function testCannotSetPaletteWithMoreThan256Colors() public { + vm.prank(descriptor); + vm.expectRevert(INounsArt.BadPaletteLength.selector); + art.setPalette(0, new bytes(769)); + } + /// - /// addBodies, addBodiesFromPointer, bodiesPageCount, bodiesPage, bodies + /// addBodies, addBodiesFromPointer, bodiesPageCount, bodiesPage, bodies, bodiesTrait /// function testAddBodiesRevertsIfSenderNotDescriptor() public { @@ -142,7 +181,28 @@ contract NounsArtTest is Test, Utils { art.addBodies(fromHex('123456'), uint80(12), uint16(1)); } + function testCannotAddBodiesWithNoBytes() public { + vm.prank(descriptor); + vm.expectRevert(INounsArt.EmptyBytes.selector); + art.addBodies(new bytes(0), 0, 0); + } + + function testCannotAddBodiesWithZeroDecompressedLength() public { + vm.prank(descriptor); + vm.expectRevert(INounsArt.BadDecompressedLength.selector); + art.addBodies(fromHex(FIRST_TWO_IMAGES_COMPRESSED), 0, 0); + } + + function testCannotAddBodiesWithZeroImageCount() public { + vm.prank(descriptor); + vm.expectRevert(INounsArt.BadImageCount.selector); + art.addBodies(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, 0); + } + function testAddBodiesWorksWithMultiplePages() public { + assertEq(art.bodiesTrait().storedImagesCount, 0); + assertEq(art.bodiesPageCount(), 0); + vm.startPrank(descriptor); art.addBodies(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); art.addBodies(fromHex(NEXT_TWO_IMAGES_COMPRESSED), NEXT_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); @@ -151,7 +211,24 @@ contract NounsArtTest is Test, Utils { _assertBodiesStoredOK(); } + function testCannotAddBodiesFromPointerWithZeroDecompressedLength() public { + address pointer = SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)); + vm.prank(descriptor); + vm.expectRevert(INounsArt.BadDecompressedLength.selector); + art.addBodiesFromPointer(pointer, 0, 0); + } + + function testCannotAddBodiesFromPointerWithZeroImageCount() public { + address pointer = SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)); + vm.prank(descriptor); + vm.expectRevert(INounsArt.BadImageCount.selector); + art.addBodiesFromPointer(pointer, FIRST_TWO_IMAGES_DEFLATED_LENGTH, 0); + } + function testAddBodiesFromPointerWorksWithMultiplePages() public { + assertEq(art.bodiesTrait().storedImagesCount, 0); + assertEq(art.bodiesPageCount(), 0); + vm.startPrank(descriptor); art.addBodiesFromPointer( SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)), @@ -168,6 +245,229 @@ contract NounsArtTest is Test, Utils { _assertBodiesStoredOK(); } + /// + /// addAccessories, addAccessoriesFromPointer, accessoriesPageCount, accessoriesPage, accessories, accessoriesTrait + /// + + function testAddAccessoriesRevertsIfSenderNotDescriptor() public { + vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); + art.addAccessories(fromHex('123456'), uint80(12), uint16(1)); + } + + function testCannotAddAccessoriesWithNoBytes() public { + vm.prank(descriptor); + vm.expectRevert(INounsArt.EmptyBytes.selector); + art.addAccessories(new bytes(0), 0, 0); + } + + function testCannotAddAccessoriesWithZeroDecompressedLength() public { + vm.prank(descriptor); + vm.expectRevert(INounsArt.BadDecompressedLength.selector); + art.addAccessories(fromHex(FIRST_TWO_IMAGES_COMPRESSED), 0, 0); + } + + function testCannotAddAccessoriesWithZeroImageCount() public { + vm.prank(descriptor); + vm.expectRevert(INounsArt.BadImageCount.selector); + art.addAccessories(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, 0); + } + + function testAddAccessoriesWorksWithMultiplePages() public { + assertEq(art.accessoriesTrait().storedImagesCount, 0); + assertEq(art.accessoriesPageCount(), 0); + + vm.startPrank(descriptor); + art.addAccessories(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); + art.addAccessories(fromHex(NEXT_TWO_IMAGES_COMPRESSED), NEXT_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); + vm.stopPrank(); + + _assertAccessoriesStoredOK(); + } + + function testCannotAddAccessoriesFromPointerWithZeroDecompressedLength() public { + address pointer = SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)); + vm.prank(descriptor); + vm.expectRevert(INounsArt.BadDecompressedLength.selector); + art.addAccessoriesFromPointer(pointer, 0, 0); + } + + function testCannotAddAccessoriesFromPointerWithZeroImageCount() public { + address pointer = SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)); + vm.prank(descriptor); + vm.expectRevert(INounsArt.BadImageCount.selector); + art.addAccessoriesFromPointer(pointer, FIRST_TWO_IMAGES_DEFLATED_LENGTH, 0); + } + + function testAddAccessoriesFromPointerWorksWithMultiplePages() public { + assertEq(art.accessoriesTrait().storedImagesCount, 0); + assertEq(art.accessoriesPageCount(), 0); + + vm.startPrank(descriptor); + art.addAccessoriesFromPointer( + SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)), + FIRST_TWO_IMAGES_DEFLATED_LENGTH, + uint16(2) + ); + art.addAccessoriesFromPointer( + SSTORE2.write(fromHex(NEXT_TWO_IMAGES_COMPRESSED)), + NEXT_TWO_IMAGES_DEFLATED_LENGTH, + uint16(2) + ); + vm.stopPrank(); + + _assertAccessoriesStoredOK(); + } + + /// + /// addHeads, addHeadsFromPointer, headsPageCount, headsPage, heads, headsTrait + /// + + function testAddHeadsRevertsIfSenderNotDescriptor() public { + vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); + art.addHeads(fromHex('123456'), uint80(12), uint16(1)); + } + + function testCannotAddHeadsWithNoBytes() public { + vm.prank(descriptor); + vm.expectRevert(INounsArt.EmptyBytes.selector); + art.addHeads(new bytes(0), 0, 0); + } + + function testCannotAddHeadsWithZeroDecompressedLength() public { + vm.prank(descriptor); + vm.expectRevert(INounsArt.BadDecompressedLength.selector); + art.addHeads(fromHex(FIRST_TWO_IMAGES_COMPRESSED), 0, 0); + } + + function testCannotAddHeadsWithZeroImageCount() public { + vm.prank(descriptor); + vm.expectRevert(INounsArt.BadImageCount.selector); + art.addHeads(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, 0); + } + + function testAddHeadsWorksWithMultiplePages() public { + assertEq(art.headsTrait().storedImagesCount, 0); + assertEq(art.headsPageCount(), 0); + + vm.startPrank(descriptor); + art.addHeads(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); + art.addHeads(fromHex(NEXT_TWO_IMAGES_COMPRESSED), NEXT_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); + vm.stopPrank(); + + _assertHeadsStoredOK(); + } + + function testCannotAddHeadsFromPointerWithZeroDecompressedLength() public { + address pointer = SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)); + vm.prank(descriptor); + vm.expectRevert(INounsArt.BadDecompressedLength.selector); + art.addHeadsFromPointer(pointer, 0, 0); + } + + function testCannotAddHeadsFromPointerWithZeroImageCount() public { + address pointer = SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)); + vm.prank(descriptor); + vm.expectRevert(INounsArt.BadImageCount.selector); + art.addHeadsFromPointer(pointer, FIRST_TWO_IMAGES_DEFLATED_LENGTH, 0); + } + + function testAddHeadsFromPointerWorksWithMultiplePages() public { + assertEq(art.headsTrait().storedImagesCount, 0); + assertEq(art.headsPageCount(), 0); + + vm.startPrank(descriptor); + art.addHeadsFromPointer( + SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)), + FIRST_TWO_IMAGES_DEFLATED_LENGTH, + uint16(2) + ); + art.addHeadsFromPointer( + SSTORE2.write(fromHex(NEXT_TWO_IMAGES_COMPRESSED)), + NEXT_TWO_IMAGES_DEFLATED_LENGTH, + uint16(2) + ); + vm.stopPrank(); + + _assertHeadsStoredOK(); + } + + /// + /// addGlasses, addGlassesFromPointer, glassesPageCount, glassesPage, glasses, glassesTrait + /// + + function testAddGlassesRevertsIfSenderNotDescriptor() public { + vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); + art.addGlasses(fromHex('123456'), uint80(12), uint16(1)); + } + + function testCannotAddGlassesWithNoBytes() public { + vm.prank(descriptor); + vm.expectRevert(INounsArt.EmptyBytes.selector); + art.addGlasses(new bytes(0), 0, 0); + } + + function testCannotAddGlassesWithZeroDecompressedLength() public { + vm.prank(descriptor); + vm.expectRevert(INounsArt.BadDecompressedLength.selector); + art.addGlasses(fromHex(FIRST_TWO_IMAGES_COMPRESSED), 0, 0); + } + + function testCannotAddGlassesWithZeroImageCount() public { + vm.prank(descriptor); + vm.expectRevert(INounsArt.BadImageCount.selector); + art.addGlasses(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, 0); + } + + function testAddGlassesWorksWithMultiplePages() public { + assertEq(art.glassesTrait().storedImagesCount, 0); + assertEq(art.glassesPageCount(), 0); + + vm.startPrank(descriptor); + art.addGlasses(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); + art.addGlasses(fromHex(NEXT_TWO_IMAGES_COMPRESSED), NEXT_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); + vm.stopPrank(); + + _assertGlassesStoredOK(); + } + + function testCannotAddGlassesFromPointerWithZeroDecompressedLength() public { + address pointer = SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)); + vm.prank(descriptor); + vm.expectRevert(INounsArt.BadDecompressedLength.selector); + art.addGlassesFromPointer(pointer, 0, 0); + } + + function testCannotAddGlassesFromPointerWithZeroImageCount() public { + address pointer = SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)); + vm.prank(descriptor); + vm.expectRevert(INounsArt.BadImageCount.selector); + art.addGlassesFromPointer(pointer, FIRST_TWO_IMAGES_DEFLATED_LENGTH, 0); + } + + function testAddGlassesFromPointerWorksWithMultiplePages() public { + assertEq(art.headsTrait().storedImagesCount, 0); + assertEq(art.glassesPageCount(), 0); + + vm.startPrank(descriptor); + art.addGlassesFromPointer( + SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)), + FIRST_TWO_IMAGES_DEFLATED_LENGTH, + uint16(2) + ); + art.addGlassesFromPointer( + SSTORE2.write(fromHex(NEXT_TWO_IMAGES_COMPRESSED)), + NEXT_TWO_IMAGES_DEFLATED_LENGTH, + uint16(2) + ); + vm.stopPrank(); + + _assertGlassesStoredOK(); + } + + /// + /// INTERNAL + /// + function _assertBodiesStoredOK() internal { assertEq(art.bodiesPageCount(), 2); @@ -181,33 +481,87 @@ contract NounsArtTest is Test, Utils { assertEq(page.decompressedLength, NEXT_TWO_IMAGES_DEFLATED_LENGTH); assertEq(SSTORE2.read(page.pointer), fromHex(NEXT_TWO_IMAGES_COMPRESSED)); + assertEq(art.bodiesTrait().storedImagesCount, 4); + // These hard-coded values are copied from image-data.json -> images -> BODIES -> the first items - assertEq( - art.bodies(0), - fromHex( - '0015171f090e020e020e020e02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02' - ) - ); - assertEq( - art.bodies(1), - fromHex( - '0015171f090e030e030e030e03020301000b03020301000b03020301000b03020301000b03020301000b03020301000b03020301000b03' - ) - ); + assertEq(art.bodies(0), fromHex(IMAGE_0)); + assertEq(art.bodies(1), fromHex(IMAGE_1)); // These hard-coded values are copied from image-data.json -> images -> HEADS -> the first items - assertEq( - art.bodies(2), - fromHex( - '0005191406030004800c0002000980080001000e80040002000f80020001001080020002000f80020002000f800200020001800e810200020001800e810200020001800e810200020001800e81020003800e8102000180018101800f8101000180018103800d82018005800d81018002001180' - ) - ); - assertEq( - art.bodies(3), - fromHex( - '00031c140306000e3a050006000e3a05000400023a0e00023a03000400023a0e00023a03000400023a0e00023a030002000207023a0e07023a02070100020001070126023a040706260407023a01260107010001000126010702260607042606070226010701000100012608070626080701000100013a16070100013a0100013a15070100013a0100013a15070100013a0107013a1607013a0107013a1607010018070100070703760e0701001807020016070100' - ) - ); + assertEq(art.bodies(2), fromHex(IMAGE_2)); + assertEq(art.bodies(3), fromHex(IMAGE_3)); + } + + function _assertAccessoriesStoredOK() internal { + assertEq(art.accessoriesPageCount(), 2); + + INounsArt.NounArtStoragePage memory page = art.accessoriesPage(0); + assertEq(page.imageCount, 2); + assertEq(page.decompressedLength, FIRST_TWO_IMAGES_DEFLATED_LENGTH); + assertEq(SSTORE2.read(page.pointer), fromHex(FIRST_TWO_IMAGES_COMPRESSED)); + + page = art.accessoriesPage(1); + assertEq(page.imageCount, 2); + assertEq(page.decompressedLength, NEXT_TWO_IMAGES_DEFLATED_LENGTH); + assertEq(SSTORE2.read(page.pointer), fromHex(NEXT_TWO_IMAGES_COMPRESSED)); + + assertEq(art.accessoriesTrait().storedImagesCount, 4); + + // These hard-coded values are copied from image-data.json -> images -> BODIES -> the first items + assertEq(art.accessories(0), fromHex(IMAGE_0)); + assertEq(art.accessories(1), fromHex(IMAGE_1)); + + // These hard-coded values are copied from image-data.json -> images -> HEADS -> the first items + assertEq(art.accessories(2), fromHex(IMAGE_2)); + assertEq(art.accessories(3), fromHex(IMAGE_3)); + } + + function _assertHeadsStoredOK() internal { + assertEq(art.headsPageCount(), 2); + + INounsArt.NounArtStoragePage memory page = art.headsPage(0); + assertEq(page.imageCount, 2); + assertEq(page.decompressedLength, FIRST_TWO_IMAGES_DEFLATED_LENGTH); + assertEq(SSTORE2.read(page.pointer), fromHex(FIRST_TWO_IMAGES_COMPRESSED)); + + page = art.headsPage(1); + assertEq(page.imageCount, 2); + assertEq(page.decompressedLength, NEXT_TWO_IMAGES_DEFLATED_LENGTH); + assertEq(SSTORE2.read(page.pointer), fromHex(NEXT_TWO_IMAGES_COMPRESSED)); + + assertEq(art.headsTrait().storedImagesCount, 4); + + // These hard-coded values are copied from image-data.json -> images -> BODIES -> the first items + assertEq(art.heads(0), fromHex(IMAGE_0)); + assertEq(art.heads(1), fromHex(IMAGE_1)); + + // These hard-coded values are copied from image-data.json -> images -> HEADS -> the first items + assertEq(art.heads(2), fromHex(IMAGE_2)); + assertEq(art.heads(3), fromHex(IMAGE_3)); + } + + function _assertGlassesStoredOK() internal { + assertEq(art.glassesPageCount(), 2); + + INounsArt.NounArtStoragePage memory page = art.glassesPage(0); + assertEq(page.imageCount, 2); + assertEq(page.decompressedLength, FIRST_TWO_IMAGES_DEFLATED_LENGTH); + assertEq(SSTORE2.read(page.pointer), fromHex(FIRST_TWO_IMAGES_COMPRESSED)); + + page = art.glassesPage(1); + assertEq(page.imageCount, 2); + assertEq(page.decompressedLength, NEXT_TWO_IMAGES_DEFLATED_LENGTH); + assertEq(SSTORE2.read(page.pointer), fromHex(NEXT_TWO_IMAGES_COMPRESSED)); + + assertEq(art.glassesTrait().storedImagesCount, 4); + + // These hard-coded values are copied from image-data.json -> images -> BODIES -> the first items + assertEq(art.glasses(0), fromHex(IMAGE_0)); + assertEq(art.glasses(1), fromHex(IMAGE_1)); + + // These hard-coded values are copied from image-data.json -> images -> HEADS -> the first items + assertEq(art.glasses(2), fromHex(IMAGE_2)); + assertEq(art.glasses(3), fromHex(IMAGE_3)); } // the value below was copied from running the hardhat task `descriptor-art-to-console` with @@ -221,4 +575,13 @@ contract NounsArtTest is Test, Utils { string constant NEXT_TWO_IMAGES_COMPRESSED = '858f410a02310c4593b4d38ee0548551145cb8ea21baf24e82eb8c77f23e1ec5df0e232a3a0dfcfcd7fc4253a2d93acdc72495fc5cc91f95fc42cda17786ac2ef1d6425b620a6ac12b15f01a7de4a9b386e1bf9bd25979605d0d5cc86877636db4c34c68a395953eea4ee6d81b4721353476ec9602647e1236f160483ce7ad3c4749d6bb6831e388337e955da2f31692d7acc5ad76e4b4cb9eb2b6dfe44b3a39ed21efcd351416cab3b77a02'; uint80 constant NEXT_TWO_IMAGES_DEFLATED_LENGTH = 512; + + string constant IMAGE_0 = + '0015171f090e020e020e020e02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02'; + string constant IMAGE_1 = + '0015171f090e030e030e030e03020301000b03020301000b03020301000b03020301000b03020301000b03020301000b03020301000b03'; + string constant IMAGE_2 = + '0005191406030004800c0002000980080001000e80040002000f80020001001080020002000f80020002000f800200020001800e810200020001800e810200020001800e810200020001800e81020003800e8102000180018101800f8101000180018103800d82018005800d81018002001180'; + string constant IMAGE_3 = + '00031c140306000e3a050006000e3a05000400023a0e00023a03000400023a0e00023a03000400023a0e00023a030002000207023a0e07023a02070100020001070126023a040706260407023a01260107010001000126010702260607042606070226010701000100012608070626080701000100013a16070100013a0100013a15070100013a0100013a15070100013a0107013a1607013a0107013a1607010018070100070703760e0701001807020016070100'; } From 509ef6ee01fbfabbfb493c7e0b4f15696aed31a7 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Tue, 28 Jun 2022 15:39:51 -0500 Subject: [PATCH 029/116] add descriptor v2 tests --- .../test/foundry/NounsDescriptorV2.t.sol | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol diff --git a/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol b/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol new file mode 100644 index 0000000000..9ed637bfc5 --- /dev/null +++ b/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.6; + +import 'forge-std/Test.sol'; +import { NounsDescriptorV2 } from '../../contracts/NounsDescriptorV2.sol'; +import { SVGRenderer } from '../../contracts/SVGRenderer.sol'; +import { ISVGRenderer } from '../../contracts/interfaces/ISVGRenderer.sol'; +import { NounsArt } from '../../contracts/NounsArt.sol'; +import { INounsArt } from '../../contracts/interfaces/INounsArt.sol'; + +contract NounsDescriptorV2Test is Test { + NounsDescriptorV2 descriptor; + NounsArt art; + + function setUp() public { + descriptor = new NounsDescriptorV2(INounsArt(address(0)), new SVGRenderer()); + art = new NounsArt(address(descriptor)); + descriptor.setArt(art); + } + + function testCannotSetArtIfNotOwner() public { + vm.prank(address(1)); + vm.expectRevert(bytes('Ownable: caller is not the owner')); + descriptor.setArt(INounsArt(address(2))); + } + + function testCannotSetArtIfPartsAreLocked() public { + descriptor.lockParts(); + vm.expectRevert(bytes('Parts are locked')); + descriptor.setArt(INounsArt(address(2))); + } + + function testSetArtWorks() public { + descriptor.setArt(INounsArt(address(2))); + assertEq(address(descriptor.art()), address(2)); + } + + function testCannotSetRendererIfNotOwner() public { + vm.prank(address(1)); + vm.expectRevert(bytes('Ownable: caller is not the owner')); + descriptor.setRenderer(ISVGRenderer(address(2))); + } + + function testSetRendererWorksIfPartsAreLocked() public { + descriptor.lockParts(); + descriptor.setRenderer(ISVGRenderer(address(2))); + assertEq(address(descriptor.renderer()), address(2)); + } + + function testSetRendererWorks() public { + descriptor.setRenderer(ISVGRenderer(address(2))); + assertEq(address(descriptor.renderer()), address(2)); + } + + function testBackgroundCountUsesArt() public { + vm.mockCall(address(art), abi.encodeWithSelector(NounsArt.backgroundsCount.selector), abi.encode(42)); + assertEq(descriptor.backgroundCount(), 42); + vm.clearMockedCalls(); + } + + function testBodyCountUsesArt() public { + vm.mockCall( + address(art), + abi.encodeWithSelector(NounsArt.bodiesTrait.selector), + abi.encode(INounsArt.Trait({ storedImagesCount: 42, storagePages: new INounsArt.NounArtStoragePage[](0) })) + ); + assertEq(descriptor.bodyCount(), 42); + vm.clearMockedCalls(); + } + + function testAccessoryCountUsesArt() public { + vm.mockCall( + address(art), + abi.encodeWithSelector(NounsArt.accessoriesTrait.selector), + abi.encode(INounsArt.Trait({ storedImagesCount: 42, storagePages: new INounsArt.NounArtStoragePage[](0) })) + ); + assertEq(descriptor.accessoryCount(), 42); + vm.clearMockedCalls(); + } + + function testHeadCountUsesArt() public { + vm.mockCall( + address(art), + abi.encodeWithSelector(NounsArt.headsTrait.selector), + abi.encode(INounsArt.Trait({ storedImagesCount: 42, storagePages: new INounsArt.NounArtStoragePage[](0) })) + ); + assertEq(descriptor.headCount(), 42); + vm.clearMockedCalls(); + } + + function testGlassesCountUsesArt() public { + vm.mockCall( + address(art), + abi.encodeWithSelector(NounsArt.glassesTrait.selector), + abi.encode(INounsArt.Trait({ storedImagesCount: 42, storagePages: new INounsArt.NounArtStoragePage[](0) })) + ); + assertEq(descriptor.glassesCount(), 42); + vm.clearMockedCalls(); + } +} From ebb8ab53c925b775db8159139ff8a4706d9b4b6b Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 29 Jun 2022 13:06:20 -0500 Subject: [PATCH 030/116] add test: descriptor upgrade via proposal --- .../test/foundry/DescriptorUpgrade.t.sol | 6 +- .../DescriptorUpgradeViaProposal.t.sol | 63 ++++++++++++++++ .../test/foundry/NounsToken.t.sol | 6 +- .../test/foundry/helpers/DeployUtils.sol | 71 +++++++++++++++++++ .../foundry/helpers/DescriptorHelpers.sol | 11 --- 5 files changed, 140 insertions(+), 17 deletions(-) create mode 100644 packages/nouns-contracts/test/foundry/DescriptorUpgradeViaProposal.t.sol create mode 100644 packages/nouns-contracts/test/foundry/helpers/DeployUtils.sol diff --git a/packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol b/packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol index 6e9ce9a93e..f70285eef6 100644 --- a/packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol +++ b/packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol @@ -2,14 +2,14 @@ pragma solidity ^0.8.6; import 'forge-std/Test.sol'; -import { DescriptorHelpers } from './helpers/DescriptorHelpers.sol'; +import { DeployUtils } from './helpers/DeployUtils.sol'; import { NounsToken } from '../../contracts/NounsToken.sol'; import { NounsDescriptor } from '../../contracts/NounsDescriptor.sol'; import { NounsDescriptorV2 } from '../../contracts/NounsDescriptorV2.sol'; import { NounsSeeder } from '../../contracts/NounsSeeder.sol'; import { IProxyRegistry } from '../../contracts/external/opensea/IProxyRegistry.sol'; -contract DescriptorUpgradeTest is Test, DescriptorHelpers { +contract DescriptorUpgradeTest is Test, DeployUtils { NounsToken nounsToken; function setUp() public { @@ -28,7 +28,7 @@ contract DescriptorUpgradeTest is Test, DescriptorHelpers { function testUpgradeToV2MaintainsTokenURI() public { string memory tokenURIwithV1 = nounsToken.tokenURI(1); - NounsDescriptorV2 descriptorV2 = _deployV2(); + NounsDescriptorV2 descriptorV2 = _deployAndPopulateV2(); _populateDescriptorV2(descriptorV2); nounsToken.setDescriptor(descriptorV2); diff --git a/packages/nouns-contracts/test/foundry/DescriptorUpgradeViaProposal.t.sol b/packages/nouns-contracts/test/foundry/DescriptorUpgradeViaProposal.t.sol new file mode 100644 index 0000000000..b717bafb7e --- /dev/null +++ b/packages/nouns-contracts/test/foundry/DescriptorUpgradeViaProposal.t.sol @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.6; + +import 'forge-std/Test.sol'; +import { DeployUtils } from './helpers/DeployUtils.sol'; +import { NounsToken } from '../../contracts/NounsToken.sol'; +import { NounsDescriptorV2 } from '../../contracts/NounsDescriptorV2.sol'; +import { NounsDAOLogicV1 } from '../../contracts/governance/NounsDAOLogicV1.sol'; + +contract DescriptorUpgradeViaProposalTest is Test, DeployUtils { + NounsToken nounsToken; + NounsDAOLogicV1 dao; + address minter = address(2); + address tokenHolder = address(1337); + + function setUp() public { + address noundersDAO = address(42); + (address tokenAddress, address daoAddress) = _deployTokenAndDAOAndPopulateDescriptor( + noundersDAO, + noundersDAO, + minter + ); + nounsToken = NounsToken(tokenAddress); + dao = NounsDAOLogicV1(daoAddress); + + vm.startPrank(minter); + nounsToken.mint(); + nounsToken.transferFrom(minter, tokenHolder, 1); + vm.stopPrank(); + } + + function testUpgradeToV2ViaProposal() public { + NounsDescriptorV2 descriptorV2 = _deployAndPopulateV2(); + + address[] memory targets = new address[](1); + targets[0] = address(nounsToken); + uint256[] memory values = new uint256[](1); + values[0] = 0; + string[] memory signatures = new string[](1); + signatures[0] = 'setDescriptor(address)'; + bytes[] memory calldatas = new bytes[](1); + calldatas[0] = abi.encode(address(descriptorV2)); + + uint256 blockNumber = block.number + 1; + vm.roll(blockNumber); + + vm.startPrank(tokenHolder); + dao.propose(targets, values, signatures, calldatas, 'upgrade descriptor'); + blockNumber += VOTING_DELAY + 1; + vm.roll(blockNumber); + dao.castVote(1, 1); + vm.stopPrank(); + + blockNumber += VOTING_PERIOD + 1; + vm.roll(blockNumber); + dao.queue(1); + + vm.warp(block.timestamp + TIMELOCK_DELAY + 1); + dao.execute(1); + + assertEq(address(nounsToken.descriptor()), address(descriptorV2)); + } +} diff --git a/packages/nouns-contracts/test/foundry/NounsToken.t.sol b/packages/nouns-contracts/test/foundry/NounsToken.t.sol index aa67b0d5bb..6e423cb2f9 100644 --- a/packages/nouns-contracts/test/foundry/NounsToken.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsToken.t.sol @@ -8,15 +8,15 @@ import { NounsSeeder } from '../../contracts/NounsSeeder.sol'; import { IProxyRegistry } from '../../contracts/external/opensea/IProxyRegistry.sol'; import { SVGRenderer } from '../../contracts/SVGRenderer.sol'; import { NounsArt } from '../../contracts/NounsArt.sol'; -import { DescriptorHelpers } from './helpers/DescriptorHelpers.sol'; +import { DeployUtils } from './helpers/DeployUtils.sol'; -contract NounsTokenTest is Test, DescriptorHelpers { +contract NounsTokenTest is Test, DeployUtils { NounsToken nounsToken; address noundersDAO = address(1); address minter = address(2); function setUp() public { - NounsDescriptorV2 descriptor = _deployV2(); + NounsDescriptorV2 descriptor = _deployAndPopulateV2(); _populateDescriptorV2(descriptor); nounsToken = new NounsToken(noundersDAO, minter, descriptor, new NounsSeeder(), IProxyRegistry(address(0))); diff --git a/packages/nouns-contracts/test/foundry/helpers/DeployUtils.sol b/packages/nouns-contracts/test/foundry/helpers/DeployUtils.sol new file mode 100644 index 0000000000..96bae9b7a9 --- /dev/null +++ b/packages/nouns-contracts/test/foundry/helpers/DeployUtils.sol @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.6; + +import 'forge-std/Test.sol'; +import { DescriptorHelpers } from './DescriptorHelpers.sol'; +import { NounsDescriptorV2 } from '../../../contracts/NounsDescriptorV2.sol'; +import { SVGRenderer } from '../../../contracts/SVGRenderer.sol'; +import { NounsArt } from '../../../contracts/NounsArt.sol'; +import { NounsDAOExecutor } from '../../../contracts/governance/NounsDAOExecutor.sol'; +import { NounsDAOLogicV1 } from '../../../contracts/governance/NounsDAOLogicV1.sol'; +import { IProxyRegistry } from '../../../contracts/external/opensea/IProxyRegistry.sol'; +import { NounsDescriptor } from '../../../contracts/NounsDescriptor.sol'; +import { NounsSeeder } from '../../../contracts/NounsSeeder.sol'; +import { NounsToken } from '../../../contracts/NounsToken.sol'; +import { NounsDAOProxy } from '../../../contracts/governance/NounsDAOProxy.sol'; + +abstract contract DeployUtils is Test, DescriptorHelpers { + uint256 constant TIMELOCK_DELAY = 2 days; + uint256 constant VOTING_PERIOD = 5_760; // About 24 hours + uint256 constant VOTING_DELAY = 1; + uint256 constant PROPOSAL_THRESHOLD = 1; + uint256 constant QUORUM_VOTES_BPS = 2000; + + function _deployAndPopulateV2() internal returns (NounsDescriptorV2) { + NounsDescriptorV2 descriptorV2 = _deployDescriptorV2(); + _populateDescriptorV2(descriptorV2); + return descriptorV2; + } + + function _deployDescriptorV2() internal returns (NounsDescriptorV2) { + SVGRenderer renderer = new SVGRenderer(); + NounsDescriptorV2 descriptorV2 = new NounsDescriptorV2(NounsArt(address(0)), renderer); + NounsArt art = new NounsArt(address(descriptorV2)); + descriptorV2.setArt(art); + return descriptorV2; + } + + function _deployTokenAndDAOAndPopulateDescriptor( + address noundersDAO, + address vetoer, + address minter + ) internal returns (address, address) { + IProxyRegistry proxyRegistry = IProxyRegistry(address(3)); + + NounsDAOExecutor timelock = new NounsDAOExecutor(address(1), TIMELOCK_DELAY); + NounsDescriptor descriptor = new NounsDescriptor(); + NounsToken nounsToken = new NounsToken(noundersDAO, minter, descriptor, new NounsSeeder(), proxyRegistry); + NounsDAOProxy proxy = new NounsDAOProxy( + address(timelock), + address(nounsToken), + vetoer, + address(timelock), + address(new NounsDAOLogicV1()), + VOTING_PERIOD, + VOTING_DELAY, + PROPOSAL_THRESHOLD, + QUORUM_VOTES_BPS + ); + + vm.prank(address(timelock)); + timelock.setPendingAdmin(address(proxy)); + vm.prank(address(proxy)); + timelock.acceptAdmin(); + + nounsToken.transferOwnership(address(timelock)); + + _populateDescriptor(descriptor); + + return (address(nounsToken), address(proxy)); + } +} diff --git a/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol b/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol index e9a8ff8d53..239ecdf3d5 100644 --- a/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol +++ b/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol @@ -3,21 +3,10 @@ pragma solidity ^0.8.6; import { NounsDescriptor } from '../../../contracts/NounsDescriptor.sol'; import { NounsDescriptorV2 } from '../../../contracts/NounsDescriptorV2.sol'; -import { SVGRenderer } from '../../../contracts/SVGRenderer.sol'; -import { NounsArt } from '../../../contracts/NounsArt.sol'; import { Utils } from './Utils.sol'; import { Constants } from './Constants.sol'; abstract contract DescriptorHelpers is Utils, Constants { - function _deployV2() internal returns (NounsDescriptorV2) { - SVGRenderer renderer = new SVGRenderer(); - NounsDescriptorV2 descriptorV2 = new NounsDescriptorV2(NounsArt(address(0)), renderer); - NounsArt art = new NounsArt(address(descriptorV2)); - descriptorV2.setArt(art); - _populateDescriptorV2(descriptorV2); - return descriptorV2; - } - function _populateDescriptor(NounsDescriptor descriptor) internal { descriptor.addBackground('d5d7e1'); descriptor.addAccessory( From ad44679d546d6f1842e566fa1c518a8decdf9cf1 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 29 Jun 2022 17:17:29 -0500 Subject: [PATCH 031/116] add descriptor v2 tests --- .../contracts/NounsDescriptorV2.sol | 18 +- .../test/foundry/NounsDescriptorV2.t.sol | 295 +++++++++++++++++- 2 files changed, 303 insertions(+), 10 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol index a411ea261f..e89ab01944 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol @@ -135,7 +135,7 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { * @notice Update a single color palette. This function can be used to * add a new color palette or update an existing palette. */ - function setPalette(uint8 paletteIndex, bytes calldata palette) external override onlyOwner { + function setPalette(uint8 paletteIndex, bytes calldata palette) external override onlyOwner whenPartsNotLocked { art.setPalette(paletteIndex, palette); } @@ -150,7 +150,7 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount - ) external override onlyOwner { + ) external override onlyOwner whenPartsNotLocked { art.addBodies(encodedCompressed, decompressedLength, imageCount); } @@ -165,7 +165,7 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount - ) external override onlyOwner { + ) external override onlyOwner whenPartsNotLocked { art.addAccessories(encodedCompressed, decompressedLength, imageCount); } @@ -180,7 +180,7 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount - ) external override onlyOwner { + ) external override onlyOwner whenPartsNotLocked { art.addHeads(encodedCompressed, decompressedLength, imageCount); } @@ -195,7 +195,7 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { bytes calldata encodedCompressed, uint80 decompressedLength, uint16 imageCount - ) external override onlyOwner { + ) external override onlyOwner whenPartsNotLocked { art.addGlasses(encodedCompressed, decompressedLength, imageCount); } @@ -211,7 +211,7 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { address pointer, uint80 decompressedLength, uint16 imageCount - ) external override onlyOwner { + ) external override onlyOwner whenPartsNotLocked { art.addBodiesFromPointer(pointer, decompressedLength, imageCount); } @@ -227,7 +227,7 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { address pointer, uint80 decompressedLength, uint16 imageCount - ) external override onlyOwner { + ) external override onlyOwner whenPartsNotLocked { art.addAccessoriesFromPointer(pointer, decompressedLength, imageCount); } @@ -243,7 +243,7 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { address pointer, uint80 decompressedLength, uint16 imageCount - ) external override onlyOwner { + ) external override onlyOwner whenPartsNotLocked { art.addHeadsFromPointer(pointer, decompressedLength, imageCount); } @@ -259,7 +259,7 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { address pointer, uint80 decompressedLength, uint16 imageCount - ) external override onlyOwner { + ) external override onlyOwner whenPartsNotLocked { art.addGlassesFromPointer(pointer, decompressedLength, imageCount); } diff --git a/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol b/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol index 9ed637bfc5..dc7bfb3792 100644 --- a/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol @@ -5,15 +5,19 @@ import 'forge-std/Test.sol'; import { NounsDescriptorV2 } from '../../contracts/NounsDescriptorV2.sol'; import { SVGRenderer } from '../../contracts/SVGRenderer.sol'; import { ISVGRenderer } from '../../contracts/interfaces/ISVGRenderer.sol'; +import { INounsSeeder } from '../../contracts/interfaces/INounsSeeder.sol'; import { NounsArt } from '../../contracts/NounsArt.sol'; import { INounsArt } from '../../contracts/interfaces/INounsArt.sol'; +import { Base64 } from 'base64-sol/base64.sol'; contract NounsDescriptorV2Test is Test { NounsDescriptorV2 descriptor; NounsArt art; + SVGRenderer renderer; function setUp() public { - descriptor = new NounsDescriptorV2(INounsArt(address(0)), new SVGRenderer()); + renderer = new SVGRenderer(); + descriptor = new NounsDescriptorV2(INounsArt(address(0)), renderer); art = new NounsArt(address(descriptor)); descriptor.setArt(art); } @@ -52,6 +56,55 @@ contract NounsDescriptorV2Test is Test { assertEq(address(descriptor.renderer()), address(2)); } + function testDataURIEnabledByDefault() public { + assertEq(descriptor.isDataURIEnabled(), true); + } + + function testCannotToggleDataURIIfNotOwner() public { + vm.prank(address(1)); + vm.expectRevert(bytes('Ownable: caller is not the owner')); + descriptor.toggleDataURIEnabled(); + } + + function testToggleDataURIWorks() public { + descriptor.setBaseURI('https://nouns.wtf/'); + _makeArtGettersNotRevert(); + vm.mockCall( + address(renderer), + abi.encodeWithSelector(SVGRenderer.generateSVG.selector), + abi.encode('mock svg') + ); + + descriptor.toggleDataURIEnabled(); + assertEq(descriptor.tokenURI(42, INounsSeeder.Seed(0, 0, 0, 0, 0)), 'https://nouns.wtf/42'); + + descriptor.toggleDataURIEnabled(); + assertEq( + descriptor.tokenURI(42, INounsSeeder.Seed(0, 0, 0, 0, 0)), + string( + abi.encodePacked( + 'data:application/json;base64,', + Base64.encode( + bytes( + abi.encodePacked( + '{"name":"', + 'Noun 42', + '", "description":"', + 'Noun 42 is a member of the Nouns DAO', + '", "image": "', + 'data:image/svg+xml;base64,', + Base64.encode(bytes('mock svg')), + '"}' + ) + ) + ) + ) + ) + ); + + vm.clearMockedCalls(); + } + function testBackgroundCountUsesArt() public { vm.mockCall(address(art), abi.encodeWithSelector(NounsArt.backgroundsCount.selector), abi.encode(42)); assertEq(descriptor.backgroundCount(), 42); @@ -97,4 +150,244 @@ contract NounsDescriptorV2Test is Test { assertEq(descriptor.glassesCount(), 42); vm.clearMockedCalls(); } + + function testAddManyBackgroundsUsesArt() public { + string[] memory params = new string[](2); + params[0] = 'ff00ff'; + params[1] = '00ff00'; + + vm.expectCall(address(art), abi.encodeCall(art.addManyBackgrounds, (params))); + descriptor.addManyBackgrounds(params); + } + + function testCannotAddManyBackgroundsWhenPartsLocked() public { + descriptor.lockParts(); + vm.expectRevert(bytes('Parts are locked')); + descriptor.addManyBackgrounds(new string[](0)); + } + + function testAddBackgroundUsesArt() public { + vm.expectCall(address(art), abi.encodeCall(art.addBackground, ('fff000'))); + descriptor.addBackground('fff000'); + } + + function testCannotAddBackgroundWhenPartsLocked() public { + descriptor.lockParts(); + vm.expectRevert(bytes('Parts are locked')); + descriptor.addBackground(''); + } + + function testSetPaletteUsesArt() public { + vm.expectCall(address(art), abi.encodeCall(art.setPalette, (0, '123456'))); + descriptor.setPalette(0, '123456'); + + vm.expectCall(address(art), abi.encodeCall(art.setPalette, (1, '654321'))); + descriptor.setPalette(1, '654321'); + } + + function testCannotSetPaletteWhenPartsLocked() public { + descriptor.lockParts(); + vm.expectRevert(bytes('Parts are locked')); + descriptor.setPalette(0, '000000'); + } + + function testAddBodiesUsesArt() public { + bytes memory someBytes = 'some bytes'; + uint80 decompressedLen = 123; + uint16 imageCount = 456; + vm.expectCall(address(art), abi.encodeCall(art.addBodies, (someBytes, decompressedLen, imageCount))); + descriptor.addBodies(someBytes, decompressedLen, imageCount); + } + + function testCannotAddBodiesWhenPartsLocked() public { + descriptor.lockParts(); + vm.expectRevert(bytes('Parts are locked')); + descriptor.addBodies('00', 1, 1); + } + + function testAddAccessoriesUsesArt() public { + bytes memory someBytes = 'some bytes'; + uint80 decompressedLen = 123; + uint16 imageCount = 456; + vm.expectCall(address(art), abi.encodeCall(art.addAccessories, (someBytes, decompressedLen, imageCount))); + descriptor.addAccessories(someBytes, decompressedLen, imageCount); + } + + function testCannotAddAccessoriesWhenPartsLocked() public { + descriptor.lockParts(); + vm.expectRevert(bytes('Parts are locked')); + descriptor.addAccessories('00', 1, 1); + } + + function testAddHeadsUsesArt() public { + bytes memory someBytes = 'some bytes'; + uint80 decompressedLen = 123; + uint16 imageCount = 456; + vm.expectCall(address(art), abi.encodeCall(art.addHeads, (someBytes, decompressedLen, imageCount))); + descriptor.addHeads(someBytes, decompressedLen, imageCount); + } + + function testCannotAddHeadsWhenPartsLocked() public { + descriptor.lockParts(); + vm.expectRevert(bytes('Parts are locked')); + descriptor.addHeads('00', 1, 1); + } + + function testAddGlassesUsesArt() public { + bytes memory someBytes = 'some bytes'; + uint80 decompressedLen = 123; + uint16 imageCount = 456; + vm.expectCall(address(art), abi.encodeCall(art.addGlasses, (someBytes, decompressedLen, imageCount))); + descriptor.addGlasses(someBytes, decompressedLen, imageCount); + } + + function testCannotAddGlassesWhenPartsLocked() public { + descriptor.lockParts(); + vm.expectRevert(bytes('Parts are locked')); + descriptor.addGlasses('00', 1, 1); + } + + function testAddBodiesFromPointerUsesArt() public { + address somePointer = address(1337); + uint80 decompressedLen = 123; + uint16 imageCount = 456; + vm.expectCall( + address(art), + abi.encodeCall(art.addBodiesFromPointer, (somePointer, decompressedLen, imageCount)) + ); + descriptor.addBodiesFromPointer(somePointer, decompressedLen, imageCount); + } + + function testCannotAddBodiesFromPointerWhenPartsLocked() public { + descriptor.lockParts(); + vm.expectRevert(bytes('Parts are locked')); + descriptor.addBodiesFromPointer(address(1337), 1, 1); + } + + function testAddAccessoriesFromPointerUsesArt() public { + address somePointer = address(1337); + uint80 decompressedLen = 123; + uint16 imageCount = 456; + vm.expectCall( + address(art), + abi.encodeCall(art.addAccessoriesFromPointer, (somePointer, decompressedLen, imageCount)) + ); + descriptor.addAccessoriesFromPointer(somePointer, decompressedLen, imageCount); + } + + function testCannotAddAccessoriesFromPointerWhenPartsLocked() public { + descriptor.lockParts(); + vm.expectRevert(bytes('Parts are locked')); + descriptor.addAccessoriesFromPointer(address(1337), 1, 1); + } + + function testAddHeadsFromPointerUsesArt() public { + address somePointer = address(1337); + uint80 decompressedLen = 123; + uint16 imageCount = 456; + vm.expectCall( + address(art), + abi.encodeCall(art.addHeadsFromPointer, (somePointer, decompressedLen, imageCount)) + ); + descriptor.addHeadsFromPointer(somePointer, decompressedLen, imageCount); + } + + function testCannotAddHeadsFromPointerWhenPartsLocked() public { + descriptor.lockParts(); + vm.expectRevert(bytes('Parts are locked')); + descriptor.addHeadsFromPointer(address(1337), 1, 1); + } + + function testAddGlassesFromPointerUsesArt() public { + address somePointer = address(1337); + uint80 decompressedLen = 123; + uint16 imageCount = 456; + vm.expectCall( + address(art), + abi.encodeCall(art.addGlassesFromPointer, (somePointer, decompressedLen, imageCount)) + ); + descriptor.addGlassesFromPointer(somePointer, decompressedLen, imageCount); + } + + function testCannotAddGlassesFromPointerWhenPartsLocked() public { + descriptor.lockParts(); + vm.expectRevert(bytes('Parts are locked')); + descriptor.addGlassesFromPointer(address(1337), 1, 1); + } + + function testBackgroundsUsesArt() public { + vm.mockCall( + address(art), + abi.encodeWithSelector(INounsArt.backgrounds.selector, 17), + abi.encode('return value') + ); + assertEq(descriptor.backgrounds(17), 'return value'); + vm.clearMockedCalls(); + } + + function testHeadsUsesArt() public { + vm.mockCall(address(art), abi.encodeWithSelector(INounsArt.heads.selector, 17), abi.encode('return value')); + assertEq(descriptor.heads(17), 'return value'); + vm.clearMockedCalls(); + } + + function testBodiesUsesArt() public { + vm.mockCall(address(art), abi.encodeWithSelector(INounsArt.bodies.selector, 17), abi.encode('return value')); + assertEq(descriptor.bodies(17), 'return value'); + vm.clearMockedCalls(); + } + + function testAccessoriesUsesArt() public { + vm.mockCall( + address(art), + abi.encodeWithSelector(INounsArt.accessories.selector, 17), + abi.encode('return value') + ); + assertEq(descriptor.accessories(17), 'return value'); + vm.clearMockedCalls(); + } + + function testGlassesUsesArt() public { + vm.mockCall(address(art), abi.encodeWithSelector(INounsArt.glasses.selector, 17), abi.encode('return value')); + assertEq(descriptor.glasses(17), 'return value'); + vm.clearMockedCalls(); + } + + function testPalettesUsesArt() public { + vm.mockCall(address(art), abi.encodeWithSelector(INounsArt.palettes.selector, 17), abi.encode('return value')); + assertEq(descriptor.palettes(17), 'return value'); + vm.clearMockedCalls(); + } + + function testGetPartsForSeedWorks() public { + vm.mockCall(address(art), abi.encodeWithSelector(INounsArt.bodies.selector), abi.encode('the body')); + vm.mockCall(address(art), abi.encodeWithSelector(INounsArt.accessories.selector), abi.encode('the accessory')); + vm.mockCall(address(art), abi.encodeWithSelector(INounsArt.heads.selector), abi.encode('the head')); + vm.mockCall(address(art), abi.encodeWithSelector(INounsArt.glasses.selector), abi.encode('the glasses')); + vm.mockCall(address(art), abi.encodeWithSelector(INounsArt.palettes.selector), abi.encode('the palette')); + + ISVGRenderer.Part[] memory parts = descriptor.getPartsForSeed(INounsSeeder.Seed(0, 0, 0, 0, 0)); + + assertEq(parts[0].image, 'the body'); + assertEq(parts[0].palette, 'the palette'); + + assertEq(parts[1].image, 'the accessory'); + assertEq(parts[1].palette, 'the palette'); + + assertEq(parts[2].image, 'the head'); + assertEq(parts[2].palette, 'the palette'); + + assertEq(parts[3].image, 'the glasses'); + assertEq(parts[3].palette, 'the palette'); + } + + function _makeArtGettersNotRevert() internal { + vm.mockCall(address(art), abi.encodeWithSelector(NounsArt.backgroundsCount.selector), abi.encode(123)); + vm.mockCall(address(art), abi.encodeWithSelector(INounsArt.backgrounds.selector), abi.encode('return value')); + vm.mockCall(address(art), abi.encodeWithSelector(INounsArt.bodies.selector), abi.encode('return value')); + vm.mockCall(address(art), abi.encodeWithSelector(INounsArt.accessories.selector), abi.encode('return value')); + vm.mockCall(address(art), abi.encodeWithSelector(INounsArt.heads.selector), abi.encode('return value')); + vm.mockCall(address(art), abi.encodeWithSelector(INounsArt.glasses.selector), abi.encode('return value')); + vm.mockCall(address(art), abi.encodeWithSelector(INounsArt.palettes.selector), abi.encode('return value')); + } } From 60cf4669c96af7bf237335be2ec46bcea7df4194 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Thu, 30 Jun 2022 10:11:31 -0500 Subject: [PATCH 032/116] remove redundant art functions --- .../nouns-contracts/contracts/NounsArt.sol | 56 ---------------- .../contracts/interfaces/INounsArt.sol | 16 ----- .../test/foundry/NounsArt.t.sol | 64 ++----------------- 3 files changed, 4 insertions(+), 132 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsArt.sol b/packages/nouns-contracts/contracts/NounsArt.sol index 4411a3a40a..e48d0d8365 100644 --- a/packages/nouns-contracts/contracts/NounsArt.sol +++ b/packages/nouns-contracts/contracts/NounsArt.sol @@ -289,62 +289,6 @@ contract NounsArt is INounsArt { return backgrounds.length; } - /** - * @notice Get the number of heads storage pages. - */ - function headsPageCount() public view override returns (uint256) { - return _heads.storagePages.length; - } - - /** - * @notice Get the number of bodies storage pages. - */ - function bodiesPageCount() public view override returns (uint256) { - return _bodies.storagePages.length; - } - - /** - * @notice Get the number of accessories storage pages. - */ - function accessoriesPageCount() public view override returns (uint256) { - return _accessories.storagePages.length; - } - - /** - * @notice Get the number of glasses storage pages. - */ - function glassesPageCount() public view override returns (uint256) { - return _glasses.storagePages.length; - } - - /** - * @notice Get a storage page of head images. - */ - function headsPage(uint256 pageIndex) public view override returns (INounsArt.NounArtStoragePage memory) { - return _heads.storagePages[pageIndex]; - } - - /** - * @notice Get a storage page of body images. - */ - function bodiesPage(uint256 pageIndex) public view override returns (INounsArt.NounArtStoragePage memory) { - return _bodies.storagePages[pageIndex]; - } - - /** - * @notice Get a storage page of accessory images. - */ - function accessoriesPage(uint256 pageIndex) public view override returns (INounsArt.NounArtStoragePage memory) { - return _accessories.storagePages[pageIndex]; - } - - /** - * @notice Get a storage page of glasses images. - */ - function glassesPage(uint256 pageIndex) public view override returns (INounsArt.NounArtStoragePage memory) { - return _glasses.storagePages[pageIndex]; - } - /** * @notice Get a head image bytes (RLE-encoded). */ diff --git a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol index e54163f7f0..4db6532ab8 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol @@ -115,22 +115,6 @@ interface INounsArt { function backgroundsCount() external view returns (uint256); - function headsPageCount() external view returns (uint256); - - function bodiesPageCount() external view returns (uint256); - - function accessoriesPageCount() external view returns (uint256); - - function glassesPageCount() external view returns (uint256); - - function headsPage(uint256 pageIndex) external view returns (INounsArt.NounArtStoragePage memory); - - function bodiesPage(uint256 pageIndex) external view returns (INounsArt.NounArtStoragePage memory); - - function accessoriesPage(uint256 pageIndex) external view returns (INounsArt.NounArtStoragePage memory); - - function glassesPage(uint256 pageIndex) external view returns (INounsArt.NounArtStoragePage memory); - function backgrounds(uint256 index) external view returns (string memory); function heads(uint256 index) external view returns (bytes memory); diff --git a/packages/nouns-contracts/test/foundry/NounsArt.t.sol b/packages/nouns-contracts/test/foundry/NounsArt.t.sol index 581923f409..461fe3f39e 100644 --- a/packages/nouns-contracts/test/foundry/NounsArt.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsArt.t.sol @@ -173,7 +173,7 @@ contract NounsArtTest is Test, Utils { } /// - /// addBodies, addBodiesFromPointer, bodiesPageCount, bodiesPage, bodies, bodiesTrait + /// addBodies, addBodiesFromPointer, bodies, bodiesTrait /// function testAddBodiesRevertsIfSenderNotDescriptor() public { @@ -201,7 +201,6 @@ contract NounsArtTest is Test, Utils { function testAddBodiesWorksWithMultiplePages() public { assertEq(art.bodiesTrait().storedImagesCount, 0); - assertEq(art.bodiesPageCount(), 0); vm.startPrank(descriptor); art.addBodies(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); @@ -227,7 +226,6 @@ contract NounsArtTest is Test, Utils { function testAddBodiesFromPointerWorksWithMultiplePages() public { assertEq(art.bodiesTrait().storedImagesCount, 0); - assertEq(art.bodiesPageCount(), 0); vm.startPrank(descriptor); art.addBodiesFromPointer( @@ -246,7 +244,7 @@ contract NounsArtTest is Test, Utils { } /// - /// addAccessories, addAccessoriesFromPointer, accessoriesPageCount, accessoriesPage, accessories, accessoriesTrait + /// addAccessories, addAccessoriesFromPointer, accessories, accessoriesTrait /// function testAddAccessoriesRevertsIfSenderNotDescriptor() public { @@ -274,7 +272,6 @@ contract NounsArtTest is Test, Utils { function testAddAccessoriesWorksWithMultiplePages() public { assertEq(art.accessoriesTrait().storedImagesCount, 0); - assertEq(art.accessoriesPageCount(), 0); vm.startPrank(descriptor); art.addAccessories(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); @@ -300,7 +297,6 @@ contract NounsArtTest is Test, Utils { function testAddAccessoriesFromPointerWorksWithMultiplePages() public { assertEq(art.accessoriesTrait().storedImagesCount, 0); - assertEq(art.accessoriesPageCount(), 0); vm.startPrank(descriptor); art.addAccessoriesFromPointer( @@ -319,7 +315,7 @@ contract NounsArtTest is Test, Utils { } /// - /// addHeads, addHeadsFromPointer, headsPageCount, headsPage, heads, headsTrait + /// addHeads, addHeadsFromPointer, heads, headsTrait /// function testAddHeadsRevertsIfSenderNotDescriptor() public { @@ -347,7 +343,6 @@ contract NounsArtTest is Test, Utils { function testAddHeadsWorksWithMultiplePages() public { assertEq(art.headsTrait().storedImagesCount, 0); - assertEq(art.headsPageCount(), 0); vm.startPrank(descriptor); art.addHeads(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); @@ -373,7 +368,6 @@ contract NounsArtTest is Test, Utils { function testAddHeadsFromPointerWorksWithMultiplePages() public { assertEq(art.headsTrait().storedImagesCount, 0); - assertEq(art.headsPageCount(), 0); vm.startPrank(descriptor); art.addHeadsFromPointer( @@ -392,7 +386,7 @@ contract NounsArtTest is Test, Utils { } /// - /// addGlasses, addGlassesFromPointer, glassesPageCount, glassesPage, glasses, glassesTrait + /// addGlasses, addGlassesFromPointer, glasses, glassesTrait /// function testAddGlassesRevertsIfSenderNotDescriptor() public { @@ -420,7 +414,6 @@ contract NounsArtTest is Test, Utils { function testAddGlassesWorksWithMultiplePages() public { assertEq(art.glassesTrait().storedImagesCount, 0); - assertEq(art.glassesPageCount(), 0); vm.startPrank(descriptor); art.addGlasses(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); @@ -446,7 +439,6 @@ contract NounsArtTest is Test, Utils { function testAddGlassesFromPointerWorksWithMultiplePages() public { assertEq(art.headsTrait().storedImagesCount, 0); - assertEq(art.glassesPageCount(), 0); vm.startPrank(descriptor); art.addGlassesFromPointer( @@ -469,18 +461,6 @@ contract NounsArtTest is Test, Utils { /// function _assertBodiesStoredOK() internal { - assertEq(art.bodiesPageCount(), 2); - - INounsArt.NounArtStoragePage memory page = art.bodiesPage(0); - assertEq(page.imageCount, 2); - assertEq(page.decompressedLength, FIRST_TWO_IMAGES_DEFLATED_LENGTH); - assertEq(SSTORE2.read(page.pointer), fromHex(FIRST_TWO_IMAGES_COMPRESSED)); - - page = art.bodiesPage(1); - assertEq(page.imageCount, 2); - assertEq(page.decompressedLength, NEXT_TWO_IMAGES_DEFLATED_LENGTH); - assertEq(SSTORE2.read(page.pointer), fromHex(NEXT_TWO_IMAGES_COMPRESSED)); - assertEq(art.bodiesTrait().storedImagesCount, 4); // These hard-coded values are copied from image-data.json -> images -> BODIES -> the first items @@ -493,18 +473,6 @@ contract NounsArtTest is Test, Utils { } function _assertAccessoriesStoredOK() internal { - assertEq(art.accessoriesPageCount(), 2); - - INounsArt.NounArtStoragePage memory page = art.accessoriesPage(0); - assertEq(page.imageCount, 2); - assertEq(page.decompressedLength, FIRST_TWO_IMAGES_DEFLATED_LENGTH); - assertEq(SSTORE2.read(page.pointer), fromHex(FIRST_TWO_IMAGES_COMPRESSED)); - - page = art.accessoriesPage(1); - assertEq(page.imageCount, 2); - assertEq(page.decompressedLength, NEXT_TWO_IMAGES_DEFLATED_LENGTH); - assertEq(SSTORE2.read(page.pointer), fromHex(NEXT_TWO_IMAGES_COMPRESSED)); - assertEq(art.accessoriesTrait().storedImagesCount, 4); // These hard-coded values are copied from image-data.json -> images -> BODIES -> the first items @@ -517,18 +485,6 @@ contract NounsArtTest is Test, Utils { } function _assertHeadsStoredOK() internal { - assertEq(art.headsPageCount(), 2); - - INounsArt.NounArtStoragePage memory page = art.headsPage(0); - assertEq(page.imageCount, 2); - assertEq(page.decompressedLength, FIRST_TWO_IMAGES_DEFLATED_LENGTH); - assertEq(SSTORE2.read(page.pointer), fromHex(FIRST_TWO_IMAGES_COMPRESSED)); - - page = art.headsPage(1); - assertEq(page.imageCount, 2); - assertEq(page.decompressedLength, NEXT_TWO_IMAGES_DEFLATED_LENGTH); - assertEq(SSTORE2.read(page.pointer), fromHex(NEXT_TWO_IMAGES_COMPRESSED)); - assertEq(art.headsTrait().storedImagesCount, 4); // These hard-coded values are copied from image-data.json -> images -> BODIES -> the first items @@ -541,18 +497,6 @@ contract NounsArtTest is Test, Utils { } function _assertGlassesStoredOK() internal { - assertEq(art.glassesPageCount(), 2); - - INounsArt.NounArtStoragePage memory page = art.glassesPage(0); - assertEq(page.imageCount, 2); - assertEq(page.decompressedLength, FIRST_TWO_IMAGES_DEFLATED_LENGTH); - assertEq(SSTORE2.read(page.pointer), fromHex(FIRST_TWO_IMAGES_COMPRESSED)); - - page = art.glassesPage(1); - assertEq(page.imageCount, 2); - assertEq(page.decompressedLength, NEXT_TWO_IMAGES_DEFLATED_LENGTH); - assertEq(SSTORE2.read(page.pointer), fromHex(NEXT_TWO_IMAGES_COMPRESSED)); - assertEq(art.glassesTrait().storedImagesCount, 4); // These hard-coded values are copied from image-data.json -> images -> BODIES -> the first items From cf922a108188b5b3af04437711cd80da2ac85297 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Thu, 30 Jun 2022 10:14:39 -0500 Subject: [PATCH 033/116] inflate: add dev natspec --- .../contracts/libs/Inflate.sol | 1712 ++++++++--------- 1 file changed, 829 insertions(+), 883 deletions(-) diff --git a/packages/nouns-contracts/contracts/libs/Inflate.sol b/packages/nouns-contracts/contracts/libs/Inflate.sol index f65c31ff0e..80e408caad 100644 --- a/packages/nouns-contracts/contracts/libs/Inflate.sol +++ b/packages/nouns-contracts/contracts/libs/Inflate.sol @@ -2,923 +2,869 @@ pragma solidity >=0.8.0 <0.9.0; /// @notice Based on https://github.com/madler/zlib/blob/master/contrib/puff +/// @dev Modified the original code for gas optimizations +/// 1. Disable overflow/underflow checks +/// 2. Chunk some loop iterations library Inflate { - // Maximum bits in a code - uint256 constant MAXBITS = 15; - // Maximum number of literal/length codes - uint256 constant MAXLCODES = 286; - // Maximum number of distance codes - uint256 constant MAXDCODES = 30; - // Maximum codes lengths to read - uint256 constant MAXCODES = (MAXLCODES + MAXDCODES); - // Number of fixed literal/length codes - uint256 constant FIXLCODES = 288; - - // Error codes - enum ErrorCode { - ERR_NONE, // 0 successful inflate - ERR_NOT_TERMINATED, // 1 available inflate data did not terminate - ERR_OUTPUT_EXHAUSTED, // 2 output space exhausted before completing inflate - ERR_INVALID_BLOCK_TYPE, // 3 invalid block type (type == 3) - ERR_STORED_LENGTH_NO_MATCH, // 4 stored block length did not match one's complement - ERR_TOO_MANY_LENGTH_OR_DISTANCE_CODES, // 5 dynamic block code description: too many length or distance codes - ERR_CODE_LENGTHS_CODES_INCOMPLETE, // 6 dynamic block code description: code lengths codes incomplete - ERR_REPEAT_NO_FIRST_LENGTH, // 7 dynamic block code description: repeat lengths with no first length - ERR_REPEAT_MORE, // 8 dynamic block code description: repeat more than specified lengths - ERR_INVALID_LITERAL_LENGTH_CODE_LENGTHS, // 9 dynamic block code description: invalid literal/length code lengths - ERR_INVALID_DISTANCE_CODE_LENGTHS, // 10 dynamic block code description: invalid distance code lengths - ERR_MISSING_END_OF_BLOCK, // 11 dynamic block code description: missing end-of-block code - ERR_INVALID_LENGTH_OR_DISTANCE_CODE, // 12 invalid literal/length or distance code in fixed or dynamic block - ERR_DISTANCE_TOO_FAR, // 13 distance is too far back in fixed or dynamic block - ERR_CONSTRUCT // 14 internal: error in construct() - } - - // Input and output state - struct State { - ////////////////// - // Output state // - ////////////////// - // Output buffer - bytes output; - // Bytes written to out so far - uint256 outcnt; - ///////////////// - // Input state // - ///////////////// - // Input buffer - bytes input; - // Bytes read so far - uint256 incnt; - //////////////// - // Temp state // - //////////////// - // Bit buffer - uint256 bitbuf; - // Number of bits in bit buffer - uint256 bitcnt; - ////////////////////////// - // Static Huffman codes // - ////////////////////////// - Huffman lencode; - Huffman distcode; - } - - // Huffman code decoding tables - struct Huffman { - uint256[] counts; - uint256[] symbols; - } - - function bits(State memory s, uint256 need) - private - pure - returns (ErrorCode, uint256) - { - unchecked { - // Bit accumulator (can use up to 20 bits) - uint256 val; - - // Load at least need bits into val - val = s.bitbuf; - while (s.bitcnt < need) { - if (s.incnt == s.input.length) { - // Out of input - return (ErrorCode.ERR_NOT_TERMINATED, 0); - } - - // Load eight bits - val |= uint256(uint8(s.input[s.incnt++])) << s.bitcnt; - s.bitcnt += 8; - } - - // Drop need bits and update buffer, always zero to seven bits left - s.bitbuf = val >> need; - s.bitcnt -= need; + // Maximum bits in a code + uint256 constant MAXBITS = 15; + // Maximum number of literal/length codes + uint256 constant MAXLCODES = 286; + // Maximum number of distance codes + uint256 constant MAXDCODES = 30; + // Maximum codes lengths to read + uint256 constant MAXCODES = (MAXLCODES + MAXDCODES); + // Number of fixed literal/length codes + uint256 constant FIXLCODES = 288; + + // Error codes + enum ErrorCode { + ERR_NONE, // 0 successful inflate + ERR_NOT_TERMINATED, // 1 available inflate data did not terminate + ERR_OUTPUT_EXHAUSTED, // 2 output space exhausted before completing inflate + ERR_INVALID_BLOCK_TYPE, // 3 invalid block type (type == 3) + ERR_STORED_LENGTH_NO_MATCH, // 4 stored block length did not match one's complement + ERR_TOO_MANY_LENGTH_OR_DISTANCE_CODES, // 5 dynamic block code description: too many length or distance codes + ERR_CODE_LENGTHS_CODES_INCOMPLETE, // 6 dynamic block code description: code lengths codes incomplete + ERR_REPEAT_NO_FIRST_LENGTH, // 7 dynamic block code description: repeat lengths with no first length + ERR_REPEAT_MORE, // 8 dynamic block code description: repeat more than specified lengths + ERR_INVALID_LITERAL_LENGTH_CODE_LENGTHS, // 9 dynamic block code description: invalid literal/length code lengths + ERR_INVALID_DISTANCE_CODE_LENGTHS, // 10 dynamic block code description: invalid distance code lengths + ERR_MISSING_END_OF_BLOCK, // 11 dynamic block code description: missing end-of-block code + ERR_INVALID_LENGTH_OR_DISTANCE_CODE, // 12 invalid literal/length or distance code in fixed or dynamic block + ERR_DISTANCE_TOO_FAR, // 13 distance is too far back in fixed or dynamic block + ERR_CONSTRUCT // 14 internal: error in construct() + } - // Return need bits, zeroing the bits above that - uint256 ret = (val & ((1 << need) - 1)); - return (ErrorCode.ERR_NONE, ret); + // Input and output state + struct State { + ////////////////// + // Output state // + ////////////////// + // Output buffer + bytes output; + // Bytes written to out so far + uint256 outcnt; + ///////////////// + // Input state // + ///////////////// + // Input buffer + bytes input; + // Bytes read so far + uint256 incnt; + //////////////// + // Temp state // + //////////////// + // Bit buffer + uint256 bitbuf; + // Number of bits in bit buffer + uint256 bitcnt; + ////////////////////////// + // Static Huffman codes // + ////////////////////////// + Huffman lencode; + Huffman distcode; } - } - - function _stored(State memory s) private pure returns (ErrorCode) { - unchecked { - // Length of stored block - uint256 len; - - // Discard leftover bits from current byte (assumes s.bitcnt < 8) - s.bitbuf = 0; - s.bitcnt = 0; - - // Get length and check against its one's complement - if (s.incnt + 4 > s.input.length) { - // Not enough input - return ErrorCode.ERR_NOT_TERMINATED; - } - len = uint256(uint8(s.input[s.incnt++])); - len |= uint256(uint8(s.input[s.incnt++])) << 8; - - if ( - uint8(s.input[s.incnt++]) != (~len & 0xFF) || - uint8(s.input[s.incnt++]) != ((~len >> 8) & 0xFF) - ) { - // Didn't match complement! - return ErrorCode.ERR_STORED_LENGTH_NO_MATCH; - } - - // Copy len bytes from in to out - if (s.incnt + len > s.input.length) { - // Not enough input - return ErrorCode.ERR_NOT_TERMINATED; - } - if (s.outcnt + len > s.output.length) { - // Not enough output space - return ErrorCode.ERR_OUTPUT_EXHAUSTED; - } - while (len != 0) { - // Note: Solidity reverts on underflow, so we decrement here - len -= 1; - s.output[s.outcnt++] = s.input[s.incnt++]; - } - - // Done with a valid stored block - return ErrorCode.ERR_NONE; + + // Huffman code decoding tables + struct Huffman { + uint256[] counts; + uint256[] symbols; } - } - - function _decode(State memory s, Huffman memory h) - private - pure - returns (ErrorCode, uint256) - { - unchecked { - // Current number of bits in code - uint256 len; - // Len bits being decoded - uint256 code = 0; - // First code of length len - uint256 first = 0; - // Number of codes of length len - uint256 count; - // Index of first code of length len in symbol table - uint256 index = 0; - // Error code - ErrorCode err; - - uint256 tempCode; - for (len = 1; len <= MAXBITS; len += 5) { - // Get next bit - (err, tempCode) = bits(s, 1); - if (err != ErrorCode.ERR_NONE) { - return (err, 0); - } - code |= tempCode; - count = h.counts[len]; - // If length len, return symbol - if (code < first + count) { - return (ErrorCode.ERR_NONE, h.symbols[index + (code - first)]); - } - // Else update for next length - index += count; - first += count; - first <<= 1; - code <<= 1; - - // Get next bit - (err, tempCode) = bits(s, 1); - if (err != ErrorCode.ERR_NONE) { - return (err, 0); - } - code |= tempCode; - count = h.counts[len + 1]; + function bits(State memory s, uint256 need) private pure returns (ErrorCode, uint256) { + unchecked { + // Bit accumulator (can use up to 20 bits) + uint256 val; + + // Load at least need bits into val + val = s.bitbuf; + while (s.bitcnt < need) { + if (s.incnt == s.input.length) { + // Out of input + return (ErrorCode.ERR_NOT_TERMINATED, 0); + } + + // Load eight bits + val |= uint256(uint8(s.input[s.incnt++])) << s.bitcnt; + s.bitcnt += 8; + } - // If length len, return symbol - if (code < first + count) { - return (ErrorCode.ERR_NONE, h.symbols[index + (code - first)]); - } - // Else update for next length - index += count; - first += count; - first <<= 1; - code <<= 1; - - // Get next bit - (err, tempCode) = bits(s, 1); - if (err != ErrorCode.ERR_NONE) { - return (err, 0); - } - code |= tempCode; - count = h.counts[len + 2]; + // Drop need bits and update buffer, always zero to seven bits left + s.bitbuf = val >> need; + s.bitcnt -= need; - // If length len, return symbol - if (code < first + count) { - return (ErrorCode.ERR_NONE, h.symbols[index + (code - first)]); - } - // Else update for next length - index += count; - first += count; - first <<= 1; - code <<= 1; - - // Get next bit - (err, tempCode) = bits(s, 1); - if (err != ErrorCode.ERR_NONE) { - return (err, 0); + // Return need bits, zeroing the bits above that + uint256 ret = (val & ((1 << need) - 1)); + return (ErrorCode.ERR_NONE, ret); } - code |= tempCode; - count = h.counts[len + 3]; + } - // If length len, return symbol - if (code < first + count) { - return (ErrorCode.ERR_NONE, h.symbols[index + (code - first)]); - } - // Else update for next length - index += count; - first += count; - first <<= 1; - code <<= 1; - - // Get next bit - (err, tempCode) = bits(s, 1); - if (err != ErrorCode.ERR_NONE) { - return (err, 0); - } - code |= tempCode; - count = h.counts[len + 4]; + function _stored(State memory s) private pure returns (ErrorCode) { + unchecked { + // Length of stored block + uint256 len; + + // Discard leftover bits from current byte (assumes s.bitcnt < 8) + s.bitbuf = 0; + s.bitcnt = 0; + + // Get length and check against its one's complement + if (s.incnt + 4 > s.input.length) { + // Not enough input + return ErrorCode.ERR_NOT_TERMINATED; + } + len = uint256(uint8(s.input[s.incnt++])); + len |= uint256(uint8(s.input[s.incnt++])) << 8; + + if (uint8(s.input[s.incnt++]) != (~len & 0xFF) || uint8(s.input[s.incnt++]) != ((~len >> 8) & 0xFF)) { + // Didn't match complement! + return ErrorCode.ERR_STORED_LENGTH_NO_MATCH; + } + + // Copy len bytes from in to out + if (s.incnt + len > s.input.length) { + // Not enough input + return ErrorCode.ERR_NOT_TERMINATED; + } + if (s.outcnt + len > s.output.length) { + // Not enough output space + return ErrorCode.ERR_OUTPUT_EXHAUSTED; + } + while (len != 0) { + // Note: Solidity reverts on underflow, so we decrement here + len -= 1; + s.output[s.outcnt++] = s.input[s.incnt++]; + } - // If length len, return symbol - if (code < first + count) { - return (ErrorCode.ERR_NONE, h.symbols[index + (code - first)]); + // Done with a valid stored block + return ErrorCode.ERR_NONE; } - // Else update for next length - index += count; - first += count; - first <<= 1; - code <<= 1; - } - - // Ran out of codes - return (ErrorCode.ERR_INVALID_LENGTH_OR_DISTANCE_CODE, 0); } - } - - function _construct( - Huffman memory h, - uint256[] memory lengths, - uint256 n, - uint256 start - ) private pure returns (ErrorCode) { - unchecked { - // Current symbol when stepping through lengths[] - uint256 symbol; - // Current length when stepping through h.counts[] - uint256 len; - // Number of possible codes left of current length - uint256 left; - // Offsets in symbol table for each length - uint256[MAXBITS + 1] memory offs; - - // Count number of codes of each length - for (len = 0; len <= MAXBITS; ++len) { - h.counts[len] = 0; - } - for (symbol = 0; symbol < n; ++symbol) { - // Assumes lengths are within bounds - ++h.counts[lengths[start + symbol]]; - } - // No codes! - if (h.counts[0] == n) { - // Complete, but decode() will fail - return (ErrorCode.ERR_NONE); - } - - // Check for an over-subscribed or incomplete set of lengths - - // One possible code of zero length - left = 1; - - for (len = 1; len <= MAXBITS; len += 5) { - // One more bit, double codes left - left <<= 1; - if (left < h.counts[len]) { - // Over-subscribed--return error - return ErrorCode.ERR_CONSTRUCT; - } - // Deduct count from possible codes - left -= h.counts[len]; - - // One more bit, double codes left - left <<= 1; - if (left < h.counts[len + 1]) { - // Over-subscribed--return error - return ErrorCode.ERR_CONSTRUCT; - } - // Deduct count from possible codes - left -= h.counts[len + 1]; - - // One more bit, double codes left - left <<= 1; - if (left < h.counts[len + 2]) { - // Over-subscribed--return error - return ErrorCode.ERR_CONSTRUCT; - } - // Deduct count from possible codes - left -= h.counts[len + 2]; - - // One more bit, double codes left - left <<= 1; - if (left < h.counts[len + 3]) { - // Over-subscribed--return error - return ErrorCode.ERR_CONSTRUCT; - } - // Deduct count from possible codes - left -= h.counts[len + 3]; - - // One more bit, double codes left - left <<= 1; - if (left < h.counts[len + 4]) { - // Over-subscribed--return error - return ErrorCode.ERR_CONSTRUCT; - } - // Deduct count from possible codes - left -= h.counts[len + 4]; - } - - // Generate offsets into symbol table for each length for sorting - offs[1] = 0; - for (len = 1; len < MAXBITS; ++len) { - offs[len + 1] = offs[len] + h.counts[len]; - } - - // Put symbols in table sorted by length, by symbol order within each length - for (symbol = 0; symbol < n; ++symbol) { - if (lengths[start + symbol] != 0) { - h.symbols[offs[lengths[start + symbol]]++] = symbol; - } - } - // Left > 0 means incomplete - return left > 0 ? ErrorCode.ERR_CONSTRUCT : ErrorCode.ERR_NONE; - } - } - - function _codes( - State memory s, - Huffman memory lencode, - Huffman memory distcode - ) private pure returns (ErrorCode) { - unchecked { - // Decoded symbol - uint256 symbol; - // Length for copy - uint256 len; - // Distance for copy - uint256 dist; - // TODO Solidity doesn't support constant arrays, but these are fixed at compile-time - // Size base for length codes 257..285 - uint16[29] memory lens = [ - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 13, - 15, - 17, - 19, - 23, - 27, - 31, - 35, - 43, - 51, - 59, - 67, - 83, - 99, - 115, - 131, - 163, - 195, - 227, - 258 - ]; - // Extra bits for length codes 257..285 - uint8[29] memory lext = [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 2, - 2, - 2, - 2, - 3, - 3, - 3, - 3, - 4, - 4, - 4, - 4, - 5, - 5, - 5, - 5, - 0 - ]; - // Offset base for distance codes 0..29 - uint16[30] memory dists = [ - 1, - 2, - 3, - 4, - 5, - 7, - 9, - 13, - 17, - 25, - 33, - 49, - 65, - 97, - 129, - 193, - 257, - 385, - 513, - 769, - 1025, - 1537, - 2049, - 3073, - 4097, - 6145, - 8193, - 12289, - 16385, - 24577 - ]; - // Extra bits for distance codes 0..29 - uint8[30] memory dext = [ - 0, - 0, - 0, - 0, - 1, - 1, - 2, - 2, - 3, - 3, - 4, - 4, - 5, - 5, - 6, - 6, - 7, - 7, - 8, - 8, - 9, - 9, - 10, - 10, - 11, - 11, - 12, - 12, - 13, - 13 - ]; - // Error code - ErrorCode err; - - // Decode literals and length/distance pairs - while (symbol != 256) { - (err, symbol) = _decode(s, lencode); - if (err != ErrorCode.ERR_NONE) { - // Invalid symbol - return err; - } + function _decode(State memory s, Huffman memory h) private pure returns (ErrorCode, uint256) { + unchecked { + // Current number of bits in code + uint256 len; + // Len bits being decoded + uint256 code = 0; + // First code of length len + uint256 first = 0; + // Number of codes of length len + uint256 count; + // Index of first code of length len in symbol table + uint256 index = 0; + // Error code + ErrorCode err; + + uint256 tempCode; + for (len = 1; len <= MAXBITS; len += 5) { + // Get next bit + (err, tempCode) = bits(s, 1); + if (err != ErrorCode.ERR_NONE) { + return (err, 0); + } + code |= tempCode; + count = h.counts[len]; + + // If length len, return symbol + if (code < first + count) { + return (ErrorCode.ERR_NONE, h.symbols[index + (code - first)]); + } + // Else update for next length + index += count; + first += count; + first <<= 1; + code <<= 1; + + // Get next bit + (err, tempCode) = bits(s, 1); + if (err != ErrorCode.ERR_NONE) { + return (err, 0); + } + code |= tempCode; + count = h.counts[len + 1]; + + // If length len, return symbol + if (code < first + count) { + return (ErrorCode.ERR_NONE, h.symbols[index + (code - first)]); + } + // Else update for next length + index += count; + first += count; + first <<= 1; + code <<= 1; + + // Get next bit + (err, tempCode) = bits(s, 1); + if (err != ErrorCode.ERR_NONE) { + return (err, 0); + } + code |= tempCode; + count = h.counts[len + 2]; + + // If length len, return symbol + if (code < first + count) { + return (ErrorCode.ERR_NONE, h.symbols[index + (code - first)]); + } + // Else update for next length + index += count; + first += count; + first <<= 1; + code <<= 1; + + // Get next bit + (err, tempCode) = bits(s, 1); + if (err != ErrorCode.ERR_NONE) { + return (err, 0); + } + code |= tempCode; + count = h.counts[len + 3]; + + // If length len, return symbol + if (code < first + count) { + return (ErrorCode.ERR_NONE, h.symbols[index + (code - first)]); + } + // Else update for next length + index += count; + first += count; + first <<= 1; + code <<= 1; + + // Get next bit + (err, tempCode) = bits(s, 1); + if (err != ErrorCode.ERR_NONE) { + return (err, 0); + } + code |= tempCode; + count = h.counts[len + 4]; + + // If length len, return symbol + if (code < first + count) { + return (ErrorCode.ERR_NONE, h.symbols[index + (code - first)]); + } + // Else update for next length + index += count; + first += count; + first <<= 1; + code <<= 1; + } - if (symbol < 256) { - // Literal: symbol is the byte - // Write out the literal - if (s.outcnt == s.output.length) { - return ErrorCode.ERR_OUTPUT_EXHAUSTED; - } - s.output[s.outcnt] = bytes1(uint8(symbol)); - ++s.outcnt; - } else if (symbol > 256) { - uint256 tempBits; - // Length - // Get and compute length - symbol -= 257; - if (symbol >= 29) { - // Invalid fixed code - return ErrorCode.ERR_INVALID_LENGTH_OR_DISTANCE_CODE; - } - - (err, tempBits) = bits(s, lext[symbol]); - if (err != ErrorCode.ERR_NONE) { - return err; - } - len = lens[symbol] + tempBits; - - // Get and check distance - (err, symbol) = _decode(s, distcode); - if (err != ErrorCode.ERR_NONE) { - // Invalid symbol - return err; - } - (err, tempBits) = bits(s, dext[symbol]); - if (err != ErrorCode.ERR_NONE) { - return err; - } - dist = dists[symbol] + tempBits; - if (dist > s.outcnt) { - // Distance too far back - return ErrorCode.ERR_DISTANCE_TOO_FAR; - } - - // Copy length bytes from distance bytes back - if (s.outcnt + len > s.output.length) { - return ErrorCode.ERR_OUTPUT_EXHAUSTED; - } - while (len != 0) { - // Note: Solidity reverts on underflow, so we decrement here - len -= 1; - s.output[s.outcnt] = s.output[s.outcnt - dist]; - ++s.outcnt; - } - } else { - s.outcnt += len; + // Ran out of codes + return (ErrorCode.ERR_INVALID_LENGTH_OR_DISTANCE_CODE, 0); } - } - - // Done with a valid fixed or dynamic block - return ErrorCode.ERR_NONE; } - } - - function _build_fixed(State memory s) private pure returns (ErrorCode) { - unchecked { - // Build fixed Huffman tables - // TODO this is all a compile-time constant - uint256 symbol; - uint256[] memory lengths = new uint256[](FIXLCODES); - - // Literal/length table - for (symbol = 0; symbol < 144; ++symbol) { - lengths[symbol] = 8; - } - for (; symbol < 256; ++symbol) { - lengths[symbol] = 9; - } - for (; symbol < 280; ++symbol) { - lengths[symbol] = 7; - } - for (; symbol < FIXLCODES; ++symbol) { - lengths[symbol] = 8; - } - - _construct(s.lencode, lengths, FIXLCODES, 0); - - // Distance table - for (symbol = 0; symbol < MAXDCODES; ++symbol) { - lengths[symbol] = 5; - } - - _construct(s.distcode, lengths, MAXDCODES, 0); - - return ErrorCode.ERR_NONE; + + function _construct( + Huffman memory h, + uint256[] memory lengths, + uint256 n, + uint256 start + ) private pure returns (ErrorCode) { + unchecked { + // Current symbol when stepping through lengths[] + uint256 symbol; + // Current length when stepping through h.counts[] + uint256 len; + // Number of possible codes left of current length + uint256 left; + // Offsets in symbol table for each length + uint256[MAXBITS + 1] memory offs; + + // Count number of codes of each length + for (len = 0; len <= MAXBITS; ++len) { + h.counts[len] = 0; + } + for (symbol = 0; symbol < n; ++symbol) { + // Assumes lengths are within bounds + ++h.counts[lengths[start + symbol]]; + } + // No codes! + if (h.counts[0] == n) { + // Complete, but decode() will fail + return (ErrorCode.ERR_NONE); + } + + // Check for an over-subscribed or incomplete set of lengths + + // One possible code of zero length + left = 1; + + for (len = 1; len <= MAXBITS; len += 5) { + // One more bit, double codes left + left <<= 1; + if (left < h.counts[len]) { + // Over-subscribed--return error + return ErrorCode.ERR_CONSTRUCT; + } + // Deduct count from possible codes + left -= h.counts[len]; + + // One more bit, double codes left + left <<= 1; + if (left < h.counts[len + 1]) { + // Over-subscribed--return error + return ErrorCode.ERR_CONSTRUCT; + } + // Deduct count from possible codes + left -= h.counts[len + 1]; + + // One more bit, double codes left + left <<= 1; + if (left < h.counts[len + 2]) { + // Over-subscribed--return error + return ErrorCode.ERR_CONSTRUCT; + } + // Deduct count from possible codes + left -= h.counts[len + 2]; + + // One more bit, double codes left + left <<= 1; + if (left < h.counts[len + 3]) { + // Over-subscribed--return error + return ErrorCode.ERR_CONSTRUCT; + } + // Deduct count from possible codes + left -= h.counts[len + 3]; + + // One more bit, double codes left + left <<= 1; + if (left < h.counts[len + 4]) { + // Over-subscribed--return error + return ErrorCode.ERR_CONSTRUCT; + } + // Deduct count from possible codes + left -= h.counts[len + 4]; + } + + // Generate offsets into symbol table for each length for sorting + offs[1] = 0; + for (len = 1; len < MAXBITS; ++len) { + offs[len + 1] = offs[len] + h.counts[len]; + } + + // Put symbols in table sorted by length, by symbol order within each length + for (symbol = 0; symbol < n; ++symbol) { + if (lengths[start + symbol] != 0) { + h.symbols[offs[lengths[start + symbol]]++] = symbol; + } + } + + // Left > 0 means incomplete + return left > 0 ? ErrorCode.ERR_CONSTRUCT : ErrorCode.ERR_NONE; + } } - } - function _fixed(State memory s) private pure returns (ErrorCode) { - unchecked { - // Decode data until end-of-block code - return _codes(s, s.lencode, s.distcode); + function _codes( + State memory s, + Huffman memory lencode, + Huffman memory distcode + ) private pure returns (ErrorCode) { + unchecked { + // Decoded symbol + uint256 symbol; + // Length for copy + uint256 len; + // Distance for copy + uint256 dist; + // TODO Solidity doesn't support constant arrays, but these are fixed at compile-time + // Size base for length codes 257..285 + uint16[29] memory lens = [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 13, + 15, + 17, + 19, + 23, + 27, + 31, + 35, + 43, + 51, + 59, + 67, + 83, + 99, + 115, + 131, + 163, + 195, + 227, + 258 + ]; + // Extra bits for length codes 257..285 + uint8[29] memory lext = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 2, + 2, + 2, + 2, + 3, + 3, + 3, + 3, + 4, + 4, + 4, + 4, + 5, + 5, + 5, + 5, + 0 + ]; + // Offset base for distance codes 0..29 + uint16[30] memory dists = [ + 1, + 2, + 3, + 4, + 5, + 7, + 9, + 13, + 17, + 25, + 33, + 49, + 65, + 97, + 129, + 193, + 257, + 385, + 513, + 769, + 1025, + 1537, + 2049, + 3073, + 4097, + 6145, + 8193, + 12289, + 16385, + 24577 + ]; + // Extra bits for distance codes 0..29 + uint8[30] memory dext = [ + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 2, + 3, + 3, + 4, + 4, + 5, + 5, + 6, + 6, + 7, + 7, + 8, + 8, + 9, + 9, + 10, + 10, + 11, + 11, + 12, + 12, + 13, + 13 + ]; + // Error code + ErrorCode err; + + // Decode literals and length/distance pairs + while (symbol != 256) { + (err, symbol) = _decode(s, lencode); + if (err != ErrorCode.ERR_NONE) { + // Invalid symbol + return err; + } + + if (symbol < 256) { + // Literal: symbol is the byte + // Write out the literal + if (s.outcnt == s.output.length) { + return ErrorCode.ERR_OUTPUT_EXHAUSTED; + } + s.output[s.outcnt] = bytes1(uint8(symbol)); + ++s.outcnt; + } else if (symbol > 256) { + uint256 tempBits; + // Length + // Get and compute length + symbol -= 257; + if (symbol >= 29) { + // Invalid fixed code + return ErrorCode.ERR_INVALID_LENGTH_OR_DISTANCE_CODE; + } + + (err, tempBits) = bits(s, lext[symbol]); + if (err != ErrorCode.ERR_NONE) { + return err; + } + len = lens[symbol] + tempBits; + + // Get and check distance + (err, symbol) = _decode(s, distcode); + if (err != ErrorCode.ERR_NONE) { + // Invalid symbol + return err; + } + (err, tempBits) = bits(s, dext[symbol]); + if (err != ErrorCode.ERR_NONE) { + return err; + } + dist = dists[symbol] + tempBits; + if (dist > s.outcnt) { + // Distance too far back + return ErrorCode.ERR_DISTANCE_TOO_FAR; + } + + // Copy length bytes from distance bytes back + if (s.outcnt + len > s.output.length) { + return ErrorCode.ERR_OUTPUT_EXHAUSTED; + } + while (len != 0) { + // Note: Solidity reverts on underflow, so we decrement here + len -= 1; + s.output[s.outcnt] = s.output[s.outcnt - dist]; + ++s.outcnt; + } + } else { + s.outcnt += len; + } + } + + // Done with a valid fixed or dynamic block + return ErrorCode.ERR_NONE; + } } - } - - function _build_dynamic_lengths(State memory s) - private - pure - returns (ErrorCode, uint256[] memory) - { - unchecked { - uint256 ncode; - // Index of lengths[] - uint256 index; - // Descriptor code lengths - uint256[] memory lengths = new uint256[](MAXCODES); - // Error code - ErrorCode err; - // Permutation of code length codes - uint8[19] memory order = [ - 16, - 17, - 18, - 0, - 8, - 7, - 9, - 6, - 10, - 5, - 11, - 4, - 12, - 3, - 13, - 2, - 14, - 1, - 15 - ]; - - (err, ncode) = bits(s, 4); - if (err != ErrorCode.ERR_NONE) { - return (err, lengths); - } - ncode += 4; - - // Read code length code lengths (really), missing lengths are zero - for (index = 0; index < ncode; ++index) { - (err, lengths[order[index]]) = bits(s, 3); - if (err != ErrorCode.ERR_NONE) { - return (err, lengths); + + function _build_fixed(State memory s) private pure returns (ErrorCode) { + unchecked { + // Build fixed Huffman tables + // TODO this is all a compile-time constant + uint256 symbol; + uint256[] memory lengths = new uint256[](FIXLCODES); + + // Literal/length table + for (symbol = 0; symbol < 144; ++symbol) { + lengths[symbol] = 8; + } + for (; symbol < 256; ++symbol) { + lengths[symbol] = 9; + } + for (; symbol < 280; ++symbol) { + lengths[symbol] = 7; + } + for (; symbol < FIXLCODES; ++symbol) { + lengths[symbol] = 8; + } + + _construct(s.lencode, lengths, FIXLCODES, 0); + + // Distance table + for (symbol = 0; symbol < MAXDCODES; ++symbol) { + lengths[symbol] = 5; + } + + _construct(s.distcode, lengths, MAXDCODES, 0); + + return ErrorCode.ERR_NONE; } - } - for (; index < 19; ++index) { - lengths[order[index]] = 0; - } + } - return (ErrorCode.ERR_NONE, lengths); + function _fixed(State memory s) private pure returns (ErrorCode) { + unchecked { + // Decode data until end-of-block code + return _codes(s, s.lencode, s.distcode); + } } - } - - function _build_dynamic(State memory s) - private - pure - returns ( - ErrorCode, - Huffman memory, - Huffman memory - ) - { - unchecked { - // Number of lengths in descriptor - uint256 nlen; - uint256 ndist; - // Index of lengths[] - uint256 index; - // Error code - ErrorCode err; - // Descriptor code lengths - uint256[] memory lengths = new uint256[](MAXCODES); - // Length and distance codes - Huffman memory lencode = Huffman( - new uint256[](MAXBITS + 1), - new uint256[](MAXLCODES) - ); - Huffman memory distcode = Huffman( - new uint256[](MAXBITS + 1), - new uint256[](MAXDCODES) - ); - uint256 tempBits; - - // Get number of lengths in each table, check lengths - (err, nlen) = bits(s, 5); - if (err != ErrorCode.ERR_NONE) { - return (err, lencode, distcode); - } - nlen += 257; - (err, ndist) = bits(s, 5); - if (err != ErrorCode.ERR_NONE) { - return (err, lencode, distcode); - } - ndist += 1; - - if (nlen > MAXLCODES || ndist > MAXDCODES) { - // Bad counts - return ( - ErrorCode.ERR_TOO_MANY_LENGTH_OR_DISTANCE_CODES, - lencode, - distcode - ); - } - - (err, lengths) = _build_dynamic_lengths(s); - if (err != ErrorCode.ERR_NONE) { - return (err, lencode, distcode); - } - - // Build huffman table for code lengths codes (use lencode temporarily) - err = _construct(lencode, lengths, 19, 0); - if (err != ErrorCode.ERR_NONE) { - // Require complete code set here - return (ErrorCode.ERR_CODE_LENGTHS_CODES_INCOMPLETE, lencode, distcode); - } - - // Read length/literal and distance code length tables - index = 0; - while (index < nlen + ndist) { - // Decoded value - uint256 symbol; - // Last length to repeat - uint256 len; - - (err, symbol) = _decode(s, lencode); - if (err != ErrorCode.ERR_NONE) { - // Invalid symbol - return (err, lencode, distcode); + + function _build_dynamic_lengths(State memory s) private pure returns (ErrorCode, uint256[] memory) { + unchecked { + uint256 ncode; + // Index of lengths[] + uint256 index; + // Descriptor code lengths + uint256[] memory lengths = new uint256[](MAXCODES); + // Error code + ErrorCode err; + // Permutation of code length codes + uint8[19] memory order = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; + + (err, ncode) = bits(s, 4); + if (err != ErrorCode.ERR_NONE) { + return (err, lengths); + } + ncode += 4; + + // Read code length code lengths (really), missing lengths are zero + for (index = 0; index < ncode; ++index) { + (err, lengths[order[index]]) = bits(s, 3); + if (err != ErrorCode.ERR_NONE) { + return (err, lengths); + } + } + for (; index < 19; ++index) { + lengths[order[index]] = 0; + } + + return (ErrorCode.ERR_NONE, lengths); } + } - if (symbol < 16) { - // Length in 0..15 - lengths[index++] = symbol; - } else { - // Repeat instruction - // Assume repeating zeros - len = 0; - if (symbol == 16) { - // Repeat last length 3..6 times - if (index == 0) { - // No last length! - return (ErrorCode.ERR_REPEAT_NO_FIRST_LENGTH, lencode, distcode); - } - // Last length - len = lengths[index - 1]; - (err, tempBits) = bits(s, 2); + function _build_dynamic(State memory s) + private + pure + returns ( + ErrorCode, + Huffman memory, + Huffman memory + ) + { + unchecked { + // Number of lengths in descriptor + uint256 nlen; + uint256 ndist; + // Index of lengths[] + uint256 index; + // Error code + ErrorCode err; + // Descriptor code lengths + uint256[] memory lengths = new uint256[](MAXCODES); + // Length and distance codes + Huffman memory lencode = Huffman(new uint256[](MAXBITS + 1), new uint256[](MAXLCODES)); + Huffman memory distcode = Huffman(new uint256[](MAXBITS + 1), new uint256[](MAXDCODES)); + uint256 tempBits; + + // Get number of lengths in each table, check lengths + (err, nlen) = bits(s, 5); if (err != ErrorCode.ERR_NONE) { - return (err, lencode, distcode); + return (err, lencode, distcode); } - symbol = 3 + tempBits; - } else if (symbol == 17) { - // Repeat zero 3..10 times - (err, tempBits) = bits(s, 3); + nlen += 257; + (err, ndist) = bits(s, 5); if (err != ErrorCode.ERR_NONE) { - return (err, lencode, distcode); + return (err, lencode, distcode); + } + ndist += 1; + + if (nlen > MAXLCODES || ndist > MAXDCODES) { + // Bad counts + return (ErrorCode.ERR_TOO_MANY_LENGTH_OR_DISTANCE_CODES, lencode, distcode); } - symbol = 3 + tempBits; - } else { - // == 18, repeat zero 11..138 times - (err, tempBits) = bits(s, 7); + + (err, lengths) = _build_dynamic_lengths(s); if (err != ErrorCode.ERR_NONE) { - return (err, lencode, distcode); - } - symbol = 11 + tempBits; - } - - if (index + symbol > nlen + ndist) { - // Too many lengths! - return (ErrorCode.ERR_REPEAT_MORE, lencode, distcode); - } - while (symbol != 0) { - // Note: Solidity reverts on underflow, so we decrement here - symbol -= 1; - - // Repeat last or zero symbol times - lengths[index++] = len; - } + return (err, lencode, distcode); + } + + // Build huffman table for code lengths codes (use lencode temporarily) + err = _construct(lencode, lengths, 19, 0); + if (err != ErrorCode.ERR_NONE) { + // Require complete code set here + return (ErrorCode.ERR_CODE_LENGTHS_CODES_INCOMPLETE, lencode, distcode); + } + + // Read length/literal and distance code length tables + index = 0; + while (index < nlen + ndist) { + // Decoded value + uint256 symbol; + // Last length to repeat + uint256 len; + + (err, symbol) = _decode(s, lencode); + if (err != ErrorCode.ERR_NONE) { + // Invalid symbol + return (err, lencode, distcode); + } + + if (symbol < 16) { + // Length in 0..15 + lengths[index++] = symbol; + } else { + // Repeat instruction + // Assume repeating zeros + len = 0; + if (symbol == 16) { + // Repeat last length 3..6 times + if (index == 0) { + // No last length! + return (ErrorCode.ERR_REPEAT_NO_FIRST_LENGTH, lencode, distcode); + } + // Last length + len = lengths[index - 1]; + (err, tempBits) = bits(s, 2); + if (err != ErrorCode.ERR_NONE) { + return (err, lencode, distcode); + } + symbol = 3 + tempBits; + } else if (symbol == 17) { + // Repeat zero 3..10 times + (err, tempBits) = bits(s, 3); + if (err != ErrorCode.ERR_NONE) { + return (err, lencode, distcode); + } + symbol = 3 + tempBits; + } else { + // == 18, repeat zero 11..138 times + (err, tempBits) = bits(s, 7); + if (err != ErrorCode.ERR_NONE) { + return (err, lencode, distcode); + } + symbol = 11 + tempBits; + } + + if (index + symbol > nlen + ndist) { + // Too many lengths! + return (ErrorCode.ERR_REPEAT_MORE, lencode, distcode); + } + while (symbol != 0) { + // Note: Solidity reverts on underflow, so we decrement here + symbol -= 1; + + // Repeat last or zero symbol times + lengths[index++] = len; + } + } + } + + // Check for end-of-block code -- there better be one! + if (lengths[256] == 0) { + return (ErrorCode.ERR_MISSING_END_OF_BLOCK, lencode, distcode); + } + + // Build huffman table for literal/length codes + err = _construct(lencode, lengths, nlen, 0); + if ( + err != ErrorCode.ERR_NONE && + (err == ErrorCode.ERR_NOT_TERMINATED || + err == ErrorCode.ERR_OUTPUT_EXHAUSTED || + nlen != lencode.counts[0] + lencode.counts[1]) + ) { + // Incomplete code ok only for single length 1 code + return (ErrorCode.ERR_INVALID_LITERAL_LENGTH_CODE_LENGTHS, lencode, distcode); + } + + // Build huffman table for distance codes + err = _construct(distcode, lengths, ndist, nlen); + if ( + err != ErrorCode.ERR_NONE && + (err == ErrorCode.ERR_NOT_TERMINATED || + err == ErrorCode.ERR_OUTPUT_EXHAUSTED || + ndist != distcode.counts[0] + distcode.counts[1]) + ) { + // Incomplete code ok only for single length 1 code + return (ErrorCode.ERR_INVALID_DISTANCE_CODE_LENGTHS, lencode, distcode); + } + + return (ErrorCode.ERR_NONE, lencode, distcode); } - } - - // Check for end-of-block code -- there better be one! - if (lengths[256] == 0) { - return (ErrorCode.ERR_MISSING_END_OF_BLOCK, lencode, distcode); - } - - // Build huffman table for literal/length codes - err = _construct(lencode, lengths, nlen, 0); - if ( - err != ErrorCode.ERR_NONE && - (err == ErrorCode.ERR_NOT_TERMINATED || - err == ErrorCode.ERR_OUTPUT_EXHAUSTED || - nlen != lencode.counts[0] + lencode.counts[1]) - ) { - // Incomplete code ok only for single length 1 code - return ( - ErrorCode.ERR_INVALID_LITERAL_LENGTH_CODE_LENGTHS, - lencode, - distcode - ); - } - - // Build huffman table for distance codes - err = _construct(distcode, lengths, ndist, nlen); - if ( - err != ErrorCode.ERR_NONE && - (err == ErrorCode.ERR_NOT_TERMINATED || - err == ErrorCode.ERR_OUTPUT_EXHAUSTED || - ndist != distcode.counts[0] + distcode.counts[1]) - ) { - // Incomplete code ok only for single length 1 code - return (ErrorCode.ERR_INVALID_DISTANCE_CODE_LENGTHS, lencode, distcode); - } - - return (ErrorCode.ERR_NONE, lencode, distcode); - } - } - - function _dynamic(State memory s) private pure returns (ErrorCode) { - unchecked { - // Length and distance codes - Huffman memory lencode; - Huffman memory distcode; - // Error code - ErrorCode err; - - (err, lencode, distcode) = _build_dynamic(s); - if (err != ErrorCode.ERR_NONE) { - return err; - } - - // Decode data until end-of-block code - return _codes(s, lencode, distcode); } - } - - function puff(bytes memory source, uint256 destlen) - internal - pure - returns (ErrorCode, bytes memory) - { - unchecked { - // Input/output state - State memory s = State( - new bytes(destlen), - 0, - source, - 0, - 0, - 0, - Huffman(new uint256[](MAXBITS + 1), new uint256[](FIXLCODES)), - Huffman(new uint256[](MAXBITS + 1), new uint256[](MAXDCODES)) - ); - // Temp: last bit - uint256 last; - // Temp: block type bit - uint256 t; - // Error code - ErrorCode err; - - // Build fixed Huffman tables - err = _build_fixed(s); - if (err != ErrorCode.ERR_NONE) { - return (err, s.output); - } - - // Process blocks until last block or error - while (last == 0) { - // One if last block - (err, last) = bits(s, 1); - if (err != ErrorCode.ERR_NONE) { - return (err, s.output); - } - // Block type 0..3 - (err, t) = bits(s, 2); - if (err != ErrorCode.ERR_NONE) { - return (err, s.output); - } + function _dynamic(State memory s) private pure returns (ErrorCode) { + unchecked { + // Length and distance codes + Huffman memory lencode; + Huffman memory distcode; + // Error code + ErrorCode err; + + (err, lencode, distcode) = _build_dynamic(s); + if (err != ErrorCode.ERR_NONE) { + return err; + } - err = ( - t == 0 - ? _stored(s) - : ( - t == 1 - ? _fixed(s) - : (t == 2 ? _dynamic(s) : ErrorCode.ERR_INVALID_BLOCK_TYPE) - ) - ); - // type == 3, invalid - - if (err != ErrorCode.ERR_NONE) { - // Return with error - break; + // Decode data until end-of-block code + return _codes(s, lencode, distcode); } - } + } - return (err, s.output); + function puff(bytes memory source, uint256 destlen) internal pure returns (ErrorCode, bytes memory) { + unchecked { + // Input/output state + State memory s = State( + new bytes(destlen), + 0, + source, + 0, + 0, + 0, + Huffman(new uint256[](MAXBITS + 1), new uint256[](FIXLCODES)), + Huffman(new uint256[](MAXBITS + 1), new uint256[](MAXDCODES)) + ); + // Temp: last bit + uint256 last; + // Temp: block type bit + uint256 t; + // Error code + ErrorCode err; + + // Build fixed Huffman tables + err = _build_fixed(s); + if (err != ErrorCode.ERR_NONE) { + return (err, s.output); + } + + // Process blocks until last block or error + while (last == 0) { + // One if last block + (err, last) = bits(s, 1); + if (err != ErrorCode.ERR_NONE) { + return (err, s.output); + } + + // Block type 0..3 + (err, t) = bits(s, 2); + if (err != ErrorCode.ERR_NONE) { + return (err, s.output); + } + + err = ( + t == 0 + ? _stored(s) + : (t == 1 ? _fixed(s) : (t == 2 ? _dynamic(s) : ErrorCode.ERR_INVALID_BLOCK_TYPE)) + ); + // type == 3, invalid + + if (err != ErrorCode.ERR_NONE) { + // Return with error + break; + } + } + + return (err, s.output); + } } - } } From 35eaa1812b94d3c6613e54096047af1d86f87c1b Mon Sep 17 00:00:00 2001 From: eladmallel Date: Thu, 30 Jun 2022 10:20:09 -0500 Subject: [PATCH 034/116] add @notice natspec on public state vars --- packages/nouns-contracts/contracts/NounsArt.sol | 16 ++++++++-------- .../contracts/NounsDescriptorV2.sol | 10 +++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsArt.sol b/packages/nouns-contracts/contracts/NounsArt.sol index e48d0d8365..dd8ca7df31 100644 --- a/packages/nouns-contracts/contracts/NounsArt.sol +++ b/packages/nouns-contracts/contracts/NounsArt.sol @@ -22,28 +22,28 @@ import { Inflate } from './libs/Inflate.sol'; import { SSTORE2 } from './libs/SSTORE2.sol'; contract NounsArt is INounsArt { - // Current Nouns Descriptor address + /// @notice Current Nouns Descriptor address address public override descriptor; - // Pending Nouns Descriptor address + /// @notice Pending Nouns Descriptor address address public override pendingDescriptor; - // Noun Backgrounds (Hex Colors) + /// @notice Noun Backgrounds (Hex Colors) string[] public override backgrounds; - // Noun Color Palettes (Index => Hex Colors) + /// @notice Noun Color Palettes (Index => Hex Colors, stored as a contract using SSTORE2) mapping(uint8 => address) public palettesPointers; - // Noun Bodies (Custom RLE) + /// @notice Noun Bodies Trait Trait public _bodies; - // Noun Accessories (Custom RLE) + /// @notice Noun Accessories Trait Trait public _accessories; - // Noun Heads (Custom RLE) + /// @notice Noun Heads Trait Trait public _heads; - // Noun Glasses (Custom RLE) + /// @notice Noun Glasses Trait Trait public _glasses; /** diff --git a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol index e89ab01944..696c030774 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol @@ -32,19 +32,19 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { // https://creativecommons.org/publicdomain/zero/1.0/legalcode.txt bytes32 constant COPYRIGHT_CC0_1_0_UNIVERSAL_LICENSE = 0xa2010f343487d3f7618affe54f789f5487602331c0a8d03f49e9a7c547cf0499; - // The contract responsible for holding compressed Noun art + /// @notice The contract responsible for holding compressed Noun art INounsArt public art; - // The contract responsible for constructing SVGs + /// @notice The contract responsible for constructing SVGs ISVGRenderer public renderer; - // Whether or not new Noun parts can be added + /// @notice Whether or not new Noun parts can be added bool public override arePartsLocked; - // Whether or not `tokenURI` should be returned as a data URI (Default: true) + /// @notice Whether or not `tokenURI` should be returned as a data URI (Default: true) bool public override isDataURIEnabled = true; - // Base URI + /// @notice Base URI, used when isDataURIEnabled is false string public override baseURI; /** From c8ffe3c644473a7413530338804820b954b9168a Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Thu, 30 Jun 2022 17:23:34 +0200 Subject: [PATCH 035/116] sdk: add multiline RLE support svg-builder supports multilines Image2 encodes with multilines --- packages/nouns-sdk/src/image/image2.ts | 139 ++++++++++++++++++++ packages/nouns-sdk/src/image/svg-builder.ts | 43 ++++-- packages/nouns-sdk/test/image2.test.ts | 54 ++++++++ 3 files changed, 222 insertions(+), 14 deletions(-) create mode 100644 packages/nouns-sdk/src/image/image2.ts create mode 100644 packages/nouns-sdk/test/image2.test.ts diff --git a/packages/nouns-sdk/src/image/image2.ts b/packages/nouns-sdk/src/image/image2.ts new file mode 100644 index 0000000000..175e25ff30 --- /dev/null +++ b/packages/nouns-sdk/src/image/image2.ts @@ -0,0 +1,139 @@ +import { ImageBounds, RGBAColor } from './types'; +import { rgbToHex, toPaddedHex } from './utils'; + +/** + * A class used to convert an image into the following RLE format: + * Palette Index, Bounds [Top (Y), Right (X), Bottom (Y), Left (X)] (4 Bytes), [Pixel Length (1 Byte), Color Index (1 Byte)][]. + * + * As opposed to the first encoding version, this supports multiline run-length encoding + */ +export class Image2 { + private _width: number; + private _height: number; + private _bounds: ImageBounds = { top: 0, bottom: 0, left: 0, right: 0 }; + public tuples: number[][] = []; + private _getRgbaAt: (x: number, y: number) => RGBAColor; + + constructor(width: number, height: number, getRgbaAt: (x: number, y: number) => RGBAColor) { + this._width = width; + this._height = height; + + this._getRgbaAt = getRgbaAt; + } + + get height(): number { + return this._height; + } + + get width(): number { + return this._width; + } + + get bounds(): ImageBounds { + return this._bounds; + } + + public toRLE(colors: Map): string { + this._bounds = this.calcBounds(); + + const indexes: number[] = []; + + for (let y = this.bounds.top; y <= this.bounds.bottom; y++) { + for (let x = this.bounds.left; x < this.bounds.right; x++) { + const { r, g, b, a } = this._getRgbaAt(x, y); + const hexColor = rgbToHex(r, g, b); + + // Insert the color if it does not yet exist + if (!colors.has(hexColor)) { + colors.set(hexColor, colors.size); + } + + // If alpha is 0, use 'transparent' index, otherwise get color index + indexes.push(a === 0 ? 0 : colors.get(hexColor)!); + } + } + + // [palette_index, top, right, bottom, left] + const metadata = [ + 0, + this.bounds.top, + this.bounds.right, + this.bounds.bottom, + this.bounds.left, + ].map(v => toPaddedHex(v)); + return `0x${metadata.join('')}${this.encode(indexes)}`; + } + + /** + * Given a numeric array, return a string of padded hex run-length encoded values + * @param data The numeric array to run-length encode + */ + private encode(data: number[]) { + const encoding: string[] = []; + let previous = data[0]; + let count = 1; + + for (let i = 1; i < data.length; i++) { + if (data[i] !== previous) { + encoding.push(toPaddedHex(count), toPaddedHex(previous)); + this.tuples.push([count, previous]); + count = 1; + previous = data[i]; + } else { + count++; + } + } + + if (previous !== undefined) { + encoding.push(toPaddedHex(count), toPaddedHex(previous)); + } + return encoding.join(''); + } + + calcBounds(): ImageBounds { + let top = 0; + while (top < this.height - 1 && this._isTransparentRow(top)) { + top++; + } + + let bottom = this.height - 1; + while (bottom > 0 && this._isTransparentRow(bottom)) { + bottom--; + } + + let left = 0; + while (left < this.width - 1 && this._isTransparentColumn(left)) { + left++; + } + + let right = this.width - 1; + while (right > 0 && this._isTransparentColumn(right)) { + right--; + } + + return { + top: top, + bottom: bottom, + left: left, + right: right + 1, // right bound is calculated to be one pixel outside the content + }; + } + + private _isTransparentColumn(column: number) { + for (let row = 0; row < this.height; row++) { + if (this._getRgbaAt(column, row).a !== 0) { + return false; + } + } + return true; + } + + private _isTransparentRow(row: number) { + for (let column = 0; column < this.width; column++) { + if (this._getRgbaAt(column, row).a !== 0) { + return false; + } + } + return true; + } +} diff --git a/packages/nouns-sdk/src/image/svg-builder.ts b/packages/nouns-sdk/src/image/svg-builder.ts index 9509a98d06..a1ec8f2829 100644 --- a/packages/nouns-sdk/src/image/svg-builder.ts +++ b/packages/nouns-sdk/src/image/svg-builder.ts @@ -26,6 +26,15 @@ const decodeImage = (image: string): DecodedImage => { }; }; +/** + * @notice Given an x-coordinate, draw length, and right bound, return the draw + * length for a single SVG rectangle. + */ +const getRectLength = (currentX: number, drawLength: number, rightBound: number): number => { + const remainingPixelsInLine = rightBound - currentX; + return drawLength <= remainingPixelsInLine ? drawLength : remainingPixelsInLine; +}; + /** * Given RLE parts, palette colors, and a background color, build an SVG image. * @param parts The RLE part datas @@ -44,23 +53,29 @@ export const buildSVG = ( let currentX = bounds.left; let currentY = bounds.top; - rects.forEach(rect => { - const [length, colorIndex] = rect; + rects.forEach(draw => { + let [drawLength, colorIndex] = draw; const hexColor = paletteColors[colorIndex]; - // Do not push rect if transparent - if (colorIndex !== 0) { - svgRects.push( - ``, - ); - } + let length = getRectLength(currentX, drawLength, bounds.right); + while (length > 0) { + // Do not push rect if transparent + if (colorIndex !== 0) { + svgRects.push( + ``, + ); + } + + currentX += length; + if (currentX === bounds.right) { + currentX = bounds.left; + currentY++; + } - currentX += length; - if (currentX === bounds.right) { - currentX = bounds.left; - currentY++; + drawLength -= length; + length = getRectLength(currentX, drawLength, bounds.right); } }); result += svgRects.join(''); diff --git a/packages/nouns-sdk/test/image2.test.ts b/packages/nouns-sdk/test/image2.test.ts new file mode 100644 index 0000000000..1dcea25a0a --- /dev/null +++ b/packages/nouns-sdk/test/image2.test.ts @@ -0,0 +1,54 @@ +import { expect } from 'chai'; +import { join } from 'path'; +import { Image2 } from '../src/image/image2'; +import { Image } from '../src/image/image'; +import { readPngImage } from './lib'; +import { buildSVG } from '../src'; +import { glob } from 'glob'; + +async function encodeSingleLineRLE(filepath: string) { + const transparent: [string, number] = ['', 0]; + const colors: Map = new Map([transparent]); + const pngImage = await readPngImage(filepath); + const image = new Image(pngImage.width, pngImage.height); + const rle = image.toRLE(pngImage.rgbaAt, colors); + return { rle, colors }; +} + +async function encodeMultiLineRLE(filepath: string) { + const transparent: [string, number] = ['', 0]; + const colors: Map = new Map([transparent]); + const pngImage = await readPngImage(filepath); + const image = new Image2(pngImage.width, pngImage.height, pngImage.rgbaAt); + const rle = image.toRLE(colors); + return { rle, colors }; +} + +describe('Image2', () => { + it('builds the same svg with both encoders', async () => { + const filepath = join(__dirname, `./lib/images/head-cone.png`); + const { rle: rle1, colors: colors1 } = await encodeSingleLineRLE(filepath); + const { rle: rle2, colors: colors2 } = await encodeMultiLineRLE(filepath); + + const svg1 = buildSVG([{ data: rle1 }], Array.from(colors1.keys()), 'ffffff'); + const svg2 = buildSVG([{ data: rle2 }], Array.from(colors2.keys()), 'ffffff'); + + expect(svg1).to.be.equal(svg2); + }); + + it('builds the same svg for all images', async () => { + const transparent: [string, number] = ['', 0]; + + const filepaths = glob.sync(join(__dirname, '../../nouns-assets/images/+(1|2|3|4)*/*.png')); + + for (const filepath of filepaths) { + const { rle: rle1, colors: colors1 } = await encodeSingleLineRLE(filepath); + const { rle: rle2, colors: colors2 } = await encodeMultiLineRLE(filepath); + + const svg1 = buildSVG([{ data: rle1 }], Array.from(colors1.keys()), 'ffffff'); + const svg2 = buildSVG([{ data: rle2 }], Array.from(colors2.keys()), 'ffffff'); + + expect(svg1).to.be.equal(svg2); + } + }); +}); From 07c57cd54d3a152942a8b94bba7d62a71e0cd748 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Thu, 30 Jun 2022 10:54:08 -0500 Subject: [PATCH 036/116] temp skip the test that causes CI memory issues --- packages/nouns-contracts/test/descriptorV2.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/nouns-contracts/test/descriptorV2.test.ts b/packages/nouns-contracts/test/descriptorV2.test.ts index 2ef897ac28..b594c72798 100644 --- a/packages/nouns-contracts/test/descriptorV2.test.ts +++ b/packages/nouns-contracts/test/descriptorV2.test.ts @@ -66,7 +66,8 @@ describe('NounsDescriptorV2', () => { expect(tokenUri).to.equal(`${BASE_URI}0`); }); - it('should generate valid token uri metadata when data uris are enabled', async () => { + // Skipping until we resolve the CI memory issue + it.skip('should generate valid token uri metadata when data uris are enabled', async () => { const tokenUri = await nounsDescriptor.tokenURI( 0, { From 15d27b69c1844d5d017747d4acc3745e6a5f289b Mon Sep 17 00:00:00 2001 From: eladmallel Date: Thu, 30 Jun 2022 11:32:31 -0500 Subject: [PATCH 037/116] cleanup per code review --- .../nouns-contracts/contracts/NounsArt.sol | 34 +++++++++++-------- .../contracts/interfaces/INounsArt.sol | 2 -- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsArt.sol b/packages/nouns-contracts/contracts/NounsArt.sol index dd8ca7df31..9d0a991b66 100644 --- a/packages/nouns-contracts/contracts/NounsArt.sol +++ b/packages/nouns-contracts/contracts/NounsArt.sol @@ -163,7 +163,7 @@ contract NounsArt is INounsArt { uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { - addToTraitFromBytes(_bodies, encodedCompressed, decompressedLength, imageCount); + addPage(_bodies, encodedCompressed, decompressedLength, imageCount); } /** @@ -179,7 +179,7 @@ contract NounsArt is INounsArt { uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { - addToTraitFromBytes(_accessories, encodedCompressed, decompressedLength, imageCount); + addPage(_accessories, encodedCompressed, decompressedLength, imageCount); } /** @@ -195,7 +195,7 @@ contract NounsArt is INounsArt { uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { - addToTraitFromBytes(_heads, encodedCompressed, decompressedLength, imageCount); + addPage(_heads, encodedCompressed, decompressedLength, imageCount); } /** @@ -211,7 +211,7 @@ contract NounsArt is INounsArt { uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { - addToTraitFromBytes(_glasses, encodedCompressed, decompressedLength, imageCount); + addPage(_glasses, encodedCompressed, decompressedLength, imageCount); } /** @@ -228,7 +228,7 @@ contract NounsArt is INounsArt { uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { - addToTraitFromPointer(_bodies, pointer, decompressedLength, imageCount); + addPage(_bodies, pointer, decompressedLength, imageCount); } /** @@ -245,7 +245,7 @@ contract NounsArt is INounsArt { uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { - addToTraitFromPointer(_accessories, pointer, decompressedLength, imageCount); + addPage(_accessories, pointer, decompressedLength, imageCount); } /** @@ -262,7 +262,7 @@ contract NounsArt is INounsArt { uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { - addToTraitFromPointer(_heads, pointer, decompressedLength, imageCount); + addPage(_heads, pointer, decompressedLength, imageCount); } /** @@ -279,7 +279,7 @@ contract NounsArt is INounsArt { uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { - addToTraitFromPointer(_glasses, pointer, decompressedLength, imageCount); + addPage(_glasses, pointer, decompressedLength, imageCount); } /** @@ -328,7 +328,7 @@ contract NounsArt is INounsArt { backgrounds.push(_background); } - function addToTraitFromBytes( + function addPage( Trait storage trait, bytes calldata encodedCompressed, uint80 decompressedLength, @@ -338,10 +338,10 @@ contract NounsArt is INounsArt { revert EmptyBytes(); } address pointer = SSTORE2.write(encodedCompressed); - addToTraitFromPointer(trait, pointer, decompressedLength, imageCount); + addPage(trait, pointer, decompressedLength, imageCount); } - function addToTraitFromPointer( + function addPage( Trait storage trait, address pointer, uint80 decompressedLength, @@ -365,16 +365,20 @@ contract NounsArt is INounsArt { return decompressedImages[indexInPage]; } + /** + * @dev Given an image index, this function finds the storage page the image is in, and the relative index + * inside the page, so the image can be read from storage. + * Example: if you have 2 pages with 100 images each, and you want to get image 150, this function would return + * the 2nd page, and the 50th index. + * @return INounsArt.NounArtStoragePage the page containing the image at index + * @return uint256 the index of the image in the page + */ function getPage(INounsArt.NounArtStoragePage[] storage pages, uint256 index) internal view returns (INounsArt.NounArtStoragePage storage, uint256) { uint256 len = pages.length; - if (len == 0) { - revert NoPages(); - } - uint256 pageFirstImageIndex = 0; for (uint256 i = 0; i < len; i++) { INounsArt.NounArtStoragePage storage page = pages[i]; diff --git a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol index 4db6532ab8..eb66df300d 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol @@ -32,8 +32,6 @@ interface INounsArt { error BadImageCount(); - error NoPages(); - error ImageNotFound(); event DescriptorUpdated(address oldDescriptor, address newDescriptor); From c388c0ebb8a639dd8cbbe3d20462e30df1591fb6 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Thu, 30 Jun 2022 11:46:36 -0500 Subject: [PATCH 038/116] art: add puff function as 'public good' per CR comment --- packages/nouns-contracts/contracts/NounsArt.sol | 12 ++++++++++++ .../contracts/interfaces/INounsArt.sol | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/packages/nouns-contracts/contracts/NounsArt.sol b/packages/nouns-contracts/contracts/NounsArt.sol index 9d0a991b66..8246ece0d4 100644 --- a/packages/nouns-contracts/contracts/NounsArt.sol +++ b/packages/nouns-contracts/contracts/NounsArt.sol @@ -324,6 +324,18 @@ contract NounsArt is INounsArt { return SSTORE2.read(palettesPointers[paletteIndex]); } + /** + * @notice Decompresses Deflated bytes using the Puff algorithm + * based on Based on https://github.com/adlerjohn/inflate-sol. + * @param source the bytes to decompress. + * @param destlen the length of the original decompressed bytes. + * @return Inflate.ErrorCode 0 if successful, otherwise an error code specifying the reason for failure. + * @return bytes the decompressed bytes. + */ + function puff(bytes memory source, uint256 destlen) public pure override returns (Inflate.ErrorCode, bytes memory) { + return Inflate.puff(source, destlen); + } + function _addBackground(string calldata _background) internal { backgrounds.push(_background); } diff --git a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol index eb66df300d..94eb474b70 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol @@ -17,6 +17,8 @@ pragma solidity ^0.8.6; +import { Inflate } from '../libs/Inflate.sol'; + interface INounsArt { error SenderIsNotDescriptor(); @@ -130,4 +132,6 @@ interface INounsArt { function headsTrait() external view returns (Trait memory); function glassesTrait() external view returns (Trait memory); + + function puff(bytes memory source, uint256 destlen) external pure returns (Inflate.ErrorCode, bytes memory); } From 75002d0727c636010b85352e97c1323465a3f691 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Thu, 30 Jun 2022 11:51:15 -0500 Subject: [PATCH 039/116] rename --- .../contracts/NounsDescriptorV2.sol | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol index 696c030774..ba4ed35a79 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol @@ -405,16 +405,16 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { * @notice Get all Noun parts for the passed `seed`. */ function getPartsForSeed(INounsSeeder.Seed memory seed) public view returns (ISVGRenderer.Part[] memory) { - bytes memory _body = art.bodies(seed.body); - bytes memory _accessory = art.accessories(seed.accessory); - bytes memory _head = art.heads(seed.head); - bytes memory _glassesBytes = art.glasses(seed.glasses); + bytes memory body = art.bodies(seed.body); + bytes memory accessory = art.accessories(seed.accessory); + bytes memory head = art.heads(seed.head); + bytes memory glassesBytes = art.glasses(seed.glasses); ISVGRenderer.Part[] memory _parts = new ISVGRenderer.Part[](4); - _parts[0] = ISVGRenderer.Part({ image: _body, palette: _getPalette(_body) }); - _parts[1] = ISVGRenderer.Part({ image: _accessory, palette: _getPalette(_accessory) }); - _parts[2] = ISVGRenderer.Part({ image: _head, palette: _getPalette(_head) }); - _parts[3] = ISVGRenderer.Part({ image: _glassesBytes, palette: _getPalette(_glassesBytes) }); + _parts[0] = ISVGRenderer.Part({ image: body, palette: _getPalette(body) }); + _parts[1] = ISVGRenderer.Part({ image: accessory, palette: _getPalette(accessory) }); + _parts[2] = ISVGRenderer.Part({ image: head, palette: _getPalette(head) }); + _parts[3] = ISVGRenderer.Part({ image: glassesBytes, palette: _getPalette(glassesBytes) }); return _parts; } From a368b6e67b3a655b87907670a730c79fa3e0b103 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Thu, 30 Jun 2022 11:54:18 -0500 Subject: [PATCH 040/116] rename --- .../nouns-contracts/contracts/NounsDescriptorV2.sol | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol index ba4ed35a79..9497c81094 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol @@ -410,12 +410,12 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { bytes memory head = art.heads(seed.head); bytes memory glassesBytes = art.glasses(seed.glasses); - ISVGRenderer.Part[] memory _parts = new ISVGRenderer.Part[](4); - _parts[0] = ISVGRenderer.Part({ image: body, palette: _getPalette(body) }); - _parts[1] = ISVGRenderer.Part({ image: accessory, palette: _getPalette(accessory) }); - _parts[2] = ISVGRenderer.Part({ image: head, palette: _getPalette(head) }); - _parts[3] = ISVGRenderer.Part({ image: glassesBytes, palette: _getPalette(glassesBytes) }); - return _parts; + ISVGRenderer.Part[] memory parts = new ISVGRenderer.Part[](4); + parts[0] = ISVGRenderer.Part({ image: body, palette: _getPalette(body) }); + parts[1] = ISVGRenderer.Part({ image: accessory, palette: _getPalette(accessory) }); + parts[2] = ISVGRenderer.Part({ image: head, palette: _getPalette(head) }); + parts[3] = ISVGRenderer.Part({ image: glassesBytes, palette: _getPalette(glassesBytes) }); + return parts; } /** From 38b51630e69b3f57488e8f3caca68f5cd63303e0 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Thu, 30 Jun 2022 12:02:56 -0500 Subject: [PATCH 041/116] art test cleanup: discovered hex literals --- .../test/foundry/NounsArt.t.sol | 149 ++++++++---------- .../foundry/helpers/DescriptorHelpers.sol | 37 ++--- .../test/foundry/helpers/Utils.sol | 29 ---- 3 files changed, 80 insertions(+), 135 deletions(-) delete mode 100644 packages/nouns-contracts/test/foundry/helpers/Utils.sol diff --git a/packages/nouns-contracts/test/foundry/NounsArt.t.sol b/packages/nouns-contracts/test/foundry/NounsArt.t.sol index 461fe3f39e..421755902d 100644 --- a/packages/nouns-contracts/test/foundry/NounsArt.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsArt.t.sol @@ -4,10 +4,9 @@ pragma solidity ^0.8.6; import 'forge-std/Test.sol'; import { NounsArt } from '../../contracts/NounsArt.sol'; import { INounsArt } from '../../contracts/interfaces/INounsArt.sol'; -import { Utils } from './helpers/Utils.sol'; import { SSTORE2 } from '../../contracts/libs/SSTORE2.sol'; -contract NounsArtTest is Test, Utils { +contract NounsArtTest is Test { NounsArt art; address descriptor = address(1); @@ -100,12 +99,12 @@ contract NounsArtTest is Test, Utils { function testSetPaletteRevertsIfSenderNotDescriptor() public { vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); - art.setPalette(0, fromHex('ffffff')); + art.setPalette(0, hex'ffffff'); } function testSetPaletteWorks() public { - bytes memory palette0 = fromHex('ffffffc5b9a1'); - bytes memory palette1 = fromHex('cfc2ab63a0f9'); + bytes memory palette0 = hex'ffffffc5b9a1'; + bytes memory palette1 = hex'cfc2ab63a0f9'; vm.startPrank(descriptor); art.setPalette(0, palette0); art.setPalette(1, palette1); @@ -119,8 +118,8 @@ contract NounsArtTest is Test, Utils { } function testSetPaletteUpdatesAnExistingPalette() public { - bytes memory paletteV1 = fromHex('ffffffc5b9a1'); - bytes memory paletteV2 = fromHex('cfc2ab63a0f9'); + bytes memory paletteV1 = hex'ffffffc5b9a1'; + bytes memory paletteV2 = hex'cfc2ab63a0f9'; vm.prank(descriptor); art.setPalette(0, paletteV1); @@ -178,7 +177,7 @@ contract NounsArtTest is Test, Utils { function testAddBodiesRevertsIfSenderNotDescriptor() public { vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); - art.addBodies(fromHex('123456'), uint80(12), uint16(1)); + art.addBodies(hex'123456', uint80(12), uint16(1)); } function testCannotAddBodiesWithNoBytes() public { @@ -190,35 +189,35 @@ contract NounsArtTest is Test, Utils { function testCannotAddBodiesWithZeroDecompressedLength() public { vm.prank(descriptor); vm.expectRevert(INounsArt.BadDecompressedLength.selector); - art.addBodies(fromHex(FIRST_TWO_IMAGES_COMPRESSED), 0, 0); + art.addBodies(FIRST_TWO_IMAGES_COMPRESSED, 0, 0); } function testCannotAddBodiesWithZeroImageCount() public { vm.prank(descriptor); vm.expectRevert(INounsArt.BadImageCount.selector); - art.addBodies(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, 0); + art.addBodies(FIRST_TWO_IMAGES_COMPRESSED, FIRST_TWO_IMAGES_DEFLATED_LENGTH, 0); } function testAddBodiesWorksWithMultiplePages() public { assertEq(art.bodiesTrait().storedImagesCount, 0); vm.startPrank(descriptor); - art.addBodies(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); - art.addBodies(fromHex(NEXT_TWO_IMAGES_COMPRESSED), NEXT_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); + art.addBodies(FIRST_TWO_IMAGES_COMPRESSED, FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); + art.addBodies(NEXT_TWO_IMAGES_COMPRESSED, NEXT_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); vm.stopPrank(); _assertBodiesStoredOK(); } function testCannotAddBodiesFromPointerWithZeroDecompressedLength() public { - address pointer = SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)); + address pointer = SSTORE2.write(FIRST_TWO_IMAGES_COMPRESSED); vm.prank(descriptor); vm.expectRevert(INounsArt.BadDecompressedLength.selector); art.addBodiesFromPointer(pointer, 0, 0); } function testCannotAddBodiesFromPointerWithZeroImageCount() public { - address pointer = SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)); + address pointer = SSTORE2.write(FIRST_TWO_IMAGES_COMPRESSED); vm.prank(descriptor); vm.expectRevert(INounsArt.BadImageCount.selector); art.addBodiesFromPointer(pointer, FIRST_TWO_IMAGES_DEFLATED_LENGTH, 0); @@ -229,15 +228,11 @@ contract NounsArtTest is Test, Utils { vm.startPrank(descriptor); art.addBodiesFromPointer( - SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)), + SSTORE2.write(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2) ); - art.addBodiesFromPointer( - SSTORE2.write(fromHex(NEXT_TWO_IMAGES_COMPRESSED)), - NEXT_TWO_IMAGES_DEFLATED_LENGTH, - uint16(2) - ); + art.addBodiesFromPointer(SSTORE2.write(NEXT_TWO_IMAGES_COMPRESSED), NEXT_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); vm.stopPrank(); _assertBodiesStoredOK(); @@ -249,7 +244,7 @@ contract NounsArtTest is Test, Utils { function testAddAccessoriesRevertsIfSenderNotDescriptor() public { vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); - art.addAccessories(fromHex('123456'), uint80(12), uint16(1)); + art.addAccessories(hex'123456', uint80(12), uint16(1)); } function testCannotAddAccessoriesWithNoBytes() public { @@ -261,35 +256,35 @@ contract NounsArtTest is Test, Utils { function testCannotAddAccessoriesWithZeroDecompressedLength() public { vm.prank(descriptor); vm.expectRevert(INounsArt.BadDecompressedLength.selector); - art.addAccessories(fromHex(FIRST_TWO_IMAGES_COMPRESSED), 0, 0); + art.addAccessories(FIRST_TWO_IMAGES_COMPRESSED, 0, 0); } function testCannotAddAccessoriesWithZeroImageCount() public { vm.prank(descriptor); vm.expectRevert(INounsArt.BadImageCount.selector); - art.addAccessories(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, 0); + art.addAccessories(FIRST_TWO_IMAGES_COMPRESSED, FIRST_TWO_IMAGES_DEFLATED_LENGTH, 0); } function testAddAccessoriesWorksWithMultiplePages() public { assertEq(art.accessoriesTrait().storedImagesCount, 0); vm.startPrank(descriptor); - art.addAccessories(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); - art.addAccessories(fromHex(NEXT_TWO_IMAGES_COMPRESSED), NEXT_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); + art.addAccessories(FIRST_TWO_IMAGES_COMPRESSED, FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); + art.addAccessories(NEXT_TWO_IMAGES_COMPRESSED, NEXT_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); vm.stopPrank(); _assertAccessoriesStoredOK(); } function testCannotAddAccessoriesFromPointerWithZeroDecompressedLength() public { - address pointer = SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)); + address pointer = SSTORE2.write(FIRST_TWO_IMAGES_COMPRESSED); vm.prank(descriptor); vm.expectRevert(INounsArt.BadDecompressedLength.selector); art.addAccessoriesFromPointer(pointer, 0, 0); } function testCannotAddAccessoriesFromPointerWithZeroImageCount() public { - address pointer = SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)); + address pointer = SSTORE2.write(FIRST_TWO_IMAGES_COMPRESSED); vm.prank(descriptor); vm.expectRevert(INounsArt.BadImageCount.selector); art.addAccessoriesFromPointer(pointer, FIRST_TWO_IMAGES_DEFLATED_LENGTH, 0); @@ -300,12 +295,12 @@ contract NounsArtTest is Test, Utils { vm.startPrank(descriptor); art.addAccessoriesFromPointer( - SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)), + SSTORE2.write(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2) ); art.addAccessoriesFromPointer( - SSTORE2.write(fromHex(NEXT_TWO_IMAGES_COMPRESSED)), + SSTORE2.write(NEXT_TWO_IMAGES_COMPRESSED), NEXT_TWO_IMAGES_DEFLATED_LENGTH, uint16(2) ); @@ -320,7 +315,7 @@ contract NounsArtTest is Test, Utils { function testAddHeadsRevertsIfSenderNotDescriptor() public { vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); - art.addHeads(fromHex('123456'), uint80(12), uint16(1)); + art.addHeads(hex'123456', uint80(12), uint16(1)); } function testCannotAddHeadsWithNoBytes() public { @@ -332,35 +327,35 @@ contract NounsArtTest is Test, Utils { function testCannotAddHeadsWithZeroDecompressedLength() public { vm.prank(descriptor); vm.expectRevert(INounsArt.BadDecompressedLength.selector); - art.addHeads(fromHex(FIRST_TWO_IMAGES_COMPRESSED), 0, 0); + art.addHeads(FIRST_TWO_IMAGES_COMPRESSED, 0, 0); } function testCannotAddHeadsWithZeroImageCount() public { vm.prank(descriptor); vm.expectRevert(INounsArt.BadImageCount.selector); - art.addHeads(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, 0); + art.addHeads(FIRST_TWO_IMAGES_COMPRESSED, FIRST_TWO_IMAGES_DEFLATED_LENGTH, 0); } function testAddHeadsWorksWithMultiplePages() public { assertEq(art.headsTrait().storedImagesCount, 0); vm.startPrank(descriptor); - art.addHeads(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); - art.addHeads(fromHex(NEXT_TWO_IMAGES_COMPRESSED), NEXT_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); + art.addHeads(FIRST_TWO_IMAGES_COMPRESSED, FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); + art.addHeads(NEXT_TWO_IMAGES_COMPRESSED, NEXT_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); vm.stopPrank(); _assertHeadsStoredOK(); } function testCannotAddHeadsFromPointerWithZeroDecompressedLength() public { - address pointer = SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)); + address pointer = SSTORE2.write(FIRST_TWO_IMAGES_COMPRESSED); vm.prank(descriptor); vm.expectRevert(INounsArt.BadDecompressedLength.selector); art.addHeadsFromPointer(pointer, 0, 0); } function testCannotAddHeadsFromPointerWithZeroImageCount() public { - address pointer = SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)); + address pointer = SSTORE2.write(FIRST_TWO_IMAGES_COMPRESSED); vm.prank(descriptor); vm.expectRevert(INounsArt.BadImageCount.selector); art.addHeadsFromPointer(pointer, FIRST_TWO_IMAGES_DEFLATED_LENGTH, 0); @@ -371,15 +366,11 @@ contract NounsArtTest is Test, Utils { vm.startPrank(descriptor); art.addHeadsFromPointer( - SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)), + SSTORE2.write(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2) ); - art.addHeadsFromPointer( - SSTORE2.write(fromHex(NEXT_TWO_IMAGES_COMPRESSED)), - NEXT_TWO_IMAGES_DEFLATED_LENGTH, - uint16(2) - ); + art.addHeadsFromPointer(SSTORE2.write(NEXT_TWO_IMAGES_COMPRESSED), NEXT_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); vm.stopPrank(); _assertHeadsStoredOK(); @@ -391,7 +382,7 @@ contract NounsArtTest is Test, Utils { function testAddGlassesRevertsIfSenderNotDescriptor() public { vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); - art.addGlasses(fromHex('123456'), uint80(12), uint16(1)); + art.addGlasses(hex'123456', uint80(12), uint16(1)); } function testCannotAddGlassesWithNoBytes() public { @@ -403,35 +394,35 @@ contract NounsArtTest is Test, Utils { function testCannotAddGlassesWithZeroDecompressedLength() public { vm.prank(descriptor); vm.expectRevert(INounsArt.BadDecompressedLength.selector); - art.addGlasses(fromHex(FIRST_TWO_IMAGES_COMPRESSED), 0, 0); + art.addGlasses(FIRST_TWO_IMAGES_COMPRESSED, 0, 0); } function testCannotAddGlassesWithZeroImageCount() public { vm.prank(descriptor); vm.expectRevert(INounsArt.BadImageCount.selector); - art.addGlasses(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, 0); + art.addGlasses(FIRST_TWO_IMAGES_COMPRESSED, FIRST_TWO_IMAGES_DEFLATED_LENGTH, 0); } function testAddGlassesWorksWithMultiplePages() public { assertEq(art.glassesTrait().storedImagesCount, 0); vm.startPrank(descriptor); - art.addGlasses(fromHex(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); - art.addGlasses(fromHex(NEXT_TWO_IMAGES_COMPRESSED), NEXT_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); + art.addGlasses(FIRST_TWO_IMAGES_COMPRESSED, FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); + art.addGlasses(NEXT_TWO_IMAGES_COMPRESSED, NEXT_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); vm.stopPrank(); _assertGlassesStoredOK(); } function testCannotAddGlassesFromPointerWithZeroDecompressedLength() public { - address pointer = SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)); + address pointer = SSTORE2.write(FIRST_TWO_IMAGES_COMPRESSED); vm.prank(descriptor); vm.expectRevert(INounsArt.BadDecompressedLength.selector); art.addGlassesFromPointer(pointer, 0, 0); } function testCannotAddGlassesFromPointerWithZeroImageCount() public { - address pointer = SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)); + address pointer = SSTORE2.write(FIRST_TWO_IMAGES_COMPRESSED); vm.prank(descriptor); vm.expectRevert(INounsArt.BadImageCount.selector); art.addGlassesFromPointer(pointer, FIRST_TWO_IMAGES_DEFLATED_LENGTH, 0); @@ -442,12 +433,12 @@ contract NounsArtTest is Test, Utils { vm.startPrank(descriptor); art.addGlassesFromPointer( - SSTORE2.write(fromHex(FIRST_TWO_IMAGES_COMPRESSED)), + SSTORE2.write(FIRST_TWO_IMAGES_COMPRESSED), FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2) ); art.addGlassesFromPointer( - SSTORE2.write(fromHex(NEXT_TWO_IMAGES_COMPRESSED)), + SSTORE2.write(NEXT_TWO_IMAGES_COMPRESSED), NEXT_TWO_IMAGES_DEFLATED_LENGTH, uint16(2) ); @@ -464,68 +455,68 @@ contract NounsArtTest is Test, Utils { assertEq(art.bodiesTrait().storedImagesCount, 4); // These hard-coded values are copied from image-data.json -> images -> BODIES -> the first items - assertEq(art.bodies(0), fromHex(IMAGE_0)); - assertEq(art.bodies(1), fromHex(IMAGE_1)); + assertEq(art.bodies(0), IMAGE_0); + assertEq(art.bodies(1), IMAGE_1); // These hard-coded values are copied from image-data.json -> images -> HEADS -> the first items - assertEq(art.bodies(2), fromHex(IMAGE_2)); - assertEq(art.bodies(3), fromHex(IMAGE_3)); + assertEq(art.bodies(2), IMAGE_2); + assertEq(art.bodies(3), IMAGE_3); } function _assertAccessoriesStoredOK() internal { assertEq(art.accessoriesTrait().storedImagesCount, 4); // These hard-coded values are copied from image-data.json -> images -> BODIES -> the first items - assertEq(art.accessories(0), fromHex(IMAGE_0)); - assertEq(art.accessories(1), fromHex(IMAGE_1)); + assertEq(art.accessories(0), IMAGE_0); + assertEq(art.accessories(1), IMAGE_1); // These hard-coded values are copied from image-data.json -> images -> HEADS -> the first items - assertEq(art.accessories(2), fromHex(IMAGE_2)); - assertEq(art.accessories(3), fromHex(IMAGE_3)); + assertEq(art.accessories(2), IMAGE_2); + assertEq(art.accessories(3), IMAGE_3); } function _assertHeadsStoredOK() internal { assertEq(art.headsTrait().storedImagesCount, 4); // These hard-coded values are copied from image-data.json -> images -> BODIES -> the first items - assertEq(art.heads(0), fromHex(IMAGE_0)); - assertEq(art.heads(1), fromHex(IMAGE_1)); + assertEq(art.heads(0), IMAGE_0); + assertEq(art.heads(1), IMAGE_1); // These hard-coded values are copied from image-data.json -> images -> HEADS -> the first items - assertEq(art.heads(2), fromHex(IMAGE_2)); - assertEq(art.heads(3), fromHex(IMAGE_3)); + assertEq(art.heads(2), IMAGE_2); + assertEq(art.heads(3), IMAGE_3); } function _assertGlassesStoredOK() internal { assertEq(art.glassesTrait().storedImagesCount, 4); // These hard-coded values are copied from image-data.json -> images -> BODIES -> the first items - assertEq(art.glasses(0), fromHex(IMAGE_0)); - assertEq(art.glasses(1), fromHex(IMAGE_1)); + assertEq(art.glasses(0), IMAGE_0); + assertEq(art.glasses(1), IMAGE_1); // These hard-coded values are copied from image-data.json -> images -> HEADS -> the first items - assertEq(art.glasses(2), fromHex(IMAGE_2)); - assertEq(art.glasses(3), fromHex(IMAGE_3)); + assertEq(art.glasses(2), IMAGE_2); + assertEq(art.glasses(3), IMAGE_3); } // the value below was copied from running the hardhat task `descriptor-art-to-console` with // the parameter `count` set to 2, and taking the bodies values. - string constant FIRST_TWO_IMAGES_COMPRESSED = - '6360c00b14f04b33301190772020bf8080bc3983a8b83c271f130432313132701345123016dd7c6608646206ea258a841b0000'; + bytes constant FIRST_TWO_IMAGES_COMPRESSED = + hex'6360c00b14f04b33301190772020bf8080bc3983a8b83c271f130432313132701345123016dd7c6608646206ea258a841b0000'; uint80 constant FIRST_TWO_IMAGES_DEFLATED_LENGTH = 320; // the value below was copied from running the hardhat task `descriptor-art-to-console` with // the parameter `count` set to 2 and `start` set to 2, and taking the heads values. - string constant NEXT_TWO_IMAGES_COMPRESSED = - '858f410a02310c4593b4d38ee0548551145cb8ea21baf24e82eb8c77f23e1ec5df0e232a3a0dfcfcd7fc4253a2d93acdc72495fc5cc91f95fc42cda17786ac2ef1d6425b620a6ac12b15f01a7de4a9b386e1bf9bd25979605d0d5cc86877636db4c34c68a395953eea4ee6d81b4721353476ec9602647e1236f160483ce7ad3c4749d6bb6831e388337e955da2f31692d7acc5ad76e4b4cb9eb2b6dfe44b3a39ed21efcd351416cab3b77a02'; + bytes constant NEXT_TWO_IMAGES_COMPRESSED = + hex'858f410a02310c4593b4d38ee0548551145cb8ea21baf24e82eb8c77f23e1ec5df0e232a3a0dfcfcd7fc4253a2d93acdc72495fc5cc91f95fc42cda17786ac2ef1d6425b620a6ac12b15f01a7de4a9b386e1bf9bd25979605d0d5cc86877636db4c34c68a395953eea4ee6d81b4721353476ec9602647e1236f160483ce7ad3c4749d6bb6831e388337e955da2f31692d7acc5ad76e4b4cb9eb2b6dfe44b3a39ed21efcd351416cab3b77a02'; uint80 constant NEXT_TWO_IMAGES_DEFLATED_LENGTH = 512; - string constant IMAGE_0 = - '0015171f090e020e020e020e02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02'; - string constant IMAGE_1 = - '0015171f090e030e030e030e03020301000b03020301000b03020301000b03020301000b03020301000b03020301000b03020301000b03'; - string constant IMAGE_2 = - '0005191406030004800c0002000980080001000e80040002000f80020001001080020002000f80020002000f800200020001800e810200020001800e810200020001800e810200020001800e81020003800e8102000180018101800f8101000180018103800d82018005800d81018002001180'; - string constant IMAGE_3 = - '00031c140306000e3a050006000e3a05000400023a0e00023a03000400023a0e00023a03000400023a0e00023a030002000207023a0e07023a02070100020001070126023a040706260407023a01260107010001000126010702260607042606070226010701000100012608070626080701000100013a16070100013a0100013a15070100013a0100013a15070100013a0107013a1607013a0107013a1607010018070100070703760e0701001807020016070100'; + bytes constant IMAGE_0 = + hex'0015171f090e020e020e020e02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02'; + bytes constant IMAGE_1 = + hex'0015171f090e030e030e030e03020301000b03020301000b03020301000b03020301000b03020301000b03020301000b03020301000b03'; + bytes constant IMAGE_2 = + hex'0005191406030004800c0002000980080001000e80040002000f80020001001080020002000f80020002000f800200020001800e810200020001800e810200020001800e810200020001800e81020003800e8102000180018101800f8101000180018103800d82018005800d81018002001180'; + bytes constant IMAGE_3 = + hex'00031c140306000e3a050006000e3a05000400023a0e00023a03000400023a0e00023a03000400023a0e00023a030002000207023a0e07023a02070100020001070126023a040706260407023a01260107010001000126010702260607042606070226010701000100012608070626080701000100013a16070100013a0100013a15070100013a0100013a15070100013a0107013a1607013a0107013a1607010018070100070703760e0701001807020016070100'; } diff --git a/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol b/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol index 239ecdf3d5..8802babff2 100644 --- a/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol +++ b/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol @@ -3,31 +3,22 @@ pragma solidity ^0.8.6; import { NounsDescriptor } from '../../../contracts/NounsDescriptor.sol'; import { NounsDescriptorV2 } from '../../../contracts/NounsDescriptorV2.sol'; -import { Utils } from './Utils.sol'; import { Constants } from './Constants.sol'; -abstract contract DescriptorHelpers is Utils, Constants { +abstract contract DescriptorHelpers is Constants { function _populateDescriptor(NounsDescriptor descriptor) internal { descriptor.addBackground('d5d7e1'); descriptor.addAccessory( - fromHex( - '0017141e0d0100011f0500021f05000100011f0300011f01000100011f0200011f02000300011f03000200011f0200021f0100011f0200011f0100011f0400011f0100011f' - ) + hex'0017141e0d0100011f0500021f05000100011f0300011f01000100011f0200011f02000300011f03000200011f0200021f0100011f0200011f0100011f0400011f0100011f' ); descriptor.addBody( - fromHex( - '0015171f090e020e020e020e02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02' - ) + hex'0015171f090e020e020e020e02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02' ); descriptor.addGlasses( - fromHex( - '000b1710070300062001000620030001200201022301200100012002010223012004200201022303200201022301200420020102230320020102230120012002000120020102230120010001200201022301200300062001000620' - ) + hex'000b1710070300062001000620030001200201022301200100012002010223012004200201022303200201022301200420020102230320020102230120012002000120020102230120010001200201022301200300062001000620' ); descriptor.addHead( - fromHex( - '00021e140605000137020001370f0004000237020002370e0003000337020003370d0002000437020004370c0003000337020003370d0004000237020002370e0005000137020001370f000d370b000d370b000d370b000d370b000d370b000d370b000d370600057d0d370600017d017e017d017e017d0b37097d017e017d017e017d0b370d7d0a370523097d0b370d7d' - ) + hex'00021e140605000137020001370f0004000237020002370e0003000337020003370d0002000437020004370c0003000337020003370d0004000237020002370e0005000137020001370f000d370b000d370b000d370b000d370b000d370b000d370b000d370600057d0d370600017d017e017d017e017d0b37097d017e017d017e017d0b370d7d0a370523097d0b370d7d' ); descriptor.addManyColorsToPalette(0, paletteColors); } @@ -39,32 +30,24 @@ abstract contract DescriptorHelpers is Utils, Constants { function _populateDescriptorV2(NounsDescriptorV2 descriptorV2) internal { descriptorV2.addBackground('d5d7e1'); descriptorV2.addAccessories( - fromHex( - '6360c00b14f04b3330129027a4df95415c448e979181519e95810988412c66206604b398c098192c066133c9c3c441340b94c6630100' - ), + hex'6360c00b14f04b3330129027a4df95415c448e979181519e95810988412c66206604b398c098192c066133c9c3c441340b94c6630100', 224, 1 ); - descriptorV2.addBodies(fromHex('6360c00b14f04b3330129027a4df9c41545c9e938f090299981819b88922e1060000'), 192, 1); + descriptorV2.addBodies(hex'6360c00b14f04b3330129027a4df9c41545c9e938f090299981819b88922e1060000', 192, 1); descriptorV2.addGlasses( - fromHex( - '6360c00b14f04b3330129027a43f9a815b5c809d99814d811188991918159818999419813c188b054c3363e501d560d101330d6c0100' - ), + hex'6360c00b14f04b3330129027a43f9a815b5c809d99814d811188991918159818999419813c188b054c3363e501d560d101330d6c0100', 224, 1 ); descriptorV2.addHeads( - fromHex( - '6360c00b14f04b3330129027a47f2203939c081b2b03a3391310f333b0303001594ce67c0ccc0ccc4016b3392f0313038b3908f3208921d421f4f29a73e3c06c0cacb52092b196b10e82b9cd3991d8bcb55ce6acca9c60169a0301' - ), + hex'6360c00b14f04b3330129027a47f2203939c081b2b03a3391310f333b0303001594ce67c0ccc0ccc4016b3392f0313038b3908f3208921d421f4f29a73e3c06c0cacb52092b196b10e82b9cd3991d8bcb55ce6acca9c60169a0301', 288, 1 ); descriptorV2.setPalette( 0, - fromHex( - '000000ffffffc5b9a1cfc2ab63a0f9807f7ecaeff95648ed5a423fb9185cb87b11fffdf24b49493432351f1d29068940867c1dae32089f21a0f98f30fe500cd26451fd8b5b5a65fad22209e9265cc54e3880a72d4bea6934ac80eed81162616dff638d8bc0c5c4da53000000f3322cffae1affc110505a5cffef16fff671fff449db8323df2c39f938d85c25fb2a86fd45faff38dd56ff3a0ed32a099037076e3206552e05e8705bf38b7ce4a499667af9648df97cc4f297f2fba3efd087e4d971bde4ff1a0bf78a182b83f6d62149834398ffc925d9391fbd2d24ff7216254efbe5e5de00a556c5030eabf131fb4694e7a32cfff0ee009c590385eb00499ce1183326b1f3fff0bed8dadfd7d3cd1929f4eab1180b5027f9f5cbcfc9b8feb9d5f8d6895d606176858b757576ff0e0e0adc4dfdf8ff70e890f7913dff1ad2ff82ad535a15fa6fe2ffe939ab36beadc8cc604666f20422abaaa84b65f7a19c9a58565cda42cb027c92cec189909b0e74580d027ee6b2958defad817d635eeff2fa6f597ad4b7b2d18687cd916d6b3f394d271b85634ff9f4e6f8ddb0b92b3cd08b11257ceda3baed5fd4fbc16710a28ef43a085b67b1e31e3445ffd067962236769ca95a6b7b7e5243a86f608f785ecc059542ffb0d56333b8ced2b91b43f39713e8e8e2ec5b43235476b2a8a5d6c3be49b38bfccf25f59b34375dfc99e6de27a463554543b19e00d4a0159f4b27f9e8dd6b72129d8e6e4243f8fa5e20f82905555353876f69410d66552d1df71248fee3f3c169232b28340079fcd31e14f830018dd122fffdf4ffa21ee4afa3fbc311aa940ceedc00fff0069cb4b8a38654ae6c0a2bb26be2c8c0f89865f86100dcd8d3049d43d0aea9f39d44eeb78cf9f5e95d3500c3a199aaa6a4caa26afde7f5fdf008fdcef2f681e6018146d19a549eb5e1f5fcff3f932300fcff4a5358fbc800d596a6ffb913e9ba12767c0ef9f6d1d29607f8ce47395ed1ffc5f0cbc1bcd4cfc0' - ) + hex'000000ffffffc5b9a1cfc2ab63a0f9807f7ecaeff95648ed5a423fb9185cb87b11fffdf24b49493432351f1d29068940867c1dae32089f21a0f98f30fe500cd26451fd8b5b5a65fad22209e9265cc54e3880a72d4bea6934ac80eed81162616dff638d8bc0c5c4da53000000f3322cffae1affc110505a5cffef16fff671fff449db8323df2c39f938d85c25fb2a86fd45faff38dd56ff3a0ed32a099037076e3206552e05e8705bf38b7ce4a499667af9648df97cc4f297f2fba3efd087e4d971bde4ff1a0bf78a182b83f6d62149834398ffc925d9391fbd2d24ff7216254efbe5e5de00a556c5030eabf131fb4694e7a32cfff0ee009c590385eb00499ce1183326b1f3fff0bed8dadfd7d3cd1929f4eab1180b5027f9f5cbcfc9b8feb9d5f8d6895d606176858b757576ff0e0e0adc4dfdf8ff70e890f7913dff1ad2ff82ad535a15fa6fe2ffe939ab36beadc8cc604666f20422abaaa84b65f7a19c9a58565cda42cb027c92cec189909b0e74580d027ee6b2958defad817d635eeff2fa6f597ad4b7b2d18687cd916d6b3f394d271b85634ff9f4e6f8ddb0b92b3cd08b11257ceda3baed5fd4fbc16710a28ef43a085b67b1e31e3445ffd067962236769ca95a6b7b7e5243a86f608f785ecc059542ffb0d56333b8ced2b91b43f39713e8e8e2ec5b43235476b2a8a5d6c3be49b38bfccf25f59b34375dfc99e6de27a463554543b19e00d4a0159f4b27f9e8dd6b72129d8e6e4243f8fa5e20f82905555353876f69410d66552d1df71248fee3f3c169232b28340079fcd31e14f830018dd122fffdf4ffa21ee4afa3fbc311aa940ceedc00fff0069cb4b8a38654ae6c0a2bb26be2c8c0f89865f86100dcd8d3049d43d0aea9f39d44eeb78cf9f5e95d3500c3a199aaa6a4caa26afde7f5fdf008fdcef2f681e6018146d19a549eb5e1f5fcff3f932300fcff4a5358fbc800d596a6ffb913e9ba12767c0ef9f6d1d29607f8ce47395ed1ffc5f0cbc1bcd4cfc0' ); } } diff --git a/packages/nouns-contracts/test/foundry/helpers/Utils.sol b/packages/nouns-contracts/test/foundry/helpers/Utils.sol deleted file mode 100644 index 972a71f180..0000000000 --- a/packages/nouns-contracts/test/foundry/helpers/Utils.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.6; - -abstract contract Utils { - // Convert an hexadecimal string to raw bytes - function fromHex(string memory s) internal pure returns (bytes memory) { - bytes memory ss = bytes(s); - require(ss.length % 2 == 0); // length must be even - bytes memory r = new bytes(ss.length / 2); - for (uint256 i = 0; i < ss.length / 2; ++i) { - r[i] = bytes1(fromHexChar(uint8(ss[2 * i])) * 16 + fromHexChar(uint8(ss[2 * i + 1]))); - } - return r; - } - - // Convert an hexadecimal character to their value - function fromHexChar(uint8 c) internal pure returns (uint8) { - if (bytes1(c) >= bytes1('0') && bytes1(c) <= bytes1('9')) { - return c - uint8(bytes1('0')); - } - if (bytes1(c) >= bytes1('a') && bytes1(c) <= bytes1('f')) { - return 10 + c - uint8(bytes1('a')); - } - if (bytes1(c) >= bytes1('A') && bytes1(c) <= bytes1('F')) { - return 10 + c - uint8(bytes1('A')); - } - revert('fail'); - } -} From 7d183566d9191948f8847a9c2cc38131e2b44255 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Thu, 30 Jun 2022 12:03:50 -0500 Subject: [PATCH 042/116] test cleanup --- packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol b/packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol index f70285eef6..97c0e9cf35 100644 --- a/packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol +++ b/packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol @@ -29,7 +29,6 @@ contract DescriptorUpgradeTest is Test, DeployUtils { string memory tokenURIwithV1 = nounsToken.tokenURI(1); NounsDescriptorV2 descriptorV2 = _deployAndPopulateV2(); - _populateDescriptorV2(descriptorV2); nounsToken.setDescriptor(descriptorV2); string memory tokenURIwithV2 = nounsToken.tokenURI(1); From 8988ec2a0b17fee69557c56bbe6195f207e94aa6 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Thu, 30 Jun 2022 12:15:07 -0500 Subject: [PATCH 043/116] remove comment --- packages/nouns-contracts/contracts/interfaces/ISVGRenderer.sol | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/nouns-contracts/contracts/interfaces/ISVGRenderer.sol b/packages/nouns-contracts/contracts/interfaces/ISVGRenderer.sol index 1d6df0f4dc..5935b0f935 100644 --- a/packages/nouns-contracts/contracts/interfaces/ISVGRenderer.sol +++ b/packages/nouns-contracts/contracts/interfaces/ISVGRenderer.sol @@ -17,9 +17,6 @@ pragma solidity ^0.8.6; -// TODO: Generalize to `IRenderer`? -// May be a day when we drop SVG support. - interface ISVGRenderer { struct Part { bytes image; From 606826bbc8f0b087b9f89fe48ce852e550458789 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Thu, 30 Jun 2022 12:32:04 -0500 Subject: [PATCH 044/116] cleanup per CR --- .../tasks/descriptor-art-to-console.ts | 64 +++------------ .../tasks/populate-descriptor.ts | 81 ++++++------------- packages/nouns-contracts/tasks/utils/index.ts | 22 +++++ 3 files changed, 61 insertions(+), 106 deletions(-) create mode 100644 packages/nouns-contracts/tasks/utils/index.ts diff --git a/packages/nouns-contracts/tasks/descriptor-art-to-console.ts b/packages/nouns-contracts/tasks/descriptor-art-to-console.ts index 9c111ab76e..502fb9da17 100644 --- a/packages/nouns-contracts/tasks/descriptor-art-to-console.ts +++ b/packages/nouns-contracts/tasks/descriptor-art-to-console.ts @@ -1,7 +1,6 @@ import { task, types } from 'hardhat/config'; import ImageData from '../files/image-data.json'; -import { deflateRawSync } from 'zlib'; -import { ethers } from 'ethers'; +import { dataToDescriptorInput } from './utils'; task( 'descriptor-art-to-console', @@ -27,65 +26,28 @@ task( glasses = glasses.slice(start, count + start); } - const { - encodedCompressed: bodiesCompressed, - originalLength: bodiesLength, - itemCount: bodiesCount, - } = dataToDescriptorInput(bodies.map(({ data }) => data)); - const { - encodedCompressed: accessoriesCompressed, - originalLength: accessoriesLength, - itemCount: accessoriesCount, - } = dataToDescriptorInput(accessories.map(({ data }) => data)); - const { - encodedCompressed: headsCompressed, - originalLength: headsLength, - itemCount: headsCount, - } = dataToDescriptorInput(heads.map(({ data }) => data)); - const { - encodedCompressed: glassesCompressed, - originalLength: glassesLength, - itemCount: glassesCount, - } = dataToDescriptorInput(glasses.map(({ data }) => data)); - + const bodiesPage = dataToDescriptorInput(bodies.map(({ data }) => data)); + const accessoriesPage = dataToDescriptorInput(accessories.map(({ data }) => data)); + const headsPage = dataToDescriptorInput(heads.map(({ data }) => data)); + const glassesPage = dataToDescriptorInput(glasses.map(({ data }) => data)); const paletteValue = `0x000000${palette.join('')}`; console.log('=== PALETTE ===\n'); console.log(`paletteValue: '${paletteValue}'\n`); console.log('=== BODIES ===\n'); - console.log(`bodiesCompressed: '${bodiesCompressed}'\n`); - console.log(`bodiesLength: ${bodiesLength}\n`); + console.log(`bodiesCompressed: '${bodiesPage.encodedCompressed}'\n`); + console.log(`bodiesLength: ${bodiesPage.originalLength}\n`); console.log('=== ACCESSORIES ===\n'); - console.log(`accessoriesCompressed: '${accessoriesCompressed}'\n`); - console.log(`accessoriesLength: ${accessoriesLength}\n`); + console.log(`accessoriesCompressed: '${accessoriesPage.encodedCompressed}'\n`); + console.log(`accessoriesLength: ${accessoriesPage.originalLength}\n`); console.log('=== HEADS ===\n'); - console.log(`headsCompressed: '${headsCompressed}'\n`); - console.log(`headsLength: ${headsLength}\n`); + console.log(`headsCompressed: '${headsPage.encodedCompressed}'\n`); + console.log(`headsLength: ${headsPage.originalLength}\n`); console.log('=== GLASSES ===\n'); - console.log(`glassesCompressed: '${glassesCompressed}'\n`); - console.log(`glassesLength: ${glassesLength}\n`); + console.log(`glassesCompressed: '${glassesPage.encodedCompressed}'\n`); + console.log(`glassesLength: ${glassesPage.originalLength}\n`); }); - -function dataToDescriptorInput(data: string[]): { - encodedCompressed: string; - originalLength: number; - itemCount: number; -} { - const abiEncoded = ethers.utils.defaultAbiCoder.encode(['bytes[]'], [data]); - const encodedCompressed = `0x${deflateRawSync( - Buffer.from(abiEncoded.substring(2), 'hex'), - ).toString('hex')}`; - - const originalLength = abiEncoded.substring(2).length / 2; - const itemCount = data.length; - - return { - encodedCompressed, - originalLength, - itemCount, - }; -} diff --git a/packages/nouns-contracts/tasks/populate-descriptor.ts b/packages/nouns-contracts/tasks/populate-descriptor.ts index 2db9489458..8de141b295 100644 --- a/packages/nouns-contracts/tasks/populate-descriptor.ts +++ b/packages/nouns-contracts/tasks/populate-descriptor.ts @@ -1,8 +1,6 @@ import { task, types } from 'hardhat/config'; import ImageData from '../files/image-data.json'; -import { chunkArray } from '../utils'; -import { deflateRawSync } from 'zlib'; -import { ethers } from 'ethers'; +import { dataToDescriptorInput } from './utils'; task('populate-descriptor', 'Populates the descriptor with color palettes and Noun parts') .addOptionalParam( @@ -28,65 +26,38 @@ task('populate-descriptor', 'Populates the descriptor with color palettes and No const { bgcolors, palette, images } = ImageData; const { bodies, accessories, heads, glasses } = images; - const { - encodedCompressed: bodiesCompressed, - originalLength: bodiesLength, - itemCount: bodiesCount, - } = dataToDescriptorInput(bodies.map(({ data }) => data)); - const { - encodedCompressed: accessoriesCompressed, - originalLength: accessoriesLength, - itemCount: accessoriesCount, - } = dataToDescriptorInput(accessories.map(({ data }) => data)); - const { - encodedCompressed: headsCompressed, - originalLength: headsLength, - itemCount: headsCount, - } = dataToDescriptorInput(heads.map(({ data }) => data)); - const { - encodedCompressed: glassesCompressed, - originalLength: glassesLength, - itemCount: glassesCount, - } = dataToDescriptorInput(glasses.map(({ data }) => data)); + const bodiesPage = dataToDescriptorInput(bodies.map(({ data }) => data)); + const headsPage = dataToDescriptorInput(heads.map(({ data }) => data)); + const glassesPage = dataToDescriptorInput(glasses.map(({ data }) => data)); + const accessoriesPage = dataToDescriptorInput(accessories.map(({ data }) => data)); await descriptorContract.addManyBackgrounds(bgcolors); await descriptorContract.setPalette(0, `0x000000${palette.join('')}`); - await descriptorContract.addBodies(bodiesCompressed, bodiesLength, bodiesCount, { - gasLimit: 30_000_000, - }); - await descriptorContract.addHeads(headsCompressed, headsLength, headsCount, { - gasLimit: 30_000_000, - }); - await descriptorContract.addGlasses(glassesCompressed, glassesLength, glassesCount, { - gasLimit: 30_000_000, - }); + await descriptorContract.addBodies( + bodiesPage.encodedCompressed, + bodiesPage.originalLength, + bodiesPage.itemCount, + { gasLimit: 30_000_000 }, + ); + await descriptorContract.addHeads( + headsPage.encodedCompressed, + headsPage.originalLength, + headsPage.itemCount, + { gasLimit: 30_000_000 }, + ); + await descriptorContract.addGlasses( + glassesPage.encodedCompressed, + glassesPage.originalLength, + glassesPage.itemCount, + { gasLimit: 30_000_000 }, + ); await descriptorContract.addAccessories( - accessoriesCompressed, - accessoriesLength, - accessoriesCount, + accessoriesPage.encodedCompressed, + accessoriesPage.originalLength, + accessoriesPage.itemCount, { gasLimit: 30_000_000 }, ); console.log('Descriptor populated with palettes and parts.'); }); - -function dataToDescriptorInput(data: string[]): { - encodedCompressed: string; - originalLength: number; - itemCount: number; -} { - const abiEncoded = ethers.utils.defaultAbiCoder.encode(['bytes[]'], [data]); - const encodedCompressed = `0x${deflateRawSync( - Buffer.from(abiEncoded.substring(2), 'hex'), - ).toString('hex')}`; - - const originalLength = abiEncoded.substring(2).length / 2; - const itemCount = data.length; - - return { - encodedCompressed, - originalLength, - itemCount, - }; -} diff --git a/packages/nouns-contracts/tasks/utils/index.ts b/packages/nouns-contracts/tasks/utils/index.ts new file mode 100644 index 0000000000..07ffbcc498 --- /dev/null +++ b/packages/nouns-contracts/tasks/utils/index.ts @@ -0,0 +1,22 @@ +import { ethers } from 'ethers'; +import { deflateRawSync } from 'zlib'; + +export function dataToDescriptorInput(data: string[]): { + encodedCompressed: string; + originalLength: number; + itemCount: number; +} { + const abiEncoded = ethers.utils.defaultAbiCoder.encode(['bytes[]'], [data]); + const encodedCompressed = `0x${deflateRawSync( + Buffer.from(abiEncoded.substring(2), 'hex'), + ).toString('hex')}`; + + const originalLength = abiEncoded.substring(2).length / 2; + const itemCount = data.length; + + return { + encodedCompressed, + originalLength, + itemCount, + }; +} From 19097d56f7ca324f28adf9500a40c77f0694e11a Mon Sep 17 00:00:00 2001 From: eladmallel Date: Thu, 30 Jun 2022 12:44:49 -0500 Subject: [PATCH 045/116] get coverage working with custom errors --- packages/nouns-contracts/.solcover.js | 1 + packages/nouns-contracts/hardhat.config.ts | 2 +- packages/nouns-contracts/package.json | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/nouns-contracts/.solcover.js b/packages/nouns-contracts/.solcover.js index fea730f945..40aa1cd5d6 100644 --- a/packages/nouns-contracts/.solcover.js +++ b/packages/nouns-contracts/.solcover.js @@ -3,4 +3,5 @@ module.exports = { // WETH is for testing purposes only 'test/WETH.sol', ], + configureYulOptimizer: true, }; diff --git a/packages/nouns-contracts/hardhat.config.ts b/packages/nouns-contracts/hardhat.config.ts index a95f899dff..493b2e43e4 100644 --- a/packages/nouns-contracts/hardhat.config.ts +++ b/packages/nouns-contracts/hardhat.config.ts @@ -3,7 +3,7 @@ import { HardhatUserConfig } from 'hardhat/config'; import dotenv from 'dotenv'; import '@nomiclabs/hardhat-waffle'; import '@nomiclabs/hardhat-etherscan'; -import '@float-capital/solidity-coverage'; +import 'solidity-coverage'; import '@typechain/hardhat'; import 'hardhat-abi-exporter'; import '@openzeppelin/hardhat-upgrades'; diff --git a/packages/nouns-contracts/package.json b/packages/nouns-contracts/package.json index 2cf4ec8475..15e20edf69 100644 --- a/packages/nouns-contracts/package.json +++ b/packages/nouns-contracts/package.json @@ -25,7 +25,7 @@ "prepare": "yarn build" }, "devDependencies": { - "@float-capital/solidity-coverage": "^0.7.17", + "solidity-coverage": "0.7.21", "@nomiclabs/hardhat-ethers": "^2.0.6", "@nomiclabs/hardhat-etherscan": "^3.0.3", "@nomiclabs/hardhat-waffle": "^2.0.3", From 5a2df0db756a2cb5895e3df44be2718a4a492a87 Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Fri, 1 Jul 2022 12:03:47 +0200 Subject: [PATCH 046/116] multi rle encoder: limit at 255 length, and added tests --- packages/nouns-sdk/src/image/image2.ts | 2 +- packages/nouns-sdk/src/image/svg-builder.ts | 2 +- packages/nouns-sdk/test/image2.test.ts | 140 +++++++++++++++++--- 3 files changed, 125 insertions(+), 19 deletions(-) diff --git a/packages/nouns-sdk/src/image/image2.ts b/packages/nouns-sdk/src/image/image2.ts index 175e25ff30..45cda225ed 100644 --- a/packages/nouns-sdk/src/image/image2.ts +++ b/packages/nouns-sdk/src/image/image2.ts @@ -74,7 +74,7 @@ export class Image2 { let count = 1; for (let i = 1; i < data.length; i++) { - if (data[i] !== previous) { + if (data[i] !== previous || count === 255) { encoding.push(toPaddedHex(count), toPaddedHex(previous)); this.tuples.push([count, previous]); count = 1; diff --git a/packages/nouns-sdk/src/image/svg-builder.ts b/packages/nouns-sdk/src/image/svg-builder.ts index a1ec8f2829..e8796bba9d 100644 --- a/packages/nouns-sdk/src/image/svg-builder.ts +++ b/packages/nouns-sdk/src/image/svg-builder.ts @@ -4,7 +4,7 @@ import { DecodedImage } from './types'; * Decode the RLE image data into a format that's easier to consume in `buildSVG`. * @param image The RLE image data */ -const decodeImage = (image: string): DecodedImage => { +export const decodeImage = (image: string): DecodedImage => { const data = image.replace(/^0x/, ''); const paletteIndex = parseInt(data.substring(0, 2), 16); const bounds = { diff --git a/packages/nouns-sdk/test/image2.test.ts b/packages/nouns-sdk/test/image2.test.ts index 1dcea25a0a..901de557c0 100644 --- a/packages/nouns-sdk/test/image2.test.ts +++ b/packages/nouns-sdk/test/image2.test.ts @@ -3,8 +3,9 @@ import { join } from 'path'; import { Image2 } from '../src/image/image2'; import { Image } from '../src/image/image'; import { readPngImage } from './lib'; -import { buildSVG } from '../src'; +import { buildSVG, RGBAColor } from '../src'; import { glob } from 'glob'; +import { decodeImage } from '../src/image/svg-builder'; async function encodeSingleLineRLE(filepath: string) { const transparent: [string, number] = ['', 0]; @@ -25,30 +26,135 @@ async function encodeMultiLineRLE(filepath: string) { } describe('Image2', () => { - it('builds the same svg with both encoders', async () => { - const filepath = join(__dirname, `./lib/images/head-cone.png`); - const { rle: rle1, colors: colors1 } = await encodeSingleLineRLE(filepath); - const { rle: rle2, colors: colors2 } = await encodeMultiLineRLE(filepath); + describe('Comparing single line RLE to multiline RLE encoding', async () => { + it('builds the same svg with both encoders', async () => { + const filepath = join(__dirname, `./lib/images/head-cone.png`); + const { rle: rle1, colors: colors1 } = await encodeSingleLineRLE(filepath); + const { rle: rle2, colors: colors2 } = await encodeMultiLineRLE(filepath); + + const svg1 = buildSVG([{ data: rle1 }], Array.from(colors1.keys()), 'ffffff'); + const svg2 = buildSVG([{ data: rle2 }], Array.from(colors2.keys()), 'ffffff'); + + expect(svg1).to.be.equal(svg2); + }); + + it('builds the same svg for all images', async () => { + const transparent: [string, number] = ['', 0]; - const svg1 = buildSVG([{ data: rle1 }], Array.from(colors1.keys()), 'ffffff'); - const svg2 = buildSVG([{ data: rle2 }], Array.from(colors2.keys()), 'ffffff'); + const filepaths = glob.sync(join(__dirname, '../../nouns-assets/images/+(1|2|3|4)*/*.png')); - expect(svg1).to.be.equal(svg2); + for (const filepath of filepaths) { + const { rle: rle1, colors: colors1 } = await encodeSingleLineRLE(filepath); + const { rle: rle2, colors: colors2 } = await encodeMultiLineRLE(filepath); + + const svg1 = buildSVG([{ data: rle1 }], Array.from(colors1.keys()), 'ffffff'); + const svg2 = buildSVG([{ data: rle2 }], Array.from(colors2.keys()), 'ffffff'); + + expect(svg1).to.be.equal(svg2); + } + }); }); - it('builds the same svg for all images', async () => { + describe('Multiline RLE encoding', async () => { + const R: RGBAColor = { r: 255, g: 0, b: 0, a: 255 }; + const B: RGBAColor = { r: 0, g: 0, b: 255, a: 255 }; + const T: RGBAColor = { r: 0, g: 0, b: 0, a: 0 }; const transparent: [string, number] = ['', 0]; + let colors: Map; - const filepaths = glob.sync(join(__dirname, '../../nouns-assets/images/+(1|2|3|4)*/*.png')); + beforeEach(async () => { + colors = new Map([transparent]); + }); - for (const filepath of filepaths) { - const { rle: rle1, colors: colors1 } = await encodeSingleLineRLE(filepath); - const { rle: rle2, colors: colors2 } = await encodeMultiLineRLE(filepath); + const encodePixels = (pixels: RGBAColor[][], colors: Map) => { + const rle = new Image2(pixels[0].length, pixels.length, (x, y) => pixels[y][x]).toRLE(colors); + const decoded = decodeImage(rle); + const colorsArray = Array.from(colors.keys()); + return { decoded, colorsArray }; + }; - const svg1 = buildSVG([{ data: rle1 }], Array.from(colors1.keys()), 'ffffff'); - const svg2 = buildSVG([{ data: rle2 }], Array.from(colors2.keys()), 'ffffff'); + it('encodes single pixel', async () => { + const pixels: RGBAColor[][] = [[R]]; - expect(svg1).to.be.equal(svg2); - } + const { decoded, colorsArray } = encodePixels(pixels, colors); + + expect(decoded.bounds).to.eql({ top: 0, bottom: 0, left: 0, right: 1 }); + expect(decoded.rects).to.eql([[1, 1]]); + expect(colorsArray[1]).to.eq('ff0000'); + }); + + it('encodes repeating pixel', async () => { + const pixels: RGBAColor[][] = [[R, R, R, R]]; + + const { decoded, colorsArray } = encodePixels(pixels, colors); + + expect(decoded.bounds).to.eql({ top: 0, bottom: 0, left: 0, right: 4 }); + expect(decoded.rects).to.eql([[4, 1]]); + expect(colorsArray[1]).to.eq('ff0000'); + }); + + it('encodes 2 colors', async () => { + const pixels: RGBAColor[][] = [[B, B, B, R, R]]; + + const { decoded, colorsArray } = encodePixels(pixels, colors); + + expect(decoded.bounds).to.eql({ top: 0, bottom: 0, left: 0, right: 5 }); + expect(decoded.rects).to.eql([ + [3, 1], + [2, 2], + ]); + expect(colorsArray[1]).to.eq('0000ff'); + expect(colorsArray[2]).to.eq('ff0000'); + }); + + it('skips transparent rows & columns when calculating bounds', async () => { + const pixels: RGBAColor[][] = [ + [T, T, T, T, T], + [T, T, T, T, T], + [T, T, R, T, T], + [T, T, R, R, T], + [T, T, T, T, T], + ]; + + const { decoded, colorsArray } = encodePixels(pixels, colors); + + expect(decoded.bounds).to.eql({ top: 2, bottom: 3, left: 2, right: 4 }); + expect(decoded.rects).to.eql([ + [1, 1], + [1, 0], + [2, 1], + ]); + }); + + it('encodes RLE over multiple lines', async () => { + const pixels: RGBAColor[][] = [ + [R, R, R, R], + [R, R, B, B], + ]; + + const { decoded, colorsArray } = encodePixels(pixels, colors); + + expect(decoded.bounds).to.eql({ top: 0, bottom: 1, left: 0, right: 4 }); + expect(decoded.rects).to.eql([ + [6, 1], + [2, 2], + ]); + }); + + it('limits RLE to length of 255', async () => { + const pixels: RGBAColor[][] = [ + Array(200).fill(R), + Array(100).fill(R).concat(Array(100).fill(B)), + ]; + + const { decoded, colorsArray } = encodePixels(pixels, colors); + + expect(decoded.bounds).to.eql({ top: 0, bottom: 1, left: 0, right: 200 }); + expect(decoded.rects).to.eql([ + [255, 1], + [45, 1], + [100, 2], + ]); + }); }); }); From fb54fa84cb5414c049ab38e2eae634b60109abc0 Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Sat, 2 Jul 2022 10:56:31 +0200 Subject: [PATCH 047/116] update rle encoding to use multiline RLE this means a given color-length tuple can span multiple rows --- packages/nouns-assets/scripts/encode.ts | 2 +- packages/nouns-assets/src/image-data_v2.json | 1945 +++++++++++++++++ .../nouns-contracts/files/image-data_v2.json | 1945 +++++++++++++++++ .../tasks/populate-descriptor.ts | 2 +- packages/nouns-contracts/test/utils.ts | 18 +- packages/nouns-sdk/src/image/image2.ts | 16 +- .../src/image/png-collection-encoder.ts | 6 +- packages/nouns-sdk/test/image2.test.ts | 10 + packages/nouns-sdk/test/lib/data/expected.ts | 4 +- 9 files changed, 3923 insertions(+), 25 deletions(-) create mode 100644 packages/nouns-assets/src/image-data_v2.json create mode 100644 packages/nouns-contracts/files/image-data_v2.json diff --git a/packages/nouns-assets/scripts/encode.ts b/packages/nouns-assets/scripts/encode.ts index f12dadf311..99f45844e5 100644 --- a/packages/nouns-assets/scripts/encode.ts +++ b/packages/nouns-assets/scripts/encode.ts @@ -3,7 +3,7 @@ import { promises as fs } from 'fs'; import { PNG } from 'pngjs'; import path from 'path'; -const DESTINATION = path.join(__dirname, '../src/image-data.json'); +const DESTINATION = path.join(__dirname, '../src/image-data_v2.json'); /** * Read a PNG image file and return a `PngImage` object. diff --git a/packages/nouns-assets/src/image-data_v2.json b/packages/nouns-assets/src/image-data_v2.json new file mode 100644 index 0000000000..375ef220d5 --- /dev/null +++ b/packages/nouns-assets/src/image-data_v2.json @@ -0,0 +1,1945 @@ +{ + "bgcolors": [ + "d5d7e1", + "e1d7d5" + ], + "palette": [ + "", + "c5b9a1", + "ffffff", + "cfc2ab", + "63a0f9", + "807f7e", + "caeff9", + "5648ed", + "5a423f", + "b9185c", + "b87b11", + "fffdf2", + "4b4949", + "343235", + "1f1d29", + "068940", + "867c1d", + "ae3208", + "9f21a0", + "f98f30", + "fe500c", + "d26451", + "fd8b5b", + "5a65fa", + "d22209", + "e9265c", + "c54e38", + "80a72d", + "4bea69", + "34ac80", + "eed811", + "62616d", + "ff638d", + "8bc0c5", + "c4da53", + "000000", + "f3322c", + "ffae1a", + "ffc110", + "505a5c", + "ffef16", + "fff671", + "fff449", + "db8323", + "df2c39", + "f938d8", + "5c25fb", + "2a86fd", + "45faff", + "38dd56", + "ff3a0e", + "d32a09", + "903707", + "6e3206", + "552e05", + "e8705b", + "f38b7c", + "e4a499", + "667af9", + "648df9", + "7cc4f2", + "97f2fb", + "a3efd0", + "87e4d9", + "71bde4", + "ff1a0b", + "f78a18", + "2b83f6", + "d62149", + "834398", + "ffc925", + "d9391f", + "bd2d24", + "ff7216", + "254efb", + "e5e5de", + "00a556", + "c5030e", + "abf131", + "fb4694", + "e7a32c", + "fff0ee", + "009c59", + "0385eb", + "00499c", + "e11833", + "26b1f3", + "fff0be", + "d8dadf", + "d7d3cd", + "1929f4", + "eab118", + "0b5027", + "f9f5cb", + "cfc9b8", + "feb9d5", + "f8d689", + "5d6061", + "76858b", + "757576", + "ff0e0e", + "0adc4d", + "fdf8ff", + "70e890", + "f7913d", + "ff1ad2", + "ff82ad", + "535a15", + "fa6fe2", + "ffe939", + "ab36be", + "adc8cc", + "604666", + "f20422", + "abaaa8", + "4b65f7", + "a19c9a", + "58565c", + "da42cb", + "027c92", + "cec189", + "909b0e", + "74580d", + "027ee6", + "b2958d", + "efad81", + "7d635e", + "eff2fa", + "6f597a", + "d4b7b2", + "d18687", + "cd916d", + "6b3f39", + "4d271b", + "85634f", + "f9f4e6", + "f8ddb0", + "b92b3c", + "d08b11", + "257ced", + "a3baed", + "5fd4fb", + "c16710", + "a28ef4", + "3a085b", + "67b1e3", + "1e3445", + "ffd067", + "962236", + "769ca9", + "5a6b7b", + "7e5243", + "a86f60", + "8f785e", + "cc0595", + "42ffb0", + "d56333", + "b8ced2", + "f39713", + "e8e8e2", + "ec5b43", + "235476", + "b2a8a5", + "d6c3be", + "49b38b", + "fccf25", + "f59b34", + "375dfc", + "99e6de", + "27a463", + "554543", + "b19e00", + "d4a015", + "9f4b27", + "f9e8dd", + "6b7212", + "9d8e6e", + "4243f8", + "fa5e20", + "f82905", + "555353", + "876f69", + "410d66", + "552d1d", + "f71248", + "fee3f3", + "c16923", + "2b2834", + "0079fc", + "d31e14", + "f83001", + "8dd122", + "fffdf4", + "ffa21e", + "e4afa3", + "fbc311", + "aa940c", + "eedc00", + "fff006", + "9cb4b8", + "a38654", + "ae6c0a", + "2bb26b", + "e2c8c0", + "f89865", + "f86100", + "dcd8d3", + "049d43", + "d0aea9", + "f39d44", + "eeb78c", + "f9f5e9", + "5d3500", + "c3a199", + "aaa6a4", + "caa26a", + "fde7f5", + "fdf008", + "fdcef2", + "f681e6", + "018146", + "d19a54", + "9eb5e1", + "f5fcff", + "3f9323", + "00fcff", + "4a5358", + "fbc800", + "d596a6", + "ffb913", + "e9ba12", + "767c0e", + "f9f6d1", + "d29607", + "f8ce47", + "395ed1", + "ffc5f0", + "cbc1bc", + "d4cfc0" + ], + "images": { + "bodies": [ + { + "filename": "body-bege-bsod", + "data": "0x0015171f093a0101000d0101000d0101000d0101000d0101000d0101000d0101000b01" + }, + { + "filename": "body-bege-crt", + "data": "0x0015171f093a0301000d0301000d0301000d0301000d0301000d0301000d0301000b03" + }, + { + "filename": "body-blue-sky", + "data": "0x0015171f093a0401000d0401000d0401000d0401000d0401000d0401000d0401000b04" + }, + { + "filename": "body-bluegrey", + "data": "0x0015171f093a0501000d0501000d0501000d0501000d0501000d0501000d0501000b05" + }, + { + "filename": "body-cold", + "data": "0x0015171f093a0601000d0601000d0601000d0601000d0601000d0601000d0601000b06" + }, + { + "filename": "body-computerblue", + "data": "0x0015171f093a0701000d0701000d0701000d0701000d0701000d0701000d0701000b07" + }, + { + "filename": "body-darkbrown", + "data": "0x0015171f093a0801000d0801000d0801000d0801000d0801000d0801000d0801000b08" + }, + { + "filename": "body-darkpink", + "data": "0x0015171f093a0901000d0901000d0901000d0901000d0901000d0901000d0901000b09" + }, + { + "filename": "body-foggrey", + "data": "0x0015171f093a0301000d0301000d0301000d0301000d0301000d0301000d0301000b03" + }, + { + "filename": "body-gold", + "data": "0x0015171f093a0a01000d0a01000d0a01000d0a01000d0a01000d0a01000d0a01000b0a" + }, + { + "filename": "body-grayscale-1", + "data": "0x0015171f093a0b01000d0b01000d0b01000d0b01000d0b01000d0b01000d0b01000b0b" + }, + { + "filename": "body-grayscale-7", + "data": "0x0015171f093a0c01000d0c01000d0c01000d0c01000d0c01000d0c01000d0c01000b0c" + }, + { + "filename": "body-grayscale-8", + "data": "0x0015171f093a0d01000d0d01000d0d01000d0d01000d0d01000d0d01000d0d01000b0d" + }, + { + "filename": "body-grayscale-9", + "data": "0x0015171f093a0e01000d0e01000d0e01000d0e01000d0e01000d0e01000d0e01000b0e" + }, + { + "filename": "body-green", + "data": "0x0015171f093a0f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f01000b0f" + }, + { + "filename": "body-gunk", + "data": "0x0015171f093a1001000d1001000d1001000d1001000d1001000d1001000d1001000b10" + }, + { + "filename": "body-hotbrown", + "data": "0x0015171f093a1101000d1101000d1101000d1101000d1101000d1101000d1101000b11" + }, + { + "filename": "body-magenta", + "data": "0x0015171f093a1201000d1201000d1201000d1201000d1201000d1201000d1201000b12" + }, + { + "filename": "body-orange-yellow", + "data": "0x0015171f093a1301000d1301000d1301000d1301000d1301000d1301000d1301000b13" + }, + { + "filename": "body-orange", + "data": "0x0015171f093a1401000d1401000d1401000d1401000d1401000d1401000d1401000b14" + }, + { + "filename": "body-peachy-B", + "data": "0x0015171f093a1501000d1501000d1501000d1501000d1501000d1501000d1501000b15" + }, + { + "filename": "body-peachy-a", + "data": "0x0015171f093a1601000d1601000d1601000d1601000d1601000d1601000d1601000b16" + }, + { + "filename": "body-purple", + "data": "0x0015171f093a1701000d1701000d1701000d1701000d1701000d1701000d1701000b17" + }, + { + "filename": "body-red", + "data": "0x0015171f093a1801000d1801000d1801000d1801000d1801000d1801000d1801000b18" + }, + { + "filename": "body-redpinkish", + "data": "0x0015171f093a1901000d1901000d1901000d1901000d1901000d1901000d1901000b19" + }, + { + "filename": "body-rust", + "data": "0x0015171f093a1a01000d1a01000d1a01000d1a01000d1a01000d1a01000d1a01000b1a" + }, + { + "filename": "body-slimegreen", + "data": "0x0015171f093a1b01000d1b01000d1b01000d1b01000d1b01000d1b01000d1b01000b1b" + }, + { + "filename": "body-teal-light", + "data": "0x0015171f093a1c01000d1c01000d1c01000d1c01000d1c01000d1c01000d1c01000b1c" + }, + { + "filename": "body-teal", + "data": "0x0015171f093a1d01000d1d01000d1d01000d1d01000d1d01000d1d01000d1d01000b1d" + }, + { + "filename": "body-yellow", + "data": "0x0015171f093a1e01000d1e01000d1e01000d1e01000d1e01000d1e01000d1e01000b1e" + } + ], + "accessories": [ + { + "filename": "accessory-1n", + "data": "0x0017141e0d0100011f0500021f0600011f0300011f0200011f0200011f0500011f0500011f0200021f0100011f0200011f0100011f0400011f0100011f" + }, + { + "filename": "accessory-aardvark", + "data": "0x0018151a0d02000320010001200200052002000120010001200100012001000220" + }, + { + "filename": "accessory-axe", + "data": "0x0017141d0e010205210102042101000102032102000102012101000121020001020200012105000121050001210200" + }, + { + "filename": "accessory-belly-chameleon", + "data": "0x0017121e0d0100012201000122060002220100022205000222010002220500022201000122020001220300" + }, + { + "filename": "accessory-bird-flying", + "data": "0x0018151a0d0100022302000223010001230200022302000123030002230300" + }, + { + "filename": "accessory-bird-side", + "data": "0x0017131c0d040001240400022401000424012301250100042403000324020001240400" + }, + { + "filename": "accessory-bling-anchor", + "data": "0x0015141d0d0126050001260100012603000126030001260100012605000126060001260500032605000126040001260100012601000126030003260200" + }, + { + "filename": "accessory-bling-anvil", + "data": "0x0015161e0b012709000127010001270700012703000127050001270500012703000127070003270900010d0700020d05270500020d03270700030d0700020d03270300" + }, + { + "filename": "accessory-bling-arrow", + "data": "0x0018141e0d04000326050002260400012601000126030001260400022604000326050001260500" + }, + { + "filename": "accessory-bling-cheese", + "data": "0x0015141e0c0126060001260100012604000126030001260200012605000226050001260200012603000626030001260128012601280126040004260500012601280126060002260100" + }, + { + "filename": "accessory-bling-gold-ingot", + "data": "0x0015141b0c0126060001260100012604000126030001260200012605000226040006290200042602290200042602290100" + }, + { + "filename": "accessory-bling-love", + "data": "0x0015141d0c0126060001260100012604000126030001260200012605000226050001260200012603000126012804260200062603000426050002260300" + }, + { + "filename": "accessory-bling-mask", + "data": "0x0015141e0c012606000126010001260400012603000126020001260500022604000626020001260100022601000126020006260300042603000126010002260100012602000126040001260100" + }, + { + "filename": "accessory-bling-rings", + "data": "0x0017141d0d0300032a0300012a0300012a0100032a0200022a0100012a0100012a0100022a0200032a0100012a0300012a0300032a0300" + }, + { + "filename": "accessory-bling-scissors", + "data": "0x0016131c0e012b0300022b0300012b0100012b0100012b0200012b0100012b0300012b0200022b0100042b0100022b" + }, + { + "filename": "accessory-bling-sparkles", + "data": "0x0016141d0c01000126060003260100012602000126010001260200012606000326030007260300032606000126070001260300" + }, + { + "filename": "accessory-body-gradient-checkerdisco", + "data": "0x0015171f09022c0223022c0223022c0223042c0223022c0223022c0223022c0223022d0223022d0223022d0423022d0223022d0223022d0223022e01000123022e0223022e0223042e01000123022e0223022e0223022e02230100012f0223022f0223022f04230100012f0223022f0223022f022302300100012302300223023002230430010001230230022302300223023002230100013102230231022302310223" + }, + { + "filename": "accessory-body-gradient-dawn", + "data": "0x0015171f091c321c33021101000d1101000b11023401000d3401000b34023501000d3501000b35023601000b36" + }, + { + "filename": "accessory-body-gradient-dusk", + "data": "0x0015171f091c321c24023701000d3701000d3701000d3701000b37023801000d3801000b38023901000b39" + }, + { + "filename": "accessory-body-gradient-glacier", + "data": "0x0015171f090f3a013b013a013b013a013b013a013b013a013b013a013b013a103b0104013b0104013b0104013b0104013b0104013b0104013b030401000d0401000d0401000c04013c0100013c0104013c0104013c0104013c0104013c0104033c01000c3c013d0100013d013c013d013c013d013c013d013c013d013c033d01000b3d" + }, + { + "filename": "accessory-body-gradient-ice", + "data": "0x0015171f091c3e1e3f01000d3f01000b3f023c01000d3c01000d3c01000d3c01000b3c024001000b40" + }, + { + "filename": "accessory-body-gradient-pride", + "data": "0x0015171f091c411c42022a01000d2a01000b2a020f01000d0f01000b0f024301000d4301000b43021201000b12" + }, + { + "filename": "accessory-body-gradient-redpink", + "data": "0x0015171f092a44100901000d0901000d0901000d0901000d0901000b09024501000d4501000b45" + }, + { + "filename": "accessory-body-gradient-sunset", + "data": "0x0015171f092a460e25024201000b42021401000b14024701000d4701000b47024801000d4801000d4801000b48" + }, + { + "filename": "accessory-carrot", + "data": "0x0018131d0e0200011d0100011d0300011d030002490200024903000149030001490400" + }, + { + "filename": "accessory-chain-logo", + "data": "0x0018171c09012601000326010003260100032602000126030001260300012603000326020003260100032601000226010001260300012603000126030002260200022601000326010003260100" + }, + { + "filename": "accessory-checker-RGB", + "data": "0x0015171f090224021c024a0224021c024a0424021c024a0224021c024a0224024a0224021c024a0224021c044a0224021c024a0224021c024a021c0100014a0224021c024a0224041c0100014a0224021c024a0224021c02240100011c024a0224021c024a04240100011c024a0224021c024a0224024a01000124021c024a0224021c044a01000124021c024a0224021c024a021c0100014a0224021c024a0224021c" + }, + { + "filename": "accessory-checker-bigwalk-blue-prime", + "data": "0x0015171f090400030701000307010005070100030701000307030003070100030707000307070003070700030701000307040002070100030701000307010001070200020701000307050001070200020707000307070003070100020704000307010003070100040702000307010003070300" + }, + { + "filename": "accessory-checker-bigwalk-greylight", + "data": "0x0015171f090400034b0100034b0100054b0100034b0100034b0300034b0100034b0700034b0700034b0700034b0100034b0400024b0100034b0100034b0100014b0200024b0100034b0500014b0200024b0700034b0700034b0100024b0400034b0100034b0100044b0200034b0100034b0300" + }, + { + "filename": "accessory-checker-bigwalk-rainbow", + "data": "0x0015171f090400034c010003460100021403120100034c01000346030003120100034c040006120400034d01000312030003140100034d010003120246010003140100034d040002460100031404000346010002460400034c01000346040002120100034c010003460100014d020002120100034c04000112014d020002120400034d01000112" + }, + { + "filename": "accessory-checker-spaced-black", + "data": "0x0015171f09030002230400022306000223040002231100022304000223040004230400022304000223110002230400022306000223040002231100022304000223040004230400022304000223" + }, + { + "filename": "accessory-checker-spaced-white", + "data": "0x0015171f09030002020400020206000202040002021100020204000202040004020400020204000202110002020400020206000202040002021100020204000202040004020400020204000202" + }, + { + "filename": "accessory-checker-vibrant", + "data": "0x0015171f09024e0243024f024e0243024f044e0243024f024e0243024f024e024f024e0243024f024e0243044f024e0243024f024e0243024f02430100014f024e0243024f024e04430100014f024e0243024f024e0243024e01000143024f024e0243024f044e01000143024f024e0243024f024e024f0100014e0243024f024e0243044f0100014e0243024f024e0243024f02430100014f024e0243024f024e0243" + }, + { + "filename": "accessory-checkers-big-green", + "data": "0x0015171f09030f0300030f0300050f0300030f0300050f0300030f0300020f0300030f0300030f0500030f0300030f0500030f0300030f0200020f0400030f0300040f0400030f0300040f0400030f0300020f0300030f0300030f0500030f0300030f0200" + }, + { + "filename": "accessory-checkers-big-red-cold", + "data": "0x0015171f09031903000319030005190300031903000519030003190300021903000319030003190500031903000319050003190300031902000219040003190300041904000319030004190400031903000219030003190300031905000319030003190200" + }, + { + "filename": "accessory-checkers-black", + "data": "0x0015171f09020002230200022302000223040002230200022302000223020002230200022302000223020004230200022302000223020002230300012302000223020002230500012302000223020002230200022302000223020002230200042302000223020002230200022303000123020002230200022305000123020002230200022302000223020002230200022302000223" + }, + { + "filename": "accessory-checkers-blue", + "data": "0x0015171f09024a0200024a0200024a0200044a0200024a0200024a0200024a0200024a0200024a0200024a0400024a0200024a0200024a0200024a0200024a0200024a0200044a0200024a0200024a0200024a0300014a0200024a0200024a0500014a0200024a0200024a0200024a0200024a0200024a0200044a0200024a0200024a0200024a0300014a0200024a0200024a0200" + }, + { + "filename": "accessory-checkers-magenta-80", + "data": "0x0015171f09020002200200022002000220040002200200022002000220020002200200022002000220020004200200022002000220020002200300012002000220020002200500012002000220020002200200022002000220020002200200042002000220020002200200022003000120020002200200022005000120020002200200022002000220020002200200022002000220" + }, + { + "filename": "accessory-chicken", + "data": "0x0018131d0d0300024701000202020001020150010004020300020204000102050001500300" + }, + { + "filename": "accessory-cloud", + "data": "0x0018131a0d0200030202000b02" + }, + { + "filename": "accessory-clover", + "data": "0x0017151e0d0200021d0600031d0400011d0100011d0100021d0100031d0100031d0100021d0100011d0100011d0400031d0500021d0100011d0800021d" + }, + { + "filename": "accessory-collar-sunset", + "data": "0x00151717090e190e260e42" + }, + { + "filename": "accessory-cow", + "data": "0x0018141c0d05000151020003510123015101380151010001510123025101000151010001510238015103000151020001510100" + }, + { + "filename": "accessory-decay-gray-dark", + "data": "0x0015171f090e27020006270300032702000b2702000927010002270100022701000127010003270200062701000827030001270200012702000327080008270600012704000227010002270200012701000b2703000b27" + }, + { + "filename": "accessory-decay-pride", + "data": "0x0015171f090e27024106270341032702420b2702420927014202270142022701000127012a0327022a062701000827032a0127010f01000127020f0327070f01000827030f02430100012704430227014302270243012701000b27021201000b27" + }, + { + "filename": "accessory-dinosaur", + "data": "0x0017131d0d0200035203000152010001520300045202000352010001520100035201000652030001520200" + }, + { + "filename": "accessory-dollar-bling", + "data": "0x0015141e0c012606000226060001260100012604000126030004260500022605000426040002260800022604000426050002260300" + }, + { + "filename": "accessory-dragon", + "data": "0x0017141e0d020f0100030f0200030f0100040f0300010f0400030f0200020f0400010f0300020f0200030f0200010f0200010f0400" + }, + { + "filename": "accessory-ducky", + "data": "0x0018131a0e012801000228020003280114010003280100" + }, + { + "filename": "accessory-eth", + "data": "0x0018131d0e020001530400015303000153015401530100055401000353030001530200" + }, + { + "filename": "accessory-eye", + "data": "0x0018151c0d020004540300015401000254010001540100015402000254020001540100015404000154030004540200" + }, + { + "filename": "accessory-flash", + "data": "0x0017151d0d010001020800020207000302020008020200030207000202080001020100" + }, + { + "filename": "accessory-fries", + "data": "0x0017131d0e0126010a0126010a0226010a0126010a01260655032602550226035501260855" + }, + { + "filename": "accessory-glasses-logo-sun", + "data": "0x0018161a0d072302000323010008230100032301000123" + }, + { + "filename": "accessory-glasses-logo", + "data": "0x0018161a0d0756020001560100015601000156010006560100035601000156" + }, + { + "filename": "accessory-glasses", + "data": "0x0017141d0d0856010002560100025602000256010002560700081d0100021d0100021d0200021d0100021d" + }, + { + "filename": "accessory-grid-simple-bege", + "data": "0x0016171e090157010001570100015701000157010001570100015701000157100001570100015701000157010001570100015701000157010001570e0001570300015701000157010001570100015701000157100001570100015701000157010001570100015701000157010001570e00015703000157010001570100015701000157010001570100" + }, + { + "filename": "accessory-heart", + "data": "0x0018141d0d010002580100025801000e580100055803000358050001580300" + }, + { + "filename": "accessory-hoodiestrings-uneven", + "data": "0x0016121b0f0102010002020100020201000202010001590102020001590200" + }, + { + "filename": "accessory-id", + "data": "0x0017151a1002000102020005260a02" + }, + { + "filename": "accessory-infinity", + "data": "0x0017141e0d0100020b0400010b0200010b0300010b0700030b0600030b0700010b0300010b0200010b0400020b0100" + }, + { + "filename": "accessory-insignia", + "data": "0x0016131d0e0200015b0300015b012b015b0300015b0300035b0100015b032b035b022b025b032b015b0100035b0100" + }, + { + "filename": "accessory-leaf", + "data": "0x0018141d0d0300045c0200055c0200055c0200055c0200045c0100025c0500" + }, + { + "filename": "accessory-lightbulb", + "data": "0x0017121c0e0c5d0100025d0200025e0200025e0100" + }, + { + "filename": "accessory-lines-45-greens", + "data": "0x0015171f090200010f0200010f0200010f0200010f0200015c0200015c0200015c0200015c0200015c0200010f0200010f0200010f0200010f0200010f0200015c0200015c0200015c0200015c0200010f0200010f0200010f0200010f0200010f0200015c0200015c0200015c0200015c0200015c0500010f0200010f0200010f0200015c0200015c0200015c0200015c0200015c0200010f0200010f0200010f0200010f0200010f0500015c0200015c0200015c0200010f0200010f0200010f0200010f0200010f0100" + }, + { + "filename": "accessory-lines-45-rose", + "data": "0x0015171f090200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0500015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0500015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0100" + }, + { + "filename": "accessory-lp", + "data": "0x0016161e0d03000323040007230200072301000323030206230102010001020623030203230100072302000723040003230300" + }, + { + "filename": "accessory-marsface", + "data": "0x0018131d0e0400032301000223030002230200032303000723" + }, + { + "filename": "accessory-matrix-white", + "data": "0x0018131c0e010b0100010b0100010b0500010b0100010b0100010b0500010b0100010b0100010b" + }, + { + "filename": "accessory-moon-block", + "data": "0x0017131d0e0660010001600100016001000160010001600100016001000160010001600100016001000160010003600100026001000360" + }, + { + "filename": "accessory-none", + "data": "0x00000100000100" + }, + { + "filename": "accessory-oldshirt", + "data": "0x0015171f09206107581161026201000261035802610158056101000161015803610258046102620100036101580961010001610258016104580361026201000d610100016107580361026201000b61" + }, + { + "filename": "accessory-pizza-bling", + "data": "0x0015141d0c012606000126010001260400012603000126020001260500022606000226050004260400042603000626020006260100" + }, + { + "filename": "accessory-pocket-pencil", + "data": "0x0017151910010001370400010203000563" + }, + { + "filename": "accessory-rain", + "data": "0x0018131d0e04000143010001430200014301000143060001430100014302000143010001430400" + }, + { + "filename": "accessory-rainbow-steps", + "data": "0x0017171c090b000312070004180312030004140418031202460100041404180300024601000414070002460c00" + }, + { + "filename": "accessory-rgb", + "data": "0x0018151e0d030002640500046404000464030002650264025a01000465045a0465045a010002650200025a0100" + }, + { + "filename": "accessory-robot", + "data": "0x0019171b090123020001230200012302000123020001230f00022301000b23" + }, + { + "filename": "accessory-safety-vest", + "data": "0x0015171f0b0413030009130300091303000913030005130100036603000566010003660300056601000366030005660100036603000566010003130300051301000313030005130100031303000513" + }, + { + "filename": "accessory-scarf-clown", + "data": "0x0015151f0c031c0300061c0300061c0300031c0323030006230300062303000323031c0300061c0300061c0300031c03230300062303000323" + }, + { + "filename": "accessory-secret-x", + "data": "0x0018121b0e01670200016701000267020002670100016702000167" + }, + { + "filename": "accessory-shirt-black", + "data": "0x0015151f0c0e23010005230100022302000323020001230168030001230300022307000223070002230700022307000123016807000223070002230400" + }, + { + "filename": "accessory-shrimp", + "data": "0x0018121c0e0100025f0100035f0100025f0300015f0220020001200100" + }, + { + "filename": "accessory-slimesplat", + "data": "0x0017121d0d0200014e0100024e0100024e0200034e0200024e0100024e0100014e0500014e0200014e0300" + }, + { + "filename": "accessory-small-bling", + "data": "0x001514170d0126050001260100012603000126030003260200" + }, + { + "filename": "accessory-snowflake", + "data": "0x0017141d0d010001020300010201000202010001020100020202000302030005020300030202000202010001020100020201000102030001020100" + }, + { + "filename": "accessory-stains-blood", + "data": "0x0016151d0d05000219030001190100041904000419050002190100011901000219060002190d0001190600" + }, + { + "filename": "accessory-stains-zombie", + "data": "0x0017151e0d0100010f1000020f0400010f0100020f0900020f0500040f0200010f0100040f0500020f0100" + }, + { + "filename": "accessory-stripes-and-checks", + "data": "0x0015171f090e690e430e280e1c020201000123020202230202022304020100012302020223020202230202022301000102022302020223020204230100010202230202022302020223026901000b69024301000b43022801000b28" + }, + { + "filename": "accessory-stripes-big-red", + "data": "0x0015171d092a242a00022401000d2401000d2401000b24" + }, + { + "filename": "accessory-stripes-blit", + "data": "0x0015171b092a5a0e00026a01000b6a0e00022a01000b2a" + }, + { + "filename": "accessory-stripes-blue-med", + "data": "0x0015171f090e430e000e430e00024301000b430e00024301000b430e00024301000b430e00024301000b43" + }, + { + "filename": "accessory-stripes-brown", + "data": "0x0015171f090e350e000e350e00023501000b350e00023501000b350e00023501000b350e00023501000b35" + }, + { + "filename": "accessory-stripes-olive", + "data": "0x0015171f090e6b0e000e6b0e00026b01000b6b0e00026b01000b6b0e00026b01000b6b0e00026b01000b6b" + }, + { + "filename": "accessory-stripes-red-cold", + "data": "0x0015171f090e190e000e190e00021901000b190e00021901000b190e00021901000b190e00021901000b19" + }, + { + "filename": "accessory-sunset", + "data": "0x0017141a0d03000126040001260300012603000326020001260100032601000126" + }, + { + "filename": "accessory-taxi-checkers", + "data": "0x0017171a090266020d0266020d0266020d0466020d0266020d0266020d0266020d01000166020d0266020d0266040d01000166020d0266020d0266020d" + }, + { + "filename": "accessory-tee-yo", + "data": "0x0015171f09022802000128040001280300032803000428040004280900052809000428020001280100012803000128010004280300012801000228010001280100042803000128010002280300042808000128010004280a0004280a0004280a000228" + }, + { + "filename": "accessory-text-yolo", + "data": "0x0017131d0d014e0100014e010002570100014e020002570100014e02000257060001570200024e010001570200024e010002570100024e0100" + }, + { + "filename": "accessory-think", + "data": "0x0018131c0e0302020003020900010206000102" + }, + { + "filename": "accessory-tie-black-on-white", + "data": "0x0015121f0e0423014b0223024b0223024b0223024b0223024b0223024b0223024b0223024b0223024b0223024b0223014b" + }, + { + "filename": "accessory-tie-dye", + "data": "0x0016151f0b0200023b0100016c0200016c0100013b0100033b0200016c0300013b0300013b0200026c0300026d0100013b0100026c0200016d0100011c016d013b0100016c0200016d0100011c016c013b0100016c0100011c0100016d0100011c0100026c0400016d0200011c0300011c0300016d0200031c0100011c0100016d0200016d0100021c0200" + }, + { + "filename": "accessory-tie-purple-on-white", + "data": "0x0015121f0e046e014b026e024b026e024b026e024b026e024b026e024b026e024b026e024b026e024b026e024b026e014b" + }, + { + "filename": "accessory-tie-red", + "data": "0x0016111e0f044102000c41" + }, + { + "filename": "accessory-txt-a2+b2", + "data": "0x0017151d0d0200016f0500026f0600026f0100016f0600036f0600016f0100016f0100016f0500026f0600026f0100" + }, + { + "filename": "accessory-txt-cc", + "data": "0x0017151d0c01000770010001700700027001000270010002700100027001000170020001700200027001000270010002700100027007000170010007700100" + }, + { + "filename": "accessory-txt-cc2", + "data": "0x0017141c0d037101000471030001710200017103000171020001710300017102000171030001710200037101000371" + }, + { + "filename": "accessory-txt-copy", + "data": "0x0017131d0d027201000272010001720200027201000272010002720700027201000172010003720100027201000172020001720200" + }, + { + "filename": "accessory-txt-dao-black", + "data": "0x0018151b0c022302000123020001230100012301000223010002230100022301000523010003230100012301000123010001230100" + }, + { + "filename": "accessory-txt-doom", + "data": "0x0016161d0b0200012308000323080001230100032307000223010003230700022301000323070002230100032308000123010001230a000123" + }, + { + "filename": "accessory-txt-dope-text", + "data": "0x0017131d0d010001730200017301000273010001730100037302000173070002730100017302000273010002730100017302000373" + }, + { + "filename": "accessory-txt-foo-black", + "data": "0x0019151b0d05230100042301000223010003230200022301000223" + }, + { + "filename": "accessory-txt-ico", + "data": "0x0019171d09027401000d7401000d7401000d7401000d7401000b74" + }, + { + "filename": "accessory-txt-io", + "data": "0x0018131c0d0156030001560100015602000156020001560100015601000256010001560200035603000256" + }, + { + "filename": "accessory-txt-lmao", + "data": "0x0017131d0d013e0300033e0200023e0100023e0100013e0900013e0200033e0100013e0100033e0100013e0100023e" + }, + { + "filename": "accessory-txt-lol", + "data": "0x001715190d01020200020201000102010001020200020201000102010002020100020201000202" + }, + { + "filename": "accessory-txt-mint", + "data": "0x0016141c0d06000114070002140100011402000214010001140100011401000114070002140200041401000114020001140100" + }, + { + "filename": "accessory-txt-nil-grey-dark", + "data": "0x0018151a0d037501000175010001750100017501000175010001750100017501000175010001750100017501000275" + }, + { + "filename": "accessory-txt-noun-f0f", + "data": "0x0017131e0d0100026901000169020001690100026907000269010001690100036901000369070002690100016902000169010002690100" + }, + { + "filename": "accessory-txt-noun-green", + "data": "0x0017131e0d0100023e0100013e0200013e0100023e0700023e0100013e0100033e0100033e0700023e0100013e0200013e0100023e0100" + }, + { + "filename": "accessory-txt-noun-multicolor", + "data": "0x0017131e0d010002170100011702000117010002170700027601000114010001140276010003140700020f0100010f0200010f0100020f0100" + }, + { + "filename": "accessory-txt-noun", + "data": "0x0016131d0d0100026c0100016c0200016c0100026c0700026c0100016c0100036c0100036c0700026c0100016c0200016c0100026c0100" + }, + { + "filename": "accessory-txt-pi", + "data": "0x0018131b0d0100061f0100011f0100011f0300011f0100011f0300011f0200011f" + }, + { + "filename": "accessory-txt-pop", + "data": "0x0017131d0d0228040002280400012801000228040002280600022804000228040001280100" + }, + { + "filename": "accessory-txt-rofl", + "data": "0x0017131d0d02020200027702020200027701020100010201000277060003370100012601000237020001260100013703000226" + }, + { + "filename": "accessory-txt-we", + "data": "0x0018151d0c0700011c050001560100011c0100011c02000156010001560100031c015601000156010001560100011c0200015601000156010001560200011c02000156010001560500" + }, + { + "filename": "accessory-txt-yay", + "data": "0x0018151a0c0143010001430100011c0100014301000143010001430100031c01000143020001430100011c0100011c010001430100" + }, + { + "filename": "accessory-wall", + "data": "0x0015171f090a0001620d0001620300026201000b62040001620d0001620900026201000462010006620a0001620d0001620300026201000b62040001620d0001620900" + }, + { + "filename": "accessory-wave", + "data": "0x0017151b0d01000356040002560200015605000156020001560400015603000256010001560600" + }, + { + "filename": "accessory-wet-money", + "data": "0x0018141e0d01780279017805790178017a017804790178017a01780579017802790178010001040100010401000104020001040a0001040100" + }, + { + "filename": "accessory-woolweave-bicolor", + "data": "0x0015171f09037b010003140100037b0100027b0e00017b010003140100037b01000314020001140300017b030001140300017b01140200027b010003140100037b0f00027b020003140100037b01000214030001140300017b030001140200017b01140200037b010003140100027b0e00017b0200027b010003140100037b0100" + }, + { + "filename": "accessory-woolweave-dirt", + "data": "0x0015171f09037c0100037c0100037c0100027c0e00017c0100037c0100037c0100037c0200017c0300017c0300017c0300027c0200027c0100037c0100037c0f00027c0200037c0100037c0100027c0300017c0300017c0300017c0200027c0200037c0100037c0100027c0e00017c0200027c0100037c0100037c0100" + }, + { + "filename": "accessory-yingyang", + "data": "0x0018121b0e060d024b020d064b" + }, + { + "filename": "body-bege", + "data": "0x0015171f093a0101000d0101000d0101000d0101000d0101000d0101000d0101000b01" + }, + { + "filename": "body-gray-scale-1", + "data": "0x0015171f093a0b01000d0b01000d0b01000d0b01000d0b01000d0b01000d0b01000b0b" + }, + { + "filename": "body-gray-scale-9", + "data": "0x0015171f093a0e01000d0e01000d0e01000d0e01000d0e01000d0e01000d0e01000b0e" + }, + { + "filename": "body-ice-cold", + "data": "0x0015171f093a0601000d0601000d0601000d0601000d0601000d0601000d0601000b06" + } + ], + "heads": [ + { + "filename": "head-aardvark", + "data": "0x00021e14060500013702000137130002370200023711000337020003370f000437020004370f00033702000337110002370200023713000137020001370f000d370b000d370b000d370b000d370b000d370b000d370b000d370600057d0d370600017d017e017d017e017d0b37097d017e017d017e017d0b370d7d0a370523097d0b370d7d" + }, + { + "filename": "head-abstract", + "data": "0x00041a1405045c01000447010004470100017f01000114010001140100045c01230447012304470123017f01230114012301140123045c01230447012304470123017f01230114012301140123045c01230447012304470123017f01230114012301140123045c01230447012304470123017f01230114012301140123010015230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f012304460100132301000123015401230154012301540123040701230455012304550123015401230154012301540123040701230455012304550123015401230154012301540123010703540123045501230455012301540123015401230154012304070123045501230455012301540123015401230154012304070123045501230455" + }, + { + "filename": "head-ape", + "data": "0x0005191406030004800e00098009000e8006000f800300108004000f8004000f80040001800e81040001800e81040001800e81040001800e81020003800e8102000180018101800f8101000180018103800d8206800d81018002001180" + }, + { + "filename": "head-bag", + "data": "0x00031c140306000e3a0b000e3a0900023a0e00023a0700023a0e00023a0700023a0e00023a05000207023a0e07023a0207030001070126023a040706260407023a01260107020001260107022606070426060702260107020001260807062608070200013a16070100013a0100013a15070100013a0100013a15070100013a0107013a1607013a0107013a1607010018070100070703760e0701001807020016070100" + }, + { + "filename": "head-bagpipe", + "data": "0x00011d19050a0001831700030f150001830200010f010001831200020f0300010f017a11000108010f017a020f0108017a010f1000020f017a020f0183017a020f06000183080001830100017a010f010001080100020f01830600010807000108040001080200010f017a010f06000108060001080300010803000183017a010f070001080500010803000108020001080100017a010f0200010f0200017a030f017a030f010803000108020001080200020f017a0200010f017a030f017a030f017a03000108010001080400010f017a010f0100010f017a030f017a030f017a010f01000108020001080400010f0300010f017a030f017a030f017a020f0108010001080900010f017a030f017a030f017a030f017a020f0800010f017a030f017a030f017a030f017a030f017a06000108017a030f017a030f017a030f017a030f017a010f050001080200020f017a030f0211020f017a030f017a010f050001080400017a030f017a030f017a030f017a010f050001080400017a030f017a030f017a030f017a060001080500030f017a030f017a030f017a060001080700010f017a030f017a020f0800010817000183160003831500" + }, + { + "filename": "head-banana", + "data": "0x00041d140304000523047903260f000323047905260f000123047907260f00037909260e0002790226012b07260e0001790326012b0326022b02260e000226012b0526022b02260700012606000826022b02260600032605000826022b02260500052604000c2604000426012b022602000e2602000626012b022601000e2601000826012b1226012b032601001426012b032603000a26032b09260500062601570626015706260700042603570526025704260400" + }, + { + "filename": "head-bank", + "data": "0x00031c15040b00021f1400061f1000031f0472031f0c00021f020c011f0472011f020c021f0800021f020c031f0472031f020c021f0400161f020016720300031f0272041f0272041f0272031f0400011f010c011f0272041f0272041f0272011f010c011f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400011f1272011f0300161f0100021f1472021f" + }, + { + "filename": "head-baseball-gameball", + "data": "0x00041a17060800040b0e00080b0a0001240b0b0700020b01240a0b0124010b0400030b01240a0b0124010b0400030b01240a0b0124010b0300040b01240a0b0124020b0200030b01240c0b0124010b0100040b01240c0b0124050b01240e0b0124040b01240e0b0124040b01240e0b0124010b0100030b01240c0b0124010b0200030b01240c0b0124010b0300030b01240a0b0124010b0400040b0224060b0224020b0500050b0624030b07000c0b0a00080b0e00040b0800" + }, + { + "filename": "head-basketball", + "data": "0x00031a160607000542011a0c000442011a0242011a024208000242021a0542011a044205000542011a0442011a0442011a04000142011a0442011a0342011a0342011a014203000842011a0242011a0242011a034202000142011a0742051a044201000c42011a1342011a1342011a0742141a0c42011a1342011a074201000b42011a064202000942051a0442030004420166010e0166010e0166010e011a0242011a024204000642011a0342011a0342011a014205000442011a0442011a04420800021a0542011a02420c000542011a0700" + }, + { + "filename": "head-bat", + "data": "0x00031e14020900018408000184120001840800018411000384060003840c000184020002840185018406000184018502840200018408000584018502840400028401850584070001840185038401850a8401850384018501840600058401850a840185058405000184018514840185018404000184018514840185018403000184018516840185018402000184018516840185018402000184018516840185018402000184018516840185018401000184018518840185028401851884018508840185048402230162012301620223018401850984030002840185038403230102012301020123028401850284030003840500108405000184" + }, + { + "filename": "head-bear", + "data": "0x000518150805860600068602370286060002860237a1860208028602080223018701230187022301080286020802860208072301080286020802860208028602080286020802860208028602080286020802860208028601000e080100" + }, + { + "filename": "head-beer", + "data": "0x000219140605000287020003870b000b8707000f8704000f87030011870200018701420c87016d02870300024201680287016802470587016d018701000388024201680247016802470168014702870168016d0187010003880342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701420247016802470268016d0200028801000342024701420247016802470268016d020003880342024701420247016802470268016d030002880342024701420247014202470268016d05000c420168016d050005880785028805000e880200" + }, + { + "filename": "head-beet", + "data": "0x00021a14060400031d020002800d00011d0119021d0280010c01800c00021d0119011d0180010c02800d00021d0119010c02800f00011d0119010c0180110002850d001089030009190189011901890119018901190389010014890319108901193a890219288902190f89031901000a89022006890300041901890119078901190189011905000e890300" + }, + { + "filename": "head-bell", + "data": "0x00011c14040b00022616000226130008260f000226010207260d000226010209260b00022601020b260a000e260a000e2609001026080010260800102608001026080010260800108a0800108a06001426040001260102122602000c2603372126010016260100" + }, + { + "filename": "head-bigfoot-yeti", + "data": "0x00021d14020d00047f1700067f1400037f0156017f0156017f1400027f0156015a0156015a017f1400027f028b0156018b017f1100057f018b0156015a0156017f10000b7f0f000b7f0f000d7f0d000e7f018c0b00047f01000a7f038c0800047f02000a7f058c0500047f02000b7f078c0100047f03000c7f0300058c037f04000c7f0400018c0100018c08000b7f1000087f028d027f1000028c0a7f0e00068c087f0600" + }, + { + "filename": "head-bigfoot", + "data": "0x00021d14020d0004341700063414000334012b0134012b013414000234012b0136012b0136013414000234028e012b018e013411000534018e012b0136012b013410000b340f000b340f000d340d000e3401360b00043401000a3403360800043402000a3405360500043402000b3407360100043403000c3403000536033404000c34040001360100013608000b341000083402160234100002360a340e00063608340600" + }, + { + "filename": "head-blackhole", + "data": "0x00011d17030e00018f1800018f1000018f1800018f0600015f0600015f0400018f0600018f0500015f0600015f0600018f0a00015f0300045f0300015f0e00015f01190120015f032003190c00015f0200015f01190220045f0220025f0b00015f0100015f01190120025f0490025f01200119015f0a00015f0100015f0120015f029004230290015f01200119015f0100015f0500015f0200025f0120015f019006230190015f022001190300018f06000119025f019008230190025f01190400028f0500025f019008230190015f0120015f01190300028f0400015f0120015f019008230190015f0120015f0600018f0300015f0120015f019008230190015f0120015f0a00015f01190120015f019006230190015f02200119015f0700015f0200035f029004230290025f02190100015f0700025f02190120025f0490025f0220015f01190100015f0a00015f01190220045f0120015f01200119015f0c000219055f0320015f02190200015f0600018f0700015f01000319015f0d00018f0900015f0900018f1800018f0300" + }, + { + "filename": "head-blueberry", + "data": "0x00041a1706070006430c000543069107000143019101560591035403910500024306910154037701540391040001430691025404770154029103000243079101540477015403910200014301560891045404910100024312910343119103431191024312910243129102431291010001430391067708910200014304910292099101430191030002430e91040004430c91060002430991014308000543069101430b0006430700" + }, + { + "filename": "head-bomb", + "data": "0x00041c16070f00010d0b00060d0200030d02830600040d0172090d010001830400020d02720a0d030001830200030d0272090d040001830100100d030001830100100d03000193120d02000141120d0300120d0300120d0300120d0300120d0400100d0500100d0600060d0572030d08000c0d0a000a0d0d00060d0900" + }, + { + "filename": "head-bonsai", + "data": "0x00021e15030c00070f1200030f031c040f0f00050f031c010f021c020f0c00040f011c020f031c010f021c020f0b00100f0c000e0f0200030f0c00080f0300020f011c020f0200070f0600027c03000a0f021c060f0400037c060f021c040f021c010f011c050f0400017c070f021c0d0f0400037c080f01000b0f0300097c0500080f087c0c00030f047c0300047c1500067c1400087c0e001294090005940d0e090012940b000e940700" + }, + { + "filename": "head-boombox", + "data": "0x00041b1f060400025815000258150002580d00089502580795040001950900025804000195040001950b0002580200019502000296136f0296016f011c016f0195016f090e016f0195016f0124016f0296136f0296036f030e026f0195016f0195026f030e036f0296026f050e056f050e026f0296016f070e016f0195016f070e016f0296016f070e036f070e016f0296016f070e016f0195016f070e016f0296026f050e056f050e026f0296036f030e026f0195016f0195026f030e036f0296136f1200020e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e0100" + }, + { + "filename": "head-boot", + "data": "0x00061c140701000697030002970a00069702080100019701980a0007970208019701980a0008970108019701980a000b970a000b970a000b9709000d9708000e970700149701002e9703262397010013830100" + }, + { + "filename": "head-box", + "data": "0x00061c1403040003970f990108050004970f9901080400049701080f9902080300049701080f9902080200049702080f9902080100059702080f990308040003080f990308040003080f99070003080f990700029901080f990700029901080f9907000299010805990a010700030805990a010700030805990a01070003080f990300" + }, + { + "filename": "head-boxingglove", + "data": "0x000418140504000d5504000a550438025502004d550189015506070b550189015506070b550189015506070b550189015506070b550189015506070955030001550607095503000f55050003550b260500035501260502012301020326050003550b2605000e550100" + }, + { + "filename": "head-brain", + "data": "0x00051a14060600086a0900036a0320016a0420036a0500016a0320036a0120046a0320016a0300016a0120026a0120016a0120016a0120016a0120026a0120026a0120016a0200016a0120016a0120026a0120026a0120026a0120056a0100066a0120036a0120026a0120026a0120016a0120026a0120046a0120066a0120046a0120026a0120026a0120026a0120036a0120066a0120056a0120026a0120046a0120016a0220026a0120026a0120026a0120036a0120096a0120026a0120036a0120056a0120066a0120076a0120056a0220046a0120016a0100126a0200016a0120036a0220026a0120056a0220016a0300016a0120016a0120026a0220046a0220026a05000e6a0300" + }, + { + "filename": "head-bubble-speech", + "data": "0x00041b160504000e0206001202030014020200140201009a0201001402020014020300120206000f02120003021300020213000202140001020700" + }, + { + "filename": "head-bubblegum", + "data": "0x00021b1705080006690e000369029a05690a000269029a04690202046907000269019a05690402046905000269019a06690402056904000a69020202690202026903000f6902020369020002690102116901008469010014690200146903000a69019a076904000b69019a066905000169019a0769019a0469019a016907000169039a0669039a01690a000a9a0e00069a0800" + }, + { + "filename": "head-burger-dollarmenu", + "data": "0x00071a14060600080a0a00060a0125050a0700040a0125050a0125030a0500020a01250d0a04000e0a0125010a0300120a0200120a020012260100082601970626029701260197012601970226019704260e9701260c9701260497010012970300100a0400100a0200" + }, + { + "filename": "head-cake", + "data": "0x00021a14060500013704000137030001370900013701290137020001370129013701000137012901370800013701290126020001370129012601000137012901260900012604000126030001260900033c0200033c0100033c08000156023c02000156023c01000156023c0600102003000520060207200200042008020620020004200802052001020200010203200902032002020200020202200e020200020202200e020200020201200f0202001202020012020200012001020220020205200202022002020120010001200102012002020220050202200202022001021520" + }, + { + "filename": "head-calculator", + "data": "0x00051a16060200120302001203020001030488010303880103070701030200060303880103070701030200010304880d03020006030388010303880103038801030200010304880d03020006030388010303880103038801030200010304180d0302000103041801030388010303880103038801030200120302000103105c010302080103015c019b035c019b035c019b015c019b015c029b015c010302080103015c039b015c029b025c019b015c019b015c029b015c010302080103015c019b015c019b015c039b015c019b015c019b015c029b015c010302080103105c010302000103109c010302001203" + }, + { + "filename": "head-calendar", + "data": "0x00041a14050100029d0200029d0200029d0200029d0200029d02000202019d0302019d0302019d0302019d0302019d180201230102012301020123010201230102012301020123010201230102059e1002029e0102029e02020d9f0102019e0102019e0102019e0302019f0102019f0102019f0102019f0102019f0102019f0202059e02020d9f0102059e0302019f0102019f0102019f0102019f0102019f0102019f0202059e02020d9f0102059e0302019f0102019f0102019f0102019f0102019f0102019f0202059e02020d9f0102059e0302019f0102019f0102019f0102019f0102019f0102019f0202059e02020d9f0102059e0302019f0102019f0102019f0623019f0102059e02020d9f0102059e1602" + }, + { + "filename": "head-camcorder", + "data": "0x00091c14050400047e0500047e060001230100117c03000223017e017c01240f7c02000323017e117c027e03230100117c027e02230200117c027e02230200117c027e022302001123027e022302001123027e022302000e23027e0123027e0223020001230b7c0223027e0123020002230200112303000123" + }, + { + "filename": "head-cannedham", + "data": "0x00041a14060f00017a10000383017a1200027a0f00047a0c00067a030002390200097a0500053901001483508c14a12d07010e0151010e0151010e0151010e01511b071483" + }, + { + "filename": "head-car", + "data": "0x00091c1406050008550d000155080401550b00035508040155090005550804015507000755060401a20104015505000e5502a20455020014550157010014550157045501230227095502270123045502a20155012702a20127015502230455012702a20127025504a20100012702a2012707a2012702a20127010002a205000227090002270500" + }, + { + "filename": "head-cash-register", + "data": "0x00021a1408010004580e000158026201580e00045802000a27010001610158016202580261012708430127026104580261012701430654014301270261016f0262016f02610127084301270261046f0261012701430354044301270261042702610127084301278e61022a026102870161028701610287016102870161042a026102870161028701610287016102870161042a1361" + }, + { + "filename": "head-cassettetape", + "data": "0x00071b14050100140e0100020e1202040e0102010e1002030e0102010e0102010e1002020e05a3010203a3020203a3010205a3020e04a3030203a3010202a3030204a3020e04a3030203a3010202a3030204a3020e05a3010203a3020203a3010205a3020e14a3020e1426020e1426010e060c0a1f0b0c021f0100061f0100021f090c0e1f040c" + }, + { + "filename": "head-cat", + "data": "0x00031a14060100020e0d00020e0300040e0900040e0300010e0106040e0500040e0106010e0300010e0306020e0500020e0306010e0300010e0406070e0406010e0300010e0306090e0306010e0300010e01060d0e0106010e0300110e0400100e0400100e0400100e0400100e0400100e0400100e0200053c0506026c0406043c02000806019607060200053c030604960406043c020010060200" + }, + { + "filename": "head-cd", + "data": "0x00031b1805080006a30e0002a3066702a30a0002a30a6702a3070001a30e6701a3050001a301220f6701a3040001a302220e6701a3030001a305220b67024301a3020001a30622016704080367044301a3010001a304200322010804a30108074302a30620010806a30108064302a30620010802a3020002a30108064302a30620010802a3020002a30108069a02a30626010806a30108069a02a30726010804a30108026e059a01a3010001a30426036704080167046e029a01a3020001a302260b67056e01a3030001a30d67036e01a3040001a30f67016e01a3050001a30e6701a3070002a30a6702a30a0002a3066702a30e0006a30800" + }, + { + "filename": "head-chain", + "data": "0x00051e1602030004840100068401000684010003840600049301840693018406930184039306000484010a0684010a0684010a038407000184010a0184010a018402000184010a0184010a018402000184010a0184010a01840700038401930684019306840193068404000393018401020593018401020593018401020593040003840100068401000684010006847500068401000684010006840100048402000184010205930184010205930184010205930184010203930100018401930684010a0684010a06840193048401000184010a0184010a018402000184010a0184010a018402000184010a0184010a018402000184010a0184010a01840100048401930684019306840193068401930184010004930184069301840693018406930184020004840100068401000684010006840300" + }, + { + "filename": "head-chainsaw", + "data": "0x00051d16040300036315000163030001631400016303000163120008630200010d0200010d0200010d0200010d05000863010d0100020d0100020d0100020d0100020d04000863020d0263010d0263010d0263010d0263020d0300010d06630e0d0163020d08630e0d0163010d0200010d06630f0d020008630e0d0163020d0100010d06630e0d0163010d010008630f0d020008630e0d0163020d03630102010d0102010d01630e0d0163010d02000263010d0102010d010201630f0d04000863010d0263010d0263010d0263010d0263010d05000563020d0100020d0100020d0100020d0100020d070004630100010d0200010d0200010d0200010d0200010d0300" + }, + { + "filename": "head-chameleon", + "data": "0x00021c16040b00021d1600021d1500041d1300061d0e000184031d0184041d0184031d01840800030f0184031d0484031d0184030f0500010f0222020f0184011d0184041d0184011d0184050f0300010f0423010f0184021d0484021d0184060f0200010f012202230122020f0184061d0184050f02220200020f0222030f0184061d0184040f03230200070f0184061d0184040f012202230200070f0184061d0184050f02220300040f0284081d0284040f050003840c1d03840500141d0300161d0200041d048406230484041d0100021d03840e220384031d01840522010f0122060f0122010f05220184011d01001622030003220e0003220200" + }, + { + "filename": "head-chart-bars", + "data": "0x00041a1406100004730800041c040004730800041c040004730800041c0469047304000428041c0469047304000428041c0469047304000428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428011c06230169047304190428041c0469047304190428041c04690473" + }, + { + "filename": "head-cheese", + "data": "0x00031a140605000226012b022602290d00052602290d00052603290b000226012902260229012b01290b0001260129022b01260129012b03290a0001260129022b012601290126032909000526032902260229080005260729080005260829060005260929060005260a29050005260a29040005260c29030005260c2903000126012903260d29010001260129012b02260429012b012903230529010001260129012b02260229022607290126032905260f29" + }, + { + "filename": "head-chefhat", + "data": "0x00051c14040500060210000b020c00090203a308020300060204a30c020200030203a310020100250201a3060201a3030201000b0201a3050202a303020300030201a3060201a3030202a304020500030201a3050201a3020201a3050208000e7c0a000ea30a000ea30a0001020c5501020a000e020a000e020500" + }, + { + "filename": "head-cherry", + "data": "0x00011b15050900030f0e00010f0200070f0d000b0f0b00010f0100070f0e00010f0200030f1000010f0300010f1200010f0300010f1100010f0400010f0d000318010f01180400010f0441060009180941030009180b4102000918094101020141010009180d4109180d4109180d4109180d4109180d410100091806410318024102000918054101180202034103000918094106000518040005410400" + }, + { + "filename": "head-chicken", + "data": "0x000318140805000155010003550a000755080008550700028707550387030006870455048702000987015504870100888704130c8706130a8704550c8704550487" + }, + { + "filename": "head-chilli", + "data": "0x00041c16050600081c0d000a1c0b00081c0e000a1c0d00071c0224011c0c00041c07240c00011c0a240d000a240d000a240d000b240c000b240d000b240900012402000c240700022403000d240400032404000524052309240500112407000f2409000c240e0007240600" + }, + { + "filename": "head-chipboard", + "data": "0x00061c140513a4040001a401a503a402a601a408a701a401a501a4040005a402a606a401a806a4030001a403a901a402a601a40aaa02a4030001a401a901aa01a902a401a806a401a807a401ab01a501a403a901a401a804a401a803a401a805a401a802a505a401a803a401a805a401a803a401a801a401ab01a505a401a803a401a805a401a802a401a802a402a502a410a803a401ab01a501a401a803a401a80fa4020001a401a802a410a801a401ab01a501a401a801a401a810a401a802a503a401a801a402aa01a402aa01a402aa01a402aa01a402aa02a401ab01a501a401a501a401a801a402aa01a402aa01a402aa01a402aa01a402aa02a402a515a401ab01a5" + }, + { + "filename": "head-chips", + "data": "0x00021c19040d0001231600010702231400030702231200020701020207022310000287050702230e000487050702230c000287010203870507034209000287010205870507024208000a8705070142012306000c870507022304000e8705070223020001070f8705070123010003070f870407010005070f870207020006070f87040006070d87020001420300060703870214068702000242040006070987020003420500060707874c00034215000242160001420200" + }, + { + "filename": "head-chocolate", + "data": "0x000319140701000185010e03970185039709000185010e02850197038501970900020e098507000185010e0397018503970185019707000185010e02850197038501970385019701850400020e0c8504000185010e03970185039701850397018502970100038c0f065a8c010002890e190200101902001019020003190c890119020010190100" + }, + { + "filename": "head-cloud", + "data": "0x00041c14040b000502110009020e000b020c000d020a000f0207001102050014020300150203001502020016020200170201003002010017020100170202001502050012020200" + }, + { + "filename": "head-clover", + "data": "0x00041d16070400031d0500031c0a00051d0300051c0900051d0300051c0700031c051d0100061c021d0400041c061d041c051d0300051c051d031c061d0300061c010f021d031c010f061d0400061c010f011d021c010f061d0700051c010f011c010f051d0a00021d031c010f031c021d0a00051d010f011c010f051c0700061d010f021c011d010f061c0400061d010f031c021d010f061c0300061d031c051d051c0300051d041c011d055c041c0100020f0100021d061c010f051d031c040f0300051c030f051d050f0400051c0300051d0a00031c0500031d0700" + }, + { + "filename": "head-clutch", + "data": "0x00071b14030b0004120b0009760412097602000876015b0412015b087602000876065b087602000812015b04ac015b0812010001120876015b0412015b087601000112097604120976015b0100097604120976015b0100097604120976020009760412097602000976041209760200097601020123010201230102087602000976041209760200097604120976" + }, + { + "filename": "head-coffeebean", + "data": "0x0005191608040004ad010004ad060005ad01340135013405ad030002ad013403ad01340123013406ad010002ad013404ad01340123013408ad013405ad01340123013408ad013405ad01340123013408ad013405ad0134012301340ead0134012301340ead0134012301340ead0134012301340ead0134012301340ead0134012301340ead0134012301340bad03230134012301340ead01340123013407ad010006ad01340123013406ad030005ad01340135013405ad060004ad010004ad0400" + }, + { + "filename": "head-cone", + "data": "0x000319140708000224100002240f0004240e0004240e0004240d0006240c0006ae0c0006ae0b0008ae0a0008240a00082409000a2408000aae08000aae07000cae06000c24030004240c481424" + }, + { + "filename": "head-console-handheld", + "data": "0x000319140713031010020301100f7902030110077901af07790203011005790510017901af011001af017902030110067903af0279011001af01100179020301100179021001790110017901af017901af027901af011001af0179020301100f79020301100f79020301100f79020301100f79020301100f79020301100f79150301b0100303b0020301b0010301b0010303b101030324030301b0020301b0010301b0020303b1010303241303" + }, + { + "filename": "head-cookie", + "data": "0x00031a1606070006980c000a9808000e98050007980185089804000d98018502980300129802001298010073980285039801000e9802850298020003980285029801850a98030002980285029805850598040006980185099805000498018504980185049808000a980c0006980700" + }, + { + "filename": "head-cordlessphone", + "data": "0x000a1d1402020009030db00303020005030389010301b0028801b0028801b0028802b0018901b003030200020301b002030389010301b0028801b0028801b0028802b0018901b0030302000503038901030db0010301230103020005030389010301b0028801b0028801b0028804b00103012301030200010301b0010301b001030389010301b0028801b0028801b0028804b0010301230103020005030389010301b0028801b0028801b0028804b001030123010302230503038901030db00103012301030223020301b002030389010301b0028801b0028801b0028802b0018801b0010301230103020005030389010301b0028801b0028801b0028802b0018801b00303020009030db00303" + }, + { + "filename": "head-cottonball", + "data": "0x00021c16040a00010216000302014b0202020001020a00010202000202014b07020c000502014b0402014b03020200010206000102014b0402014b0502014b040207000202014b0a02014b020207000302014b0602014b0302014b030206000102014b0202014b0602014b0402014b010204000202014b0302014b0602014b070204000502014b0d02014b04000402014b0f0204001102014b02020100010201001202014b03020100010201000302014b0d02014b020205000102014b0d02014b020206000402014b0202014b0202014b0302014b030207000302014b0302024b07020100010205000302014b0302014b0202014b0402014b01020900014b0d020c000802014b010210000102014b0302014b0900" + }, + { + "filename": "head-cow", + "data": "0x00061914060300017f0323057f05230500017f0323057f05230300037f0323057f0523017f01000c7f0523197f02230d7f030003230b7f05000323047f0323047f0500077f0323047f0500077f0323047f0500027f0e5f03000123017f045f0208035f0208035f030002230e5f03000223035f0908025f030002230e5f" + }, + { + "filename": "head-crab", + "data": "0x00021b14050400041306000413060007130400071303000913020009130100031302b20c0002b20d130200131304000b13010005130600051301000413070001230200012307000413010010130100041301001013010044130300101306001013060010130600061304b2061306001013060010130300" + }, + { + "filename": "head-crane", + "data": "0x00061f1405060005b313000ab30f000cb30d0003b3050206230b0002b306020823090001b30802092308000902072304b506000a02052308b50300060209230bb5050207230e00040208230f0002020a230f0002020323040205230d0002020d230c0002020c230800" + }, + { + "filename": "head-croc-hat", + "data": "0x00061e150801000e2308000e230700102307000e1d08000e1d08000e1d08000e1d08000e1d08000e1d08000e1d0800151d0100151d0100031d0323021d0423021d0423031d0100051d0123021d0123021d0123021d0123021d0123031d0100051d0423021d0423021d0323011d0100151d" + }, + { + "filename": "head-crown", + "data": "0x00041a14060100015b0700025b0700015b0200015b0700025b0700015b0200025b0500045b0500025b0100028b012b015b0300015b041d015b0300015b012b0241018b0154012b025b0100025b011d029b010f025b0100025b012b011801410254012b055b021d020f055b012b02180100125b0200125b0200125b0200125b0200125b0200125b0200125b0200125b03000135052b0435052b01350300125b0200125b0100" + }, + { + "filename": "head-crt-bsod", + "data": "0x00051a15040400120104001201020004010166025a01660a5a0801025a01660b5a08010166025a01660a5a08010e5a08010e5a08010e5a08010e5a020102b004010e5a08010e5a020102b004010e5a08010e5a020102b004010e5a0f01012301010123060102000a0101230101012301010123050104001201" + }, + { + "filename": "head-crystalball", + "data": "0x00021a14060700062d0c00022d06b6022d0900012d0ab6012d0700012d07b6012d04b6012d0500012d03b6012d0ab6012d0300012d03b6012d01b6012d05b6012d04b6012d0200012d04b6012d05b6032d03b6012d0100012d0cb6012d05b6022d07b6012d0ab6022d12b6022d12b6022d12b6022d12b6012d0100012d10b6012d0200012d10b6012d0300012d0eb6012d040010b7040005b7072304b7040010b70200" + }, + { + "filename": "head-diamond-blue", + "data": "0x00051a18060500024a0104044a0104024a0900034a0104044a0104034a0700034a0104064a0104034a0500044a0104064a0104044a0300044a0102084a0104044a01000204010201040302010401020b04054a0102084a01040a4a0104084a01040a4a0104084a01040a4a0104084a0104054a14040100054a0104064a0104054a0300044a0104064a0104044a0500044a0104044a0104044a0700034a0104044a0104034a0900024a0104044a0104024a0b00024a0104024a0104024a0d00014a0104024a0104014a0f000104024a01041100024a0900" + }, + { + "filename": "head-diamond-red", + "data": "0x00051a1806050002b8014204b8014202b8090003b8014204b8014203b8070003b8014206b8014203b8050004b8014206b8014204b8030004b8010208b8014204b801000242010201420302014201020b4205b8010208b801420ab8014208b801420ab8014208b801420ab8014208b8014205b81442010005b8014206b8014205b8030004b8014206b8014204b8050004b8014204b8014204b8070003b8014204b8014203b8090002b8014204b8014202b80b0002b8014202b8014202b80d0001b8014202b8014201b80f00014202b80142110002b80900" + }, + { + "filename": "head-dictionary", + "data": "0x00051b150501000802040008020100014a01020372010203720102020001020372010203720102024a1402024a010203720102037204020372010203720102024a1402024a010203720102037204020372010203720102024a1402024a010203720d0202720102024a1402024a010203720d0202720102024a1402024a010203720d0202720102024a070206410702024a1402024a14020b4a02020a4a0900044a0900" + }, + { + "filename": "head-dino", + "data": "0x00071d15080300061d0f00061d0c00bd1d0100051d0302011d0302011d0302011d03020100051d0302011d0302011d0302011d03020100141d0100141d" + }, + { + "filename": "head-dna", + "data": "0x00091d160304431200045501000126010004430c000455010001510200012601000155010004430800035501430100012601000151020001260100015501000143010001510243060002550143010001430100012601000151020001260100015501000143010001510100024304000255010001430100014301000126010001510200012601000155010001430100015101000343020002550143010001430100014301000126010001510200012601000155010001430100015101000143010002430255010001430100014301000143010001260100015102000143010001510100012601000155010001430200025502000143010001430100015501000143010001550200014301000151010001260100015501000143010002550243010001430100014301000155010001430100015502000143010001510100012601000155010001430255020003430100014301000155010001430100015502000143010001510100012601000155010002550400024301000143010001550100014301000155020001430100015101000126010003550600034301000155010001430100015502000143010005550a000543010001550100055510000543" + }, + { + "filename": "head-dog", + "data": "0x00061a140603000e97040004850d970185010005850d9706850e9706850e9706850e9706850e9706850e970685049706380497068504970638049706850397083803970685019708380223020d0138028502000397083804230138040003970438022301020323010201230138040003970d380200" + }, + { + "filename": "head-doughnut", + "data": "0x00031a160607000156056c0c00026c0156046c01b9026c08000a6c01b9036c0500086c016d056c02190400026c02b9016c0119036c016d066c0300076c0119016c0138056c0156026c0200076c0538026c0156036c0100046c016d026c013804000138066c011c016c021c016c016d016c013806000138026d036c011c066c0138060001380c6c013806000138086c0156036c013806000138036c02b9036c0156036c023804000138026c0156046c0100076c0538036c0156026c0200046c01b9066c0219056c0300026c01b9046c0156086c0400076c0156040e016d036c0500026c0119096c016d016c08000119096c0c00016c021c036c0700" + }, + { + "filename": "head-drill", + "data": "0x00071c140502000e1401a307000f1401a3017e06000f1401a3017e017c017e017c017e017c101401a3027e017c017e017c017e101401a3017e06000f1401a307000f1401a308000e1401a30b00057e01a31100057e02a31000057e03a30f00077e0f00011401230126012301260123081409000e140500" + }, + { + "filename": "head-duck", + "data": "0x00041d1407070006020e0005020c001002060011020500110205001102050011020500110205001102050011020500110205001102050011020500050210460100050204460142014601420a4605021146010005021046" + }, + { + "filename": "head-ducky", + "data": "0x00031c14040c0008260e000526045102260c00052602510223025101260c000526025102230251012601140b0006260451022603140100022607000a2603140200052605000a2603001626020017260100482601001726010017260200162602000b26018a092604000726038a0926070010260300" + }, + { + "filename": "head-earth", + "data": "0x00031a1606070006430c000a4308000343011c0543011c0243021c05000243031c0543061c04000243021c0543071c0300011c0243031c0343091c0200021c0243011c0443091c0100031c08430c1c0d43081c07430e1c0543091c0143061c0443081c0243061c0443071c03430100031c0643071c02430200021c0843041c04430300011c0943041c02430400011c0443081c034305000e4308000a430c0006430700" + }, + { + "filename": "head-egg", + "data": "0x0001191507070004020c00020202ae04020900010201ae010202ae020202ae010207000c020500010201ae020201ae020201ae06020400010201ae060202ae020201ae01020300010201ae020201ae040202ae030201ae01020200010201ae0c0201ae01020200010201ae0b0201ae02020100100201ae060201ae0a0201ae030201ae0a0201ae020201ae030201ae0a0201ae020201ae330202ae0202010010020200030201ae080201ae030203000502021e070205000c020800050201ae02020500" + }, + { + "filename": "head-faberge", + "data": "0x0001191406080003260d0001260207012601070126020701260a00020701260307012602070900010f0407010f0407010f07000d070600010701260407012604070126010705000107012601890126020701260189012602070126018901260107040002070126040701260407012602070300110702001126010013260100118a020011070200110703000f0704000f0704000f0705000d0706000626032303260900098a0500" + }, + { + "filename": "head-factory-dark", + "data": "0x00031a14080300057c0b00010e0300087c0600020e0b00047c010002241000020e0400010e0300010e0300010e0300020e0300020e0200020e0200020e0200040e0100030e0100030e0100030e0200100e0200100e0200100e0200100e0200100e0200100e0200100e0200100e0200020e0172010e026d010e026d010e0172050e0200100e0200100e0200" + }, + { + "filename": "head-fan", + "data": "0x00031a1606070006510c0003510100015102000351080003510200015102000151020003510500035102000151027e0151027e0151020002510400025102000151027e0151027e0151027e01510100015103000251020001510100017e0151027e0151027e0151017e01000251020001510200015102000151027e0151027e0151017e01000151010001510100025101000151020001510100017e0262017e0151017e010001510200035101000151027e015102000462020001510200015101000351027e0151027e06620151027e0151020002510100017e0151027e01510662027e0151017e0100035101000151027e0151027e0462027e0151027e0151010003510100017e0151027e0151017e0262027e0151027e0151017e02510100015101000151027e0151027e01510100017e0151027e0151027e0151020002510100017e0151027e01510100017e0151027e0151027e02510300015101000151027e015102000151027e0151017e01000251040002510200015102000151027e015102000351050003510200015102000151020003510800035102000151010003510c0006510700" + }, + { + "filename": "head-fence", + "data": "0x00041d1403020001ba060001ba060001ba06000134030003ba0400013402ba040003ba040001ba013401ba010005ba020001ba013403ba020005ba020002ba013407ba020001ba013403ba020003ba013401ba020002ba013405ba013401ba020001ba013403ba020003ba013401ba020008ba013401ba023401ba013403ba023403ba013401ba023402ba013405ba013401ba023401ba013403ba023405ba023408ba013401ba023401ba013403ba023405ba023408ba013401ba020005ba020005ba020005ba013404ba020005ba020001ba013403ba020003ba013401ba013404ba020005ba020001ba013403ba020003ba013401ba013402ba013401ba023405ba023401ba013403ba023403ba013401ba013404ba023405ba023401ba013403ba023401ba013401ba013401ba013404ba023405ba023401ba013403ba023403ba013401ba013404ba020005ba02000585020003ba013406ba020003ba013401ba02000585020003ba013406ba020003ba013401ba020001ba013403ba020005ba" + }, + { + "filename": "head-film-35mm", + "data": "0x0003181405080006230d0006230800102303420726078702260100014201000726078702260342072607870226034207260787022603420726078702260342072607870226034207260787022603420726078702260342072607870226034207260787022603420726078702260342072607870226010001420100022603ad022607870226034207260787022603001023" + }, + { + "filename": "head-film-strip", + "data": "0x00051b140516bb010002bb010002bb010002bb010002bb010002bb010002bb010002bb010016bb02bc01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb03bc017b01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb02bc16bb010002bb010002bb010002bb010002bb010002bb010002bb010002bb010016bb" + }, + { + "filename": "head-fir", + "data": "0x00011f18010e00020f1b00040f1900060f1700030f015c040f1500030f015c060f1300030f015c040f015c030f11000a0f015c030f0f000c0f015c030f0d00120f0b00140f0900160f0700180f05001a0f03001c0f01001e0f0600120f0b00140f0900160f0700060f065c0c0f05001a0f2700010f0e00010f0d00020f0e00020f0b00030f0e00030f0500" + }, + { + "filename": "head-firehydrant", + "data": "0x00021c14040b0002bd140006bd110002be01bd02be01bd02be0f0003be01bd02be01bd03be0d0003be01bd04be01bd03be0c0003be01bd04be01bd03be0b0003be01bd06be01bd03be0a0003be01bd06be01bd03be080012bd060012bd08000ebe0a000ebe060002be012310bd012302be020002be012310bd012302be010001bd02be012310bd012302be02bd02be012310bd012302be01bd010002be012303bd0b2302bd012302be020002be012310bd012302be06000ebe0500" + }, + { + "filename": "head-flamingo", + "data": "0x00031b14050c00042003b90d00062001b9012301b901200b00072003b902200900042005000320025f070004200800035f070004200800025f010e070005200800020e080006200600020e090008200300010e0b0009200e0009200f0008201000062002002b6a0b2006091b20010014200100" + }, + { + "filename": "head-flower", + "data": "0x00031b18050a00024f1300044f0d0002b90200019a044f019a020002b9070005b9019a044f019a05b9050007b9019a024f019a07b9040007b9041307b9050004b90213046d021304b9060003b90113086d011303b90500029a02b90113086d011302b9029a0300034f019a01130a6d0113019a034f0100054f01130a6d01130a4f01130a6d0113054f0100034f019a01130a6d0113019a034f0300029a02b90113086d011302b9029a050003b90113086d011303b9060004b90213016d0385021304b9050007b9041307b9040007b9019a024f019a07b9050005b9019a044f019a05b9070002b90200019a044f019a020002b90d00044f1300024f0a00" + }, + { + "filename": "head-fox", + "data": "0x00031c190405000302140005021200014205020800022301000223040002420502080002420100024203000442030209000642010007420400022306420111014201110742070006020a4209000b02054209000a020100054209000902020004420a00080204000f42050204001042040204001142030204001242020204000542070207420102040005420623020206420500054209020442060001420e000242040004420e000142050001421100024204000123120002420223010001231600" + }, + { + "filename": "head-frog", + "data": "0x00061914070300051c0300041c0500071c0100061c0300041c020f0a1c0200041c020f0a1c02000d1c020f011c02000d1c020f011c0200101c0200101c0200020f0e1c0100011c020f331c14670e5c0267010010670100" + }, + { + "filename": "head-garlic", + "data": "0x00051914070700010b0100010b0100010b0e00030b0f00030b0e000157030b015709000157030b0157030b0157030b0500010b0157030b0157030b0157030b01570300020b0157030b0157030b0157030b0157010b0100030b0157030b0157030b0157030b0157050b0157030b0157030b0157030b0157050b0157030b0157030b0157030b0157050b0157030b0157030b0157030b0157050b0157030b0157030b0157030b0157050b0157010b01bf010b0157030b0157030b0157050b0157020b04bf010b0157030b0157020b0100020b0157030b0157030b0157030b0157010b0300010b0157030b0157030b0157030b01570200" + }, + { + "filename": "head-gavel", + "data": "0x000419140108000f3409000f340a000d230b000d260b000126015d0b260b000126015d0b260200013401000234010004340d2604000134020004340d2603000234010005340d260b000d260b000d260b000d260a000f3409000f230800118e0700118e07001123" + }, + { + "filename": "head-ghost-B", + "data": "0x00051b16030c00028c1500048c0b00028c0700058c0600028c0200048c0400028c0104018c0104018c0400048c0200068c0200068c0200068c0300148c0400148c0400148c0400148c0500128c0600128c0600118c0700118c08000f8c07000f8c0600118c0b00028c1400048c1200" + }, + { + "filename": "head-glasses-big", + "data": "0x00091c120204000a8002000a800400018005020480020001800502048004000180050204800200018005020980050207800502098005020780050205800300018005020480020001800502058003000180050204800200018005020580030001800502048002000180050204800400018005020480020001800502048004000a8002000a80" + }, + { + "filename": "head-gnome", + "data": "0x00011a14060900024112000241110004410f0006410e0006410d0008410c0008410b000a4108000ec0030001c1010001c00ec101c0010003c101c00ec101c004c101c00ec101c004c101c00ec101c002c10200104c0400104c0400104c0400104c040003c10123010201230102012301020123010201230102012302c1040003c10b4102c10500088a018e078a0100" + }, + { + "filename": "head-goat", + "data": "0x00051d1805030001b00c00040d060002b00e0004b0030002b00e0002b0017e022301b0020002b00e0002b0017e04b001000fb0017e02b0017e02b0029802000eb0017e02b0017e01b0017e02b003000eb0027e02b0010002b0030010b0030001b0040010b0080010b0080011b0070011b0060005b0017e0cb0060005b0017e01230102012301020123010207b0050004b0017e0ab0010003b0050003b001000ab0040001b0040002b0110001b0030003b0100002b0030001b0120001b0040001b0120001b00400" + }, + { + "filename": "head-goldcoin", + "data": "0x00031a1606070006260c000326042b032608000326022b0426022b032605000226022b0826022b022604000126012b0c26012b012603000226012b0c26012b022602000126012b092603290226012b012601000226012b032603290826012b0326012b1026012b0226012b1026012b0226012b1026012b0226012b1026012b0326012b112601000126012b102602000226012b0f2603000126012b02260129012604290426012b012604000226022b0826022b022605000326022b0426022b032608000326042b03260c0006260700" + }, + { + "filename": "head-goldfish", + "data": "0x00051b1405020012210500109504001421010029210151032112070151010702211407022112070151010702211407022114070221140703210807032507070221010001210707011401250123022506070121020002210707032506070221030003210c07032106000e210400" + }, + { + "filename": "head-grouper", + "data": "0x00061d1602090001080100010801000108010001080100010810000c080e000f0807000208020004080e7a040004080200137a03000408157a01000508157a02000408117a0108047a02000308107a02c4047a010004080e7a02c4047a0282020003080d7a01c4047a0282030004080c7a01c4047a018204000508057a0208047a010801c4037a018205c401000408047a0108057a020801c4027a018201c4047a010004080200077a040801c4077a030002080600027a0508027a01c4047a100003080c00" + }, + { + "filename": "head-hair", + "data": "0x00031e15020800068e0100058e0f00018e0626018e0526018e0d00018e0126068e0126058e0126018e0900018e0100018e0126018e0626018e0526018e0126018e0100018e0700018e0126018e0126068e0126058e0126018e0126018e0800018e0126018e0126018e0500018e0400018e0126018e0126018e0800018e0126018e0126018e0a00018e0126018e0126018e0800018e0126018e0126018e0a00018e0126018e0126018e0600018e0100018e0126018e0126018e0a00018e0126018e0126018e0100018e0500018e0126018e0126018e0c00018e0126018e0126018e0600018e0126018e0126018e0c00018e0126018e0126018e0600018e0126018e0126018e0c00018e0126018e0126018e0600018e0126018e0126018e0c00018e0126018e0126018e0400018e0100018e0126018e0126018e0c00018e0126018e0126018e0100018e0300018e0126018e0126018e0e00018e0126018e0126018e0400018e0126018e0126018e0e00018e0126018e0126018e0400018e0126018e0126018e0e00018e0126018e0126018e0400018e0126018e0126018e0e00018e0126018e0126018e0200028e0100018e0100018e1000018e0100018e0100028e" + }, + { + "filename": "head-hardhat", + "data": "0x00041d1405050005c505c60d0006c601c505c60b0006c502c601c505c6090007c601c502c601c505c6080008c601c501c601c505c6070009c601c502c605c501c6060009c601c508c6060009c601c508c6060009c601c508c6060009c601c508c6060009c601c508c6060009c601c508c6060009c601c508c6060003c60fc5050004c601c50d2301c509c601c50dc601c51dc6" + }, + { + "filename": "head-heart", + "data": "0x00041c1704050005240400052408000924010008240500062402020624020204240300092401020524020201240102032402001324010202240100142401024b2401001624020016240300142404001424050012240700072402020123062409000e240b000c240d000a2410000624140002240b00" + }, + { + "filename": "head-helicopter", + "data": "0x00031d14020d0002231000016104620261062302610462016110000223190002231600072007560400022006000220019a0120019a0120019a012008560300032004000320019a0120019a0120019a01200956020002620e200556030202560162022301620d200556030202560162022301620d200556030202560100026202000c200a5606000b2008560102015607000a20085601020156080009200656020201560a00082008560c000e200f0001230200012312000e230600" + }, + { + "filename": "head-highheel", + "data": "0x00061b14050200031812000518110006180f0008180e0008180e0008180e0008180e0009180d000b180c000c180b0004180200081809000218040009180700021805000a180500021806000318042304180300025b07000a5b" + }, + { + "filename": "head-hockeypuck", + "data": "0x00051b1505070008050b000305081f0305060002050e1f020503000105121f010501000105141f0205141f0205141f0105010d0105121f0105011f020d02050e1f0205010c011f040d0305081f0305020c021f070d0805060c011f040d030c020d010c010d090c021f070d0e0c011f0100030d030c020d0b0c011f0300050d030c0105010d0205010d050c0600030c020d090c0b00080c0700" + }, + { + "filename": "head-horse-deepfried", + "data": "0x00061b15050900018e0100028e0d0003ac0100068e010003ac0600028e03ac068e020003ac0600028e07ac018e06ac0500038e06ac036d05ac0600028e07ac016d06ac0600028e07ac016d06ac0500038e07ac016d06ac0600028e07ac016d06ac0600028e07ac016d06ac0500038e128a0200028e0e8a0123018a0123018a0100038e028a016d0123016d0123016d0123016d098a048e128a0100038e128a0100018e0100018e0e8a0400" + }, + { + "filename": "head-hotdog", + "data": "0x0003171409050004890700018301390689013901830300028301390689013902830100028301390289016d021903890139048301390389026d011902890139048301390589016d011901890139048301390389026d011902890139048301390289016d021903890139048301390389026d011902890139048301390589016d011901890139048301390389026d011902890139048301390289016d021903890139048301390389026d011902890139048301390589016d011901890139048301390389026d011902890139048301390289016d021903890139048301390389026d011902890139048301390589016d0119018901390283" + }, + { + "filename": "head-house", + "data": "0x00031c1505080001830f00027c04000183015101830e00021103000183035101830d0002110200018302510183025101830c000211010001830251018301c70183025101830711040002110183035103830351018307110300011101830b5101830711020001830d510183071101830f5107831a51051103510b830451051103510183031103c7031101830451051103510183021105c7021101830451051103510183011107c70111018304510311012601110351018306c7017c02c70183045105110351018305c7027c02c7018304510111032301110351018304c7037c02c701830451051103510b830351077c0e51" + }, + { + "filename": "head-icepop-b", + "data": "0x00071c19020500061c089305190600021c059b0802031603190500011c019b051c08930319020202190400011c019b051c08930319020202190400071c089305190116011904c8071c089305190116011904c8071c0893071904c8071c089305190116011904c8071c0893071904c8071c089307190400071c089307190400011c029b041c089307190400011c029b041c0193020201930102039306190600061c089305190a00021c0c0002190a00011c0d00011919000119330001190300" + }, + { + "filename": "head-igloo", + "data": "0x00051e14050800060210000402013c0202023c03020c000102033c0302013c0302023c01020a000102013c0602013c0502013c010208000102033c0102043c0102013c0102053c010207000602013c0602013c040206000102013c1002013c010205000502053c0102063c03020500140204001202013c0102013c020202000102023c0902063c0102013c040201000302013c0402013c0502013c0202013c0102013c0202013c010201000302013c0402013c0502013c0302013c0202023a013c0202023c0102053c0102033c0202043c0202023a013c0202013c0302013c0502013c0402013c0102013c0202033c010201000402013c0502013c0402013c0102013c05020100" + }, + { + "filename": "head-island", + "data": "0x00021b14060400040f1000060f0100061c0c00020f091c0800080f031c01c9031c0500040f01c9030f031c01c90200031c0400020f020002c90100010f021c02c90300021c0400010f040002c90100021c01c90400021c090002c90200011c01c90500011c0400060f01c9020002c90900080f01c9010002c90900080f01c9010002c90900080f01c9010002c90900080f01c9010002c909000e260600102604000d2601460426020002260146012602290226022902260146032601460326010006260229062601460526010014260100" + }, + { + "filename": "head-jellyfish", + "data": "0x00031c1b050700055f016a035f0b00016a0e5f0600065f016a0c5f0400135f0300085f0576055f016a025f0200015f016a045f0976065f0100055f0d76065f016a025f0f76025f016a055f0f76075f1176065f1176035f0100015f1376015f0200015f1376015f0200015f1376015f0200015f036e0176036e0176036e0176036e0176036e015f0200156e0200016a086e0690066e0200016a0200016a0e6e016a0100016a0200016a0200016a0e00016a0100016a0200016a0200016a0e00016a0100016a0100016a0200016a0f00016a0200026a0200016a1000016a0100026a1300016a0100026a1500026a1500016a" + }, + { + "filename": "head-jupiter", + "data": "0x00011d1a030900088210000c820e000982037d0b00107d02370700057d0f3706000b370938040005370a380937020006380a37087d020009370f7d01000637147d04377c7d0237167d0437147d0637010001370b7d0c3702000e3704250337038204000b3702250223022503820600048208370425048206001482070012820b000c8210000882120008820900" + }, + { + "filename": "head-kangaroo", + "data": "0x00051a1406037e0a00037e0400017e0238017e0800017e0238017e0400017e0338017e0600017e0338017e0500017e0338017e0400017e0338017e0700017e0238027e0200027e0238017e09000a7e0a00087e0c00087e0c00087e0c00087e0c00067e088103230300067e088103230300067e0b810300067e022309810300067e0b810300067e0b81" + }, + { + "filename": "head-ketchup", + "data": "0x0002181408070002240e0002240d0004240c0004240b0006890a0006230600022402890224028902240289022402000e23010082240389022403890a2404891824" + }, + { + "filename": "head-laptop", + "data": "0x00061b1605171f010b013c120b021f1456021f1456021f1456021f1456021f1456021f1456021f1456021f1456021f1456021f1456041f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e041f130e031f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e041f130e181f" + }, + { + "filename": "head-lightning-bolt", + "data": "0x00021e19050800031e1500081e11000c1e0c000c1e0d000b1e0d000b1e0e000a1e0e000a1e0f00091e0f00091e1000081e1000171e0200161e0200151e0400131e0500121e0c000b1e0d000a1e0f00081e1000071e1200051e1300041e1500021e1600011e1700" + }, + { + "filename": "head-lint", + "data": "0x00021b16050a00018c1400018c0f0001910600018c04000140080001910300018c0200038c014001000240090002910200028c0191028c03400400029106000340028c0191018c014001910240018c020001910300018c0200014001910340018c0191018c024001910240028c0300038c034001910340038c024001910140018c0500018c0100018c024001910340018c0191028c014001910140028c0600018c0191024001910240028c0191028c02400191028c010001910100028c0191018c024001910240028c0191028c0240038c010001910200018c0140028c014001910240058c0240028c0191018c01910100058c0740038c01400191038c010001910100038c01910840028c01400191028c020001910200018c01910a40018c0191028c0500038c0140018c01910640018c0191038c0191050001910140028c0191014004230140048c010002910300048c01910740028c0191028c0500018c010002910740028c0191018c0191090001910100014001000340018c0191018c0100018c0e0001400191010001910900" + }, + { + "filename": "head-lips", + "data": "0x00051d150307000424040004240c0007240200072409000d240202032407000e2403020324050013240102022403001824020006240c02062401000524100209241202072414021d240100182402001824030016240500082404020824080010240d000a240800" + }, + { + "filename": "head-lipstick2", + "data": "0x0001181408060003240b0007240800013709240500012401370a24040002240137062401370224040003240437020203240400072402370324040007240237032402000b2a01020f2a01020f2a0102042a0b0d01050f0d01050f0d01050f0d01050f0d01050f0d01050a0d0223030d01050f0d0105040d0b0501020405" + }, + { + "filename": "head-lock", + "data": "0x00031814080400081f07000a1f0500031f0600031f0400021f0800021f0400011f010d0800011f010d0400020d0800020d0200107a718a026d0a8a026d028a026d048a0223048a026d088a0223178a" + }, + { + "filename": "head-macaroni", + "data": "0x00081d1403010008290800082901000229060a022906000229060a02290126082901260600012608290b2606000b26012808260600082601280226012809260400082602281826012802260100182602001526012802260300162605000626020a0126020a0126020a0626070012260a000e260600" + }, + { + "filename": "head-mailbox", + "data": "0x00071c14050700058912000589150002890b000a050289030508000a050289030508000a050289030508000a050289030508000a0502890305060202000a05028903050402013a010202000a0502890305060202000a0502890305060202000a050289030501020423010202000f05060202001705" + }, + { + "filename": "head-maze", + "data": "0x00061b14050aca01000cca0b0001ca040001ca030002ca01000bca010001ca010004ca010002ca010001ca030001ca070001ca040001ca010002ca030001ca030007ca010004ca010007ca010002ca030001ca080002ca010001ca050001ca010001ca010001ca010006ca010002ca010005ca010001ca010003ca080002ca050001ca050001ca010009ca010003ca010003ca010001ca080001ca010002ca030001ca010001ca010001ca010008ca010001ca010004ca010001ca100002ca010001ca010004ca010007ca010006ca030001ca080001ca070015ca010001ca" + }, + { + "filename": "head-microwave", + "data": "0x00071a1f05010002950f06012102060100029501060e9201210143010e0100029501060e920121010e01430100029501060e92012102c70100029501060e92012102060100029501060e92012102c70100029501060e92012102060100029501060e92012102c70100029501060e92012102060100029501060e92012102c70100010e019501060e9201210206020e019501060e92012102c7020e01950f06012102c7010e02950f0601210206010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400" + }, + { + "filename": "head-milk", + "data": "0x00031b14080100014a0d7f0500014a067f0524027f0400034a057f09240289034a097f05240289034a0d430300034a0143017f0143027f0143047f0143017f01430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d43030003c70d7f0300034a0d430300034a0d430300" + }, + { + "filename": "head-mirror", + "data": "0x00041a1406159702060102010603020a060102029701060102010603020b06010202970102010603020c0601020297010603020d060102029703020106063c0106063c0102029702020206013c0406013c0106013c0406013c010202970102043c0406033c0406013c010202970106013c0206013c0406013c0106013c0406013c010202970106013c0206013c0406013c0106013c0406013c010202970406063c0106063c0102029711060102029711060102029711060102029711060102029712021597" + }, + { + "filename": "head-mixer", + "data": "0x00021a140603000223030002240300022407000172030001230172030001240172030001240300150c030f020c030f020c030f020c0123010c0123020c010f015c010f020c010f015c010f020c010f015c010f020c0124010c0123110c014e010c01af030c0123040c0123030c0302020c014e010c014e030c0123040c0123030c0372020c014e010c014e030c0123040c0123040c0123090c0123040c0123040c0123090c0123040c0123040c0123050c011f030c0123040c0123040c0123090c0123040c0123040c0123050c011f030c0123040c0123040c0123090c0123040c0123040c0123050c011f020c0302030c0123040c0123080c0372020c0302030c0123040c021f030c0123030c0372030c0123040c021f150c" + }, + { + "filename": "head-moon", + "data": "0x00031a1606070006870c000387035e048708000487035e078705000487025e0687015e038704000e87015e01870300128702000587015e0887015e038701000287015e1287025e1287015e4e870100128702000f87015e02870300058702230687025e018704000b87035e028705000687015e0387015e038708000a870c0006870700" + }, + { + "filename": "head-moose", + "data": "0x00051c15040383010002830c00028301000683010002830c85028301000683010002830c85028301000683010002830c85028301000a830b850d830b850d830b85068304000e850a000f8509000f8509000f85090005850d98060005850d980600058506980284029802840198060005850d980600058501980b8401980b000d980200" + }, + { + "filename": "head-mosquito", + "data": "0x00011f14030c0002351800023503000235140001350300023515000135030001351700013502000135180001350200013518000135020001351400091112000211014909110f00021101490b110d00021101490d110c0011110a00131109000211014910110900141109001b110200151108000a1107850c000211078507110d000f110800" + }, + { + "filename": "head-mountain-snowcap", + "data": "0x00031c15040a00040213000102028d030211000102018d060210000102018d06020f000a020e000102018d0602018d01020d000c020c000c020b000e020a000e020900021d0202021d0402021d0302011d0800021d0102041d0202041d0102021d0700021d0202051d0102041d0202021d0600021d02020a1d0202021d0500031d0202051d0102041d0202031d0300021d01020f1d0102031d01000b1d0302071d0102021d0100161d0400061d0600061d0300" + }, + { + "filename": "head-mouse", + "data": "0x00031e1407070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e07000e0509000e0509000e0509000e0509000e050400030e02000e050400030e02000e050400030e0200120505000e05011f0105011f010505000805024b0105024b0505050012050300" + }, + { + "filename": "head-mug", + "data": "0x00031b14020900067f0200017f0e00037f0400017f0300027f0100017f0900017f0200037f0300037f0e00027f0100017f2a00160203000102016f014b1102014b010201000102014b0102016f014b1102014b030201000102016f024b1002014b020202000102016f024b1002014b020202000102016f024b1002014b030201000102016f024b1002014b010201000102014b0102016f024b120202000102014b0102016f014b110205000102016f014b110206000102016f014b040204370402014b020208000102016f014b040202370402014b02020a000102016f024b0602024b02020400" + }, + { + "filename": "head-mushroom", + "data": "0x00021c1504080008550d000855025104550800035501510455025104550251025505000855045105550151025503000a5502510a550200035502510c55035102550100035504510655025102550551035501510255025103550151035502510255055103550151105503511b55010016550400125508000eae0a000eae0a000eae0a000eae0a000eae0a0002ae045508ae0a0002ae01550223015508ae0c0004550d00" + }, + { + "filename": "head-mustard", + "data": "0x0002181408070002260e0002260d0004260c0004260b00068a0a00062306000226028a0226028a0226028a022602000e2301008246038a0246038a0a46048a1846" + }, + { + "filename": "head-nigiri", + "data": "0x00051c1404040002cd01cc03cd01cc03cd01cc03cd01cc01cd060001cc03cd01cc03cd01cc03cd01cc03cd01cc03cd020002cd01cc04cd01cc03cd01cc03cd01cc03cd01cc07cd01cc03cd01cc03cd01cc03cd01cc03cd01cc07cd01cc03cd01cc03cd01cc03cd01cc03cd01cc07cd120203cd0100160202001602030014020300160202001602030014020300160202000a0203ce090203001402050012020300" + }, + { + "filename": "head-noodles", + "data": "0x00021e1402100001361b0001360500013614000136040002360b0001cf010001cf010001cf05000136020002360c0001cf015c01cf015c01cf015c01cf02000298038803160a0001cf015c01cf025c0316039806880216080001cf015c01cf025c02160419038803c1028801160298060001cf015c01cf015c02160619018801c1034601c101880116039803001c0b01001a0b02001a89030018890400180b050016890600160b0700140b0900070b0789040b0b00100b0e000c0b0800" + }, + { + "filename": "head-onion", + "data": "0x00041a14060a00019c1100019c0100019c0100019c1000039c10000137039c01370900029c0137039c0137039c0137039c0137019c0300039c0137039c0137039c0137039c0137029c0100049c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c01c7019c0123019c0137039c0137029c01c70137039c0100039c0137029c0423019c0137039c0137029c0300029c0137039c0137039c0137039c0137019c0500019c0137039c0137039c0137039c01370300" + }, + { + "filename": "head-orangutan", + "data": "0x0002181406070001240e000b2406000b2407000c2404000e2403000624070e042403000424070e0424030002240c0e0124030002240c0e0124030002240c0e0124030002240c0e0124030002240c0e01240300100e0200040e0a08020e0200030e0c08010e0200030e010801240208010e0108010e030801240108010e0200030e01240a080124010e0200030e01240a230124010e0200030e0c24010e" + }, + { + "filename": "head-orca", + "data": "0x00021b14010d00010d1900020d1800030d1700040d1600050d1500060d12000b0d0d000e0d0b00100d0300030d0300110d0400030d0100130d0300170d0400160d0300180d0200030d0100140d0100030d0200130d0100030d0400080d090b0a00060d090b0c00040d090b0400" + }, + { + "filename": "head-otter", + "data": "0x000918140704000b8604000e8603000f8602000f8602000f860100328602000286047f0623037f020001d00486017f0623017f0286020002d0037f04d0012303d0027f020008d0012301d0012304d0" + }, + { + "filename": "head-outlet", + "data": "0x0004181608245108a3075102a3012304a3012302a3065102a3012304a3012302a3065101a3037c02a3037c01a3065104a3022304a3065104a3022304a3075108a3185108a3075102a3012304a3012302a3065102a3012304a3012302a3065101a3037c02a3037c01a3065104a3022304a3065104a3022304a3075108a32451" + }, + { + "filename": "head-owl", + "data": "0x000218140507000ad1080001d10ad201d1060001d101d204d302d204d301d201d1050001d101d20ad301d201d1050001d101d201d302d401d202d301d202d401d301d201d1050001d101d203d301d202d301d203d301d201d1050001d101d204d302d204d301d201d1050002d101d208d302d201d10400042b01d208d301d201d10300062b08d301d201d10300062b01d107d301d201d10200072b01d107d301d201d10200072b01d107d301d201d10200072b01d107d301d201d10200062b02d107d301d10300052b03d106d301d10400032b04d106d301d1040001d1012b07d106d303000bd107d30100" + }, + { + "filename": "head-oyster", + "data": "0x00021d14040a00058111000481038204810e000181098201810c000381098203810a00018105820398058201810700048102820998028204810400018105820998058201810400018102820f980282018102000381018211980182048103821198038202810282139802820281048206980351079803820181010002810382049805510498038202810400028101820398075103980182028108000181019802550751025501980181090001810f5501810700048103550581035504810600018102d5058103d5058102d50181070011d50400" + }, + { + "filename": "head-paintbrush", + "data": "0x00091c18020700036d0572097502240600046d027201b00272097502240600046d0572087503240100096d0572087503240a6d0572087503240a6d0572087503240a6d0572077504240a6d0572077504240100096d0572077504240600046d0572077504240600036d0224017201b00272067505240700036d05720675052416000124010002241800022418000124190001240100" + }, + { + "filename": "head-panda", + "data": "0x000519140601000423090004230100062307000c23090209230b0207230d020223010002230e02012303001002030010020300100203001002030010020300100203000a020423020203000a02042302020300070206230302030010020100" + }, + { + "filename": "head-paperclip", + "data": "0x00091d14031bd6180002d6180002d6180002d6030010d6050002d6030001d6140002d6030001d6140002d6030001d6140002d6030001d6140002d6030017d6190014d60600" + }, + { + "filename": "head-peanut", + "data": "0x00041b1605040005d70f0002d7036004d70c0002d7016003c8036002d70b0002d7016001c802d7016002c8016001d70a0002d7026003d7016002d7016002d7090001d7016002c8036001d7046002d7080001d7016002d7016003d7016001d702c8016005d7040001d701600bd7016006d7020002d7016012d7020001d7016010d7016001d7020002d7016012d7020002d701600dd7026002d703000fd702c8016001d7040005d7036005d7016002d7016001d7050002d7016002d702c8056001d7026002d7060002d7026002d7016004c8016002c801d7090002d7036004d7016003d70b0003d7046003d70f0005d70400" + }, + { + "filename": "head-pencil-tip", + "data": "0x0003171409060002230c0002230b0004230a000423090006230800022301570323070002230357032306000757012305000a5704000a5703000c5702000c5701001e57042605570326015706260357072608371126" + }, + { + "filename": "head-peyote", + "data": "0x00021e14030a0001d8020001d9020001d8140001d801da010001d9010001da01d8120001d8020001da01db01d901db01da020001d8110002da05db02da0e0001d8010002a901dc02a903dc02a901dc02a9010001d8090002d802a901dc04a901dc04a901dc02a902d8090002a901dc02a902d801a901dc01a902d802a901dc02a9090002a901dc02a902d802a901dc02a902d802a901dc02a9070002a901dc0fa901dc02a9050017a9020001d8010017a9010001d8010001d817a901d8010002d817a902d8010001d817a901d8010001d8010017a9010001d8020002a901d911a901d902a9050001a913d901a9060015a9080011a90500" + }, + { + "filename": "head-piano", + "data": "0x00041b15080400050e0c00020e010501590105040e0900020e0105080e08000b0e07000d0e06000d0e06000e0e05000e0e05000f0e0400110e02004d0e0159070e0159050e0159040e0159010e0159010e0159010e0159010e0159010e0159010e0159010e0159010e0159020e1159140e" + }, + { + "filename": "head-pickle", + "data": "0x00031b15050400040f1000080f0d00030f01bf060f0c00030f015c030f01bf020f0b00020f01bf060f015c020f0a00020f015c030f01bf070f0800060f015c040f01bf015c050f0400010f01bf120f0200010f015c130f0100150f0100160f0100150f0100130f01bf010f0100020f01bf100f015c010f0200010f015c120f02000b0f012302bf015c040f0400030f01bf015c010f01bf040f025c050f0600050f015c090f09000b0f0400" + }, + { + "filename": "head-pie", + "data": "0x00011c14040b0002cb100002cb030002cb050002cb0b0002cb030002cb030002cb0b0002cb030002cb050002cb0b0002cb080002cb0b0002cb04000209040002cb0b0002cb0200020901190109020002cb0f0001dd040901dd0e0002dd010903dd020903dd010902dd080012dd050001dd010910dd010901dd030016dd020001dd04ba01dd04ba01dd04ba01dd04ba01dd01ba010033ba029503ba0196019503ba0195019603ba029505ba01950196029501960295019202950196029501960295019602950196029501ba010001950196029501960295099201960295019602950300019602950196029501920295019602950196029501960295019601950400019602950196029501960295019602950196029501960295019601950200" + }, + { + "filename": "head-piggybank", + "data": "0x00041d14020c0003421700014203930142050002760c00036c012503930125026c02000176016c01760a000276026c017605120176026c0176026c017609000176106c0176060001760100036c01020f6c0176040001760259146c0176030001760159136c0112016c03760100017601590176166c0176015901000276166c017603000176146c037603000276156c0176030001590176146c017605000376106c0276070013760900067601120202011206760d000c760700" + }, + { + "filename": "head-pill", + "data": "0x00061d140305000924071d08000c24081d0500062401020724081d0300032402020a24091d0200032402020b24081d01001124091d1124091d1124091d1124091d1124091d01001024061d010f011d02000f24071d010f011d03000a2403230124061d010f011d05000c24081d08000924071d0500" + }, + { + "filename": "head-pillow", + "data": "0x000319160702de0e0002df0dde05df010002de0edf020003de0ddf020003de08df03de02df020003de0ddf020003de02df02de09df020003de0ddf020003de0ddf020003de0ddf020003de0ddf020003de0ddf020003de0ddf020003de0ddf020003de0ddf020003de05df04de04df020003de0ddf020002de0edf01000dde05df02de0e0002df" + }, + { + "filename": "head-pineapple", + "data": "0x00031914070600010f010002e00100010f0a0001e00100020f02e0020f010001e0080003e0010f02e0010f03e00a0006e00a00022802260228022602280600022802260228022602280226022804000228022602280226022802260228030001280226022802260228022602280226012802000128022602280226022802260228022601280200012602280226022802260228022602280126020001260228022602280226022802260228012602001126010010260200102601001226010002260342012604420126034202260200022603420126044201260342022603000e260200" + }, + { + "filename": "head-pipe", + "data": "0x00061c150509160e0009980e0009980f00030804981000030804981000030804981000030804981000030804980c0003160100030804980c160398010003081398010003081398010004081298010006080123010201230102012308080398020015080300140814000308" + }, + { + "filename": "head-pirateship", + "data": "0x00011f14030c0002231b00019813000198030008230f00022304000823020002230b00019805000123015101230251012301510123020001980900025501980500032302510323010003550800035505000423015103230200035507000455030002230151042301510123010003550700065501000923030001980b00019807000198070001980b000198070001980700019806000d2601980700019806000c97012601980700019806000197022309970126089701980100052601970223099701260198010001970100019701000197010001980126049701000c970a2603970500049701231097080002970323019701230197012301970123019701230197012304970a00029701230e970c000f970800" + }, + { + "filename": "head-pizza", + "data": "0x000319140708000237100002370f000137022801370e000137022801370d000137042801370c00013701280237012801370b00013702280237022801370a0001370628013709000137082801370800013708280137070001370a280137060001370a280137050001370c280137040001370c280137030001370328033708280137020001370128013701280337052802370128013701000137082803230528023710280137" + }, + { + "filename": "head-plane", + "data": "0x00041e14030d000202180005021300090210000b020e000c0246000bc710000bc710000bc710000cc70f000cc7090002c7040012c70200010202c7040005c7060207c7020001020ac7090205c7010001c701020924020206230202052402000102010007c70b0205c702000102" + }, + { + "filename": "head-pop", + "data": "0x000318140802000ca20300061405280314010005140128031404280314022802140128011401280314042804140128021401280414052803140128081404280114022805140128031404280b1405280b1404280b1405280b1404280b1404280b1404280a140528091404280b1403280314012801230202012301280214010002280c1403000ca20200" + }, + { + "filename": "head-porkbao", + "data": "0x00051914070500025701000257010002570a0002570183025701830257090002570183025701830257018301570800015701830257018302570183025706000e5704000e5703001057020010570200105701005157037d1857010010570100" + }, + { + "filename": "head-potato", + "data": "0x00061d15040f0001c81600077a1000037a01c8077a0b000b7a02c8027a07000f7a01c8027a0400167a0200177a0100187a0100187a0100187a01c8187a0100107a02c8057a0300097a01230102012301020123017a02c8057a0400057a02c80d7a0600047a02c80b7a0b000a7a0900" + }, + { + "filename": "head-pufferfish", + "data": "0x00041c160509000168020001681000016801000668010001680700034903000568014904680700054902680349076806000449036803490368024903680500034904680349036802490468040003491068060012680500126805001268030005490d680649046801930b6801930468064902930968029306490a680449076806490293046801490235014902680193054903000693026804490168039308000e930a000c930d0008930800" + }, + { + "filename": "head-pumpkin", + "data": "0x00051b1406080003af01c401af100003af01c401af100003af01c401af0b00072401af072406000724014807240300022401480724014807240148042401480724014807240148042401480724014807240148042401480724014807240148042401480724014807240148042401480724014807240148042401480724014807240148042401480724014807240148042401480585016d0385016d058501480424014807240148072401480424014807240148072401480224" + }, + { + "filename": "head-pyramid", + "data": "0x00031e14030800018601b01900028601b01700038602b01600038603b01400058603b01300058604b0110002860284028601b0028602b01000078605b00e00088606b00d00088607b00b000a8607b00a000a8608b008000b8609b007000c8606b0028601b005000d860ab004000186038401860184078607b0038601b002000986032303860bb001000f860cb0" + }, + { + "filename": "head-queencrown", + "data": "0x00021b14050a00025b1300015b01180141015b1200015b01410118015b0e00035b0200025b0200035b0900015b0300015b0100025b0100015b0300015b0500035b0500045b0500035b0100015b0200015b03000241015b018b0154015b02410300015b0200025b0200015b01000441015b0254015b04410100015b0200025b01000141015b0541015b0154018b015b0541015b01410100015b0100015b0141015b0541045b0541015b0141015b0200015b0141015b0641025b0641015b0141015b0200015b0241015b0441045b0441015b0241015b0300015b0241015b0341015b028a015b0341015b0241015b0400015b0241015b0341015b028a015b0341015b0241015b0300025b0141035b0241015b028a015b0241035b0141025b0300125b050010350500055b0841055b0400125b0200" + }, + { + "filename": "head-rabbit", + "data": "0x0004171509037208000672080006720800067208000672080065721e050b2304050202040502021f05" + }, + { + "filename": "head-rainbow", + "data": "0x00041a140608000c1807000d18060003180b14050004180b140400021803140b460300031803140b4602000118031403460b0f01000218031403460b0f031803140346030f0854031803140346030f0854031803140346030f03540512031803140346030f03540512031803140346030f035403120200031803140346030f035403120200031803140346030f032303120200031803140346030f035403120200031803140346030f035403120200" + }, + { + "filename": "head-rangefinder", + "data": "0x00061b1405020002050100020501000d7202050b7203050172020e0102010e01720205027201050372020c037203050172040e017202050172020511720105010e010c0205110c020e140c020e140c020e140c020e140c020e140c020e140c020e120c0205020e080c0505050c0205020e140c010e010514720105" + }, + { + "filename": "head-raven", + "data": "0x00041e14080100080e1100070e0c000c0e0b000c0e09000e0e08000e0e08000f0e0600100e0600100e0600100e0600100e0600090e070d0600080e0c0d0200070e0f0d070e0f0d070e0d0d0200080e090d0500" + }, + { + "filename": "head-retainer", + "data": "0x00091d150504000320150001200119062010000320011906200d00052001190220011904200b00092001190620080002200119032001190620011903200600022002190320011903200219012003190120060002200f190220040002201119012004000120031904a3011904a3011904a30119022002a302200219012001a30120011901a3011901a3021901a3011901a30119012001a30320010001a3052001a3022003a3022003a3022006a3030003a31200" + }, + { + "filename": "head-rgb", + "data": "0x00011c16040900066410000a640d000c640b000e640a000e640900106408000164062802640669016407000165072802020769015a05000265062804020669025a03000365052806020569035a02000365052806020569035a01000565032808020369055a0565032808020369055a0665022808020269065a0765012808020169075a086501e1060201e1085a086508e1085a0100086506e1085a0200086506e1085a0300086504e1085a0500086502e1085a080006650200065a0500" + }, + { + "filename": "head-ring", + "data": "0x00021a15060600084f0c00024f0102024f016c024f0d00034f016c024f0c00032a044f032a0800022a021e022a024f022a021e022a0500012a021e0a2a021e012a0300052a011e0700052a0200032a011e0b00032a0100032a021e0c00042a0102012a011e0d00062a011e0d00062a011e0d00062a011e0d00012a0102042a011e0d00012a0102042a011e0d00032a0100032a021e0a00032a0200052a081e052a0300102a05000e2a08000a2a0500" + }, + { + "filename": "head-road", + "data": "0x00061c1403020017e2020017e2020017d3020017e2020017e2010017e2020017e2020017e2020017e2020017e2010018e2010017e3020017e2020001e203e303e203e303e203e303e203e301e2020017e20200" + }, + { + "filename": "head-robot", + "data": "0x00031c140405000e1f0a000e1f0800120506000105011f0205011f0205011f0205011f0205011f0205011f0105060012050600120506000105101f010504000105010012050400010501001205010001050100031f1205010001050100010e021f1205061f1205021f020e021f1205061f1205021f010e03000105010e0259010e0259010e0259010e0259010e0259010e0105031f03000105010e020b010e020b010e020b010e020b010e020b010e010506000105100e0105060012050300" + }, + { + "filename": "head-rock", + "data": "0x00031b14050b00030c1200010c031f020c0f00010c011f010c041f020c0c00020c021f010c051f020c0500050c051f010c061f010c0300010c121f010c0100010c051f040c0a1f010c0100010c091f010c091f010c0100010c021f010c101f010c0100010c071f020c011f070c021f010c0100010c051f020c0c1f020c141f020c041f010c0e1f030c041f010c081f020c011f030c0300010c041f010c041f030c021f010c021f010c0400010c051f030c041f010c021f010c0600050c041f030c031f010c0700010c0c1f010c0400" + }, + { + "filename": "head-rosebud", + "data": "0x00021c14040c00019415000119010002941300021904941000041906940d00041908940b0005190994090006190a94080005190b94070006190394011d0894060006190394011d08940300011d020006190294021d08940200011d0100011d010007190194021d08940100011d0200041d05190194021d0694041d0300051d03190194021d0494051d0500051d0219041d0294051d0700041d0119011d0123021d0123011d0194041d0900031d0119021d0223021d0194031d0b000c1d0c000c1d0600" + }, + { + "filename": "head-ruler-triangular", + "data": "0x00021c1508019a1300019a014f1200029a014f1100019a034f1000019a044f0f00029a044f0e00019a064f0d00019a074f0c00029a074f0b00019a094f0a00019a034f0100064f0900029a024f0200064f0800019a034f0300064f0700019a034f0400064f0600029a024f0500064f0500019a034f0600064f0400019a104f0300029a094f049a034f0200019a0a4f049a044f0100019a134f" + }, + { + "filename": "head-saguaro", + "data": "0x00031c14040c000479140005790a000479050005790a00047902000279010005790a00047902000279010005790700027901000479020002790100057907000279010004790200017902af057902000279010002790100017901af04790500057902000279010002790300047905000579010003790100027904000379050004790200037901af01790100027902000479020001790100047902000379030002790200047902000179010004790200027904000279020004790200017901af0479020002790400037901000479030001af0479010003790500027901af047904af0479010003790600017901af077902af037901000279090002790323037901af037901af02790a00077901af037901af02790500" + }, + { + "filename": "head-sailboat", + "data": "0x00011c14040d0001021600020201000102130003020100010212000402010002021000020202de0102010002020f00030202de0102010003020d000702010003020c000802010004020a0009020100040209000a020100050207000b020100050206000c020100060204000d020100060203000e02010007021a00188301000183149801830300018301981083019801830500018310980183070010830400" + }, + { + "filename": "head-sandwich", + "data": "0x00041d14030d000188180003e0170002e0011a170003e0100008830188078308000783017d028301880483017d048305000283017d088301880183017d088303000883017d0a83017d048302001883020018e4020018550200016d0655016d0855016d07550100011c186d041c066d081c056d041c0100041c0298051c0398051c0298011c0100011c0400069808230698070012980400" + }, + { + "filename": "head-saturn", + "data": "0x00051c16030b0004e5130008e50f000ce50200023a030005510ee50100023a0200015105000ee505000151040002140de5011404000151040003140ce50114050001510200025503140be502140500015101000255041409e50314060001510355061405e504140700015102550f140800015104550b140151020001e5050001550251055506140255010001510800025502510a5503000151040002e50100045503510755040001510200013a02e50200065503510355050001510200023a050007550351050001510b000455040005510100" + }, + { + "filename": "head-saw", + "data": "0x00091e15020c9710a201000b9710a2020003970100069710a2020002970300059710a2020002970300059710a2020002970300059710a2020002970300059710a202000297030005970ea2010001a202000297030005970ca2010001a20400039701000297012602970ba2010001a20500099703a2025105a2010001a20600099702a2025105a2010001a2100008a20c00" + }, + { + "filename": "head-scorpion", + "data": "0x00031e1403060008e6130008e6130008e6100004e6050003e60f0004e6020003e703e60f0004e6020001e7010002e702e60d0003e6070003e70e0003e6180003e6170003e6180003e6180003e6180003e603000de7080003e6020010e70300039e05e610e703e6019e030004e602e702e802e702e802e702e801e707e6030004e604e702e802e702e804e706e608000ee7010003e6039e" + }, + { + "filename": "head-shark", + "data": "0x00031c14030a0004eb160005eb150005eb140005eb080001eb0b0006eb080001eb08000b43050002eb05000e43040003eb02001143040003eb01001243030004eb1343030003eb1343030003eb104301eb0143040003eb104301eb0143030003eb01001143040002eb02001143040001eb0300034301eb014301eb0243023c0102013c0102013c0102013c040001eb0400024301eb014301eb0243023c0102013c0102013c0102023c09000643093c0400" + }, + { + "filename": "head-shower", + "data": "0x00011c19040b00020d1600020d1300080d0e000c0d0b000e0d0900101f0800081f010b011f030b031f0800101f09000e430a000e430900104308001043080010430700124306001243060012430500144304001443040014430300164302000143010001431000014301000143020004430e0004430100014301000143010001430e0001430100014301000143190001430100014310000143010001430100" + }, + { + "filename": "head-skateboard", + "data": "0x00091e1402030016bf040003bf016a0369016a0abf016a0369016a03bf020001bf011b01bf016a0369016a0abf016a0369016a01bf011b01bf010002bf011b01bf016a0369016a0abf016a0369016a01bf011b04bf011b03bf017c0ebf017c03bf011b04bf011b03bf017c0ebf017c03bf011b04bf011b03bf017c0ebf017c03bf011b04bf011b03bf017c0ebf017c03bf011b04bf011b01bf016a0369016a0abf016a0369016a01bf011b02bf010001bf011b01bf016a0369016a05bf030e02bf016a0369016a01bf011b01bf020003bf016a0369016a0abf016a0369016a03bf040016bf0300" + }, + { + "filename": "head-skeleton-hat", + "data": "0x000519150704000a43050010430200104301002443010010ae020010ae020010ae020010ae020010ae020010ae020010ae020007ae01b001ae01b006ae04000cae060002ae01b001ae016d01ae01b001ae01b001ae01b001ae060003ae01b001ae01b001ae01b001ae01b001ae01b007000bae0300" + }, + { + "filename": "head-skilift", + "data": "0x00011e1403010001230100142301000123010001230800012301000123100001230200152301000123070001231a0001231a0002231900042318000b230c001488060001880a77018809770188050001880a7701880777016601770188050001880a7701880777016601770188050001880a7701880777016601770188050001880a770188097701880500163305001688050016330500063306230a3305001633070012330500" + }, + { + "filename": "head-smile", + "data": "0x00051d140306000424060004240a00082402000824040001240200142402000824020208240202082401021624010202240402102404020324160205241402032401000324120203240200042410020424030004240e020424040006240a0206240500142407000a2402020624090010240c000c240700" + }, + { + "filename": "head-snowglobe", + "data": "0x00051914080600048c0a00038c0151038c0151038c0400018c0151058c0151068c01510200048c0151018c0351028c0151038c0100038c0151018c0197025101970251038c0151028c0151048c025103970251098c025105970251038c0151038c0251039701260197012601970251078c0997088c04970126019701260297088c09970151068c015109970251028c1151010004510411075102000f0802000f080100" + }, + { + "filename": "head-snowmobile", + "data": "0x00071e15050c0001041800010414000305010002041600010502041600010502041600012301040226140003230426080003230600032302260155052605000c23012603550104052603000b23022602550804020002230902022602550804020005020123110202000602032301020b05030001040a020a05030001040200012301050123010501230105012301000e040200" + }, + { + "filename": "head-spaghetti", + "data": "0x00041a1c060c0003840a00038403000184038501840800038401850484028501cf028406000184028501cf018404850284048505000485018404850184058505000f850500015503850255028501cf02550385015504001055040010550300037d0c55027d0300127d0100297d0202017d0102017d0702017d0302017d0102027d0402017d0702017d0302017d0102027d0c02017d0502027d010010020100027d0100017d0e00017d0100027d0100017d0e00017d0100027d0100017d0e00017d0100027d0100017d0e00017d0100027d0100017d0e00017d0100017d0200017d0e00017d0400017d0e00017d0400017d0e00017d0200" + }, + { + "filename": "head-sponge", + "data": "0x0004191408010003290200022902000429030001290222032901220929010001290222092903220229010007290222022903220229010003290222022902220229032202290100032902220a290100102901001029010054290100012902220d2901000129022203290523042903000d290122012902000e290200" + }, + { + "filename": "head-squid", + "data": "0x00011c1a020d00026a1700046a1500036a01ec026a1300056a01ec026a1100076a01ec026a0f000c6a0d000e6a0b00014f0e6a014f0900024f0e6a024f0700024f106a024f0500034f106a034f0300044f106a014f01ec024f0200044f106a024f01ec014f0200044f106a044f0200044f106a044f0300034f106a034f0200014f0200034f0e6a034f0200014f016a014f03000245014f0123010201230102012301020123010201230102014f02450400014f016a014f020003450c4f03450300014f016a014f010014450300014f0145010001450100024501000245060002450100024501000245030003450100014502000145080001450200014502000145040001451300014f01451800014f01451800014f01451800014f0200" + }, + { + "filename": "head-stapler", + "data": "0x00081c140407000d2408001224040016240100172401001724010017240100172405181272010006181172010004180124021811000518122401003018" + }, + { + "filename": "head-star-sparkles", + "data": "0x00021b17050a0002ac10000129020001ac022901ac120001ac022901ac110001ac042901ac030001290100012905000129040001ac042901ac0400012905000329020001ac062901ac020001290100012905000129030001ac062901ac0c0002ac082902ac080002ac0c2902ac040002ac102902ac010001ac142902ac142901ac010002ac102902ac040002ac0c2902ac080001ac0a2901ac0a0001ac0a2901ac06000129020001ac072903ac022901ac080001ac0c2901ac070001ac062902ac062901ac060001ac042902ac020002ac042901ac060001ac022902ac060002ac022901ac070002ac0a0002ac0400" + }, + { + "filename": "head-steak", + "data": "0x00071b160504000e51060002510618033805180251030001510918013808180151020001510918013808180151010001510a180138091802510a180138091802510a180138091802510a180138091802510a180138091802510138091801380918035102380518033801180351051801510100035108380118015101380151041802510200085102380118035104180151050007510238051803510b000a510d0007510400" + }, + { + "filename": "head-sunset", + "data": "0x00031d1403090008491000044901420249014204490c00054901420149024201490142054909000149014201490c4201490142014907000149014201490442012601420226014201260442014901420149050001490142014903420a2603420149014201490400024903420326012801260228012601280326034202490300024903420326082803260342024902000249024203260a2803260242024901000349024202260c28022602420549024202260e2802260242034901420149024202260d2801260242014901420349024202260e28022602420449024202260e2802260242034901420149024202260c2802260242014901420349024202260628020201260528022602420549024202260c2802260242034901000349024202260a280226024203490100" + }, + { + "filename": "head-taco-classic", + "data": "0x00051d14030a00038e0167028e1200038e0167018e0167048e0e00038e0167018e015701670157018e0167028e0167018e0b00018e0267018e0367011102570367038e0a00028e026708500157038e0800018e0167018e015702110150018a0350018a025002110267028e0600028e01670650018a0750038e0600018e01110d50018a02500167018e0500018e015701110150018a0e5001110157018e03000167018e1450018e040001670450018a0c50018a0250026703000111145001110200016701000350018a0d50018a0150018a0250030001671650016703000550018a0550018a0750018a0250010001670300145001670200" + }, + { + "filename": "head-taxi", + "data": "0x00041c170405000ee50a0001e503c7040205c701e5090001e503c7040207c701e5080001e502c7040208c701e5070001e502c7040204c7034303c701e5060001e501c7040204c7014303c7014302c701e5040016e5020016e5020016e5020016e5020016e5020016e5020016e5020002e5011f10e5011f02e50100011f0137141f01370a1f061d091f010008e5061d08e50300020e0500061d0500020e0400020d1000020d0400020d1000020d0200" + }, + { + "filename": "head-thumbsup", + "data": "0x00011a14050a00012b02e5120001e5012b02e5110001e5012b02e51100012b03e5100005e50f0006e50e0006e50e0006e5012b07e5040008e5012b07e5012b0ce5012b07e5012b0ee5012b06e5012b0de5072b01000ae5012b14e5012b08e5012b0be5012b09e5012b0ce5082b010001e5022b05e5012b02e5012b08e5010008e5042b06e5012b01e5040004e5012b03e5012b07e5012b050008e5072b0200" + }, + { + "filename": "head-toaster", + "data": "0x00031a1f0504000e84060002840cd702840500018403d7089903d70184060001840cd701840700018402d7089902d701840600010b0e72010b0500010b0e72010b0500010b0e72010b020d0300010b0e72010b020d0300010b0e72010b0500010b0e72010b0500010b0e72010b0500010b0e72010b0500010b0e72010b0500010b0e72010b0400120d0100021f120d0100011f0100120d0100011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400" + }, + { + "filename": "head-toiletpaper-full", + "data": "0x00071a1605010002ed1102020002ed1102010004ed110204ed110204ed110201ed017c010d01ed110201ed017c010d01ed110201ed017c010d01ed110201ed017c010d01ed110204ed110204ed110204ed1102010002ed027c01ed010201ed010201ed010201ed010201ed010201ed010201ed0102030002ed017c100205000c020a0008020800" + }, + { + "filename": "head-tooth", + "data": "0x00041917060a0005570700045701000257050202570400015704020157030201570502015702000157060203570702015701000157100202571102025711020257110202571102025711020257110201570100015710020157020001570e020157030001570e020157040001570202097c02020157040001570d020157050001570402035704020157060001570302015703000157030201570700015702020157040001570202015708000257060002570300" + }, + { + "filename": "head-toothbrush-fresh", + "data": "0x00021914011000016716000167011c016715000167021c046711000167061c01670d000667021c0102011c01670a000367081c0102011c0167090001670d1c0167090001670d1c016709000102011c0102011c0102011c0102011c0102011c0102011c0102011c010209000f0209000f0209000f0209000f0209000f0201000143010002430100134302000143020013430100024301000543012301460123014601230a430700114307001143" + }, + { + "filename": "head-tornado", + "data": "0x00031c150406000c8109000281017c0281047e057c038106000281027c0b81017c0381050003810f7c03810300168103000b7c0181017c0781060011810900047c0181017c0181017c05810a000c810b000d810a000b810b000b810c00098110000a8108000181080008810600018105000181010001810100017c049c0281017c0681010001810300018101000481067c08810700128106000481080004810500" + }, + { + "filename": "head-trashcan", + "data": "0x00031b1405090005050f000205040001050f0001050200090505001105050008050723010d0700010d08230a0d020006050323030d0505010d04000205031f0205031f0205031f02050100010d02000305031f0205031f0205031f03050200010501000205031f0205031f0205031f02050100010503000205031f0205031f0205031f020505000205031f0205031f0205031f020505000205031f0205031f0205031f020505000205031f0205031f0205031f020505000205031f0205031f0205031f020505000205011f0523021f0205031f020505000205031f0205031f0205031f0205050011050300" + }, + { + "filename": "head-turing", + "data": "0x00041d190315000189070012610189016105000289016101cb01820161018201cb01610282016101cb0182016101cb018201610182018901610400018901940261028201610282016101cb018201610282016102820161018201cb0289030001890194146101890300018901000261018201cb016102820161018201cb0161018201cb01610282016102820161018903000189010002890282016101cb01820161028201610282016101cb0182016101cb018201610189020002890194016101891261018901940100038901610189018201cb01610282016101cb01820161018201cb016102820161018201cb016101890100028901000189016101890282016101cb018201610282016102820161018201cb016102820161018901000289010001890161018912610189010002890100018901610189018201cb016102820161028201610282016101cb01820161028201610189010002890100038902820161018201cb0161018201cb0161018201cb01610282016101cb0182016101890100028901000189146101890100028901000189026102020161020201610202016102020161020201610202016102000289010001890261020201610202016102020161020201610202016102020161018901000289010001891461018901000289010001890194110001940100028901000189020002891100018904000189010002891600018901000194180002891600" + }, + { + "filename": "head-ufo", + "data": "0x00021e15020e00014f1a00034f1a00014f1800064f14000a4f10000e430d000a4301060143020602430c000c43020602430b0012430a0012430a0012430900144308001443080014430800144f0600184f0300054f026d014f026d014f026d014f026d014f026d014f026d044f0100064f026d014f026d014f026d014f026d014f026d014f026d054f0400144f0d000a4f0900" + }, + { + "filename": "head-undead", + "data": "0x00021b16050600027903261100047902000279032607000126030002790300057908000126017902000279020003790b000126017902000279020003790b00027902000279020002790200018003000126050002790200037901000279050001790226040002790300057905000479010001800200027902000579060003790100028001000279020005790700027904000a79040004790500107906000f790200028005000a7904000280070008790a000180030008790d0001800179012301250123012501230279018003000180070003800679038009000e80090001800100038002000280010001800e000180090001800300" + }, + { + "filename": "head-unicorn", + "data": "0x00041b16040b00021c1200011c0300021c060001260b00021c0100021c04000226080003660100051c020003260600031c0366071c032601660400011c0100031c0766011c042602660500031c01200766042603660600011c02200766032604660600032007660226056605000420076601260666060003200e66060003200e6606000320125f01000220023a0e5f0120015f0120015f0100043a035f012001660123016601230166012301660120065f0200033a125f0200033a125f0300023a1600013a1200" + }, + { + "filename": "head-vent", + "data": "0x00081c140433020123010201230102012301020123020201230102012301020123010201230802011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f0802011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f010201230602011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f010201230402011f0102011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f010201230102011f0402011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f010201230602011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f010202010502011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f08020101010201010102010101020101020201010102010101020101010201013502" + }, + { + "filename": "head-void", + "data": "0x00051b14050123020001230200012302000123020001230200012302000123020001232c000123140001232c000123140001232c000123140001232c000123140001232c00012302000123020001230200012302000123020001230200012302000123" + }, + { + "filename": "head-volcano", + "data": "0x00031c15040800081f1000011f0641011f0f00021f0642021f0e00011f014106280141011f0d00021f0341031f0241021f0c00021f0141041f0141021f0141011f0b00021f01410b1f0a00041f010c051f010c031f0900051f010c051f010c041f0800051f010c051f010c041f0700051f010c071f010c041f0600051f010c071f010c041f0500061f010c071f010c051f0400051f010c091f010c041f0300021f020c0f1f010c021f0200021f020c051f010c0c1f01000a1f010c0341010c041f020c091f010c021f010c091f020c031f0200141f0200" + }, + { + "filename": "head-volleyball", + "data": "0x00031b1505090004d30f0001d301ee02d3020202d301ee01d30a0003d301ee02d3020202d301ee03d3070001d301ee03d301ee04d301ee03d301ee01d3050003d301ee02d301ee04d301ee02d301ee03d3040004d30aee02d3010201d3030004d301ee0ad301ee04d3020003d301ee0cd301ee01d3010201d3020003d301ee0cd301ee01d3010201d3010004d301ee0cd301ee01d3010206d301ee0cd301ee02d3010205d301ee0cd301ee02d3010205d301ee0cd301ee04d3010003d301ee0cd301ee04d3010003d301ee0cd301ee03d3020001d3010202d301ee0ad301ee04d3030001d3010202d30aee04d3040003d301ee02d301ee04d301ee02d301ee03d3050001d301ee03d301ee04d301ee03d301ee01d30300" + }, + { + "filename": "head-wall", + "data": "0x00031a15060237041a01830237011a01370f1a0183131a0183131a01830d1a0100128301000237011a0137091a01830237111a0183131a0183131a0183061a0100128301000237041a01830137121a0183131a0183131a01830d1a0100128301000237011a0137091a018302370b1a0337031a0183131a0183131a0183061a" + }, + { + "filename": "head-wallet", + "data": "0x00081d1403020008a30e8c0200029701a308510ec70297012301a308510ec70e9701080d970ba30197010801970a43029701a3057c05a3019701080d9701a3017c03a3017c05a30197010801970a26029701a3017c03a3017c05a3019701080d9701a3027c01a3027c05a30197010801970a98029701a3017c03a3017c05a30197010801970a98029701a3057c01a3034701a3019701080d970ba301970108199701080c97" + }, + { + "filename": "head-wallsafe", + "data": "0x00091d14041a08117e010805240208017e0f08017e010805240208017e0f08017e0808017e0f08017e0108012401080124010801240208017e0f08017e0808017e0f08017e0108012401080124010801240208017e010801a30d08017e0808017e01a3010801a30c08017e0108012401080124010801240208017e010801a30208010201230102012301020123010201230308017e0808117e010801a301080124010801a31a08" + }, + { + "filename": "head-washingmachine", + "data": "0x0003191f0402000fed060002ed017201ed017201ed017401ed017201ed015101ed0155017402ed050002ed017401ed017401ed017201ed017403ed0143017402ed0500037210510200037206510472065102000372045102720475027204510200037203510172087501720351020003720351017208750172035102000372025101720a750172025102000372025101720a750172025102000372025101720a750172025102000372025101720a75017202510200037203510172087501720351020003720351017208750172035102000372045102720475027204510223037201510243035104720651012301000372105101230100037210510123140001231400012314000123140001231400012314000123140001231400012314000123140001231400" + }, + { + "filename": "head-watch", + "data": "0x00041a150802000c0a05000826011e0126021e0226030001260e51012602000126065102780651012602000126035101780651017803510126020001260e51012602000126015101780a51017801510126020001260e5101260100010a01260e510126010a02260e510126020a01260e510126010a02260e5101260100010a0126045101780451017804510126020001260e510126020001260651027806510126020001260e51012603000e2605000c0a0400" + }, + { + "filename": "head-watermelon", + "data": "0x00031b15050400051d1000051d02240e00051d0124011802240d00041d0224012303240b00041d08240a00031d06240123011802240800041d02240123011807240700031d0d240600031d0e240500031d0f240400031d10240300031d11240300021d12240200031d1124011d0200021d1024011d0400021d042401230118012301180624011d0600031d0a24021d0800041d0624021d0d00071d0700" + }, + { + "filename": "head-wave", + "data": "0x00021c1401120004de13000ade0f0002de014a0ade0d0005de024a0243014a02de014a02de0b0002de024a01de024a0143054a02de014a01de090002de024a01de024a01de034a01de0143024a03de090001de034a01de024a01de024a01de064a01de080002de024a01de024a01de034a01de024a0300014a01de080001de034a01de024a01de054a040001de080001de0d4a0d0001de0d4a0c0002de0d4a0c0001de0e4a0b0001de0f4a0b0001de0f4a0a0001de074a0143024a0143034a0143014a0a0001de044a01de024a0143034a0143034a0143014a050001de020001de044a01de044a0143034a0243054a040002de164a0100014a" + }, + { + "filename": "head-weed", + "data": "0x00011d15020d00010f1900020f1900020f0100010f1600040f1000010f0600040f0700010f0800020f0600030f0100010f0400020f0800030f0100010f0200050f0400030f0900040f0200060f0100040f0a00050f0200040f0100050f0b00050f0100040f0100040f0600010f06000d0f0600010f0100020f0100010f03000b0f0500020f0200040f0200130f0300170f0600130f09000f0f1000030f015c030f015c010f1100050f035c030f0e000f0f0b00110f0900020f0f00020f0400" + }, + { + "filename": "head-weight", + "data": "0x00021a140506000127089601950b0001270196072701950b0001270196060001270195070003270d960195040003270396010e0196010e0196020e04960195040003270396020e0296010e05960195040003270396010e0196010e0196010e0196010e03960195040003270396010e0196010e0296020e03960195030003270f960195020003270f960195020003270f960195020003270f960195020003270f960195020003270f960195010003271196019503271196019503270496092704960195032711960195032711960195" + }, + { + "filename": "head-werewolf", + "data": "0x00061c1404030005970700059707000597070005970700059707000597070011260700110707001126070002970e810197070002970e810197060003970e810197050004970e810197040005971181029703000297018101d5018101d50f8102000397018101d5018101d5018104230102012301020323038102000497018101d5018101d502230102062301020223018102000597018101d5018101d50c820300" + }, + { + "filename": "head-whale-alive", + "data": "0x00021e15021100044a1700064a1500084a13000a4a1100064a010e054a0300014a0400014a0600064a010e014a010e054a0200024a0200024a05000f4a01560100064a05000f4a01560200044a07000d4a03560200034a07000c4a04560200054a05000b4a055602000156134a065603000156114a0756030003560e4a0756050005560a4a085605000656084a085607000556014a030e034a085609000356074a08560b000156064a0856100009560900" + }, + { + "filename": "head-whale", + "data": "0x00041a1606080009d50a000cd5070005d5080d060005d5010d097c040005d5010d037c0281017c0281017c0181030005d5010d017c0281017c0281017c0281017c0181020005d5010d0481017c0281017c0281017c0181010005d5010d0581017c0281017c0281017c018106d5010d0581017c0281017c0281017c018106d5010d0581017c0281017c0281017c018106d5010d0581017c0281017c0281017c018106d5010d0481017c0381017c0281017c018106d5010d0381017c0381017c0381017c018103d5010d02d5010d0281017c0381017c0381017c028102d5030d01d502980181017c0281017c0381017c038103d5010d02d50398017c0281017c0281017c0381010006d50398017c0281017c0281017c028108000398110003980b00" + }, + { + "filename": "head-wine", + "data": "0x00051b14053f6f0102156f0102156f0102036f129401190194026f1494026f1494026f1494026f1494026f1494036f1294026f0100016f1294016f0200026f069404190694026f0300036f0c94036f06000e6f0400" + }, + { + "filename": "head-wizardhat", + "data": "0x00041b1404030008eb0e0006eb014604eb0c0001eb020002eb034604eb0b000146030002eb014606eb08000546020004eb014604eb08000346040002eb014601eb014601eb014602eb0700014601000146050002eb014606eb0e000aeb0c0008eb014602eb0c0001eb014605eb034602eb0b0008eb014603eb0b0004eb014607eb0a000deb09000eeb080007eb050e02eb0700125403001654" + }, + { + "filename": "head-zebra", + "data": "0x00061b14060a00010201230a000223035e0102012301020123010202230100035e05000202035e0102012301020123010201230200035e05000223055e0123035e0123045e05000202065e0323055e05000223065e0323055e05000202075e0123065e05000223075e0123065e05000202075e0123065e050002230e5e050002020c5e0623010002230d5e012301020123010201230302025e0102012301020123010201230102035e09230d5e052303020d5e0523" + } + ], + "glasses": [ + { + "filename": "glasses-hip-rose", + "data": "0x000b1710070300062001000620030001200202022301200100012002020223052002020223032002020223052002020223032002020223022002000120020202230120010001200202022301200300062001000620" + }, + { + "filename": "glasses-square-black-eyes-red", + "data": "0x000b17100703000623010006230300012302020264012301000123020202640523020202640323020202640223020001230202026401230100012302020264022302000123020202640123010001230202026401230300062301000623" + }, + { + "filename": "glasses-square-black-rgb", + "data": "0x000b1710070300062301000623030003230164022301000323016413230200012301650223015a01230100012301650223015a022302000623010006230300062301000623" + }, + { + "filename": "glasses-square-black", + "data": "0x000b171007030006230100062303000123020203230100012302020723020205230202042302000123020203230100012302020423020001230202032301000123020203230300062301000623" + }, + { + "filename": "glasses-square-blue-med-saturated", + "data": "0x000b17100703000643010006430300014302020223014301000143020202230543020202230343020202230243020001430202022301430100014302020223024302000143020202230143010001430202022301430300064301000643" + }, + { + "filename": "glasses-square-blue", + "data": "0x000b17100703000607010006070300010702020223010701000107020202230507020202230307020202230207020001070202022301070100010702020223020702000107020202230107010001070202022301070300060701000607" + }, + { + "filename": "glasses-square-frog-green", + "data": "0x000b171007030006bf010006bf030001bf0202022301bf010001bf0202022305bf0202022303bf0202022302bf020001bf0202022301bf010001bf0202022302bf020001bf0202022301bf010001bf0202022301bf030006bf010006bf" + }, + { + "filename": "glasses-square-fullblack", + "data": "0x000b1710070300062301000623030004230102012301000423010208230102062301020223020006230100072302000623010006230300062301000623" + }, + { + "filename": "glasses-square-green-blue-multi", + "data": "0x000b1710070300060f0100068b0300010f02020223010f0100018b02020223018b034a010f02020223010f014a018b02020223028b0200010f02020223010f0100018b02020223028b0200010f02020223010f0100018b02020223018b0300060f0100068b" + }, + { + "filename": "glasses-square-grey-light", + "data": "0x000b171007030006c7010006c7030001c70202022301c7010001c70202022305c70202022303c70202022302c7020001c70202022301c7010001c70202022302c7020001c70202022301c7010001c70202022301c7030006c7010006c7" + }, + { + "filename": "glasses-square-guava", + "data": "0x000b17100703000637010006370300013702020223013701000137020202230537020202230337020202230237020001370202022301370100013702020223023702000137020202230137010001370202022301370300063701000637" + }, + { + "filename": "glasses-square-honey", + "data": "0x000b171007030006dd010006dd030001dd0202022301dd010001dd0202022305dd0202022303dd0202022302dd020001dd0202022301dd010001dd0202022302dd020001dd0202022301dd010001dd0202022301dd030006dd010006dd" + }, + { + "filename": "glasses-square-magenta", + "data": "0x000b17100703000609010006090300010902020223010901000109020202230509020202230309020202230209020001090202022301090100010902020223020902000109020202230109010001090202022301090300060901000609" + }, + { + "filename": "glasses-square-orange", + "data": "0x000b17100703000614010006140300011402020223011401000114020202230514020202230314020202230214020001140202022301140100011402020223021402000114020202230114010001140202022301140300061401000614" + }, + { + "filename": "glasses-square-pink-purple-multi", + "data": "0x000b171007030006200100069a030001200202022301200100019a02020223019a036e0120020202230120016e019a02020223029a020001200202022301200100019a02020223029a020001200202022301200100019a02020223019a030006200100069a" + }, + { + "filename": "glasses-square-red", + "data": "0x000b17100703000624010006240300012402020223012401000124020202230524020202230324020202230224020001240202022301240100012402020223022402000124020202230124010001240202022301240300062401000624" + }, + { + "filename": "glasses-square-smoke", + "data": "0x000b17100703000659010006590300015902660223015901000159026602230559026602230359026602230259020001590266022301590100015902660223025902000159026602230159010001590266022301590300065901000659" + }, + { + "filename": "glasses-square-teal", + "data": "0x000b1710070300061c0100061c0300011c02020223011c0100011c02020223051c02020223031c02020223021c0200011c02020223011c0100011c02020223021c0200011c02020223011c0100011c02020223011c0300061c0100061c" + }, + { + "filename": "glasses-square-watermelon", + "data": "0x000b17100703000637010006370300013702020223013701000137020202230537020202230337020202230237020001370202022301370100013702020223023702000137020202230137010001370202022301370300063701000637" + }, + { + "filename": "glasses-square-yellow-orange-multi", + "data": "0x000b17100703000626010006130300012602020223012601000113020202230113034201260202022301260142011302020223011301260200012602020223012601000113020202230113012602000126020202230126010001130202022301130300062601000613" + }, + { + "filename": "glasses-square-yellow-saturated", + "data": "0x000b17100703000628010006280300012802020223012801000128020202230528020202230328020202230228020001280202022301280100012802020223022802000128020202230128010001280202022301280300062801000628" + } + ] + } +} \ No newline at end of file diff --git a/packages/nouns-contracts/files/image-data_v2.json b/packages/nouns-contracts/files/image-data_v2.json new file mode 100644 index 0000000000..375ef220d5 --- /dev/null +++ b/packages/nouns-contracts/files/image-data_v2.json @@ -0,0 +1,1945 @@ +{ + "bgcolors": [ + "d5d7e1", + "e1d7d5" + ], + "palette": [ + "", + "c5b9a1", + "ffffff", + "cfc2ab", + "63a0f9", + "807f7e", + "caeff9", + "5648ed", + "5a423f", + "b9185c", + "b87b11", + "fffdf2", + "4b4949", + "343235", + "1f1d29", + "068940", + "867c1d", + "ae3208", + "9f21a0", + "f98f30", + "fe500c", + "d26451", + "fd8b5b", + "5a65fa", + "d22209", + "e9265c", + "c54e38", + "80a72d", + "4bea69", + "34ac80", + "eed811", + "62616d", + "ff638d", + "8bc0c5", + "c4da53", + "000000", + "f3322c", + "ffae1a", + "ffc110", + "505a5c", + "ffef16", + "fff671", + "fff449", + "db8323", + "df2c39", + "f938d8", + "5c25fb", + "2a86fd", + "45faff", + "38dd56", + "ff3a0e", + "d32a09", + "903707", + "6e3206", + "552e05", + "e8705b", + "f38b7c", + "e4a499", + "667af9", + "648df9", + "7cc4f2", + "97f2fb", + "a3efd0", + "87e4d9", + "71bde4", + "ff1a0b", + "f78a18", + "2b83f6", + "d62149", + "834398", + "ffc925", + "d9391f", + "bd2d24", + "ff7216", + "254efb", + "e5e5de", + "00a556", + "c5030e", + "abf131", + "fb4694", + "e7a32c", + "fff0ee", + "009c59", + "0385eb", + "00499c", + "e11833", + "26b1f3", + "fff0be", + "d8dadf", + "d7d3cd", + "1929f4", + "eab118", + "0b5027", + "f9f5cb", + "cfc9b8", + "feb9d5", + "f8d689", + "5d6061", + "76858b", + "757576", + "ff0e0e", + "0adc4d", + "fdf8ff", + "70e890", + "f7913d", + "ff1ad2", + "ff82ad", + "535a15", + "fa6fe2", + "ffe939", + "ab36be", + "adc8cc", + "604666", + "f20422", + "abaaa8", + "4b65f7", + "a19c9a", + "58565c", + "da42cb", + "027c92", + "cec189", + "909b0e", + "74580d", + "027ee6", + "b2958d", + "efad81", + "7d635e", + "eff2fa", + "6f597a", + "d4b7b2", + "d18687", + "cd916d", + "6b3f39", + "4d271b", + "85634f", + "f9f4e6", + "f8ddb0", + "b92b3c", + "d08b11", + "257ced", + "a3baed", + "5fd4fb", + "c16710", + "a28ef4", + "3a085b", + "67b1e3", + "1e3445", + "ffd067", + "962236", + "769ca9", + "5a6b7b", + "7e5243", + "a86f60", + "8f785e", + "cc0595", + "42ffb0", + "d56333", + "b8ced2", + "f39713", + "e8e8e2", + "ec5b43", + "235476", + "b2a8a5", + "d6c3be", + "49b38b", + "fccf25", + "f59b34", + "375dfc", + "99e6de", + "27a463", + "554543", + "b19e00", + "d4a015", + "9f4b27", + "f9e8dd", + "6b7212", + "9d8e6e", + "4243f8", + "fa5e20", + "f82905", + "555353", + "876f69", + "410d66", + "552d1d", + "f71248", + "fee3f3", + "c16923", + "2b2834", + "0079fc", + "d31e14", + "f83001", + "8dd122", + "fffdf4", + "ffa21e", + "e4afa3", + "fbc311", + "aa940c", + "eedc00", + "fff006", + "9cb4b8", + "a38654", + "ae6c0a", + "2bb26b", + "e2c8c0", + "f89865", + "f86100", + "dcd8d3", + "049d43", + "d0aea9", + "f39d44", + "eeb78c", + "f9f5e9", + "5d3500", + "c3a199", + "aaa6a4", + "caa26a", + "fde7f5", + "fdf008", + "fdcef2", + "f681e6", + "018146", + "d19a54", + "9eb5e1", + "f5fcff", + "3f9323", + "00fcff", + "4a5358", + "fbc800", + "d596a6", + "ffb913", + "e9ba12", + "767c0e", + "f9f6d1", + "d29607", + "f8ce47", + "395ed1", + "ffc5f0", + "cbc1bc", + "d4cfc0" + ], + "images": { + "bodies": [ + { + "filename": "body-bege-bsod", + "data": "0x0015171f093a0101000d0101000d0101000d0101000d0101000d0101000d0101000b01" + }, + { + "filename": "body-bege-crt", + "data": "0x0015171f093a0301000d0301000d0301000d0301000d0301000d0301000d0301000b03" + }, + { + "filename": "body-blue-sky", + "data": "0x0015171f093a0401000d0401000d0401000d0401000d0401000d0401000d0401000b04" + }, + { + "filename": "body-bluegrey", + "data": "0x0015171f093a0501000d0501000d0501000d0501000d0501000d0501000d0501000b05" + }, + { + "filename": "body-cold", + "data": "0x0015171f093a0601000d0601000d0601000d0601000d0601000d0601000d0601000b06" + }, + { + "filename": "body-computerblue", + "data": "0x0015171f093a0701000d0701000d0701000d0701000d0701000d0701000d0701000b07" + }, + { + "filename": "body-darkbrown", + "data": "0x0015171f093a0801000d0801000d0801000d0801000d0801000d0801000d0801000b08" + }, + { + "filename": "body-darkpink", + "data": "0x0015171f093a0901000d0901000d0901000d0901000d0901000d0901000d0901000b09" + }, + { + "filename": "body-foggrey", + "data": "0x0015171f093a0301000d0301000d0301000d0301000d0301000d0301000d0301000b03" + }, + { + "filename": "body-gold", + "data": "0x0015171f093a0a01000d0a01000d0a01000d0a01000d0a01000d0a01000d0a01000b0a" + }, + { + "filename": "body-grayscale-1", + "data": "0x0015171f093a0b01000d0b01000d0b01000d0b01000d0b01000d0b01000d0b01000b0b" + }, + { + "filename": "body-grayscale-7", + "data": "0x0015171f093a0c01000d0c01000d0c01000d0c01000d0c01000d0c01000d0c01000b0c" + }, + { + "filename": "body-grayscale-8", + "data": "0x0015171f093a0d01000d0d01000d0d01000d0d01000d0d01000d0d01000d0d01000b0d" + }, + { + "filename": "body-grayscale-9", + "data": "0x0015171f093a0e01000d0e01000d0e01000d0e01000d0e01000d0e01000d0e01000b0e" + }, + { + "filename": "body-green", + "data": "0x0015171f093a0f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f01000b0f" + }, + { + "filename": "body-gunk", + "data": "0x0015171f093a1001000d1001000d1001000d1001000d1001000d1001000d1001000b10" + }, + { + "filename": "body-hotbrown", + "data": "0x0015171f093a1101000d1101000d1101000d1101000d1101000d1101000d1101000b11" + }, + { + "filename": "body-magenta", + "data": "0x0015171f093a1201000d1201000d1201000d1201000d1201000d1201000d1201000b12" + }, + { + "filename": "body-orange-yellow", + "data": "0x0015171f093a1301000d1301000d1301000d1301000d1301000d1301000d1301000b13" + }, + { + "filename": "body-orange", + "data": "0x0015171f093a1401000d1401000d1401000d1401000d1401000d1401000d1401000b14" + }, + { + "filename": "body-peachy-B", + "data": "0x0015171f093a1501000d1501000d1501000d1501000d1501000d1501000d1501000b15" + }, + { + "filename": "body-peachy-a", + "data": "0x0015171f093a1601000d1601000d1601000d1601000d1601000d1601000d1601000b16" + }, + { + "filename": "body-purple", + "data": "0x0015171f093a1701000d1701000d1701000d1701000d1701000d1701000d1701000b17" + }, + { + "filename": "body-red", + "data": "0x0015171f093a1801000d1801000d1801000d1801000d1801000d1801000d1801000b18" + }, + { + "filename": "body-redpinkish", + "data": "0x0015171f093a1901000d1901000d1901000d1901000d1901000d1901000d1901000b19" + }, + { + "filename": "body-rust", + "data": "0x0015171f093a1a01000d1a01000d1a01000d1a01000d1a01000d1a01000d1a01000b1a" + }, + { + "filename": "body-slimegreen", + "data": "0x0015171f093a1b01000d1b01000d1b01000d1b01000d1b01000d1b01000d1b01000b1b" + }, + { + "filename": "body-teal-light", + "data": "0x0015171f093a1c01000d1c01000d1c01000d1c01000d1c01000d1c01000d1c01000b1c" + }, + { + "filename": "body-teal", + "data": "0x0015171f093a1d01000d1d01000d1d01000d1d01000d1d01000d1d01000d1d01000b1d" + }, + { + "filename": "body-yellow", + "data": "0x0015171f093a1e01000d1e01000d1e01000d1e01000d1e01000d1e01000d1e01000b1e" + } + ], + "accessories": [ + { + "filename": "accessory-1n", + "data": "0x0017141e0d0100011f0500021f0600011f0300011f0200011f0200011f0500011f0500011f0200021f0100011f0200011f0100011f0400011f0100011f" + }, + { + "filename": "accessory-aardvark", + "data": "0x0018151a0d02000320010001200200052002000120010001200100012001000220" + }, + { + "filename": "accessory-axe", + "data": "0x0017141d0e010205210102042101000102032102000102012101000121020001020200012105000121050001210200" + }, + { + "filename": "accessory-belly-chameleon", + "data": "0x0017121e0d0100012201000122060002220100022205000222010002220500022201000122020001220300" + }, + { + "filename": "accessory-bird-flying", + "data": "0x0018151a0d0100022302000223010001230200022302000123030002230300" + }, + { + "filename": "accessory-bird-side", + "data": "0x0017131c0d040001240400022401000424012301250100042403000324020001240400" + }, + { + "filename": "accessory-bling-anchor", + "data": "0x0015141d0d0126050001260100012603000126030001260100012605000126060001260500032605000126040001260100012601000126030003260200" + }, + { + "filename": "accessory-bling-anvil", + "data": "0x0015161e0b012709000127010001270700012703000127050001270500012703000127070003270900010d0700020d05270500020d03270700030d0700020d03270300" + }, + { + "filename": "accessory-bling-arrow", + "data": "0x0018141e0d04000326050002260400012601000126030001260400022604000326050001260500" + }, + { + "filename": "accessory-bling-cheese", + "data": "0x0015141e0c0126060001260100012604000126030001260200012605000226050001260200012603000626030001260128012601280126040004260500012601280126060002260100" + }, + { + "filename": "accessory-bling-gold-ingot", + "data": "0x0015141b0c0126060001260100012604000126030001260200012605000226040006290200042602290200042602290100" + }, + { + "filename": "accessory-bling-love", + "data": "0x0015141d0c0126060001260100012604000126030001260200012605000226050001260200012603000126012804260200062603000426050002260300" + }, + { + "filename": "accessory-bling-mask", + "data": "0x0015141e0c012606000126010001260400012603000126020001260500022604000626020001260100022601000126020006260300042603000126010002260100012602000126040001260100" + }, + { + "filename": "accessory-bling-rings", + "data": "0x0017141d0d0300032a0300012a0300012a0100032a0200022a0100012a0100012a0100022a0200032a0100012a0300012a0300032a0300" + }, + { + "filename": "accessory-bling-scissors", + "data": "0x0016131c0e012b0300022b0300012b0100012b0100012b0200012b0100012b0300012b0200022b0100042b0100022b" + }, + { + "filename": "accessory-bling-sparkles", + "data": "0x0016141d0c01000126060003260100012602000126010001260200012606000326030007260300032606000126070001260300" + }, + { + "filename": "accessory-body-gradient-checkerdisco", + "data": "0x0015171f09022c0223022c0223022c0223042c0223022c0223022c0223022c0223022d0223022d0223022d0423022d0223022d0223022d0223022e01000123022e0223022e0223042e01000123022e0223022e0223022e02230100012f0223022f0223022f04230100012f0223022f0223022f022302300100012302300223023002230430010001230230022302300223023002230100013102230231022302310223" + }, + { + "filename": "accessory-body-gradient-dawn", + "data": "0x0015171f091c321c33021101000d1101000b11023401000d3401000b34023501000d3501000b35023601000b36" + }, + { + "filename": "accessory-body-gradient-dusk", + "data": "0x0015171f091c321c24023701000d3701000d3701000d3701000b37023801000d3801000b38023901000b39" + }, + { + "filename": "accessory-body-gradient-glacier", + "data": "0x0015171f090f3a013b013a013b013a013b013a013b013a013b013a013b013a103b0104013b0104013b0104013b0104013b0104013b0104013b030401000d0401000d0401000c04013c0100013c0104013c0104013c0104013c0104013c0104033c01000c3c013d0100013d013c013d013c013d013c013d013c013d013c033d01000b3d" + }, + { + "filename": "accessory-body-gradient-ice", + "data": "0x0015171f091c3e1e3f01000d3f01000b3f023c01000d3c01000d3c01000d3c01000b3c024001000b40" + }, + { + "filename": "accessory-body-gradient-pride", + "data": "0x0015171f091c411c42022a01000d2a01000b2a020f01000d0f01000b0f024301000d4301000b43021201000b12" + }, + { + "filename": "accessory-body-gradient-redpink", + "data": "0x0015171f092a44100901000d0901000d0901000d0901000d0901000b09024501000d4501000b45" + }, + { + "filename": "accessory-body-gradient-sunset", + "data": "0x0015171f092a460e25024201000b42021401000b14024701000d4701000b47024801000d4801000d4801000b48" + }, + { + "filename": "accessory-carrot", + "data": "0x0018131d0e0200011d0100011d0300011d030002490200024903000149030001490400" + }, + { + "filename": "accessory-chain-logo", + "data": "0x0018171c09012601000326010003260100032602000126030001260300012603000326020003260100032601000226010001260300012603000126030002260200022601000326010003260100" + }, + { + "filename": "accessory-checker-RGB", + "data": "0x0015171f090224021c024a0224021c024a0424021c024a0224021c024a0224024a0224021c024a0224021c044a0224021c024a0224021c024a021c0100014a0224021c024a0224041c0100014a0224021c024a0224021c02240100011c024a0224021c024a04240100011c024a0224021c024a0224024a01000124021c024a0224021c044a01000124021c024a0224021c024a021c0100014a0224021c024a0224021c" + }, + { + "filename": "accessory-checker-bigwalk-blue-prime", + "data": "0x0015171f090400030701000307010005070100030701000307030003070100030707000307070003070700030701000307040002070100030701000307010001070200020701000307050001070200020707000307070003070100020704000307010003070100040702000307010003070300" + }, + { + "filename": "accessory-checker-bigwalk-greylight", + "data": "0x0015171f090400034b0100034b0100054b0100034b0100034b0300034b0100034b0700034b0700034b0700034b0100034b0400024b0100034b0100034b0100014b0200024b0100034b0500014b0200024b0700034b0700034b0100024b0400034b0100034b0100044b0200034b0100034b0300" + }, + { + "filename": "accessory-checker-bigwalk-rainbow", + "data": "0x0015171f090400034c010003460100021403120100034c01000346030003120100034c040006120400034d01000312030003140100034d010003120246010003140100034d040002460100031404000346010002460400034c01000346040002120100034c010003460100014d020002120100034c04000112014d020002120400034d01000112" + }, + { + "filename": "accessory-checker-spaced-black", + "data": "0x0015171f09030002230400022306000223040002231100022304000223040004230400022304000223110002230400022306000223040002231100022304000223040004230400022304000223" + }, + { + "filename": "accessory-checker-spaced-white", + "data": "0x0015171f09030002020400020206000202040002021100020204000202040004020400020204000202110002020400020206000202040002021100020204000202040004020400020204000202" + }, + { + "filename": "accessory-checker-vibrant", + "data": "0x0015171f09024e0243024f024e0243024f044e0243024f024e0243024f024e024f024e0243024f024e0243044f024e0243024f024e0243024f02430100014f024e0243024f024e04430100014f024e0243024f024e0243024e01000143024f024e0243024f044e01000143024f024e0243024f024e024f0100014e0243024f024e0243044f0100014e0243024f024e0243024f02430100014f024e0243024f024e0243" + }, + { + "filename": "accessory-checkers-big-green", + "data": "0x0015171f09030f0300030f0300050f0300030f0300050f0300030f0300020f0300030f0300030f0500030f0300030f0500030f0300030f0200020f0400030f0300040f0400030f0300040f0400030f0300020f0300030f0300030f0500030f0300030f0200" + }, + { + "filename": "accessory-checkers-big-red-cold", + "data": "0x0015171f09031903000319030005190300031903000519030003190300021903000319030003190500031903000319050003190300031902000219040003190300041904000319030004190400031903000219030003190300031905000319030003190200" + }, + { + "filename": "accessory-checkers-black", + "data": "0x0015171f09020002230200022302000223040002230200022302000223020002230200022302000223020004230200022302000223020002230300012302000223020002230500012302000223020002230200022302000223020002230200042302000223020002230200022303000123020002230200022305000123020002230200022302000223020002230200022302000223" + }, + { + "filename": "accessory-checkers-blue", + "data": "0x0015171f09024a0200024a0200024a0200044a0200024a0200024a0200024a0200024a0200024a0200024a0400024a0200024a0200024a0200024a0200024a0200024a0200044a0200024a0200024a0200024a0300014a0200024a0200024a0500014a0200024a0200024a0200024a0200024a0200024a0200044a0200024a0200024a0200024a0300014a0200024a0200024a0200" + }, + { + "filename": "accessory-checkers-magenta-80", + "data": "0x0015171f09020002200200022002000220040002200200022002000220020002200200022002000220020004200200022002000220020002200300012002000220020002200500012002000220020002200200022002000220020002200200042002000220020002200200022003000120020002200200022005000120020002200200022002000220020002200200022002000220" + }, + { + "filename": "accessory-chicken", + "data": "0x0018131d0d0300024701000202020001020150010004020300020204000102050001500300" + }, + { + "filename": "accessory-cloud", + "data": "0x0018131a0d0200030202000b02" + }, + { + "filename": "accessory-clover", + "data": "0x0017151e0d0200021d0600031d0400011d0100011d0100021d0100031d0100031d0100021d0100011d0100011d0400031d0500021d0100011d0800021d" + }, + { + "filename": "accessory-collar-sunset", + "data": "0x00151717090e190e260e42" + }, + { + "filename": "accessory-cow", + "data": "0x0018141c0d05000151020003510123015101380151010001510123025101000151010001510238015103000151020001510100" + }, + { + "filename": "accessory-decay-gray-dark", + "data": "0x0015171f090e27020006270300032702000b2702000927010002270100022701000127010003270200062701000827030001270200012702000327080008270600012704000227010002270200012701000b2703000b27" + }, + { + "filename": "accessory-decay-pride", + "data": "0x0015171f090e27024106270341032702420b2702420927014202270142022701000127012a0327022a062701000827032a0127010f01000127020f0327070f01000827030f02430100012704430227014302270243012701000b27021201000b27" + }, + { + "filename": "accessory-dinosaur", + "data": "0x0017131d0d0200035203000152010001520300045202000352010001520100035201000652030001520200" + }, + { + "filename": "accessory-dollar-bling", + "data": "0x0015141e0c012606000226060001260100012604000126030004260500022605000426040002260800022604000426050002260300" + }, + { + "filename": "accessory-dragon", + "data": "0x0017141e0d020f0100030f0200030f0100040f0300010f0400030f0200020f0400010f0300020f0200030f0200010f0200010f0400" + }, + { + "filename": "accessory-ducky", + "data": "0x0018131a0e012801000228020003280114010003280100" + }, + { + "filename": "accessory-eth", + "data": "0x0018131d0e020001530400015303000153015401530100055401000353030001530200" + }, + { + "filename": "accessory-eye", + "data": "0x0018151c0d020004540300015401000254010001540100015402000254020001540100015404000154030004540200" + }, + { + "filename": "accessory-flash", + "data": "0x0017151d0d010001020800020207000302020008020200030207000202080001020100" + }, + { + "filename": "accessory-fries", + "data": "0x0017131d0e0126010a0126010a0226010a0126010a01260655032602550226035501260855" + }, + { + "filename": "accessory-glasses-logo-sun", + "data": "0x0018161a0d072302000323010008230100032301000123" + }, + { + "filename": "accessory-glasses-logo", + "data": "0x0018161a0d0756020001560100015601000156010006560100035601000156" + }, + { + "filename": "accessory-glasses", + "data": "0x0017141d0d0856010002560100025602000256010002560700081d0100021d0100021d0200021d0100021d" + }, + { + "filename": "accessory-grid-simple-bege", + "data": "0x0016171e090157010001570100015701000157010001570100015701000157100001570100015701000157010001570100015701000157010001570e0001570300015701000157010001570100015701000157100001570100015701000157010001570100015701000157010001570e00015703000157010001570100015701000157010001570100" + }, + { + "filename": "accessory-heart", + "data": "0x0018141d0d010002580100025801000e580100055803000358050001580300" + }, + { + "filename": "accessory-hoodiestrings-uneven", + "data": "0x0016121b0f0102010002020100020201000202010001590102020001590200" + }, + { + "filename": "accessory-id", + "data": "0x0017151a1002000102020005260a02" + }, + { + "filename": "accessory-infinity", + "data": "0x0017141e0d0100020b0400010b0200010b0300010b0700030b0600030b0700010b0300010b0200010b0400020b0100" + }, + { + "filename": "accessory-insignia", + "data": "0x0016131d0e0200015b0300015b012b015b0300015b0300035b0100015b032b035b022b025b032b015b0100035b0100" + }, + { + "filename": "accessory-leaf", + "data": "0x0018141d0d0300045c0200055c0200055c0200055c0200045c0100025c0500" + }, + { + "filename": "accessory-lightbulb", + "data": "0x0017121c0e0c5d0100025d0200025e0200025e0100" + }, + { + "filename": "accessory-lines-45-greens", + "data": "0x0015171f090200010f0200010f0200010f0200010f0200015c0200015c0200015c0200015c0200015c0200010f0200010f0200010f0200010f0200010f0200015c0200015c0200015c0200015c0200010f0200010f0200010f0200010f0200010f0200015c0200015c0200015c0200015c0200015c0500010f0200010f0200010f0200015c0200015c0200015c0200015c0200015c0200010f0200010f0200010f0200010f0200010f0500015c0200015c0200015c0200010f0200010f0200010f0200010f0200010f0100" + }, + { + "filename": "accessory-lines-45-rose", + "data": "0x0015171f090200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0500015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0500015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0100" + }, + { + "filename": "accessory-lp", + "data": "0x0016161e0d03000323040007230200072301000323030206230102010001020623030203230100072302000723040003230300" + }, + { + "filename": "accessory-marsface", + "data": "0x0018131d0e0400032301000223030002230200032303000723" + }, + { + "filename": "accessory-matrix-white", + "data": "0x0018131c0e010b0100010b0100010b0500010b0100010b0100010b0500010b0100010b0100010b" + }, + { + "filename": "accessory-moon-block", + "data": "0x0017131d0e0660010001600100016001000160010001600100016001000160010001600100016001000160010003600100026001000360" + }, + { + "filename": "accessory-none", + "data": "0x00000100000100" + }, + { + "filename": "accessory-oldshirt", + "data": "0x0015171f09206107581161026201000261035802610158056101000161015803610258046102620100036101580961010001610258016104580361026201000d610100016107580361026201000b61" + }, + { + "filename": "accessory-pizza-bling", + "data": "0x0015141d0c012606000126010001260400012603000126020001260500022606000226050004260400042603000626020006260100" + }, + { + "filename": "accessory-pocket-pencil", + "data": "0x0017151910010001370400010203000563" + }, + { + "filename": "accessory-rain", + "data": "0x0018131d0e04000143010001430200014301000143060001430100014302000143010001430400" + }, + { + "filename": "accessory-rainbow-steps", + "data": "0x0017171c090b000312070004180312030004140418031202460100041404180300024601000414070002460c00" + }, + { + "filename": "accessory-rgb", + "data": "0x0018151e0d030002640500046404000464030002650264025a01000465045a0465045a010002650200025a0100" + }, + { + "filename": "accessory-robot", + "data": "0x0019171b090123020001230200012302000123020001230f00022301000b23" + }, + { + "filename": "accessory-safety-vest", + "data": "0x0015171f0b0413030009130300091303000913030005130100036603000566010003660300056601000366030005660100036603000566010003130300051301000313030005130100031303000513" + }, + { + "filename": "accessory-scarf-clown", + "data": "0x0015151f0c031c0300061c0300061c0300031c0323030006230300062303000323031c0300061c0300061c0300031c03230300062303000323" + }, + { + "filename": "accessory-secret-x", + "data": "0x0018121b0e01670200016701000267020002670100016702000167" + }, + { + "filename": "accessory-shirt-black", + "data": "0x0015151f0c0e23010005230100022302000323020001230168030001230300022307000223070002230700022307000123016807000223070002230400" + }, + { + "filename": "accessory-shrimp", + "data": "0x0018121c0e0100025f0100035f0100025f0300015f0220020001200100" + }, + { + "filename": "accessory-slimesplat", + "data": "0x0017121d0d0200014e0100024e0100024e0200034e0200024e0100024e0100014e0500014e0200014e0300" + }, + { + "filename": "accessory-small-bling", + "data": "0x001514170d0126050001260100012603000126030003260200" + }, + { + "filename": "accessory-snowflake", + "data": "0x0017141d0d010001020300010201000202010001020100020202000302030005020300030202000202010001020100020201000102030001020100" + }, + { + "filename": "accessory-stains-blood", + "data": "0x0016151d0d05000219030001190100041904000419050002190100011901000219060002190d0001190600" + }, + { + "filename": "accessory-stains-zombie", + "data": "0x0017151e0d0100010f1000020f0400010f0100020f0900020f0500040f0200010f0100040f0500020f0100" + }, + { + "filename": "accessory-stripes-and-checks", + "data": "0x0015171f090e690e430e280e1c020201000123020202230202022304020100012302020223020202230202022301000102022302020223020204230100010202230202022302020223026901000b69024301000b43022801000b28" + }, + { + "filename": "accessory-stripes-big-red", + "data": "0x0015171d092a242a00022401000d2401000d2401000b24" + }, + { + "filename": "accessory-stripes-blit", + "data": "0x0015171b092a5a0e00026a01000b6a0e00022a01000b2a" + }, + { + "filename": "accessory-stripes-blue-med", + "data": "0x0015171f090e430e000e430e00024301000b430e00024301000b430e00024301000b430e00024301000b43" + }, + { + "filename": "accessory-stripes-brown", + "data": "0x0015171f090e350e000e350e00023501000b350e00023501000b350e00023501000b350e00023501000b35" + }, + { + "filename": "accessory-stripes-olive", + "data": "0x0015171f090e6b0e000e6b0e00026b01000b6b0e00026b01000b6b0e00026b01000b6b0e00026b01000b6b" + }, + { + "filename": "accessory-stripes-red-cold", + "data": "0x0015171f090e190e000e190e00021901000b190e00021901000b190e00021901000b190e00021901000b19" + }, + { + "filename": "accessory-sunset", + "data": "0x0017141a0d03000126040001260300012603000326020001260100032601000126" + }, + { + "filename": "accessory-taxi-checkers", + "data": "0x0017171a090266020d0266020d0266020d0466020d0266020d0266020d0266020d01000166020d0266020d0266040d01000166020d0266020d0266020d" + }, + { + "filename": "accessory-tee-yo", + "data": "0x0015171f09022802000128040001280300032803000428040004280900052809000428020001280100012803000128010004280300012801000228010001280100042803000128010002280300042808000128010004280a0004280a0004280a000228" + }, + { + "filename": "accessory-text-yolo", + "data": "0x0017131d0d014e0100014e010002570100014e020002570100014e02000257060001570200024e010001570200024e010002570100024e0100" + }, + { + "filename": "accessory-think", + "data": "0x0018131c0e0302020003020900010206000102" + }, + { + "filename": "accessory-tie-black-on-white", + "data": "0x0015121f0e0423014b0223024b0223024b0223024b0223024b0223024b0223024b0223024b0223024b0223024b0223014b" + }, + { + "filename": "accessory-tie-dye", + "data": "0x0016151f0b0200023b0100016c0200016c0100013b0100033b0200016c0300013b0300013b0200026c0300026d0100013b0100026c0200016d0100011c016d013b0100016c0200016d0100011c016c013b0100016c0100011c0100016d0100011c0100026c0400016d0200011c0300011c0300016d0200031c0100011c0100016d0200016d0100021c0200" + }, + { + "filename": "accessory-tie-purple-on-white", + "data": "0x0015121f0e046e014b026e024b026e024b026e024b026e024b026e024b026e024b026e024b026e024b026e024b026e014b" + }, + { + "filename": "accessory-tie-red", + "data": "0x0016111e0f044102000c41" + }, + { + "filename": "accessory-txt-a2+b2", + "data": "0x0017151d0d0200016f0500026f0600026f0100016f0600036f0600016f0100016f0100016f0500026f0600026f0100" + }, + { + "filename": "accessory-txt-cc", + "data": "0x0017151d0c01000770010001700700027001000270010002700100027001000170020001700200027001000270010002700100027007000170010007700100" + }, + { + "filename": "accessory-txt-cc2", + "data": "0x0017141c0d037101000471030001710200017103000171020001710300017102000171030001710200037101000371" + }, + { + "filename": "accessory-txt-copy", + "data": "0x0017131d0d027201000272010001720200027201000272010002720700027201000172010003720100027201000172020001720200" + }, + { + "filename": "accessory-txt-dao-black", + "data": "0x0018151b0c022302000123020001230100012301000223010002230100022301000523010003230100012301000123010001230100" + }, + { + "filename": "accessory-txt-doom", + "data": "0x0016161d0b0200012308000323080001230100032307000223010003230700022301000323070002230100032308000123010001230a000123" + }, + { + "filename": "accessory-txt-dope-text", + "data": "0x0017131d0d010001730200017301000273010001730100037302000173070002730100017302000273010002730100017302000373" + }, + { + "filename": "accessory-txt-foo-black", + "data": "0x0019151b0d05230100042301000223010003230200022301000223" + }, + { + "filename": "accessory-txt-ico", + "data": "0x0019171d09027401000d7401000d7401000d7401000d7401000b74" + }, + { + "filename": "accessory-txt-io", + "data": "0x0018131c0d0156030001560100015602000156020001560100015601000256010001560200035603000256" + }, + { + "filename": "accessory-txt-lmao", + "data": "0x0017131d0d013e0300033e0200023e0100023e0100013e0900013e0200033e0100013e0100033e0100013e0100023e" + }, + { + "filename": "accessory-txt-lol", + "data": "0x001715190d01020200020201000102010001020200020201000102010002020100020201000202" + }, + { + "filename": "accessory-txt-mint", + "data": "0x0016141c0d06000114070002140100011402000214010001140100011401000114070002140200041401000114020001140100" + }, + { + "filename": "accessory-txt-nil-grey-dark", + "data": "0x0018151a0d037501000175010001750100017501000175010001750100017501000175010001750100017501000275" + }, + { + "filename": "accessory-txt-noun-f0f", + "data": "0x0017131e0d0100026901000169020001690100026907000269010001690100036901000369070002690100016902000169010002690100" + }, + { + "filename": "accessory-txt-noun-green", + "data": "0x0017131e0d0100023e0100013e0200013e0100023e0700023e0100013e0100033e0100033e0700023e0100013e0200013e0100023e0100" + }, + { + "filename": "accessory-txt-noun-multicolor", + "data": "0x0017131e0d010002170100011702000117010002170700027601000114010001140276010003140700020f0100010f0200010f0100020f0100" + }, + { + "filename": "accessory-txt-noun", + "data": "0x0016131d0d0100026c0100016c0200016c0100026c0700026c0100016c0100036c0100036c0700026c0100016c0200016c0100026c0100" + }, + { + "filename": "accessory-txt-pi", + "data": "0x0018131b0d0100061f0100011f0100011f0300011f0100011f0300011f0200011f" + }, + { + "filename": "accessory-txt-pop", + "data": "0x0017131d0d0228040002280400012801000228040002280600022804000228040001280100" + }, + { + "filename": "accessory-txt-rofl", + "data": "0x0017131d0d02020200027702020200027701020100010201000277060003370100012601000237020001260100013703000226" + }, + { + "filename": "accessory-txt-we", + "data": "0x0018151d0c0700011c050001560100011c0100011c02000156010001560100031c015601000156010001560100011c0200015601000156010001560200011c02000156010001560500" + }, + { + "filename": "accessory-txt-yay", + "data": "0x0018151a0c0143010001430100011c0100014301000143010001430100031c01000143020001430100011c0100011c010001430100" + }, + { + "filename": "accessory-wall", + "data": "0x0015171f090a0001620d0001620300026201000b62040001620d0001620900026201000462010006620a0001620d0001620300026201000b62040001620d0001620900" + }, + { + "filename": "accessory-wave", + "data": "0x0017151b0d01000356040002560200015605000156020001560400015603000256010001560600" + }, + { + "filename": "accessory-wet-money", + "data": "0x0018141e0d01780279017805790178017a017804790178017a01780579017802790178010001040100010401000104020001040a0001040100" + }, + { + "filename": "accessory-woolweave-bicolor", + "data": "0x0015171f09037b010003140100037b0100027b0e00017b010003140100037b01000314020001140300017b030001140300017b01140200027b010003140100037b0f00027b020003140100037b01000214030001140300017b030001140200017b01140200037b010003140100027b0e00017b0200027b010003140100037b0100" + }, + { + "filename": "accessory-woolweave-dirt", + "data": "0x0015171f09037c0100037c0100037c0100027c0e00017c0100037c0100037c0100037c0200017c0300017c0300017c0300027c0200027c0100037c0100037c0f00027c0200037c0100037c0100027c0300017c0300017c0300017c0200027c0200037c0100037c0100027c0e00017c0200027c0100037c0100037c0100" + }, + { + "filename": "accessory-yingyang", + "data": "0x0018121b0e060d024b020d064b" + }, + { + "filename": "body-bege", + "data": "0x0015171f093a0101000d0101000d0101000d0101000d0101000d0101000d0101000b01" + }, + { + "filename": "body-gray-scale-1", + "data": "0x0015171f093a0b01000d0b01000d0b01000d0b01000d0b01000d0b01000d0b01000b0b" + }, + { + "filename": "body-gray-scale-9", + "data": "0x0015171f093a0e01000d0e01000d0e01000d0e01000d0e01000d0e01000d0e01000b0e" + }, + { + "filename": "body-ice-cold", + "data": "0x0015171f093a0601000d0601000d0601000d0601000d0601000d0601000d0601000b06" + } + ], + "heads": [ + { + "filename": "head-aardvark", + "data": "0x00021e14060500013702000137130002370200023711000337020003370f000437020004370f00033702000337110002370200023713000137020001370f000d370b000d370b000d370b000d370b000d370b000d370b000d370600057d0d370600017d017e017d017e017d0b37097d017e017d017e017d0b370d7d0a370523097d0b370d7d" + }, + { + "filename": "head-abstract", + "data": "0x00041a1405045c01000447010004470100017f01000114010001140100045c01230447012304470123017f01230114012301140123045c01230447012304470123017f01230114012301140123045c01230447012304470123017f01230114012301140123045c01230447012304470123017f01230114012301140123010015230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f012304460100132301000123015401230154012301540123040701230455012304550123015401230154012301540123040701230455012304550123015401230154012301540123010703540123045501230455012301540123015401230154012304070123045501230455012301540123015401230154012304070123045501230455" + }, + { + "filename": "head-ape", + "data": "0x0005191406030004800e00098009000e8006000f800300108004000f8004000f80040001800e81040001800e81040001800e81040001800e81020003800e8102000180018101800f8101000180018103800d8206800d81018002001180" + }, + { + "filename": "head-bag", + "data": "0x00031c140306000e3a0b000e3a0900023a0e00023a0700023a0e00023a0700023a0e00023a05000207023a0e07023a0207030001070126023a040706260407023a01260107020001260107022606070426060702260107020001260807062608070200013a16070100013a0100013a15070100013a0100013a15070100013a0107013a1607013a0107013a1607010018070100070703760e0701001807020016070100" + }, + { + "filename": "head-bagpipe", + "data": "0x00011d19050a0001831700030f150001830200010f010001831200020f0300010f017a11000108010f017a020f0108017a010f1000020f017a020f0183017a020f06000183080001830100017a010f010001080100020f01830600010807000108040001080200010f017a010f06000108060001080300010803000183017a010f070001080500010803000108020001080100017a010f0200010f0200017a030f017a030f010803000108020001080200020f017a0200010f017a030f017a030f017a03000108010001080400010f017a010f0100010f017a030f017a030f017a010f01000108020001080400010f0300010f017a030f017a030f017a020f0108010001080900010f017a030f017a030f017a030f017a020f0800010f017a030f017a030f017a030f017a030f017a06000108017a030f017a030f017a030f017a030f017a010f050001080200020f017a030f0211020f017a030f017a010f050001080400017a030f017a030f017a030f017a010f050001080400017a030f017a030f017a030f017a060001080500030f017a030f017a030f017a060001080700010f017a030f017a020f0800010817000183160003831500" + }, + { + "filename": "head-banana", + "data": "0x00041d140304000523047903260f000323047905260f000123047907260f00037909260e0002790226012b07260e0001790326012b0326022b02260e000226012b0526022b02260700012606000826022b02260600032605000826022b02260500052604000c2604000426012b022602000e2602000626012b022601000e2601000826012b1226012b032601001426012b032603000a26032b09260500062601570626015706260700042603570526025704260400" + }, + { + "filename": "head-bank", + "data": "0x00031c15040b00021f1400061f1000031f0472031f0c00021f020c011f0472011f020c021f0800021f020c031f0472031f020c021f0400161f020016720300031f0272041f0272041f0272031f0400011f010c011f0272041f0272041f0272011f010c011f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400011f1272011f0300161f0100021f1472021f" + }, + { + "filename": "head-baseball-gameball", + "data": "0x00041a17060800040b0e00080b0a0001240b0b0700020b01240a0b0124010b0400030b01240a0b0124010b0400030b01240a0b0124010b0300040b01240a0b0124020b0200030b01240c0b0124010b0100040b01240c0b0124050b01240e0b0124040b01240e0b0124040b01240e0b0124010b0100030b01240c0b0124010b0200030b01240c0b0124010b0300030b01240a0b0124010b0400040b0224060b0224020b0500050b0624030b07000c0b0a00080b0e00040b0800" + }, + { + "filename": "head-basketball", + "data": "0x00031a160607000542011a0c000442011a0242011a024208000242021a0542011a044205000542011a0442011a0442011a04000142011a0442011a0342011a0342011a014203000842011a0242011a0242011a034202000142011a0742051a044201000c42011a1342011a1342011a0742141a0c42011a1342011a074201000b42011a064202000942051a0442030004420166010e0166010e0166010e011a0242011a024204000642011a0342011a0342011a014205000442011a0442011a04420800021a0542011a02420c000542011a0700" + }, + { + "filename": "head-bat", + "data": "0x00031e14020900018408000184120001840800018411000384060003840c000184020002840185018406000184018502840200018408000584018502840400028401850584070001840185038401850a8401850384018501840600058401850a840185058405000184018514840185018404000184018514840185018403000184018516840185018402000184018516840185018402000184018516840185018402000184018516840185018401000184018518840185028401851884018508840185048402230162012301620223018401850984030002840185038403230102012301020123028401850284030003840500108405000184" + }, + { + "filename": "head-bear", + "data": "0x000518150805860600068602370286060002860237a1860208028602080223018701230187022301080286020802860208072301080286020802860208028602080286020802860208028602080286020802860208028601000e080100" + }, + { + "filename": "head-beer", + "data": "0x000219140605000287020003870b000b8707000f8704000f87030011870200018701420c87016d02870300024201680287016802470587016d018701000388024201680247016802470168014702870168016d0187010003880342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701420247016802470268016d0200028801000342024701420247016802470268016d020003880342024701420247016802470268016d030002880342024701420247014202470268016d05000c420168016d050005880785028805000e880200" + }, + { + "filename": "head-beet", + "data": "0x00021a14060400031d020002800d00011d0119021d0280010c01800c00021d0119011d0180010c02800d00021d0119010c02800f00011d0119010c0180110002850d001089030009190189011901890119018901190389010014890319108901193a890219288902190f89031901000a89022006890300041901890119078901190189011905000e890300" + }, + { + "filename": "head-bell", + "data": "0x00011c14040b00022616000226130008260f000226010207260d000226010209260b00022601020b260a000e260a000e2609001026080010260800102608001026080010260800108a0800108a06001426040001260102122602000c2603372126010016260100" + }, + { + "filename": "head-bigfoot-yeti", + "data": "0x00021d14020d00047f1700067f1400037f0156017f0156017f1400027f0156015a0156015a017f1400027f028b0156018b017f1100057f018b0156015a0156017f10000b7f0f000b7f0f000d7f0d000e7f018c0b00047f01000a7f038c0800047f02000a7f058c0500047f02000b7f078c0100047f03000c7f0300058c037f04000c7f0400018c0100018c08000b7f1000087f028d027f1000028c0a7f0e00068c087f0600" + }, + { + "filename": "head-bigfoot", + "data": "0x00021d14020d0004341700063414000334012b0134012b013414000234012b0136012b0136013414000234028e012b018e013411000534018e012b0136012b013410000b340f000b340f000d340d000e3401360b00043401000a3403360800043402000a3405360500043402000b3407360100043403000c3403000536033404000c34040001360100013608000b341000083402160234100002360a340e00063608340600" + }, + { + "filename": "head-blackhole", + "data": "0x00011d17030e00018f1800018f1000018f1800018f0600015f0600015f0400018f0600018f0500015f0600015f0600018f0a00015f0300045f0300015f0e00015f01190120015f032003190c00015f0200015f01190220045f0220025f0b00015f0100015f01190120025f0490025f01200119015f0a00015f0100015f0120015f029004230290015f01200119015f0100015f0500015f0200025f0120015f019006230190015f022001190300018f06000119025f019008230190025f01190400028f0500025f019008230190015f0120015f01190300028f0400015f0120015f019008230190015f0120015f0600018f0300015f0120015f019008230190015f0120015f0a00015f01190120015f019006230190015f02200119015f0700015f0200035f029004230290025f02190100015f0700025f02190120025f0490025f0220015f01190100015f0a00015f01190220045f0120015f01200119015f0c000219055f0320015f02190200015f0600018f0700015f01000319015f0d00018f0900015f0900018f1800018f0300" + }, + { + "filename": "head-blueberry", + "data": "0x00041a1706070006430c000543069107000143019101560591035403910500024306910154037701540391040001430691025404770154029103000243079101540477015403910200014301560891045404910100024312910343119103431191024312910243129102431291010001430391067708910200014304910292099101430191030002430e91040004430c91060002430991014308000543069101430b0006430700" + }, + { + "filename": "head-bomb", + "data": "0x00041c16070f00010d0b00060d0200030d02830600040d0172090d010001830400020d02720a0d030001830200030d0272090d040001830100100d030001830100100d03000193120d02000141120d0300120d0300120d0300120d0300120d0400100d0500100d0600060d0572030d08000c0d0a000a0d0d00060d0900" + }, + { + "filename": "head-bonsai", + "data": "0x00021e15030c00070f1200030f031c040f0f00050f031c010f021c020f0c00040f011c020f031c010f021c020f0b00100f0c000e0f0200030f0c00080f0300020f011c020f0200070f0600027c03000a0f021c060f0400037c060f021c040f021c010f011c050f0400017c070f021c0d0f0400037c080f01000b0f0300097c0500080f087c0c00030f047c0300047c1500067c1400087c0e001294090005940d0e090012940b000e940700" + }, + { + "filename": "head-boombox", + "data": "0x00041b1f060400025815000258150002580d00089502580795040001950900025804000195040001950b0002580200019502000296136f0296016f011c016f0195016f090e016f0195016f0124016f0296136f0296036f030e026f0195016f0195026f030e036f0296026f050e056f050e026f0296016f070e016f0195016f070e016f0296016f070e036f070e016f0296016f070e016f0195016f070e016f0296026f050e056f050e026f0296036f030e026f0195016f0195026f030e036f0296136f1200020e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e0100" + }, + { + "filename": "head-boot", + "data": "0x00061c140701000697030002970a00069702080100019701980a0007970208019701980a0008970108019701980a000b970a000b970a000b9709000d9708000e970700149701002e9703262397010013830100" + }, + { + "filename": "head-box", + "data": "0x00061c1403040003970f990108050004970f9901080400049701080f9902080300049701080f9902080200049702080f9902080100059702080f990308040003080f990308040003080f99070003080f990700029901080f990700029901080f9907000299010805990a010700030805990a010700030805990a01070003080f990300" + }, + { + "filename": "head-boxingglove", + "data": "0x000418140504000d5504000a550438025502004d550189015506070b550189015506070b550189015506070b550189015506070b550189015506070955030001550607095503000f55050003550b260500035501260502012301020326050003550b2605000e550100" + }, + { + "filename": "head-brain", + "data": "0x00051a14060600086a0900036a0320016a0420036a0500016a0320036a0120046a0320016a0300016a0120026a0120016a0120016a0120016a0120026a0120026a0120016a0200016a0120016a0120026a0120026a0120026a0120056a0100066a0120036a0120026a0120026a0120016a0120026a0120046a0120066a0120046a0120026a0120026a0120026a0120036a0120066a0120056a0120026a0120046a0120016a0220026a0120026a0120026a0120036a0120096a0120026a0120036a0120056a0120066a0120076a0120056a0220046a0120016a0100126a0200016a0120036a0220026a0120056a0220016a0300016a0120016a0120026a0220046a0220026a05000e6a0300" + }, + { + "filename": "head-bubble-speech", + "data": "0x00041b160504000e0206001202030014020200140201009a0201001402020014020300120206000f02120003021300020213000202140001020700" + }, + { + "filename": "head-bubblegum", + "data": "0x00021b1705080006690e000369029a05690a000269029a04690202046907000269019a05690402046905000269019a06690402056904000a69020202690202026903000f6902020369020002690102116901008469010014690200146903000a69019a076904000b69019a066905000169019a0769019a0469019a016907000169039a0669039a01690a000a9a0e00069a0800" + }, + { + "filename": "head-burger-dollarmenu", + "data": "0x00071a14060600080a0a00060a0125050a0700040a0125050a0125030a0500020a01250d0a04000e0a0125010a0300120a0200120a020012260100082601970626029701260197012601970226019704260e9701260c9701260497010012970300100a0400100a0200" + }, + { + "filename": "head-cake", + "data": "0x00021a14060500013704000137030001370900013701290137020001370129013701000137012901370800013701290126020001370129012601000137012901260900012604000126030001260900033c0200033c0100033c08000156023c02000156023c01000156023c0600102003000520060207200200042008020620020004200802052001020200010203200902032002020200020202200e020200020202200e020200020201200f0202001202020012020200012001020220020205200202022002020120010001200102012002020220050202200202022001021520" + }, + { + "filename": "head-calculator", + "data": "0x00051a16060200120302001203020001030488010303880103070701030200060303880103070701030200010304880d03020006030388010303880103038801030200010304880d03020006030388010303880103038801030200010304180d0302000103041801030388010303880103038801030200120302000103105c010302080103015c019b035c019b035c019b015c019b015c029b015c010302080103015c039b015c029b025c019b015c019b015c029b015c010302080103015c019b015c019b015c039b015c019b015c019b015c029b015c010302080103105c010302000103109c010302001203" + }, + { + "filename": "head-calendar", + "data": "0x00041a14050100029d0200029d0200029d0200029d0200029d02000202019d0302019d0302019d0302019d0302019d180201230102012301020123010201230102012301020123010201230102059e1002029e0102029e02020d9f0102019e0102019e0102019e0302019f0102019f0102019f0102019f0102019f0102019f0202059e02020d9f0102059e0302019f0102019f0102019f0102019f0102019f0102019f0202059e02020d9f0102059e0302019f0102019f0102019f0102019f0102019f0102019f0202059e02020d9f0102059e0302019f0102019f0102019f0102019f0102019f0102019f0202059e02020d9f0102059e0302019f0102019f0102019f0623019f0102059e02020d9f0102059e1602" + }, + { + "filename": "head-camcorder", + "data": "0x00091c14050400047e0500047e060001230100117c03000223017e017c01240f7c02000323017e117c027e03230100117c027e02230200117c027e02230200117c027e022302001123027e022302001123027e022302000e23027e0123027e0223020001230b7c0223027e0123020002230200112303000123" + }, + { + "filename": "head-cannedham", + "data": "0x00041a14060f00017a10000383017a1200027a0f00047a0c00067a030002390200097a0500053901001483508c14a12d07010e0151010e0151010e0151010e01511b071483" + }, + { + "filename": "head-car", + "data": "0x00091c1406050008550d000155080401550b00035508040155090005550804015507000755060401a20104015505000e5502a20455020014550157010014550157045501230227095502270123045502a20155012702a20127015502230455012702a20127025504a20100012702a2012707a2012702a20127010002a205000227090002270500" + }, + { + "filename": "head-cash-register", + "data": "0x00021a1408010004580e000158026201580e00045802000a27010001610158016202580261012708430127026104580261012701430654014301270261016f0262016f02610127084301270261046f0261012701430354044301270261042702610127084301278e61022a026102870161028701610287016102870161042a026102870161028701610287016102870161042a1361" + }, + { + "filename": "head-cassettetape", + "data": "0x00071b14050100140e0100020e1202040e0102010e1002030e0102010e0102010e1002020e05a3010203a3020203a3010205a3020e04a3030203a3010202a3030204a3020e04a3030203a3010202a3030204a3020e05a3010203a3020203a3010205a3020e14a3020e1426020e1426010e060c0a1f0b0c021f0100061f0100021f090c0e1f040c" + }, + { + "filename": "head-cat", + "data": "0x00031a14060100020e0d00020e0300040e0900040e0300010e0106040e0500040e0106010e0300010e0306020e0500020e0306010e0300010e0406070e0406010e0300010e0306090e0306010e0300010e01060d0e0106010e0300110e0400100e0400100e0400100e0400100e0400100e0400100e0200053c0506026c0406043c02000806019607060200053c030604960406043c020010060200" + }, + { + "filename": "head-cd", + "data": "0x00031b1805080006a30e0002a3066702a30a0002a30a6702a3070001a30e6701a3050001a301220f6701a3040001a302220e6701a3030001a305220b67024301a3020001a30622016704080367044301a3010001a304200322010804a30108074302a30620010806a30108064302a30620010802a3020002a30108064302a30620010802a3020002a30108069a02a30626010806a30108069a02a30726010804a30108026e059a01a3010001a30426036704080167046e029a01a3020001a302260b67056e01a3030001a30d67036e01a3040001a30f67016e01a3050001a30e6701a3070002a30a6702a30a0002a3066702a30e0006a30800" + }, + { + "filename": "head-chain", + "data": "0x00051e1602030004840100068401000684010003840600049301840693018406930184039306000484010a0684010a0684010a038407000184010a0184010a018402000184010a0184010a018402000184010a0184010a01840700038401930684019306840193068404000393018401020593018401020593018401020593040003840100068401000684010006847500068401000684010006840100048402000184010205930184010205930184010205930184010203930100018401930684010a0684010a06840193048401000184010a0184010a018402000184010a0184010a018402000184010a0184010a018402000184010a0184010a01840100048401930684019306840193068401930184010004930184069301840693018406930184020004840100068401000684010006840300" + }, + { + "filename": "head-chainsaw", + "data": "0x00051d16040300036315000163030001631400016303000163120008630200010d0200010d0200010d0200010d05000863010d0100020d0100020d0100020d0100020d04000863020d0263010d0263010d0263010d0263020d0300010d06630e0d0163020d08630e0d0163010d0200010d06630f0d020008630e0d0163020d0100010d06630e0d0163010d010008630f0d020008630e0d0163020d03630102010d0102010d01630e0d0163010d02000263010d0102010d010201630f0d04000863010d0263010d0263010d0263010d0263010d05000563020d0100020d0100020d0100020d0100020d070004630100010d0200010d0200010d0200010d0200010d0300" + }, + { + "filename": "head-chameleon", + "data": "0x00021c16040b00021d1600021d1500041d1300061d0e000184031d0184041d0184031d01840800030f0184031d0484031d0184030f0500010f0222020f0184011d0184041d0184011d0184050f0300010f0423010f0184021d0484021d0184060f0200010f012202230122020f0184061d0184050f02220200020f0222030f0184061d0184040f03230200070f0184061d0184040f012202230200070f0184061d0184050f02220300040f0284081d0284040f050003840c1d03840500141d0300161d0200041d048406230484041d0100021d03840e220384031d01840522010f0122060f0122010f05220184011d01001622030003220e0003220200" + }, + { + "filename": "head-chart-bars", + "data": "0x00041a1406100004730800041c040004730800041c040004730800041c0469047304000428041c0469047304000428041c0469047304000428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428011c06230169047304190428041c0469047304190428041c04690473" + }, + { + "filename": "head-cheese", + "data": "0x00031a140605000226012b022602290d00052602290d00052603290b000226012902260229012b01290b0001260129022b01260129012b03290a0001260129022b012601290126032909000526032902260229080005260729080005260829060005260929060005260a29050005260a29040005260c29030005260c2903000126012903260d29010001260129012b02260429012b012903230529010001260129012b02260229022607290126032905260f29" + }, + { + "filename": "head-chefhat", + "data": "0x00051c14040500060210000b020c00090203a308020300060204a30c020200030203a310020100250201a3060201a3030201000b0201a3050202a303020300030201a3060201a3030202a304020500030201a3050201a3020201a3050208000e7c0a000ea30a000ea30a0001020c5501020a000e020a000e020500" + }, + { + "filename": "head-cherry", + "data": "0x00011b15050900030f0e00010f0200070f0d000b0f0b00010f0100070f0e00010f0200030f1000010f0300010f1200010f0300010f1100010f0400010f0d000318010f01180400010f0441060009180941030009180b4102000918094101020141010009180d4109180d4109180d4109180d4109180d410100091806410318024102000918054101180202034103000918094106000518040005410400" + }, + { + "filename": "head-chicken", + "data": "0x000318140805000155010003550a000755080008550700028707550387030006870455048702000987015504870100888704130c8706130a8704550c8704550487" + }, + { + "filename": "head-chilli", + "data": "0x00041c16050600081c0d000a1c0b00081c0e000a1c0d00071c0224011c0c00041c07240c00011c0a240d000a240d000a240d000b240c000b240d000b240900012402000c240700022403000d240400032404000524052309240500112407000f2409000c240e0007240600" + }, + { + "filename": "head-chipboard", + "data": "0x00061c140513a4040001a401a503a402a601a408a701a401a501a4040005a402a606a401a806a4030001a403a901a402a601a40aaa02a4030001a401a901aa01a902a401a806a401a807a401ab01a501a403a901a401a804a401a803a401a805a401a802a505a401a803a401a805a401a803a401a801a401ab01a505a401a803a401a805a401a802a401a802a402a502a410a803a401ab01a501a401a803a401a80fa4020001a401a802a410a801a401ab01a501a401a801a401a810a401a802a503a401a801a402aa01a402aa01a402aa01a402aa01a402aa02a401ab01a501a401a501a401a801a402aa01a402aa01a402aa01a402aa01a402aa02a402a515a401ab01a5" + }, + { + "filename": "head-chips", + "data": "0x00021c19040d0001231600010702231400030702231200020701020207022310000287050702230e000487050702230c000287010203870507034209000287010205870507024208000a8705070142012306000c870507022304000e8705070223020001070f8705070123010003070f870407010005070f870207020006070f87040006070d87020001420300060703870214068702000242040006070987020003420500060707874c00034215000242160001420200" + }, + { + "filename": "head-chocolate", + "data": "0x000319140701000185010e03970185039709000185010e02850197038501970900020e098507000185010e0397018503970185019707000185010e02850197038501970385019701850400020e0c8504000185010e03970185039701850397018502970100038c0f065a8c010002890e190200101902001019020003190c890119020010190100" + }, + { + "filename": "head-cloud", + "data": "0x00041c14040b000502110009020e000b020c000d020a000f0207001102050014020300150203001502020016020200170201003002010017020100170202001502050012020200" + }, + { + "filename": "head-clover", + "data": "0x00041d16070400031d0500031c0a00051d0300051c0900051d0300051c0700031c051d0100061c021d0400041c061d041c051d0300051c051d031c061d0300061c010f021d031c010f061d0400061c010f011d021c010f061d0700051c010f011c010f051d0a00021d031c010f031c021d0a00051d010f011c010f051c0700061d010f021c011d010f061c0400061d010f031c021d010f061c0300061d031c051d051c0300051d041c011d055c041c0100020f0100021d061c010f051d031c040f0300051c030f051d050f0400051c0300051d0a00031c0500031d0700" + }, + { + "filename": "head-clutch", + "data": "0x00071b14030b0004120b0009760412097602000876015b0412015b087602000876065b087602000812015b04ac015b0812010001120876015b0412015b087601000112097604120976015b0100097604120976015b0100097604120976020009760412097602000976041209760200097601020123010201230102087602000976041209760200097604120976" + }, + { + "filename": "head-coffeebean", + "data": "0x0005191608040004ad010004ad060005ad01340135013405ad030002ad013403ad01340123013406ad010002ad013404ad01340123013408ad013405ad01340123013408ad013405ad01340123013408ad013405ad0134012301340ead0134012301340ead0134012301340ead0134012301340ead0134012301340ead0134012301340ead0134012301340bad03230134012301340ead01340123013407ad010006ad01340123013406ad030005ad01340135013405ad060004ad010004ad0400" + }, + { + "filename": "head-cone", + "data": "0x000319140708000224100002240f0004240e0004240e0004240d0006240c0006ae0c0006ae0b0008ae0a0008240a00082409000a2408000aae08000aae07000cae06000c24030004240c481424" + }, + { + "filename": "head-console-handheld", + "data": "0x000319140713031010020301100f7902030110077901af07790203011005790510017901af011001af017902030110067903af0279011001af01100179020301100179021001790110017901af017901af027901af011001af0179020301100f79020301100f79020301100f79020301100f79020301100f79020301100f79150301b0100303b0020301b0010301b0010303b101030324030301b0020301b0010301b0020303b1010303241303" + }, + { + "filename": "head-cookie", + "data": "0x00031a1606070006980c000a9808000e98050007980185089804000d98018502980300129802001298010073980285039801000e9802850298020003980285029801850a98030002980285029805850598040006980185099805000498018504980185049808000a980c0006980700" + }, + { + "filename": "head-cordlessphone", + "data": "0x000a1d1402020009030db00303020005030389010301b0028801b0028801b0028802b0018901b003030200020301b002030389010301b0028801b0028801b0028802b0018901b0030302000503038901030db0010301230103020005030389010301b0028801b0028801b0028804b00103012301030200010301b0010301b001030389010301b0028801b0028801b0028804b0010301230103020005030389010301b0028801b0028801b0028804b001030123010302230503038901030db00103012301030223020301b002030389010301b0028801b0028801b0028802b0018801b0010301230103020005030389010301b0028801b0028801b0028802b0018801b00303020009030db00303" + }, + { + "filename": "head-cottonball", + "data": "0x00021c16040a00010216000302014b0202020001020a00010202000202014b07020c000502014b0402014b03020200010206000102014b0402014b0502014b040207000202014b0a02014b020207000302014b0602014b0302014b030206000102014b0202014b0602014b0402014b010204000202014b0302014b0602014b070204000502014b0d02014b04000402014b0f0204001102014b02020100010201001202014b03020100010201000302014b0d02014b020205000102014b0d02014b020206000402014b0202014b0202014b0302014b030207000302014b0302024b07020100010205000302014b0302014b0202014b0402014b01020900014b0d020c000802014b010210000102014b0302014b0900" + }, + { + "filename": "head-cow", + "data": "0x00061914060300017f0323057f05230500017f0323057f05230300037f0323057f0523017f01000c7f0523197f02230d7f030003230b7f05000323047f0323047f0500077f0323047f0500077f0323047f0500027f0e5f03000123017f045f0208035f0208035f030002230e5f03000223035f0908025f030002230e5f" + }, + { + "filename": "head-crab", + "data": "0x00021b14050400041306000413060007130400071303000913020009130100031302b20c0002b20d130200131304000b13010005130600051301000413070001230200012307000413010010130100041301001013010044130300101306001013060010130600061304b2061306001013060010130300" + }, + { + "filename": "head-crane", + "data": "0x00061f1405060005b313000ab30f000cb30d0003b3050206230b0002b306020823090001b30802092308000902072304b506000a02052308b50300060209230bb5050207230e00040208230f0002020a230f0002020323040205230d0002020d230c0002020c230800" + }, + { + "filename": "head-croc-hat", + "data": "0x00061e150801000e2308000e230700102307000e1d08000e1d08000e1d08000e1d08000e1d08000e1d08000e1d0800151d0100151d0100031d0323021d0423021d0423031d0100051d0123021d0123021d0123021d0123021d0123031d0100051d0423021d0423021d0323011d0100151d" + }, + { + "filename": "head-crown", + "data": "0x00041a14060100015b0700025b0700015b0200015b0700025b0700015b0200025b0500045b0500025b0100028b012b015b0300015b041d015b0300015b012b0241018b0154012b025b0100025b011d029b010f025b0100025b012b011801410254012b055b021d020f055b012b02180100125b0200125b0200125b0200125b0200125b0200125b0200125b0200125b03000135052b0435052b01350300125b0200125b0100" + }, + { + "filename": "head-crt-bsod", + "data": "0x00051a15040400120104001201020004010166025a01660a5a0801025a01660b5a08010166025a01660a5a08010e5a08010e5a08010e5a08010e5a020102b004010e5a08010e5a020102b004010e5a08010e5a020102b004010e5a0f01012301010123060102000a0101230101012301010123050104001201" + }, + { + "filename": "head-crystalball", + "data": "0x00021a14060700062d0c00022d06b6022d0900012d0ab6012d0700012d07b6012d04b6012d0500012d03b6012d0ab6012d0300012d03b6012d01b6012d05b6012d04b6012d0200012d04b6012d05b6032d03b6012d0100012d0cb6012d05b6022d07b6012d0ab6022d12b6022d12b6022d12b6022d12b6012d0100012d10b6012d0200012d10b6012d0300012d0eb6012d040010b7040005b7072304b7040010b70200" + }, + { + "filename": "head-diamond-blue", + "data": "0x00051a18060500024a0104044a0104024a0900034a0104044a0104034a0700034a0104064a0104034a0500044a0104064a0104044a0300044a0102084a0104044a01000204010201040302010401020b04054a0102084a01040a4a0104084a01040a4a0104084a01040a4a0104084a0104054a14040100054a0104064a0104054a0300044a0104064a0104044a0500044a0104044a0104044a0700034a0104044a0104034a0900024a0104044a0104024a0b00024a0104024a0104024a0d00014a0104024a0104014a0f000104024a01041100024a0900" + }, + { + "filename": "head-diamond-red", + "data": "0x00051a1806050002b8014204b8014202b8090003b8014204b8014203b8070003b8014206b8014203b8050004b8014206b8014204b8030004b8010208b8014204b801000242010201420302014201020b4205b8010208b801420ab8014208b801420ab8014208b801420ab8014208b8014205b81442010005b8014206b8014205b8030004b8014206b8014204b8050004b8014204b8014204b8070003b8014204b8014203b8090002b8014204b8014202b80b0002b8014202b8014202b80d0001b8014202b8014201b80f00014202b80142110002b80900" + }, + { + "filename": "head-dictionary", + "data": "0x00051b150501000802040008020100014a01020372010203720102020001020372010203720102024a1402024a010203720102037204020372010203720102024a1402024a010203720102037204020372010203720102024a1402024a010203720d0202720102024a1402024a010203720d0202720102024a1402024a010203720d0202720102024a070206410702024a1402024a14020b4a02020a4a0900044a0900" + }, + { + "filename": "head-dino", + "data": "0x00071d15080300061d0f00061d0c00bd1d0100051d0302011d0302011d0302011d03020100051d0302011d0302011d0302011d03020100141d0100141d" + }, + { + "filename": "head-dna", + "data": "0x00091d160304431200045501000126010004430c000455010001510200012601000155010004430800035501430100012601000151020001260100015501000143010001510243060002550143010001430100012601000151020001260100015501000143010001510100024304000255010001430100014301000126010001510200012601000155010001430100015101000343020002550143010001430100014301000126010001510200012601000155010001430100015101000143010002430255010001430100014301000143010001260100015102000143010001510100012601000155010001430200025502000143010001430100015501000143010001550200014301000151010001260100015501000143010002550243010001430100014301000155010001430100015502000143010001510100012601000155010001430255020003430100014301000155010001430100015502000143010001510100012601000155010002550400024301000143010001550100014301000155020001430100015101000126010003550600034301000155010001430100015502000143010005550a000543010001550100055510000543" + }, + { + "filename": "head-dog", + "data": "0x00061a140603000e97040004850d970185010005850d9706850e9706850e9706850e9706850e9706850e970685049706380497068504970638049706850397083803970685019708380223020d0138028502000397083804230138040003970438022301020323010201230138040003970d380200" + }, + { + "filename": "head-doughnut", + "data": "0x00031a160607000156056c0c00026c0156046c01b9026c08000a6c01b9036c0500086c016d056c02190400026c02b9016c0119036c016d066c0300076c0119016c0138056c0156026c0200076c0538026c0156036c0100046c016d026c013804000138066c011c016c021c016c016d016c013806000138026d036c011c066c0138060001380c6c013806000138086c0156036c013806000138036c02b9036c0156036c023804000138026c0156046c0100076c0538036c0156026c0200046c01b9066c0219056c0300026c01b9046c0156086c0400076c0156040e016d036c0500026c0119096c016d016c08000119096c0c00016c021c036c0700" + }, + { + "filename": "head-drill", + "data": "0x00071c140502000e1401a307000f1401a3017e06000f1401a3017e017c017e017c017e017c101401a3027e017c017e017c017e101401a3017e06000f1401a307000f1401a308000e1401a30b00057e01a31100057e02a31000057e03a30f00077e0f00011401230126012301260123081409000e140500" + }, + { + "filename": "head-duck", + "data": "0x00041d1407070006020e0005020c001002060011020500110205001102050011020500110205001102050011020500110205001102050011020500050210460100050204460142014601420a4605021146010005021046" + }, + { + "filename": "head-ducky", + "data": "0x00031c14040c0008260e000526045102260c00052602510223025101260c000526025102230251012601140b0006260451022603140100022607000a2603140200052605000a2603001626020017260100482601001726010017260200162602000b26018a092604000726038a0926070010260300" + }, + { + "filename": "head-earth", + "data": "0x00031a1606070006430c000a4308000343011c0543011c0243021c05000243031c0543061c04000243021c0543071c0300011c0243031c0343091c0200021c0243011c0443091c0100031c08430c1c0d43081c07430e1c0543091c0143061c0443081c0243061c0443071c03430100031c0643071c02430200021c0843041c04430300011c0943041c02430400011c0443081c034305000e4308000a430c0006430700" + }, + { + "filename": "head-egg", + "data": "0x0001191507070004020c00020202ae04020900010201ae010202ae020202ae010207000c020500010201ae020201ae020201ae06020400010201ae060202ae020201ae01020300010201ae020201ae040202ae030201ae01020200010201ae0c0201ae01020200010201ae0b0201ae02020100100201ae060201ae0a0201ae030201ae0a0201ae020201ae030201ae0a0201ae020201ae330202ae0202010010020200030201ae080201ae030203000502021e070205000c020800050201ae02020500" + }, + { + "filename": "head-faberge", + "data": "0x0001191406080003260d0001260207012601070126020701260a00020701260307012602070900010f0407010f0407010f07000d070600010701260407012604070126010705000107012601890126020701260189012602070126018901260107040002070126040701260407012602070300110702001126010013260100118a020011070200110703000f0704000f0704000f0705000d0706000626032303260900098a0500" + }, + { + "filename": "head-factory-dark", + "data": "0x00031a14080300057c0b00010e0300087c0600020e0b00047c010002241000020e0400010e0300010e0300010e0300020e0300020e0200020e0200020e0200040e0100030e0100030e0100030e0200100e0200100e0200100e0200100e0200100e0200100e0200100e0200100e0200020e0172010e026d010e026d010e0172050e0200100e0200100e0200" + }, + { + "filename": "head-fan", + "data": "0x00031a1606070006510c0003510100015102000351080003510200015102000151020003510500035102000151027e0151027e0151020002510400025102000151027e0151027e0151027e01510100015103000251020001510100017e0151027e0151027e0151017e01000251020001510200015102000151027e0151027e0151017e01000151010001510100025101000151020001510100017e0262017e0151017e010001510200035101000151027e015102000462020001510200015101000351027e0151027e06620151027e0151020002510100017e0151027e01510662027e0151017e0100035101000151027e0151027e0462027e0151027e0151010003510100017e0151027e0151017e0262027e0151027e0151017e02510100015101000151027e0151027e01510100017e0151027e0151027e0151020002510100017e0151027e01510100017e0151027e0151027e02510300015101000151027e015102000151027e0151017e01000251040002510200015102000151027e015102000351050003510200015102000151020003510800035102000151010003510c0006510700" + }, + { + "filename": "head-fence", + "data": "0x00041d1403020001ba060001ba060001ba06000134030003ba0400013402ba040003ba040001ba013401ba010005ba020001ba013403ba020005ba020002ba013407ba020001ba013403ba020003ba013401ba020002ba013405ba013401ba020001ba013403ba020003ba013401ba020008ba013401ba023401ba013403ba023403ba013401ba023402ba013405ba013401ba023401ba013403ba023405ba023408ba013401ba023401ba013403ba023405ba023408ba013401ba020005ba020005ba020005ba013404ba020005ba020001ba013403ba020003ba013401ba013404ba020005ba020001ba013403ba020003ba013401ba013402ba013401ba023405ba023401ba013403ba023403ba013401ba013404ba023405ba023401ba013403ba023401ba013401ba013401ba013404ba023405ba023401ba013403ba023403ba013401ba013404ba020005ba02000585020003ba013406ba020003ba013401ba02000585020003ba013406ba020003ba013401ba020001ba013403ba020005ba" + }, + { + "filename": "head-film-35mm", + "data": "0x0003181405080006230d0006230800102303420726078702260100014201000726078702260342072607870226034207260787022603420726078702260342072607870226034207260787022603420726078702260342072607870226034207260787022603420726078702260342072607870226010001420100022603ad022607870226034207260787022603001023" + }, + { + "filename": "head-film-strip", + "data": "0x00051b140516bb010002bb010002bb010002bb010002bb010002bb010002bb010002bb010016bb02bc01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb03bc017b01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb02bc16bb010002bb010002bb010002bb010002bb010002bb010002bb010002bb010016bb" + }, + { + "filename": "head-fir", + "data": "0x00011f18010e00020f1b00040f1900060f1700030f015c040f1500030f015c060f1300030f015c040f015c030f11000a0f015c030f0f000c0f015c030f0d00120f0b00140f0900160f0700180f05001a0f03001c0f01001e0f0600120f0b00140f0900160f0700060f065c0c0f05001a0f2700010f0e00010f0d00020f0e00020f0b00030f0e00030f0500" + }, + { + "filename": "head-firehydrant", + "data": "0x00021c14040b0002bd140006bd110002be01bd02be01bd02be0f0003be01bd02be01bd03be0d0003be01bd04be01bd03be0c0003be01bd04be01bd03be0b0003be01bd06be01bd03be0a0003be01bd06be01bd03be080012bd060012bd08000ebe0a000ebe060002be012310bd012302be020002be012310bd012302be010001bd02be012310bd012302be02bd02be012310bd012302be01bd010002be012303bd0b2302bd012302be020002be012310bd012302be06000ebe0500" + }, + { + "filename": "head-flamingo", + "data": "0x00031b14050c00042003b90d00062001b9012301b901200b00072003b902200900042005000320025f070004200800035f070004200800025f010e070005200800020e080006200600020e090008200300010e0b0009200e0009200f0008201000062002002b6a0b2006091b20010014200100" + }, + { + "filename": "head-flower", + "data": "0x00031b18050a00024f1300044f0d0002b90200019a044f019a020002b9070005b9019a044f019a05b9050007b9019a024f019a07b9040007b9041307b9050004b90213046d021304b9060003b90113086d011303b90500029a02b90113086d011302b9029a0300034f019a01130a6d0113019a034f0100054f01130a6d01130a4f01130a6d0113054f0100034f019a01130a6d0113019a034f0300029a02b90113086d011302b9029a050003b90113086d011303b9060004b90213016d0385021304b9050007b9041307b9040007b9019a024f019a07b9050005b9019a044f019a05b9070002b90200019a044f019a020002b90d00044f1300024f0a00" + }, + { + "filename": "head-fox", + "data": "0x00031c190405000302140005021200014205020800022301000223040002420502080002420100024203000442030209000642010007420400022306420111014201110742070006020a4209000b02054209000a020100054209000902020004420a00080204000f42050204001042040204001142030204001242020204000542070207420102040005420623020206420500054209020442060001420e000242040004420e000142050001421100024204000123120002420223010001231600" + }, + { + "filename": "head-frog", + "data": "0x00061914070300051c0300041c0500071c0100061c0300041c020f0a1c0200041c020f0a1c02000d1c020f011c02000d1c020f011c0200101c0200101c0200020f0e1c0100011c020f331c14670e5c0267010010670100" + }, + { + "filename": "head-garlic", + "data": "0x00051914070700010b0100010b0100010b0e00030b0f00030b0e000157030b015709000157030b0157030b0157030b0500010b0157030b0157030b0157030b01570300020b0157030b0157030b0157030b0157010b0100030b0157030b0157030b0157030b0157050b0157030b0157030b0157030b0157050b0157030b0157030b0157030b0157050b0157030b0157030b0157030b0157050b0157030b0157030b0157030b0157050b0157010b01bf010b0157030b0157030b0157050b0157020b04bf010b0157030b0157020b0100020b0157030b0157030b0157030b0157010b0300010b0157030b0157030b0157030b01570200" + }, + { + "filename": "head-gavel", + "data": "0x000419140108000f3409000f340a000d230b000d260b000126015d0b260b000126015d0b260200013401000234010004340d2604000134020004340d2603000234010005340d260b000d260b000d260b000d260a000f3409000f230800118e0700118e07001123" + }, + { + "filename": "head-ghost-B", + "data": "0x00051b16030c00028c1500048c0b00028c0700058c0600028c0200048c0400028c0104018c0104018c0400048c0200068c0200068c0200068c0300148c0400148c0400148c0400148c0500128c0600128c0600118c0700118c08000f8c07000f8c0600118c0b00028c1400048c1200" + }, + { + "filename": "head-glasses-big", + "data": "0x00091c120204000a8002000a800400018005020480020001800502048004000180050204800200018005020980050207800502098005020780050205800300018005020480020001800502058003000180050204800200018005020580030001800502048002000180050204800400018005020480020001800502048004000a8002000a80" + }, + { + "filename": "head-gnome", + "data": "0x00011a14060900024112000241110004410f0006410e0006410d0008410c0008410b000a4108000ec0030001c1010001c00ec101c0010003c101c00ec101c004c101c00ec101c004c101c00ec101c002c10200104c0400104c0400104c0400104c040003c10123010201230102012301020123010201230102012302c1040003c10b4102c10500088a018e078a0100" + }, + { + "filename": "head-goat", + "data": "0x00051d1805030001b00c00040d060002b00e0004b0030002b00e0002b0017e022301b0020002b00e0002b0017e04b001000fb0017e02b0017e02b0029802000eb0017e02b0017e01b0017e02b003000eb0027e02b0010002b0030010b0030001b0040010b0080010b0080011b0070011b0060005b0017e0cb0060005b0017e01230102012301020123010207b0050004b0017e0ab0010003b0050003b001000ab0040001b0040002b0110001b0030003b0100002b0030001b0120001b0040001b0120001b00400" + }, + { + "filename": "head-goldcoin", + "data": "0x00031a1606070006260c000326042b032608000326022b0426022b032605000226022b0826022b022604000126012b0c26012b012603000226012b0c26012b022602000126012b092603290226012b012601000226012b032603290826012b0326012b1026012b0226012b1026012b0226012b1026012b0226012b1026012b0326012b112601000126012b102602000226012b0f2603000126012b02260129012604290426012b012604000226022b0826022b022605000326022b0426022b032608000326042b03260c0006260700" + }, + { + "filename": "head-goldfish", + "data": "0x00051b1405020012210500109504001421010029210151032112070151010702211407022112070151010702211407022114070221140703210807032507070221010001210707011401250123022506070121020002210707032506070221030003210c07032106000e210400" + }, + { + "filename": "head-grouper", + "data": "0x00061d1602090001080100010801000108010001080100010810000c080e000f0807000208020004080e7a040004080200137a03000408157a01000508157a02000408117a0108047a02000308107a02c4047a010004080e7a02c4047a0282020003080d7a01c4047a0282030004080c7a01c4047a018204000508057a0208047a010801c4037a018205c401000408047a0108057a020801c4027a018201c4047a010004080200077a040801c4077a030002080600027a0508027a01c4047a100003080c00" + }, + { + "filename": "head-hair", + "data": "0x00031e15020800068e0100058e0f00018e0626018e0526018e0d00018e0126068e0126058e0126018e0900018e0100018e0126018e0626018e0526018e0126018e0100018e0700018e0126018e0126068e0126058e0126018e0126018e0800018e0126018e0126018e0500018e0400018e0126018e0126018e0800018e0126018e0126018e0a00018e0126018e0126018e0800018e0126018e0126018e0a00018e0126018e0126018e0600018e0100018e0126018e0126018e0a00018e0126018e0126018e0100018e0500018e0126018e0126018e0c00018e0126018e0126018e0600018e0126018e0126018e0c00018e0126018e0126018e0600018e0126018e0126018e0c00018e0126018e0126018e0600018e0126018e0126018e0c00018e0126018e0126018e0400018e0100018e0126018e0126018e0c00018e0126018e0126018e0100018e0300018e0126018e0126018e0e00018e0126018e0126018e0400018e0126018e0126018e0e00018e0126018e0126018e0400018e0126018e0126018e0e00018e0126018e0126018e0400018e0126018e0126018e0e00018e0126018e0126018e0200028e0100018e0100018e1000018e0100018e0100028e" + }, + { + "filename": "head-hardhat", + "data": "0x00041d1405050005c505c60d0006c601c505c60b0006c502c601c505c6090007c601c502c601c505c6080008c601c501c601c505c6070009c601c502c605c501c6060009c601c508c6060009c601c508c6060009c601c508c6060009c601c508c6060009c601c508c6060009c601c508c6060009c601c508c6060003c60fc5050004c601c50d2301c509c601c50dc601c51dc6" + }, + { + "filename": "head-heart", + "data": "0x00041c1704050005240400052408000924010008240500062402020624020204240300092401020524020201240102032402001324010202240100142401024b2401001624020016240300142404001424050012240700072402020123062409000e240b000c240d000a2410000624140002240b00" + }, + { + "filename": "head-helicopter", + "data": "0x00031d14020d0002231000016104620261062302610462016110000223190002231600072007560400022006000220019a0120019a0120019a012008560300032004000320019a0120019a0120019a01200956020002620e200556030202560162022301620d200556030202560162022301620d200556030202560100026202000c200a5606000b2008560102015607000a20085601020156080009200656020201560a00082008560c000e200f0001230200012312000e230600" + }, + { + "filename": "head-highheel", + "data": "0x00061b14050200031812000518110006180f0008180e0008180e0008180e0008180e0009180d000b180c000c180b0004180200081809000218040009180700021805000a180500021806000318042304180300025b07000a5b" + }, + { + "filename": "head-hockeypuck", + "data": "0x00051b1505070008050b000305081f0305060002050e1f020503000105121f010501000105141f0205141f0205141f0105010d0105121f0105011f020d02050e1f0205010c011f040d0305081f0305020c021f070d0805060c011f040d030c020d010c010d090c021f070d0e0c011f0100030d030c020d0b0c011f0300050d030c0105010d0205010d050c0600030c020d090c0b00080c0700" + }, + { + "filename": "head-horse-deepfried", + "data": "0x00061b15050900018e0100028e0d0003ac0100068e010003ac0600028e03ac068e020003ac0600028e07ac018e06ac0500038e06ac036d05ac0600028e07ac016d06ac0600028e07ac016d06ac0500038e07ac016d06ac0600028e07ac016d06ac0600028e07ac016d06ac0500038e128a0200028e0e8a0123018a0123018a0100038e028a016d0123016d0123016d0123016d098a048e128a0100038e128a0100018e0100018e0e8a0400" + }, + { + "filename": "head-hotdog", + "data": "0x0003171409050004890700018301390689013901830300028301390689013902830100028301390289016d021903890139048301390389026d011902890139048301390589016d011901890139048301390389026d011902890139048301390289016d021903890139048301390389026d011902890139048301390589016d011901890139048301390389026d011902890139048301390289016d021903890139048301390389026d011902890139048301390589016d011901890139048301390389026d011902890139048301390289016d021903890139048301390389026d011902890139048301390589016d0119018901390283" + }, + { + "filename": "head-house", + "data": "0x00031c1505080001830f00027c04000183015101830e00021103000183035101830d0002110200018302510183025101830c000211010001830251018301c70183025101830711040002110183035103830351018307110300011101830b5101830711020001830d510183071101830f5107831a51051103510b830451051103510183031103c7031101830451051103510183021105c7021101830451051103510183011107c70111018304510311012601110351018306c7017c02c70183045105110351018305c7027c02c7018304510111032301110351018304c7037c02c701830451051103510b830351077c0e51" + }, + { + "filename": "head-icepop-b", + "data": "0x00071c19020500061c089305190600021c059b0802031603190500011c019b051c08930319020202190400011c019b051c08930319020202190400071c089305190116011904c8071c089305190116011904c8071c0893071904c8071c089305190116011904c8071c0893071904c8071c089307190400071c089307190400011c029b041c089307190400011c029b041c0193020201930102039306190600061c089305190a00021c0c0002190a00011c0d00011919000119330001190300" + }, + { + "filename": "head-igloo", + "data": "0x00051e14050800060210000402013c0202023c03020c000102033c0302013c0302023c01020a000102013c0602013c0502013c010208000102033c0102043c0102013c0102053c010207000602013c0602013c040206000102013c1002013c010205000502053c0102063c03020500140204001202013c0102013c020202000102023c0902063c0102013c040201000302013c0402013c0502013c0202013c0102013c0202013c010201000302013c0402013c0502013c0302013c0202023a013c0202023c0102053c0102033c0202043c0202023a013c0202013c0302013c0502013c0402013c0102013c0202033c010201000402013c0502013c0402013c0102013c05020100" + }, + { + "filename": "head-island", + "data": "0x00021b14060400040f1000060f0100061c0c00020f091c0800080f031c01c9031c0500040f01c9030f031c01c90200031c0400020f020002c90100010f021c02c90300021c0400010f040002c90100021c01c90400021c090002c90200011c01c90500011c0400060f01c9020002c90900080f01c9010002c90900080f01c9010002c90900080f01c9010002c90900080f01c9010002c909000e260600102604000d2601460426020002260146012602290226022902260146032601460326010006260229062601460526010014260100" + }, + { + "filename": "head-jellyfish", + "data": "0x00031c1b050700055f016a035f0b00016a0e5f0600065f016a0c5f0400135f0300085f0576055f016a025f0200015f016a045f0976065f0100055f0d76065f016a025f0f76025f016a055f0f76075f1176065f1176035f0100015f1376015f0200015f1376015f0200015f1376015f0200015f036e0176036e0176036e0176036e0176036e015f0200156e0200016a086e0690066e0200016a0200016a0e6e016a0100016a0200016a0200016a0e00016a0100016a0200016a0200016a0e00016a0100016a0100016a0200016a0f00016a0200026a0200016a1000016a0100026a1300016a0100026a1500026a1500016a" + }, + { + "filename": "head-jupiter", + "data": "0x00011d1a030900088210000c820e000982037d0b00107d02370700057d0f3706000b370938040005370a380937020006380a37087d020009370f7d01000637147d04377c7d0237167d0437147d0637010001370b7d0c3702000e3704250337038204000b3702250223022503820600048208370425048206001482070012820b000c8210000882120008820900" + }, + { + "filename": "head-kangaroo", + "data": "0x00051a1406037e0a00037e0400017e0238017e0800017e0238017e0400017e0338017e0600017e0338017e0500017e0338017e0400017e0338017e0700017e0238027e0200027e0238017e09000a7e0a00087e0c00087e0c00087e0c00087e0c00067e088103230300067e088103230300067e0b810300067e022309810300067e0b810300067e0b81" + }, + { + "filename": "head-ketchup", + "data": "0x0002181408070002240e0002240d0004240c0004240b0006890a0006230600022402890224028902240289022402000e23010082240389022403890a2404891824" + }, + { + "filename": "head-laptop", + "data": "0x00061b1605171f010b013c120b021f1456021f1456021f1456021f1456021f1456021f1456021f1456021f1456021f1456021f1456041f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e041f130e031f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e041f130e181f" + }, + { + "filename": "head-lightning-bolt", + "data": "0x00021e19050800031e1500081e11000c1e0c000c1e0d000b1e0d000b1e0e000a1e0e000a1e0f00091e0f00091e1000081e1000171e0200161e0200151e0400131e0500121e0c000b1e0d000a1e0f00081e1000071e1200051e1300041e1500021e1600011e1700" + }, + { + "filename": "head-lint", + "data": "0x00021b16050a00018c1400018c0f0001910600018c04000140080001910300018c0200038c014001000240090002910200028c0191028c03400400029106000340028c0191018c014001910240018c020001910300018c0200014001910340018c0191018c024001910240028c0300038c034001910340038c024001910140018c0500018c0100018c024001910340018c0191028c014001910140028c0600018c0191024001910240028c0191028c02400191028c010001910100028c0191018c024001910240028c0191028c0240038c010001910200018c0140028c014001910240058c0240028c0191018c01910100058c0740038c01400191038c010001910100038c01910840028c01400191028c020001910200018c01910a40018c0191028c0500038c0140018c01910640018c0191038c0191050001910140028c0191014004230140048c010002910300048c01910740028c0191028c0500018c010002910740028c0191018c0191090001910100014001000340018c0191018c0100018c0e0001400191010001910900" + }, + { + "filename": "head-lips", + "data": "0x00051d150307000424040004240c0007240200072409000d240202032407000e2403020324050013240102022403001824020006240c02062401000524100209241202072414021d240100182402001824030016240500082404020824080010240d000a240800" + }, + { + "filename": "head-lipstick2", + "data": "0x0001181408060003240b0007240800013709240500012401370a24040002240137062401370224040003240437020203240400072402370324040007240237032402000b2a01020f2a01020f2a0102042a0b0d01050f0d01050f0d01050f0d01050f0d01050f0d01050a0d0223030d01050f0d0105040d0b0501020405" + }, + { + "filename": "head-lock", + "data": "0x00031814080400081f07000a1f0500031f0600031f0400021f0800021f0400011f010d0800011f010d0400020d0800020d0200107a718a026d0a8a026d028a026d048a0223048a026d088a0223178a" + }, + { + "filename": "head-macaroni", + "data": "0x00081d1403010008290800082901000229060a022906000229060a02290126082901260600012608290b2606000b26012808260600082601280226012809260400082602281826012802260100182602001526012802260300162605000626020a0126020a0126020a0626070012260a000e260600" + }, + { + "filename": "head-mailbox", + "data": "0x00071c14050700058912000589150002890b000a050289030508000a050289030508000a050289030508000a050289030508000a0502890305060202000a05028903050402013a010202000a0502890305060202000a0502890305060202000a050289030501020423010202000f05060202001705" + }, + { + "filename": "head-maze", + "data": "0x00061b14050aca01000cca0b0001ca040001ca030002ca01000bca010001ca010004ca010002ca010001ca030001ca070001ca040001ca010002ca030001ca030007ca010004ca010007ca010002ca030001ca080002ca010001ca050001ca010001ca010001ca010006ca010002ca010005ca010001ca010003ca080002ca050001ca050001ca010009ca010003ca010003ca010001ca080001ca010002ca030001ca010001ca010001ca010008ca010001ca010004ca010001ca100002ca010001ca010004ca010007ca010006ca030001ca080001ca070015ca010001ca" + }, + { + "filename": "head-microwave", + "data": "0x00071a1f05010002950f06012102060100029501060e9201210143010e0100029501060e920121010e01430100029501060e92012102c70100029501060e92012102060100029501060e92012102c70100029501060e92012102060100029501060e92012102c70100029501060e92012102060100029501060e92012102c70100010e019501060e9201210206020e019501060e92012102c7020e01950f06012102c7010e02950f0601210206010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400" + }, + { + "filename": "head-milk", + "data": "0x00031b14080100014a0d7f0500014a067f0524027f0400034a057f09240289034a097f05240289034a0d430300034a0143017f0143027f0143047f0143017f01430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d43030003c70d7f0300034a0d430300034a0d430300" + }, + { + "filename": "head-mirror", + "data": "0x00041a1406159702060102010603020a060102029701060102010603020b06010202970102010603020c0601020297010603020d060102029703020106063c0106063c0102029702020206013c0406013c0106013c0406013c010202970102043c0406033c0406013c010202970106013c0206013c0406013c0106013c0406013c010202970106013c0206013c0406013c0106013c0406013c010202970406063c0106063c0102029711060102029711060102029711060102029711060102029712021597" + }, + { + "filename": "head-mixer", + "data": "0x00021a140603000223030002240300022407000172030001230172030001240172030001240300150c030f020c030f020c030f020c0123010c0123020c010f015c010f020c010f015c010f020c010f015c010f020c0124010c0123110c014e010c01af030c0123040c0123030c0302020c014e010c014e030c0123040c0123030c0372020c014e010c014e030c0123040c0123040c0123090c0123040c0123040c0123090c0123040c0123040c0123050c011f030c0123040c0123040c0123090c0123040c0123040c0123050c011f030c0123040c0123040c0123090c0123040c0123040c0123050c011f020c0302030c0123040c0123080c0372020c0302030c0123040c021f030c0123030c0372030c0123040c021f150c" + }, + { + "filename": "head-moon", + "data": "0x00031a1606070006870c000387035e048708000487035e078705000487025e0687015e038704000e87015e01870300128702000587015e0887015e038701000287015e1287025e1287015e4e870100128702000f87015e02870300058702230687025e018704000b87035e028705000687015e0387015e038708000a870c0006870700" + }, + { + "filename": "head-moose", + "data": "0x00051c15040383010002830c00028301000683010002830c85028301000683010002830c85028301000683010002830c85028301000a830b850d830b850d830b85068304000e850a000f8509000f8509000f85090005850d98060005850d980600058506980284029802840198060005850d980600058501980b8401980b000d980200" + }, + { + "filename": "head-mosquito", + "data": "0x00011f14030c0002351800023503000235140001350300023515000135030001351700013502000135180001350200013518000135020001351400091112000211014909110f00021101490b110d00021101490d110c0011110a00131109000211014910110900141109001b110200151108000a1107850c000211078507110d000f110800" + }, + { + "filename": "head-mountain-snowcap", + "data": "0x00031c15040a00040213000102028d030211000102018d060210000102018d06020f000a020e000102018d0602018d01020d000c020c000c020b000e020a000e020900021d0202021d0402021d0302011d0800021d0102041d0202041d0102021d0700021d0202051d0102041d0202021d0600021d02020a1d0202021d0500031d0202051d0102041d0202031d0300021d01020f1d0102031d01000b1d0302071d0102021d0100161d0400061d0600061d0300" + }, + { + "filename": "head-mouse", + "data": "0x00031e1407070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e07000e0509000e0509000e0509000e0509000e050400030e02000e050400030e02000e050400030e0200120505000e05011f0105011f010505000805024b0105024b0505050012050300" + }, + { + "filename": "head-mug", + "data": "0x00031b14020900067f0200017f0e00037f0400017f0300027f0100017f0900017f0200037f0300037f0e00027f0100017f2a00160203000102016f014b1102014b010201000102014b0102016f014b1102014b030201000102016f024b1002014b020202000102016f024b1002014b020202000102016f024b1002014b030201000102016f024b1002014b010201000102014b0102016f024b120202000102014b0102016f014b110205000102016f014b110206000102016f014b040204370402014b020208000102016f014b040202370402014b02020a000102016f024b0602024b02020400" + }, + { + "filename": "head-mushroom", + "data": "0x00021c1504080008550d000855025104550800035501510455025104550251025505000855045105550151025503000a5502510a550200035502510c55035102550100035504510655025102550551035501510255025103550151035502510255055103550151105503511b55010016550400125508000eae0a000eae0a000eae0a000eae0a000eae0a0002ae045508ae0a0002ae01550223015508ae0c0004550d00" + }, + { + "filename": "head-mustard", + "data": "0x0002181408070002260e0002260d0004260c0004260b00068a0a00062306000226028a0226028a0226028a022602000e2301008246038a0246038a0a46048a1846" + }, + { + "filename": "head-nigiri", + "data": "0x00051c1404040002cd01cc03cd01cc03cd01cc03cd01cc01cd060001cc03cd01cc03cd01cc03cd01cc03cd01cc03cd020002cd01cc04cd01cc03cd01cc03cd01cc03cd01cc07cd01cc03cd01cc03cd01cc03cd01cc03cd01cc07cd01cc03cd01cc03cd01cc03cd01cc03cd01cc07cd120203cd0100160202001602030014020300160202001602030014020300160202000a0203ce090203001402050012020300" + }, + { + "filename": "head-noodles", + "data": "0x00021e1402100001361b0001360500013614000136040002360b0001cf010001cf010001cf05000136020002360c0001cf015c01cf015c01cf015c01cf02000298038803160a0001cf015c01cf025c0316039806880216080001cf015c01cf025c02160419038803c1028801160298060001cf015c01cf015c02160619018801c1034601c101880116039803001c0b01001a0b02001a89030018890400180b050016890600160b0700140b0900070b0789040b0b00100b0e000c0b0800" + }, + { + "filename": "head-onion", + "data": "0x00041a14060a00019c1100019c0100019c0100019c1000039c10000137039c01370900029c0137039c0137039c0137039c0137019c0300039c0137039c0137039c0137039c0137029c0100049c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c01c7019c0123019c0137039c0137029c01c70137039c0100039c0137029c0423019c0137039c0137029c0300029c0137039c0137039c0137039c0137019c0500019c0137039c0137039c0137039c01370300" + }, + { + "filename": "head-orangutan", + "data": "0x0002181406070001240e000b2406000b2407000c2404000e2403000624070e042403000424070e0424030002240c0e0124030002240c0e0124030002240c0e0124030002240c0e0124030002240c0e01240300100e0200040e0a08020e0200030e0c08010e0200030e010801240208010e0108010e030801240108010e0200030e01240a080124010e0200030e01240a230124010e0200030e0c24010e" + }, + { + "filename": "head-orca", + "data": "0x00021b14010d00010d1900020d1800030d1700040d1600050d1500060d12000b0d0d000e0d0b00100d0300030d0300110d0400030d0100130d0300170d0400160d0300180d0200030d0100140d0100030d0200130d0100030d0400080d090b0a00060d090b0c00040d090b0400" + }, + { + "filename": "head-otter", + "data": "0x000918140704000b8604000e8603000f8602000f8602000f860100328602000286047f0623037f020001d00486017f0623017f0286020002d0037f04d0012303d0027f020008d0012301d0012304d0" + }, + { + "filename": "head-outlet", + "data": "0x0004181608245108a3075102a3012304a3012302a3065102a3012304a3012302a3065101a3037c02a3037c01a3065104a3022304a3065104a3022304a3075108a3185108a3075102a3012304a3012302a3065102a3012304a3012302a3065101a3037c02a3037c01a3065104a3022304a3065104a3022304a3075108a32451" + }, + { + "filename": "head-owl", + "data": "0x000218140507000ad1080001d10ad201d1060001d101d204d302d204d301d201d1050001d101d20ad301d201d1050001d101d201d302d401d202d301d202d401d301d201d1050001d101d203d301d202d301d203d301d201d1050001d101d204d302d204d301d201d1050002d101d208d302d201d10400042b01d208d301d201d10300062b08d301d201d10300062b01d107d301d201d10200072b01d107d301d201d10200072b01d107d301d201d10200072b01d107d301d201d10200062b02d107d301d10300052b03d106d301d10400032b04d106d301d1040001d1012b07d106d303000bd107d30100" + }, + { + "filename": "head-oyster", + "data": "0x00021d14040a00058111000481038204810e000181098201810c000381098203810a00018105820398058201810700048102820998028204810400018105820998058201810400018102820f980282018102000381018211980182048103821198038202810282139802820281048206980351079803820181010002810382049805510498038202810400028101820398075103980182028108000181019802550751025501980181090001810f5501810700048103550581035504810600018102d5058103d5058102d50181070011d50400" + }, + { + "filename": "head-paintbrush", + "data": "0x00091c18020700036d0572097502240600046d027201b00272097502240600046d0572087503240100096d0572087503240a6d0572087503240a6d0572087503240a6d0572077504240a6d0572077504240100096d0572077504240600046d0572077504240600036d0224017201b00272067505240700036d05720675052416000124010002241800022418000124190001240100" + }, + { + "filename": "head-panda", + "data": "0x000519140601000423090004230100062307000c23090209230b0207230d020223010002230e02012303001002030010020300100203001002030010020300100203000a020423020203000a02042302020300070206230302030010020100" + }, + { + "filename": "head-paperclip", + "data": "0x00091d14031bd6180002d6180002d6180002d6030010d6050002d6030001d6140002d6030001d6140002d6030001d6140002d6030001d6140002d6030017d6190014d60600" + }, + { + "filename": "head-peanut", + "data": "0x00041b1605040005d70f0002d7036004d70c0002d7016003c8036002d70b0002d7016001c802d7016002c8016001d70a0002d7026003d7016002d7016002d7090001d7016002c8036001d7046002d7080001d7016002d7016003d7016001d702c8016005d7040001d701600bd7016006d7020002d7016012d7020001d7016010d7016001d7020002d7016012d7020002d701600dd7026002d703000fd702c8016001d7040005d7036005d7016002d7016001d7050002d7016002d702c8056001d7026002d7060002d7026002d7016004c8016002c801d7090002d7036004d7016003d70b0003d7046003d70f0005d70400" + }, + { + "filename": "head-pencil-tip", + "data": "0x0003171409060002230c0002230b0004230a000423090006230800022301570323070002230357032306000757012305000a5704000a5703000c5702000c5701001e57042605570326015706260357072608371126" + }, + { + "filename": "head-peyote", + "data": "0x00021e14030a0001d8020001d9020001d8140001d801da010001d9010001da01d8120001d8020001da01db01d901db01da020001d8110002da05db02da0e0001d8010002a901dc02a903dc02a901dc02a9010001d8090002d802a901dc04a901dc04a901dc02a902d8090002a901dc02a902d801a901dc01a902d802a901dc02a9090002a901dc02a902d802a901dc02a902d802a901dc02a9070002a901dc0fa901dc02a9050017a9020001d8010017a9010001d8010001d817a901d8010002d817a902d8010001d817a901d8010001d8010017a9010001d8020002a901d911a901d902a9050001a913d901a9060015a9080011a90500" + }, + { + "filename": "head-piano", + "data": "0x00041b15080400050e0c00020e010501590105040e0900020e0105080e08000b0e07000d0e06000d0e06000e0e05000e0e05000f0e0400110e02004d0e0159070e0159050e0159040e0159010e0159010e0159010e0159010e0159010e0159010e0159010e0159010e0159020e1159140e" + }, + { + "filename": "head-pickle", + "data": "0x00031b15050400040f1000080f0d00030f01bf060f0c00030f015c030f01bf020f0b00020f01bf060f015c020f0a00020f015c030f01bf070f0800060f015c040f01bf015c050f0400010f01bf120f0200010f015c130f0100150f0100160f0100150f0100130f01bf010f0100020f01bf100f015c010f0200010f015c120f02000b0f012302bf015c040f0400030f01bf015c010f01bf040f025c050f0600050f015c090f09000b0f0400" + }, + { + "filename": "head-pie", + "data": "0x00011c14040b0002cb100002cb030002cb050002cb0b0002cb030002cb030002cb0b0002cb030002cb050002cb0b0002cb080002cb0b0002cb04000209040002cb0b0002cb0200020901190109020002cb0f0001dd040901dd0e0002dd010903dd020903dd010902dd080012dd050001dd010910dd010901dd030016dd020001dd04ba01dd04ba01dd04ba01dd04ba01dd01ba010033ba029503ba0196019503ba0195019603ba029505ba01950196029501960295019202950196029501960295019602950196029501ba010001950196029501960295099201960295019602950300019602950196029501920295019602950196029501960295019601950400019602950196029501960295019602950196029501960295019601950200" + }, + { + "filename": "head-piggybank", + "data": "0x00041d14020c0003421700014203930142050002760c00036c012503930125026c02000176016c01760a000276026c017605120176026c0176026c017609000176106c0176060001760100036c01020f6c0176040001760259146c0176030001760159136c0112016c03760100017601590176166c0176015901000276166c017603000176146c037603000276156c0176030001590176146c017605000376106c0276070013760900067601120202011206760d000c760700" + }, + { + "filename": "head-pill", + "data": "0x00061d140305000924071d08000c24081d0500062401020724081d0300032402020a24091d0200032402020b24081d01001124091d1124091d1124091d1124091d1124091d01001024061d010f011d02000f24071d010f011d03000a2403230124061d010f011d05000c24081d08000924071d0500" + }, + { + "filename": "head-pillow", + "data": "0x000319160702de0e0002df0dde05df010002de0edf020003de0ddf020003de08df03de02df020003de0ddf020003de02df02de09df020003de0ddf020003de0ddf020003de0ddf020003de0ddf020003de0ddf020003de0ddf020003de0ddf020003de0ddf020003de05df04de04df020003de0ddf020002de0edf01000dde05df02de0e0002df" + }, + { + "filename": "head-pineapple", + "data": "0x00031914070600010f010002e00100010f0a0001e00100020f02e0020f010001e0080003e0010f02e0010f03e00a0006e00a00022802260228022602280600022802260228022602280226022804000228022602280226022802260228030001280226022802260228022602280226012802000128022602280226022802260228022601280200012602280226022802260228022602280126020001260228022602280226022802260228012602001126010010260200102601001226010002260342012604420126034202260200022603420126044201260342022603000e260200" + }, + { + "filename": "head-pipe", + "data": "0x00061c150509160e0009980e0009980f00030804981000030804981000030804981000030804981000030804980c0003160100030804980c160398010003081398010003081398010004081298010006080123010201230102012308080398020015080300140814000308" + }, + { + "filename": "head-pirateship", + "data": "0x00011f14030c0002231b00019813000198030008230f00022304000823020002230b00019805000123015101230251012301510123020001980900025501980500032302510323010003550800035505000423015103230200035507000455030002230151042301510123010003550700065501000923030001980b00019807000198070001980b000198070001980700019806000d2601980700019806000c97012601980700019806000197022309970126089701980100052601970223099701260198010001970100019701000197010001980126049701000c970a2603970500049701231097080002970323019701230197012301970123019701230197012304970a00029701230e970c000f970800" + }, + { + "filename": "head-pizza", + "data": "0x000319140708000237100002370f000137022801370e000137022801370d000137042801370c00013701280237012801370b00013702280237022801370a0001370628013709000137082801370800013708280137070001370a280137060001370a280137050001370c280137040001370c280137030001370328033708280137020001370128013701280337052802370128013701000137082803230528023710280137" + }, + { + "filename": "head-plane", + "data": "0x00041e14030d000202180005021300090210000b020e000c0246000bc710000bc710000bc710000cc70f000cc7090002c7040012c70200010202c7040005c7060207c7020001020ac7090205c7010001c701020924020206230202052402000102010007c70b0205c702000102" + }, + { + "filename": "head-pop", + "data": "0x000318140802000ca20300061405280314010005140128031404280314022802140128011401280314042804140128021401280414052803140128081404280114022805140128031404280b1405280b1404280b1405280b1404280b1404280b1404280a140528091404280b1403280314012801230202012301280214010002280c1403000ca20200" + }, + { + "filename": "head-porkbao", + "data": "0x00051914070500025701000257010002570a0002570183025701830257090002570183025701830257018301570800015701830257018302570183025706000e5704000e5703001057020010570200105701005157037d1857010010570100" + }, + { + "filename": "head-potato", + "data": "0x00061d15040f0001c81600077a1000037a01c8077a0b000b7a02c8027a07000f7a01c8027a0400167a0200177a0100187a0100187a0100187a01c8187a0100107a02c8057a0300097a01230102012301020123017a02c8057a0400057a02c80d7a0600047a02c80b7a0b000a7a0900" + }, + { + "filename": "head-pufferfish", + "data": "0x00041c160509000168020001681000016801000668010001680700034903000568014904680700054902680349076806000449036803490368024903680500034904680349036802490468040003491068060012680500126805001268030005490d680649046801930b6801930468064902930968029306490a680449076806490293046801490235014902680193054903000693026804490168039308000e930a000c930d0008930800" + }, + { + "filename": "head-pumpkin", + "data": "0x00051b1406080003af01c401af100003af01c401af100003af01c401af0b00072401af072406000724014807240300022401480724014807240148042401480724014807240148042401480724014807240148042401480724014807240148042401480724014807240148042401480724014807240148042401480724014807240148042401480724014807240148042401480585016d0385016d058501480424014807240148072401480424014807240148072401480224" + }, + { + "filename": "head-pyramid", + "data": "0x00031e14030800018601b01900028601b01700038602b01600038603b01400058603b01300058604b0110002860284028601b0028602b01000078605b00e00088606b00d00088607b00b000a8607b00a000a8608b008000b8609b007000c8606b0028601b005000d860ab004000186038401860184078607b0038601b002000986032303860bb001000f860cb0" + }, + { + "filename": "head-queencrown", + "data": "0x00021b14050a00025b1300015b01180141015b1200015b01410118015b0e00035b0200025b0200035b0900015b0300015b0100025b0100015b0300015b0500035b0500045b0500035b0100015b0200015b03000241015b018b0154015b02410300015b0200025b0200015b01000441015b0254015b04410100015b0200025b01000141015b0541015b0154018b015b0541015b01410100015b0100015b0141015b0541045b0541015b0141015b0200015b0141015b0641025b0641015b0141015b0200015b0241015b0441045b0441015b0241015b0300015b0241015b0341015b028a015b0341015b0241015b0400015b0241015b0341015b028a015b0341015b0241015b0300025b0141035b0241015b028a015b0241035b0141025b0300125b050010350500055b0841055b0400125b0200" + }, + { + "filename": "head-rabbit", + "data": "0x0004171509037208000672080006720800067208000672080065721e050b2304050202040502021f05" + }, + { + "filename": "head-rainbow", + "data": "0x00041a140608000c1807000d18060003180b14050004180b140400021803140b460300031803140b4602000118031403460b0f01000218031403460b0f031803140346030f0854031803140346030f0854031803140346030f03540512031803140346030f03540512031803140346030f035403120200031803140346030f035403120200031803140346030f032303120200031803140346030f035403120200031803140346030f035403120200" + }, + { + "filename": "head-rangefinder", + "data": "0x00061b1405020002050100020501000d7202050b7203050172020e0102010e01720205027201050372020c037203050172040e017202050172020511720105010e010c0205110c020e140c020e140c020e140c020e140c020e140c020e140c020e120c0205020e080c0505050c0205020e140c010e010514720105" + }, + { + "filename": "head-raven", + "data": "0x00041e14080100080e1100070e0c000c0e0b000c0e09000e0e08000e0e08000f0e0600100e0600100e0600100e0600100e0600090e070d0600080e0c0d0200070e0f0d070e0f0d070e0d0d0200080e090d0500" + }, + { + "filename": "head-retainer", + "data": "0x00091d150504000320150001200119062010000320011906200d00052001190220011904200b00092001190620080002200119032001190620011903200600022002190320011903200219012003190120060002200f190220040002201119012004000120031904a3011904a3011904a30119022002a302200219012001a30120011901a3011901a3021901a3011901a30119012001a30320010001a3052001a3022003a3022003a3022006a3030003a31200" + }, + { + "filename": "head-rgb", + "data": "0x00011c16040900066410000a640d000c640b000e640a000e640900106408000164062802640669016407000165072802020769015a05000265062804020669025a03000365052806020569035a02000365052806020569035a01000565032808020369055a0565032808020369055a0665022808020269065a0765012808020169075a086501e1060201e1085a086508e1085a0100086506e1085a0200086506e1085a0300086504e1085a0500086502e1085a080006650200065a0500" + }, + { + "filename": "head-ring", + "data": "0x00021a15060600084f0c00024f0102024f016c024f0d00034f016c024f0c00032a044f032a0800022a021e022a024f022a021e022a0500012a021e0a2a021e012a0300052a011e0700052a0200032a011e0b00032a0100032a021e0c00042a0102012a011e0d00062a011e0d00062a011e0d00062a011e0d00012a0102042a011e0d00012a0102042a011e0d00032a0100032a021e0a00032a0200052a081e052a0300102a05000e2a08000a2a0500" + }, + { + "filename": "head-road", + "data": "0x00061c1403020017e2020017e2020017d3020017e2020017e2010017e2020017e2020017e2020017e2020017e2010018e2010017e3020017e2020001e203e303e203e303e203e303e203e301e2020017e20200" + }, + { + "filename": "head-robot", + "data": "0x00031c140405000e1f0a000e1f0800120506000105011f0205011f0205011f0205011f0205011f0205011f0105060012050600120506000105101f010504000105010012050400010501001205010001050100031f1205010001050100010e021f1205061f1205021f020e021f1205061f1205021f010e03000105010e0259010e0259010e0259010e0259010e0259010e0105031f03000105010e020b010e020b010e020b010e020b010e020b010e010506000105100e0105060012050300" + }, + { + "filename": "head-rock", + "data": "0x00031b14050b00030c1200010c031f020c0f00010c011f010c041f020c0c00020c021f010c051f020c0500050c051f010c061f010c0300010c121f010c0100010c051f040c0a1f010c0100010c091f010c091f010c0100010c021f010c101f010c0100010c071f020c011f070c021f010c0100010c051f020c0c1f020c141f020c041f010c0e1f030c041f010c081f020c011f030c0300010c041f010c041f030c021f010c021f010c0400010c051f030c041f010c021f010c0600050c041f030c031f010c0700010c0c1f010c0400" + }, + { + "filename": "head-rosebud", + "data": "0x00021c14040c00019415000119010002941300021904941000041906940d00041908940b0005190994090006190a94080005190b94070006190394011d0894060006190394011d08940300011d020006190294021d08940200011d0100011d010007190194021d08940100011d0200041d05190194021d0694041d0300051d03190194021d0494051d0500051d0219041d0294051d0700041d0119011d0123021d0123011d0194041d0900031d0119021d0223021d0194031d0b000c1d0c000c1d0600" + }, + { + "filename": "head-ruler-triangular", + "data": "0x00021c1508019a1300019a014f1200029a014f1100019a034f1000019a044f0f00029a044f0e00019a064f0d00019a074f0c00029a074f0b00019a094f0a00019a034f0100064f0900029a024f0200064f0800019a034f0300064f0700019a034f0400064f0600029a024f0500064f0500019a034f0600064f0400019a104f0300029a094f049a034f0200019a0a4f049a044f0100019a134f" + }, + { + "filename": "head-saguaro", + "data": "0x00031c14040c000479140005790a000479050005790a00047902000279010005790a00047902000279010005790700027901000479020002790100057907000279010004790200017902af057902000279010002790100017901af04790500057902000279010002790300047905000579010003790100027904000379050004790200037901af01790100027902000479020001790100047902000379030002790200047902000179010004790200027904000279020004790200017901af0479020002790400037901000479030001af0479010003790500027901af047904af0479010003790600017901af077902af037901000279090002790323037901af037901af02790a00077901af037901af02790500" + }, + { + "filename": "head-sailboat", + "data": "0x00011c14040d0001021600020201000102130003020100010212000402010002021000020202de0102010002020f00030202de0102010003020d000702010003020c000802010004020a0009020100040209000a020100050207000b020100050206000c020100060204000d020100060203000e02010007021a00188301000183149801830300018301981083019801830500018310980183070010830400" + }, + { + "filename": "head-sandwich", + "data": "0x00041d14030d000188180003e0170002e0011a170003e0100008830188078308000783017d028301880483017d048305000283017d088301880183017d088303000883017d0a83017d048302001883020018e4020018550200016d0655016d0855016d07550100011c186d041c066d081c056d041c0100041c0298051c0398051c0298011c0100011c0400069808230698070012980400" + }, + { + "filename": "head-saturn", + "data": "0x00051c16030b0004e5130008e50f000ce50200023a030005510ee50100023a0200015105000ee505000151040002140de5011404000151040003140ce50114050001510200025503140be502140500015101000255041409e50314060001510355061405e504140700015102550f140800015104550b140151020001e5050001550251055506140255010001510800025502510a5503000151040002e50100045503510755040001510200013a02e50200065503510355050001510200023a050007550351050001510b000455040005510100" + }, + { + "filename": "head-saw", + "data": "0x00091e15020c9710a201000b9710a2020003970100069710a2020002970300059710a2020002970300059710a2020002970300059710a2020002970300059710a202000297030005970ea2010001a202000297030005970ca2010001a20400039701000297012602970ba2010001a20500099703a2025105a2010001a20600099702a2025105a2010001a2100008a20c00" + }, + { + "filename": "head-scorpion", + "data": "0x00031e1403060008e6130008e6130008e6100004e6050003e60f0004e6020003e703e60f0004e6020001e7010002e702e60d0003e6070003e70e0003e6180003e6170003e6180003e6180003e6180003e603000de7080003e6020010e70300039e05e610e703e6019e030004e602e702e802e702e802e702e801e707e6030004e604e702e802e702e804e706e608000ee7010003e6039e" + }, + { + "filename": "head-shark", + "data": "0x00031c14030a0004eb160005eb150005eb140005eb080001eb0b0006eb080001eb08000b43050002eb05000e43040003eb02001143040003eb01001243030004eb1343030003eb1343030003eb104301eb0143040003eb104301eb0143030003eb01001143040002eb02001143040001eb0300034301eb014301eb0243023c0102013c0102013c0102013c040001eb0400024301eb014301eb0243023c0102013c0102013c0102023c09000643093c0400" + }, + { + "filename": "head-shower", + "data": "0x00011c19040b00020d1600020d1300080d0e000c0d0b000e0d0900101f0800081f010b011f030b031f0800101f09000e430a000e430900104308001043080010430700124306001243060012430500144304001443040014430300164302000143010001431000014301000143020004430e0004430100014301000143010001430e0001430100014301000143190001430100014310000143010001430100" + }, + { + "filename": "head-skateboard", + "data": "0x00091e1402030016bf040003bf016a0369016a0abf016a0369016a03bf020001bf011b01bf016a0369016a0abf016a0369016a01bf011b01bf010002bf011b01bf016a0369016a0abf016a0369016a01bf011b04bf011b03bf017c0ebf017c03bf011b04bf011b03bf017c0ebf017c03bf011b04bf011b03bf017c0ebf017c03bf011b04bf011b03bf017c0ebf017c03bf011b04bf011b01bf016a0369016a0abf016a0369016a01bf011b02bf010001bf011b01bf016a0369016a05bf030e02bf016a0369016a01bf011b01bf020003bf016a0369016a0abf016a0369016a03bf040016bf0300" + }, + { + "filename": "head-skeleton-hat", + "data": "0x000519150704000a43050010430200104301002443010010ae020010ae020010ae020010ae020010ae020010ae020010ae020007ae01b001ae01b006ae04000cae060002ae01b001ae016d01ae01b001ae01b001ae01b001ae060003ae01b001ae01b001ae01b001ae01b001ae01b007000bae0300" + }, + { + "filename": "head-skilift", + "data": "0x00011e1403010001230100142301000123010001230800012301000123100001230200152301000123070001231a0001231a0002231900042318000b230c001488060001880a77018809770188050001880a7701880777016601770188050001880a7701880777016601770188050001880a7701880777016601770188050001880a770188097701880500163305001688050016330500063306230a3305001633070012330500" + }, + { + "filename": "head-smile", + "data": "0x00051d140306000424060004240a00082402000824040001240200142402000824020208240202082401021624010202240402102404020324160205241402032401000324120203240200042410020424030004240e020424040006240a0206240500142407000a2402020624090010240c000c240700" + }, + { + "filename": "head-snowglobe", + "data": "0x00051914080600048c0a00038c0151038c0151038c0400018c0151058c0151068c01510200048c0151018c0351028c0151038c0100038c0151018c0197025101970251038c0151028c0151048c025103970251098c025105970251038c0151038c0251039701260197012601970251078c0997088c04970126019701260297088c09970151068c015109970251028c1151010004510411075102000f0802000f080100" + }, + { + "filename": "head-snowmobile", + "data": "0x00071e15050c0001041800010414000305010002041600010502041600010502041600012301040226140003230426080003230600032302260155052605000c23012603550104052603000b23022602550804020002230902022602550804020005020123110202000602032301020b05030001040a020a05030001040200012301050123010501230105012301000e040200" + }, + { + "filename": "head-spaghetti", + "data": "0x00041a1c060c0003840a00038403000184038501840800038401850484028501cf028406000184028501cf018404850284048505000485018404850184058505000f850500015503850255028501cf02550385015504001055040010550300037d0c55027d0300127d0100297d0202017d0102017d0702017d0302017d0102027d0402017d0702017d0302017d0102027d0c02017d0502027d010010020100027d0100017d0e00017d0100027d0100017d0e00017d0100027d0100017d0e00017d0100027d0100017d0e00017d0100027d0100017d0e00017d0100017d0200017d0e00017d0400017d0e00017d0400017d0e00017d0200" + }, + { + "filename": "head-sponge", + "data": "0x0004191408010003290200022902000429030001290222032901220929010001290222092903220229010007290222022903220229010003290222022902220229032202290100032902220a290100102901001029010054290100012902220d2901000129022203290523042903000d290122012902000e290200" + }, + { + "filename": "head-squid", + "data": "0x00011c1a020d00026a1700046a1500036a01ec026a1300056a01ec026a1100076a01ec026a0f000c6a0d000e6a0b00014f0e6a014f0900024f0e6a024f0700024f106a024f0500034f106a034f0300044f106a014f01ec024f0200044f106a024f01ec014f0200044f106a044f0200044f106a044f0300034f106a034f0200014f0200034f0e6a034f0200014f016a014f03000245014f0123010201230102012301020123010201230102014f02450400014f016a014f020003450c4f03450300014f016a014f010014450300014f0145010001450100024501000245060002450100024501000245030003450100014502000145080001450200014502000145040001451300014f01451800014f01451800014f01451800014f0200" + }, + { + "filename": "head-stapler", + "data": "0x00081c140407000d2408001224040016240100172401001724010017240100172405181272010006181172010004180124021811000518122401003018" + }, + { + "filename": "head-star-sparkles", + "data": "0x00021b17050a0002ac10000129020001ac022901ac120001ac022901ac110001ac042901ac030001290100012905000129040001ac042901ac0400012905000329020001ac062901ac020001290100012905000129030001ac062901ac0c0002ac082902ac080002ac0c2902ac040002ac102902ac010001ac142902ac142901ac010002ac102902ac040002ac0c2902ac080001ac0a2901ac0a0001ac0a2901ac06000129020001ac072903ac022901ac080001ac0c2901ac070001ac062902ac062901ac060001ac042902ac020002ac042901ac060001ac022902ac060002ac022901ac070002ac0a0002ac0400" + }, + { + "filename": "head-steak", + "data": "0x00071b160504000e51060002510618033805180251030001510918013808180151020001510918013808180151010001510a180138091802510a180138091802510a180138091802510a180138091802510a180138091802510138091801380918035102380518033801180351051801510100035108380118015101380151041802510200085102380118035104180151050007510238051803510b000a510d0007510400" + }, + { + "filename": "head-sunset", + "data": "0x00031d1403090008491000044901420249014204490c00054901420149024201490142054909000149014201490c4201490142014907000149014201490442012601420226014201260442014901420149050001490142014903420a2603420149014201490400024903420326012801260228012601280326034202490300024903420326082803260342024902000249024203260a2803260242024901000349024202260c28022602420549024202260e2802260242034901420149024202260d2801260242014901420349024202260e28022602420449024202260e2802260242034901420149024202260c2802260242014901420349024202260628020201260528022602420549024202260c2802260242034901000349024202260a280226024203490100" + }, + { + "filename": "head-taco-classic", + "data": "0x00051d14030a00038e0167028e1200038e0167018e0167048e0e00038e0167018e015701670157018e0167028e0167018e0b00018e0267018e0367011102570367038e0a00028e026708500157038e0800018e0167018e015702110150018a0350018a025002110267028e0600028e01670650018a0750038e0600018e01110d50018a02500167018e0500018e015701110150018a0e5001110157018e03000167018e1450018e040001670450018a0c50018a0250026703000111145001110200016701000350018a0d50018a0150018a0250030001671650016703000550018a0550018a0750018a0250010001670300145001670200" + }, + { + "filename": "head-taxi", + "data": "0x00041c170405000ee50a0001e503c7040205c701e5090001e503c7040207c701e5080001e502c7040208c701e5070001e502c7040204c7034303c701e5060001e501c7040204c7014303c7014302c701e5040016e5020016e5020016e5020016e5020016e5020016e5020016e5020002e5011f10e5011f02e50100011f0137141f01370a1f061d091f010008e5061d08e50300020e0500061d0500020e0400020d1000020d0400020d1000020d0200" + }, + { + "filename": "head-thumbsup", + "data": "0x00011a14050a00012b02e5120001e5012b02e5110001e5012b02e51100012b03e5100005e50f0006e50e0006e50e0006e5012b07e5040008e5012b07e5012b0ce5012b07e5012b0ee5012b06e5012b0de5072b01000ae5012b14e5012b08e5012b0be5012b09e5012b0ce5082b010001e5022b05e5012b02e5012b08e5010008e5042b06e5012b01e5040004e5012b03e5012b07e5012b050008e5072b0200" + }, + { + "filename": "head-toaster", + "data": "0x00031a1f0504000e84060002840cd702840500018403d7089903d70184060001840cd701840700018402d7089902d701840600010b0e72010b0500010b0e72010b0500010b0e72010b020d0300010b0e72010b020d0300010b0e72010b0500010b0e72010b0500010b0e72010b0500010b0e72010b0500010b0e72010b0500010b0e72010b0400120d0100021f120d0100011f0100120d0100011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400" + }, + { + "filename": "head-toiletpaper-full", + "data": "0x00071a1605010002ed1102020002ed1102010004ed110204ed110204ed110201ed017c010d01ed110201ed017c010d01ed110201ed017c010d01ed110201ed017c010d01ed110204ed110204ed110204ed1102010002ed027c01ed010201ed010201ed010201ed010201ed010201ed010201ed0102030002ed017c100205000c020a0008020800" + }, + { + "filename": "head-tooth", + "data": "0x00041917060a0005570700045701000257050202570400015704020157030201570502015702000157060203570702015701000157100202571102025711020257110202571102025711020257110201570100015710020157020001570e020157030001570e020157040001570202097c02020157040001570d020157050001570402035704020157060001570302015703000157030201570700015702020157040001570202015708000257060002570300" + }, + { + "filename": "head-toothbrush-fresh", + "data": "0x00021914011000016716000167011c016715000167021c046711000167061c01670d000667021c0102011c01670a000367081c0102011c0167090001670d1c0167090001670d1c016709000102011c0102011c0102011c0102011c0102011c0102011c0102011c010209000f0209000f0209000f0209000f0209000f0201000143010002430100134302000143020013430100024301000543012301460123014601230a430700114307001143" + }, + { + "filename": "head-tornado", + "data": "0x00031c150406000c8109000281017c0281047e057c038106000281027c0b81017c0381050003810f7c03810300168103000b7c0181017c0781060011810900047c0181017c0181017c05810a000c810b000d810a000b810b000b810c00098110000a8108000181080008810600018105000181010001810100017c049c0281017c0681010001810300018101000481067c08810700128106000481080004810500" + }, + { + "filename": "head-trashcan", + "data": "0x00031b1405090005050f000205040001050f0001050200090505001105050008050723010d0700010d08230a0d020006050323030d0505010d04000205031f0205031f0205031f02050100010d02000305031f0205031f0205031f03050200010501000205031f0205031f0205031f02050100010503000205031f0205031f0205031f020505000205031f0205031f0205031f020505000205031f0205031f0205031f020505000205031f0205031f0205031f020505000205031f0205031f0205031f020505000205011f0523021f0205031f020505000205031f0205031f0205031f0205050011050300" + }, + { + "filename": "head-turing", + "data": "0x00041d190315000189070012610189016105000289016101cb01820161018201cb01610282016101cb0182016101cb018201610182018901610400018901940261028201610282016101cb018201610282016102820161018201cb0289030001890194146101890300018901000261018201cb016102820161018201cb0161018201cb01610282016102820161018903000189010002890282016101cb01820161028201610282016101cb0182016101cb018201610189020002890194016101891261018901940100038901610189018201cb01610282016101cb01820161018201cb016102820161018201cb016101890100028901000189016101890282016101cb018201610282016102820161018201cb016102820161018901000289010001890161018912610189010002890100018901610189018201cb016102820161028201610282016101cb01820161028201610189010002890100038902820161018201cb0161018201cb0161018201cb01610282016101cb0182016101890100028901000189146101890100028901000189026102020161020201610202016102020161020201610202016102000289010001890261020201610202016102020161020201610202016102020161018901000289010001891461018901000289010001890194110001940100028901000189020002891100018904000189010002891600018901000194180002891600" + }, + { + "filename": "head-ufo", + "data": "0x00021e15020e00014f1a00034f1a00014f1800064f14000a4f10000e430d000a4301060143020602430c000c43020602430b0012430a0012430a0012430900144308001443080014430800144f0600184f0300054f026d014f026d014f026d014f026d014f026d014f026d044f0100064f026d014f026d014f026d014f026d014f026d014f026d054f0400144f0d000a4f0900" + }, + { + "filename": "head-undead", + "data": "0x00021b16050600027903261100047902000279032607000126030002790300057908000126017902000279020003790b000126017902000279020003790b00027902000279020002790200018003000126050002790200037901000279050001790226040002790300057905000479010001800200027902000579060003790100028001000279020005790700027904000a79040004790500107906000f790200028005000a7904000280070008790a000180030008790d0001800179012301250123012501230279018003000180070003800679038009000e80090001800100038002000280010001800e000180090001800300" + }, + { + "filename": "head-unicorn", + "data": "0x00041b16040b00021c1200011c0300021c060001260b00021c0100021c04000226080003660100051c020003260600031c0366071c032601660400011c0100031c0766011c042602660500031c01200766042603660600011c02200766032604660600032007660226056605000420076601260666060003200e66060003200e6606000320125f01000220023a0e5f0120015f0120015f0100043a035f012001660123016601230166012301660120065f0200033a125f0200033a125f0300023a1600013a1200" + }, + { + "filename": "head-vent", + "data": "0x00081c140433020123010201230102012301020123020201230102012301020123010201230802011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f0802011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f010201230602011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f010201230402011f0102011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f010201230102011f0402011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f010201230602011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f010202010502011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f08020101010201010102010101020101020201010102010101020101010201013502" + }, + { + "filename": "head-void", + "data": "0x00051b14050123020001230200012302000123020001230200012302000123020001232c000123140001232c000123140001232c000123140001232c000123140001232c00012302000123020001230200012302000123020001230200012302000123" + }, + { + "filename": "head-volcano", + "data": "0x00031c15040800081f1000011f0641011f0f00021f0642021f0e00011f014106280141011f0d00021f0341031f0241021f0c00021f0141041f0141021f0141011f0b00021f01410b1f0a00041f010c051f010c031f0900051f010c051f010c041f0800051f010c051f010c041f0700051f010c071f010c041f0600051f010c071f010c041f0500061f010c071f010c051f0400051f010c091f010c041f0300021f020c0f1f010c021f0200021f020c051f010c0c1f01000a1f010c0341010c041f020c091f010c021f010c091f020c031f0200141f0200" + }, + { + "filename": "head-volleyball", + "data": "0x00031b1505090004d30f0001d301ee02d3020202d301ee01d30a0003d301ee02d3020202d301ee03d3070001d301ee03d301ee04d301ee03d301ee01d3050003d301ee02d301ee04d301ee02d301ee03d3040004d30aee02d3010201d3030004d301ee0ad301ee04d3020003d301ee0cd301ee01d3010201d3020003d301ee0cd301ee01d3010201d3010004d301ee0cd301ee01d3010206d301ee0cd301ee02d3010205d301ee0cd301ee02d3010205d301ee0cd301ee04d3010003d301ee0cd301ee04d3010003d301ee0cd301ee03d3020001d3010202d301ee0ad301ee04d3030001d3010202d30aee04d3040003d301ee02d301ee04d301ee02d301ee03d3050001d301ee03d301ee04d301ee03d301ee01d30300" + }, + { + "filename": "head-wall", + "data": "0x00031a15060237041a01830237011a01370f1a0183131a0183131a01830d1a0100128301000237011a0137091a01830237111a0183131a0183131a0183061a0100128301000237041a01830137121a0183131a0183131a01830d1a0100128301000237011a0137091a018302370b1a0337031a0183131a0183131a0183061a" + }, + { + "filename": "head-wallet", + "data": "0x00081d1403020008a30e8c0200029701a308510ec70297012301a308510ec70e9701080d970ba30197010801970a43029701a3057c05a3019701080d9701a3017c03a3017c05a30197010801970a26029701a3017c03a3017c05a3019701080d9701a3027c01a3027c05a30197010801970a98029701a3017c03a3017c05a30197010801970a98029701a3057c01a3034701a3019701080d970ba301970108199701080c97" + }, + { + "filename": "head-wallsafe", + "data": "0x00091d14041a08117e010805240208017e0f08017e010805240208017e0f08017e0808017e0f08017e0108012401080124010801240208017e0f08017e0808017e0f08017e0108012401080124010801240208017e010801a30d08017e0808017e01a3010801a30c08017e0108012401080124010801240208017e010801a30208010201230102012301020123010201230308017e0808117e010801a301080124010801a31a08" + }, + { + "filename": "head-washingmachine", + "data": "0x0003191f0402000fed060002ed017201ed017201ed017401ed017201ed015101ed0155017402ed050002ed017401ed017401ed017201ed017403ed0143017402ed0500037210510200037206510472065102000372045102720475027204510200037203510172087501720351020003720351017208750172035102000372025101720a750172025102000372025101720a750172025102000372025101720a750172025102000372025101720a75017202510200037203510172087501720351020003720351017208750172035102000372045102720475027204510223037201510243035104720651012301000372105101230100037210510123140001231400012314000123140001231400012314000123140001231400012314000123140001231400" + }, + { + "filename": "head-watch", + "data": "0x00041a150802000c0a05000826011e0126021e0226030001260e51012602000126065102780651012602000126035101780651017803510126020001260e51012602000126015101780a51017801510126020001260e5101260100010a01260e510126010a02260e510126020a01260e510126010a02260e5101260100010a0126045101780451017804510126020001260e510126020001260651027806510126020001260e51012603000e2605000c0a0400" + }, + { + "filename": "head-watermelon", + "data": "0x00031b15050400051d1000051d02240e00051d0124011802240d00041d0224012303240b00041d08240a00031d06240123011802240800041d02240123011807240700031d0d240600031d0e240500031d0f240400031d10240300031d11240300021d12240200031d1124011d0200021d1024011d0400021d042401230118012301180624011d0600031d0a24021d0800041d0624021d0d00071d0700" + }, + { + "filename": "head-wave", + "data": "0x00021c1401120004de13000ade0f0002de014a0ade0d0005de024a0243014a02de014a02de0b0002de024a01de024a0143054a02de014a01de090002de024a01de024a01de034a01de0143024a03de090001de034a01de024a01de024a01de064a01de080002de024a01de024a01de034a01de024a0300014a01de080001de034a01de024a01de054a040001de080001de0d4a0d0001de0d4a0c0002de0d4a0c0001de0e4a0b0001de0f4a0b0001de0f4a0a0001de074a0143024a0143034a0143014a0a0001de044a01de024a0143034a0143034a0143014a050001de020001de044a01de044a0143034a0243054a040002de164a0100014a" + }, + { + "filename": "head-weed", + "data": "0x00011d15020d00010f1900020f1900020f0100010f1600040f1000010f0600040f0700010f0800020f0600030f0100010f0400020f0800030f0100010f0200050f0400030f0900040f0200060f0100040f0a00050f0200040f0100050f0b00050f0100040f0100040f0600010f06000d0f0600010f0100020f0100010f03000b0f0500020f0200040f0200130f0300170f0600130f09000f0f1000030f015c030f015c010f1100050f035c030f0e000f0f0b00110f0900020f0f00020f0400" + }, + { + "filename": "head-weight", + "data": "0x00021a140506000127089601950b0001270196072701950b0001270196060001270195070003270d960195040003270396010e0196010e0196020e04960195040003270396020e0296010e05960195040003270396010e0196010e0196010e0196010e03960195040003270396010e0196010e0296020e03960195030003270f960195020003270f960195020003270f960195020003270f960195020003270f960195020003270f960195010003271196019503271196019503270496092704960195032711960195032711960195" + }, + { + "filename": "head-werewolf", + "data": "0x00061c1404030005970700059707000597070005970700059707000597070011260700110707001126070002970e810197070002970e810197060003970e810197050004970e810197040005971181029703000297018101d5018101d50f8102000397018101d5018101d5018104230102012301020323038102000497018101d5018101d502230102062301020223018102000597018101d5018101d50c820300" + }, + { + "filename": "head-whale-alive", + "data": "0x00021e15021100044a1700064a1500084a13000a4a1100064a010e054a0300014a0400014a0600064a010e014a010e054a0200024a0200024a05000f4a01560100064a05000f4a01560200044a07000d4a03560200034a07000c4a04560200054a05000b4a055602000156134a065603000156114a0756030003560e4a0756050005560a4a085605000656084a085607000556014a030e034a085609000356074a08560b000156064a0856100009560900" + }, + { + "filename": "head-whale", + "data": "0x00041a1606080009d50a000cd5070005d5080d060005d5010d097c040005d5010d037c0281017c0281017c0181030005d5010d017c0281017c0281017c0281017c0181020005d5010d0481017c0281017c0281017c0181010005d5010d0581017c0281017c0281017c018106d5010d0581017c0281017c0281017c018106d5010d0581017c0281017c0281017c018106d5010d0581017c0281017c0281017c018106d5010d0481017c0381017c0281017c018106d5010d0381017c0381017c0381017c018103d5010d02d5010d0281017c0381017c0381017c028102d5030d01d502980181017c0281017c0381017c038103d5010d02d50398017c0281017c0281017c0381010006d50398017c0281017c0281017c028108000398110003980b00" + }, + { + "filename": "head-wine", + "data": "0x00051b14053f6f0102156f0102156f0102036f129401190194026f1494026f1494026f1494026f1494026f1494036f1294026f0100016f1294016f0200026f069404190694026f0300036f0c94036f06000e6f0400" + }, + { + "filename": "head-wizardhat", + "data": "0x00041b1404030008eb0e0006eb014604eb0c0001eb020002eb034604eb0b000146030002eb014606eb08000546020004eb014604eb08000346040002eb014601eb014601eb014602eb0700014601000146050002eb014606eb0e000aeb0c0008eb014602eb0c0001eb014605eb034602eb0b0008eb014603eb0b0004eb014607eb0a000deb09000eeb080007eb050e02eb0700125403001654" + }, + { + "filename": "head-zebra", + "data": "0x00061b14060a00010201230a000223035e0102012301020123010202230100035e05000202035e0102012301020123010201230200035e05000223055e0123035e0123045e05000202065e0323055e05000223065e0323055e05000202075e0123065e05000223075e0123065e05000202075e0123065e050002230e5e050002020c5e0623010002230d5e012301020123010201230302025e0102012301020123010201230102035e09230d5e052303020d5e0523" + } + ], + "glasses": [ + { + "filename": "glasses-hip-rose", + "data": "0x000b1710070300062001000620030001200202022301200100012002020223052002020223032002020223052002020223032002020223022002000120020202230120010001200202022301200300062001000620" + }, + { + "filename": "glasses-square-black-eyes-red", + "data": "0x000b17100703000623010006230300012302020264012301000123020202640523020202640323020202640223020001230202026401230100012302020264022302000123020202640123010001230202026401230300062301000623" + }, + { + "filename": "glasses-square-black-rgb", + "data": "0x000b1710070300062301000623030003230164022301000323016413230200012301650223015a01230100012301650223015a022302000623010006230300062301000623" + }, + { + "filename": "glasses-square-black", + "data": "0x000b171007030006230100062303000123020203230100012302020723020205230202042302000123020203230100012302020423020001230202032301000123020203230300062301000623" + }, + { + "filename": "glasses-square-blue-med-saturated", + "data": "0x000b17100703000643010006430300014302020223014301000143020202230543020202230343020202230243020001430202022301430100014302020223024302000143020202230143010001430202022301430300064301000643" + }, + { + "filename": "glasses-square-blue", + "data": "0x000b17100703000607010006070300010702020223010701000107020202230507020202230307020202230207020001070202022301070100010702020223020702000107020202230107010001070202022301070300060701000607" + }, + { + "filename": "glasses-square-frog-green", + "data": "0x000b171007030006bf010006bf030001bf0202022301bf010001bf0202022305bf0202022303bf0202022302bf020001bf0202022301bf010001bf0202022302bf020001bf0202022301bf010001bf0202022301bf030006bf010006bf" + }, + { + "filename": "glasses-square-fullblack", + "data": "0x000b1710070300062301000623030004230102012301000423010208230102062301020223020006230100072302000623010006230300062301000623" + }, + { + "filename": "glasses-square-green-blue-multi", + "data": "0x000b1710070300060f0100068b0300010f02020223010f0100018b02020223018b034a010f02020223010f014a018b02020223028b0200010f02020223010f0100018b02020223028b0200010f02020223010f0100018b02020223018b0300060f0100068b" + }, + { + "filename": "glasses-square-grey-light", + "data": "0x000b171007030006c7010006c7030001c70202022301c7010001c70202022305c70202022303c70202022302c7020001c70202022301c7010001c70202022302c7020001c70202022301c7010001c70202022301c7030006c7010006c7" + }, + { + "filename": "glasses-square-guava", + "data": "0x000b17100703000637010006370300013702020223013701000137020202230537020202230337020202230237020001370202022301370100013702020223023702000137020202230137010001370202022301370300063701000637" + }, + { + "filename": "glasses-square-honey", + "data": "0x000b171007030006dd010006dd030001dd0202022301dd010001dd0202022305dd0202022303dd0202022302dd020001dd0202022301dd010001dd0202022302dd020001dd0202022301dd010001dd0202022301dd030006dd010006dd" + }, + { + "filename": "glasses-square-magenta", + "data": "0x000b17100703000609010006090300010902020223010901000109020202230509020202230309020202230209020001090202022301090100010902020223020902000109020202230109010001090202022301090300060901000609" + }, + { + "filename": "glasses-square-orange", + "data": "0x000b17100703000614010006140300011402020223011401000114020202230514020202230314020202230214020001140202022301140100011402020223021402000114020202230114010001140202022301140300061401000614" + }, + { + "filename": "glasses-square-pink-purple-multi", + "data": "0x000b171007030006200100069a030001200202022301200100019a02020223019a036e0120020202230120016e019a02020223029a020001200202022301200100019a02020223029a020001200202022301200100019a02020223019a030006200100069a" + }, + { + "filename": "glasses-square-red", + "data": "0x000b17100703000624010006240300012402020223012401000124020202230524020202230324020202230224020001240202022301240100012402020223022402000124020202230124010001240202022301240300062401000624" + }, + { + "filename": "glasses-square-smoke", + "data": "0x000b17100703000659010006590300015902660223015901000159026602230559026602230359026602230259020001590266022301590100015902660223025902000159026602230159010001590266022301590300065901000659" + }, + { + "filename": "glasses-square-teal", + "data": "0x000b1710070300061c0100061c0300011c02020223011c0100011c02020223051c02020223031c02020223021c0200011c02020223011c0100011c02020223021c0200011c02020223011c0100011c02020223011c0300061c0100061c" + }, + { + "filename": "glasses-square-watermelon", + "data": "0x000b17100703000637010006370300013702020223013701000137020202230537020202230337020202230237020001370202022301370100013702020223023702000137020202230137010001370202022301370300063701000637" + }, + { + "filename": "glasses-square-yellow-orange-multi", + "data": "0x000b17100703000626010006130300012602020223012601000113020202230113034201260202022301260142011302020223011301260200012602020223012601000113020202230113012602000126020202230126010001130202022301130300062601000613" + }, + { + "filename": "glasses-square-yellow-saturated", + "data": "0x000b17100703000628010006280300012802020223012801000128020202230528020202230328020202230228020001280202022301280100012802020223022802000128020202230128010001280202022301280300062801000628" + } + ] + } +} \ No newline at end of file diff --git a/packages/nouns-contracts/tasks/populate-descriptor.ts b/packages/nouns-contracts/tasks/populate-descriptor.ts index 8de141b295..5fee9ae3df 100644 --- a/packages/nouns-contracts/tasks/populate-descriptor.ts +++ b/packages/nouns-contracts/tasks/populate-descriptor.ts @@ -1,5 +1,5 @@ import { task, types } from 'hardhat/config'; -import ImageData from '../files/image-data.json'; +import ImageData from '../files/image-data_v2.json'; import { dataToDescriptorInput } from './utils'; task('populate-descriptor', 'Populates the descriptor with color palettes and Noun parts') diff --git a/packages/nouns-contracts/test/utils.ts b/packages/nouns-contracts/test/utils.ts index 36fabe1479..528461e7a9 100644 --- a/packages/nouns-contracts/test/utils.ts +++ b/packages/nouns-contracts/test/utils.ts @@ -20,6 +20,7 @@ import { NounsDAOExecutor, } from '../typechain'; import ImageData from '../files/image-data.json'; +import ImageDataV2 from '../files/image-data_v2.json'; import { Block } from '@ethersproject/abstract-provider'; import { deflateRawSync } from 'zlib'; import { chunkArray } from '../utils'; @@ -132,7 +133,7 @@ export const populateDescriptor = async (nounsDescriptor: NounsDescriptor): Prom }; export const populateDescriptorV2 = async (nounsDescriptor: NounsDescriptorV2): Promise => { - const { bgcolors, palette, images } = ImageData; + const { bgcolors, palette, images } = ImageDataV2; const { bodies, accessories, heads, glasses } = images; const { @@ -156,15 +157,12 @@ export const populateDescriptorV2 = async (nounsDescriptor: NounsDescriptorV2): itemCount: glassesCount, } = dataToDescriptorInput(glasses.map(({ data }) => data)); - // Split up head and accessory population due to high gas usage - await Promise.all([ - nounsDescriptor.addManyBackgrounds(bgcolors), - nounsDescriptor.setPalette(0, `0x000000${palette.join('')}`), - nounsDescriptor.addBodies(bodiesCompressed, bodiesLength, bodiesCount), - nounsDescriptor.addAccessories(accessoriesCompressed, accessoriesLength, accessoriesCount), - nounsDescriptor.addHeads(headsCompressed, headsLength, headsCount), - nounsDescriptor.addGlasses(glassesCompressed, glassesLength, glassesCount), - ]); + await nounsDescriptor.addManyBackgrounds(bgcolors); + await nounsDescriptor.setPalette(0, `0x000000${palette.join('')}`); + await nounsDescriptor.addBodies(bodiesCompressed, bodiesLength, bodiesCount); + await nounsDescriptor.addAccessories(accessoriesCompressed, accessoriesLength, accessoriesCount); + await nounsDescriptor.addHeads(headsCompressed, headsLength, headsCount); + await nounsDescriptor.addGlasses(glassesCompressed, glassesLength, glassesCount); }; export const deployGovAndToken = async ( diff --git a/packages/nouns-sdk/src/image/image2.ts b/packages/nouns-sdk/src/image/image2.ts index 45cda225ed..50f9e6d26d 100644 --- a/packages/nouns-sdk/src/image/image2.ts +++ b/packages/nouns-sdk/src/image/image2.ts @@ -91,19 +91,14 @@ export class Image2 { } calcBounds(): ImageBounds { - let top = 0; - while (top < this.height - 1 && this._isTransparentRow(top)) { - top++; - } - let bottom = this.height - 1; while (bottom > 0 && this._isTransparentRow(bottom)) { bottom--; } - let left = 0; - while (left < this.width - 1 && this._isTransparentColumn(left)) { - left++; + let top = 0; + while (top < bottom && this._isTransparentRow(top)) { + top++; } let right = this.width - 1; @@ -111,6 +106,11 @@ export class Image2 { right--; } + let left = 0; + while (left < right && this._isTransparentColumn(left)) { + left++; + } + return { top: top, bottom: bottom, diff --git a/packages/nouns-sdk/src/image/png-collection-encoder.ts b/packages/nouns-sdk/src/image/png-collection-encoder.ts index fe4ddc93a8..cead6174a3 100644 --- a/packages/nouns-sdk/src/image/png-collection-encoder.ts +++ b/packages/nouns-sdk/src/image/png-collection-encoder.ts @@ -1,6 +1,6 @@ import { promises as fs } from 'fs'; import { EncodedImage, IEncoder, ImageData, PngImage } from './types'; -import { Image } from './image'; +import { Image2 } from './image2'; /** * A class used to convert PNG images into the following RLE format: @@ -38,8 +38,8 @@ export class PNGCollectionEncoder implements IEncoder { * @param folder An optional containing folder name */ public encodeImage(name: string, png: PngImage, folder?: string): string { - const image = new Image(png.width, png.height); - const rle = image.toRLE((x, y) => png.rgbaAt(x, y), this._colors); + const image = new Image2(png.width, png.height, png.rgbaAt); + const rle = image.toRLE(this._colors); this._images.set(name, rle); diff --git a/packages/nouns-sdk/test/image2.test.ts b/packages/nouns-sdk/test/image2.test.ts index 901de557c0..9814a9c9bd 100644 --- a/packages/nouns-sdk/test/image2.test.ts +++ b/packages/nouns-sdk/test/image2.test.ts @@ -53,6 +53,16 @@ describe('Image2', () => { expect(svg1).to.be.equal(svg2); } }); + + it('builds empty image correctly', async () => { + const { rle: rle2, colors: colors2 } = await encodeMultiLineRLE( + join(__dirname, './lib/images/empty.png'), + ); + const svg2 = buildSVG([{ data: rle2 }], Array.from(colors2.keys()), 'ffffff'); + expect(svg2).to.eq( + '', + ); + }); }); describe('Multiline RLE encoding', async () => { diff --git a/packages/nouns-sdk/test/lib/data/expected.ts b/packages/nouns-sdk/test/lib/data/expected.ts index 30c4dd55be..1725f6d172 100644 --- a/packages/nouns-sdk/test/lib/data/expected.ts +++ b/packages/nouns-sdk/test/lib/data/expected.ts @@ -2,10 +2,10 @@ export const expected = { palette: ['', 'ffffff', 'f3322c', 'f9e8dd', 'bd2d24'], images: { root: [ - { filename: 'empty', data: '0x0000000000' }, + { filename: 'empty', data: '0x00000100000100' }, { filename: 'head-cone', - data: '0x000319140708000202080008000202080007000402070007000402070007000402070006000602060006000603060006000603060005000803050005000802050005000802050004000a02040004000a03040004000a03040003000c03030003000c02030004020c0402021202', + data: '0x000319140708000202100002020f0004020e0004020e0004020d0006020c0006030c0006030b0008030a0008020a00080209000a0208000a0308000a0307000c0306000c02030004020c041402', }, ], }, From 044887bb5b6500da16ffa7cc75fd2a6d6764e28c Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Sat, 2 Jul 2022 10:58:22 +0200 Subject: [PATCH 048/116] update test to use mutliline rle encoded data --- packages/nouns-contracts/test/descriptorV2.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nouns-contracts/test/descriptorV2.test.ts b/packages/nouns-contracts/test/descriptorV2.test.ts index b594c72798..834d18ec78 100644 --- a/packages/nouns-contracts/test/descriptorV2.test.ts +++ b/packages/nouns-contracts/test/descriptorV2.test.ts @@ -1,7 +1,7 @@ import chai from 'chai'; import { solidity } from 'ethereum-waffle'; import { NounsDescriptorV2 } from '../typechain'; -import ImageData from '../files/image-data.json'; +import ImageData from '../files/image-data_v2.json'; import { LongestPart } from './types'; import { deployNounsDescriptorV2, populateDescriptorV2 } from './utils'; import { ethers } from 'hardhat'; From 7552ed2776a2a6c172f4073fc2e92e9590caeadf Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Sat, 2 Jul 2022 11:00:16 +0200 Subject: [PATCH 049/116] update yarn.lock --- yarn.lock | 131 +++++++++++------------------------------------------- 1 file changed, 26 insertions(+), 105 deletions(-) diff --git a/yarn.lock b/yarn.lock index 0a8ea75bb6..553523081a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2537,31 +2537,6 @@ unique-filename "^1.1.1" which "^1.3.1" -"@float-capital/solidity-coverage@^0.7.17": - version "0.7.17" - resolved "https://registry.yarnpkg.com/@float-capital/solidity-coverage/-/solidity-coverage-0.7.17.tgz#454eb53b00dd5c80d7b253db1513ccd9cfb68424" - integrity sha512-LeG+GcmrGxLWmSn5KReAp3Ii+8v5e0HXb6/ZQJPO4zNG8jpE96QRFys+NBq4A8VVgzdUyFj5ipnR5TiGyhuUgw== - dependencies: - "@solidity-parser/parser" "^0.12.0" - "@truffle/provider" "^0.2.24" - chalk "^2.4.2" - death "^1.1.0" - detect-port "^1.3.0" - fs-extra "^8.1.0" - ganache-cli "^6.11.0" - ghost-testrpc "^0.0.2" - global-modules "^2.0.0" - globby "^10.0.1" - jsonschema "^1.2.4" - lodash "^4.17.15" - node-emoji "^1.10.0" - pify "^4.0.1" - recursive-readdir "^2.2.2" - sc-istanbul "^0.4.5" - semver "^7.3.4" - shelljs "^0.8.3" - web3-utils "^1.3.0" - "@fortawesome/fontawesome-common-types@^0.2.35": version "0.2.36" resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.36.tgz#b44e52db3b6b20523e0c57ef8c42d315532cb903" @@ -4308,11 +4283,6 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@solidity-parser/parser@^0.12.0": - version "0.12.2" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.12.2.tgz#1afad367cb29a2ed8cdd4a3a62701c2821fb578f" - integrity sha512-d7VS7PxgMosm5NyaiyDJRNID5pK4AWj1l64Dbz0147hJgy5k2C0/ZiKK/9u5c5K+HRUVHmp+RMvGEjGh84oA5Q== - "@solidity-parser/parser@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.14.0.tgz#d51f074efb0acce0e953ec48133561ed710cebc0" @@ -12127,15 +12097,6 @@ fuzzaldrin@^2.1.0: resolved "https://registry.yarnpkg.com/fuzzaldrin/-/fuzzaldrin-2.1.0.tgz#90204c3e2fdaa6941bb28d16645d418063a90e9b" integrity sha1-kCBMPi/appQbso0WZF1BgGOpDps= -ganache-cli@^6.11.0: - version "6.12.2" - resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.12.2.tgz#c0920f7db0d4ac062ffe2375cb004089806f627a" - integrity sha512-bnmwnJDBDsOWBUP8E/BExWf85TsdDEFelQSzihSJm9VChVO1SHp94YXLP5BlA4j/OTxp0wR4R1Tje9OHOuAJVw== - dependencies: - ethereumjs-util "6.2.1" - source-map-support "0.5.12" - yargs "13.2.4" - ganache-core@^2.13.2, ganache-core@^2.6.0: version "2.13.2" resolved "https://registry.yarnpkg.com/ganache-core/-/ganache-core-2.13.2.tgz#27e6fc5417c10e6e76e2e646671869d7665814a3" @@ -13531,11 +13492,6 @@ invert-kv@^1.0.0: resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= -invert-kv@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" - integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== - io-ts@1.10.4: version "1.10.4" resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" @@ -15338,13 +15294,6 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" -lcid@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" - integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== - dependencies: - invert-kv "^2.0.0" - lerna@^3.22.1: version "3.22.1" resolved "https://registry.yarnpkg.com/lerna/-/lerna-3.22.1.tgz#82027ac3da9c627fd8bf02ccfeff806a98e65b62" @@ -16121,13 +16070,6 @@ makeerror@1.0.12: dependencies: tmpl "1.0.5" -map-age-cleaner@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== - dependencies: - p-defer "^1.0.0" - map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" @@ -16241,15 +16183,6 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= -mem@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" - integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== - dependencies: - map-age-cleaner "^0.1.1" - mimic-fn "^2.0.0" - p-is-promise "^2.0.0" - memdown@^1.0.0: version "1.4.1" resolved "https://registry.yarnpkg.com/memdown/-/memdown-1.4.1.tgz#b4e4e192174664ffbae41361aa500f3119efe215" @@ -16707,7 +16640,7 @@ mimic-fn@^1.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== -mimic-fn@^2.0.0, mimic-fn@^2.1.0: +mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== @@ -18057,15 +17990,6 @@ os-locale@^1.4.0: dependencies: lcid "^1.0.0" -os-locale@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" - integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== - dependencies: - execa "^1.0.0" - lcid "^2.0.0" - mem "^4.0.0" - os-name@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/os-name/-/os-name-3.1.0.tgz#dec19d966296e1cd62d701a5a66ee1ddeae70801" @@ -18097,11 +18021,6 @@ p-cancelable@^1.0.0: resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= - p-each-series@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a" @@ -18117,11 +18036,6 @@ p-finally@^2.0.0: resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== -p-is-promise@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== - p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -21779,6 +21693,30 @@ solidity-comments-extractor@^0.0.7: resolved "https://registry.yarnpkg.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz#99d8f1361438f84019795d928b931f4e5c39ca19" integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw== +solidity-coverage@0.7.21: + version "0.7.21" + resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.7.21.tgz#20c5615a3a543086b243c2ca36e2951a75316b40" + integrity sha512-O8nuzJ9yXiKUx3NdzVvHrUW0DxoNVcGzq/I7NzewNO9EZE3wYAQ4l8BwcnV64r4aC/HB6Vnw/q2sF0BQHv/3fg== + dependencies: + "@solidity-parser/parser" "^0.14.0" + "@truffle/provider" "^0.2.24" + chalk "^2.4.2" + death "^1.1.0" + detect-port "^1.3.0" + fs-extra "^8.1.0" + ghost-testrpc "^0.0.2" + global-modules "^2.0.0" + globby "^10.0.1" + jsonschema "^1.2.4" + lodash "^4.17.15" + node-emoji "^1.10.0" + pify "^4.0.1" + recursive-readdir "^2.2.2" + sc-istanbul "^0.4.5" + semver "^7.3.4" + shelljs "^0.8.3" + web3-utils "^1.3.0" + sort-keys@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" @@ -25283,7 +25221,7 @@ yaml@^1.10.0, yaml@^1.10.2, yaml@^1.5.1, yaml@^1.7.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yargs-parser@13.1.2, yargs-parser@^13.1.0, yargs-parser@^13.1.2: +yargs-parser@13.1.2, yargs-parser@^13.1.2: version "13.1.2" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== @@ -25352,23 +25290,6 @@ yargs-unparser@2.0.0: flat "^5.0.2" is-plain-obj "^2.1.0" -yargs@13.2.4: - version "13.2.4" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" - integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== - dependencies: - cliui "^5.0.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - os-locale "^3.1.0" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.0" - yargs@13.3.2, yargs@^13.2.4, yargs@^13.3.0, yargs@^13.3.2: version "13.3.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" From 59d689f93dc757012e74a5b96b3d82b56f962a30 Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Sat, 2 Jul 2022 12:14:27 +0200 Subject: [PATCH 050/116] add tests comparing descriptor v1 and descriptor v2 --- .github/workflows/contracts.yaml | 2 +- .../tasks/descriptor-art-to-console.ts | 37 +++++++- .../tasks/descriptor-v1-export-abi.ts | 34 +++++++ packages/nouns-contracts/tasks/index.ts | 1 + .../test/foundry/DescriptorUpgrade.t.sol | 56 +++++++++--- .../files/descriptor_v1/image-data.abi | 1 + .../files/descriptor_v2/accessoriesPage.abi | 1 + .../files/descriptor_v2/bodiesPage.abi | 1 + .../files/descriptor_v2/glassesPage.abi | 1 + .../foundry/files/descriptor_v2/headsPage.abi | 1 + .../descriptor_v2/paletteAndBackgrounds.abi | 1 + .../foundry/helpers/DescriptorHelpers.sol | 90 +++++++++++-------- .../nouns-contracts/test/write-to-file.sh | 10 +++ 13 files changed, 185 insertions(+), 51 deletions(-) create mode 100644 packages/nouns-contracts/tasks/descriptor-v1-export-abi.ts create mode 100644 packages/nouns-contracts/test/foundry/files/descriptor_v1/image-data.abi create mode 100644 packages/nouns-contracts/test/foundry/files/descriptor_v2/accessoriesPage.abi create mode 100644 packages/nouns-contracts/test/foundry/files/descriptor_v2/bodiesPage.abi create mode 100644 packages/nouns-contracts/test/foundry/files/descriptor_v2/glassesPage.abi create mode 100644 packages/nouns-contracts/test/foundry/files/descriptor_v2/headsPage.abi create mode 100644 packages/nouns-contracts/test/foundry/files/descriptor_v2/paletteAndBackgrounds.abi create mode 100755 packages/nouns-contracts/test/write-to-file.sh diff --git a/.github/workflows/contracts.yaml b/.github/workflows/contracts.yaml index a885d8631c..a8cd1c1f77 100644 --- a/.github/workflows/contracts.yaml +++ b/.github/workflows/contracts.yaml @@ -50,4 +50,4 @@ jobs: - name: Run Forge tests run: | cd packages/nouns-contracts - forge test -vvv + forge test -vvv --ffi diff --git a/packages/nouns-contracts/tasks/descriptor-art-to-console.ts b/packages/nouns-contracts/tasks/descriptor-art-to-console.ts index 502fb9da17..db0176f0cf 100644 --- a/packages/nouns-contracts/tasks/descriptor-art-to-console.ts +++ b/packages/nouns-contracts/tasks/descriptor-art-to-console.ts @@ -1,6 +1,21 @@ +import { writeFileSync } from 'fs'; import { task, types } from 'hardhat/config'; -import ImageData from '../files/image-data.json'; +import ImageData from '../files/image-data_v2.json'; import { dataToDescriptorInput } from './utils'; +import path from 'path'; +import { ethers } from 'ethers'; + +const saveToFileAbiEncoded = ( + filepath: string, + traitPage: { encodedCompressed: string; originalLength: number; itemCount: number }, +) => { + const abiEncoded = ethers.utils.defaultAbiCoder.encode( + ['bytes', 'uint80', 'uint16'], + [traitPage.encodedCompressed, traitPage.originalLength, traitPage.itemCount], + ); + writeFileSync(filepath, abiEncoded); + console.log(`Saved traitPage to ${filepath}`); +}; task( 'descriptor-art-to-console', @@ -13,7 +28,12 @@ task( types.int, ) .addOptionalParam('start', 'The index at which to start the image slice', undefined, types.int) - .setAction(async ({ count, start }, { ethers }) => { + .addOptionalParam( + 'exportPath', + 'Where to save abi encoded files to be used in forge tests', + path.join(__dirname, '../test/foundry/files/descriptor_v2/'), + ) + .setAction(async ({ count, start, exportPath }, { ethers }) => { const { bgcolors, palette, images } = ImageData; let { bodies, accessories, heads, glasses } = images; @@ -32,22 +52,35 @@ task( const glassesPage = dataToDescriptorInput(glasses.map(({ data }) => data)); const paletteValue = `0x000000${palette.join('')}`; + writeFileSync( + path.join(exportPath, 'paletteAndBackgrounds.abi'), + ethers.utils.defaultAbiCoder.encode(['bytes', 'string[]'], [paletteValue, bgcolors]), + ); + console.log('=== PALETTE ===\n'); console.log(`paletteValue: '${paletteValue}'\n`); console.log('=== BODIES ===\n'); console.log(`bodiesCompressed: '${bodiesPage.encodedCompressed}'\n`); console.log(`bodiesLength: ${bodiesPage.originalLength}\n`); + console.log(`bodies count: ${bodiesPage.itemCount}`); + saveToFileAbiEncoded(path.join(exportPath, 'bodiesPage.abi'), bodiesPage); console.log('=== ACCESSORIES ===\n'); console.log(`accessoriesCompressed: '${accessoriesPage.encodedCompressed}'\n`); console.log(`accessoriesLength: ${accessoriesPage.originalLength}\n`); + console.log(`accessories count: ${accessoriesPage.itemCount}`); + saveToFileAbiEncoded(path.join(exportPath, 'accessoriesPage.abi'), accessoriesPage); console.log('=== HEADS ===\n'); console.log(`headsCompressed: '${headsPage.encodedCompressed}'\n`); console.log(`headsLength: ${headsPage.originalLength}\n`); + console.log(`heads count: ${headsPage.itemCount}`); + saveToFileAbiEncoded(path.join(exportPath, 'headsPage.abi'), headsPage); console.log('=== GLASSES ===\n'); console.log(`glassesCompressed: '${glassesPage.encodedCompressed}'\n`); console.log(`glassesLength: ${glassesPage.originalLength}\n`); + console.log(`glasses count: ${glassesPage.itemCount}\n`); + saveToFileAbiEncoded(path.join(exportPath, 'glassesPage.abi'), glassesPage); }); diff --git a/packages/nouns-contracts/tasks/descriptor-v1-export-abi.ts b/packages/nouns-contracts/tasks/descriptor-v1-export-abi.ts new file mode 100644 index 0000000000..269c351c4e --- /dev/null +++ b/packages/nouns-contracts/tasks/descriptor-v1-export-abi.ts @@ -0,0 +1,34 @@ +import { writeFileSync } from 'fs'; +import { task, types } from 'hardhat/config'; +import path from 'path'; +import ImageData from '../files/image-data.json'; + +task( + 'descriptor-v1-export-abi', + 'Exports the image-data to abi files to be able to load from forge tests', +) + .addOptionalParam( + 'exportPath', + 'Where to save abi encoded files to be used in forge tests', + path.join(__dirname, '../test/foundry/files/descriptor_v1/'), + ) + .setAction(async ({ exportPath }, { ethers }) => { + const { bgcolors, palette, images } = ImageData; + let { bodies, accessories, heads, glasses } = images; + + const abiEncoded = ethers.utils.defaultAbiCoder.encode( + ['string[]', 'string[]', 'bytes[]', 'bytes[]', 'bytes[]', 'bytes[]'], + [ + bgcolors, + palette, + bodies.map(({ data }) => data), + accessories.map(({ data }) => data), + heads.map(({ data }) => data), + glasses.map(({ data }) => data), + ], + ); + + const filepath = path.join(exportPath, 'image-data.abi'); + writeFileSync(filepath, abiEncoded); + console.log(`Saved image-data to ${filepath}`); + }); diff --git a/packages/nouns-contracts/tasks/index.ts b/packages/nouns-contracts/tasks/index.ts index f2276f2451..8ae20017b5 100644 --- a/packages/nouns-contracts/tasks/index.ts +++ b/packages/nouns-contracts/tasks/index.ts @@ -10,3 +10,4 @@ export * from './run-local'; export * from './verify-etherscan'; export * from './update-configs'; export * from './descriptor-art-to-console'; +export * from './descriptor-v1-export-abi'; diff --git a/packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol b/packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol index 97c0e9cf35..a2dcdaea69 100644 --- a/packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol +++ b/packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol @@ -8,33 +8,67 @@ import { NounsDescriptor } from '../../contracts/NounsDescriptor.sol'; import { NounsDescriptorV2 } from '../../contracts/NounsDescriptorV2.sol'; import { NounsSeeder } from '../../contracts/NounsSeeder.sol'; import { IProxyRegistry } from '../../contracts/external/opensea/IProxyRegistry.sol'; +import { INounsSeeder } from '../../contracts/interfaces/INounsSeeder.sol'; +import { Base64 } from 'base64-sol/base64.sol'; contract DescriptorUpgradeTest is Test, DeployUtils { NounsToken nounsToken; + address minter = address(2); + NounsDescriptor descriptor; + NounsDescriptorV2 descriptorV2; function setUp() public { IProxyRegistry proxyRegistry = IProxyRegistry(address(0)); address noundersDAO = address(1); - address minter = address(2); - NounsDescriptor descriptor = new NounsDescriptor(); + descriptor = new NounsDescriptor(); _populateDescriptor(descriptor); nounsToken = new NounsToken(noundersDAO, minter, descriptor, new NounsSeeder(), proxyRegistry); - vm.prank(minter); - nounsToken.mint(); + descriptorV2 = _deployAndPopulateV2(); } function testUpgradeToV2MaintainsTokenURI() public { - string memory tokenURIwithV1 = nounsToken.tokenURI(1); + for (uint256 i = 0; i < 10; i++) { + vm.prank(minter); + nounsToken.mint(); + } - NounsDescriptorV2 descriptorV2 = _deployAndPopulateV2(); - nounsToken.setDescriptor(descriptorV2); + for (uint256 i = 0; i < 10; i++) { + nounsToken.setDescriptor(descriptor); + string memory tokenURIwithV1 = nounsToken.tokenURI(1); - string memory tokenURIwithV2 = nounsToken.tokenURI(1); + nounsToken.setDescriptor(descriptorV2); + string memory tokenURIwithV2 = nounsToken.tokenURI(1); - // both _populateDescriptor and _populateDescriptorV2 are hard-coded to populate - // with the first item of each type found in image-data.json. - assertEq(tokenURIwithV2, tokenURIwithV1); + // both _populateDescriptor and _populateDescriptorV2 are hard-coded to populate + // with the first item of each type found in image-data.json. + assertEq(tokenURIwithV2, tokenURIwithV1); + } + } + + /// @dev exports and html file with svgs to inspect manually. quite slow, so ignored by default + function ignore_testSaveHtmlFileWithSvgs() public { + NounsDescriptorV2 d = _deployAndPopulateV2(); + uint256 max = d.headCount(); + for (uint256 i = 0; i < max; i++) { + string memory svg = d.generateSVGImage( + INounsSeeder.Seed({ + background: uint48(i % d.backgroundCount()), + body: uint48(i % d.bodyCount()), + accessory: uint48(i % d.accessoryCount()), + head: uint48(i % d.headCount()), + glasses: uint48(i % d.glassesCount()) + }) + ); + + string memory img = string.concat('\n'); + + string[] memory inputs = new string[](3); + inputs[0] = './test/write-to-file.sh'; + inputs[1] = 'svgs.html'; + inputs[2] = img; + vm.ffi(inputs); + } } } diff --git a/packages/nouns-contracts/test/foundry/files/descriptor_v1/image-data.abi b/packages/nouns-contracts/test/foundry/files/descriptor_v1/image-data.abi new file mode 100644 index 0000000000..8ee4c4c451 --- /dev/null +++ b/packages/nouns-contracts/test/foundry/files/descriptor_v1/image-data.abi @@ -0,0 +1 @@ +0x00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000005ba00000000000000000000000000000000000000000000000000000000000006ac0000000000000000000000000000000000000000000000000000000000000b860000000000000000000000000000000000000000000000000000000000001ba80000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000664356437653100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006653164376435000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000001e200000000000000000000000000000000000000000000000000000000000001e600000000000000000000000000000000000000000000000000000000000001ea00000000000000000000000000000000000000000000000000000000000001ee00000000000000000000000000000000000000000000000000000000000001f200000000000000000000000000000000000000000000000000000000000001f600000000000000000000000000000000000000000000000000000000000001fa00000000000000000000000000000000000000000000000000000000000001fe00000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000000000000000000000206000000000000000000000000000000000000000000000000000000000000020a000000000000000000000000000000000000000000000000000000000000020e00000000000000000000000000000000000000000000000000000000000002120000000000000000000000000000000000000000000000000000000000000216000000000000000000000000000000000000000000000000000000000000021a000000000000000000000000000000000000000000000000000000000000021e00000000000000000000000000000000000000000000000000000000000002220000000000000000000000000000000000000000000000000000000000000226000000000000000000000000000000000000000000000000000000000000022a000000000000000000000000000000000000000000000000000000000000022e00000000000000000000000000000000000000000000000000000000000002320000000000000000000000000000000000000000000000000000000000000236000000000000000000000000000000000000000000000000000000000000023a000000000000000000000000000000000000000000000000000000000000023e00000000000000000000000000000000000000000000000000000000000002420000000000000000000000000000000000000000000000000000000000000246000000000000000000000000000000000000000000000000000000000000024a000000000000000000000000000000000000000000000000000000000000024e00000000000000000000000000000000000000000000000000000000000002520000000000000000000000000000000000000000000000000000000000000256000000000000000000000000000000000000000000000000000000000000025a000000000000000000000000000000000000000000000000000000000000025e00000000000000000000000000000000000000000000000000000000000002620000000000000000000000000000000000000000000000000000000000000266000000000000000000000000000000000000000000000000000000000000026a000000000000000000000000000000000000000000000000000000000000026e00000000000000000000000000000000000000000000000000000000000002720000000000000000000000000000000000000000000000000000000000000276000000000000000000000000000000000000000000000000000000000000027a000000000000000000000000000000000000000000000000000000000000027e00000000000000000000000000000000000000000000000000000000000002820000000000000000000000000000000000000000000000000000000000000286000000000000000000000000000000000000000000000000000000000000028a000000000000000000000000000000000000000000000000000000000000028e00000000000000000000000000000000000000000000000000000000000002920000000000000000000000000000000000000000000000000000000000000296000000000000000000000000000000000000000000000000000000000000029a000000000000000000000000000000000000000000000000000000000000029e00000000000000000000000000000000000000000000000000000000000002a200000000000000000000000000000000000000000000000000000000000002a600000000000000000000000000000000000000000000000000000000000002aa00000000000000000000000000000000000000000000000000000000000002ae00000000000000000000000000000000000000000000000000000000000002b200000000000000000000000000000000000000000000000000000000000002b600000000000000000000000000000000000000000000000000000000000002ba00000000000000000000000000000000000000000000000000000000000002be00000000000000000000000000000000000000000000000000000000000002c200000000000000000000000000000000000000000000000000000000000002c600000000000000000000000000000000000000000000000000000000000002ca00000000000000000000000000000000000000000000000000000000000002ce00000000000000000000000000000000000000000000000000000000000002d200000000000000000000000000000000000000000000000000000000000002d600000000000000000000000000000000000000000000000000000000000002da00000000000000000000000000000000000000000000000000000000000002de00000000000000000000000000000000000000000000000000000000000002e200000000000000000000000000000000000000000000000000000000000002e600000000000000000000000000000000000000000000000000000000000002ea00000000000000000000000000000000000000000000000000000000000002ee00000000000000000000000000000000000000000000000000000000000002f200000000000000000000000000000000000000000000000000000000000002f600000000000000000000000000000000000000000000000000000000000002fa00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000003020000000000000000000000000000000000000000000000000000000000000306000000000000000000000000000000000000000000000000000000000000030a000000000000000000000000000000000000000000000000000000000000030e00000000000000000000000000000000000000000000000000000000000003120000000000000000000000000000000000000000000000000000000000000316000000000000000000000000000000000000000000000000000000000000031a000000000000000000000000000000000000000000000000000000000000031e00000000000000000000000000000000000000000000000000000000000003220000000000000000000000000000000000000000000000000000000000000326000000000000000000000000000000000000000000000000000000000000032a000000000000000000000000000000000000000000000000000000000000032e00000000000000000000000000000000000000000000000000000000000003320000000000000000000000000000000000000000000000000000000000000336000000000000000000000000000000000000000000000000000000000000033a000000000000000000000000000000000000000000000000000000000000033e00000000000000000000000000000000000000000000000000000000000003420000000000000000000000000000000000000000000000000000000000000346000000000000000000000000000000000000000000000000000000000000034a000000000000000000000000000000000000000000000000000000000000034e00000000000000000000000000000000000000000000000000000000000003520000000000000000000000000000000000000000000000000000000000000356000000000000000000000000000000000000000000000000000000000000035a000000000000000000000000000000000000000000000000000000000000035e00000000000000000000000000000000000000000000000000000000000003620000000000000000000000000000000000000000000000000000000000000366000000000000000000000000000000000000000000000000000000000000036a000000000000000000000000000000000000000000000000000000000000036e00000000000000000000000000000000000000000000000000000000000003720000000000000000000000000000000000000000000000000000000000000376000000000000000000000000000000000000000000000000000000000000037a000000000000000000000000000000000000000000000000000000000000037e00000000000000000000000000000000000000000000000000000000000003820000000000000000000000000000000000000000000000000000000000000386000000000000000000000000000000000000000000000000000000000000038a000000000000000000000000000000000000000000000000000000000000038e00000000000000000000000000000000000000000000000000000000000003920000000000000000000000000000000000000000000000000000000000000396000000000000000000000000000000000000000000000000000000000000039a000000000000000000000000000000000000000000000000000000000000039e00000000000000000000000000000000000000000000000000000000000003a200000000000000000000000000000000000000000000000000000000000003a600000000000000000000000000000000000000000000000000000000000003aa00000000000000000000000000000000000000000000000000000000000003ae00000000000000000000000000000000000000000000000000000000000003b200000000000000000000000000000000000000000000000000000000000003b600000000000000000000000000000000000000000000000000000000000003ba00000000000000000000000000000000000000000000000000000000000003be00000000000000000000000000000000000000000000000000000000000003c200000000000000000000000000000000000000000000000000000000000003c600000000000000000000000000000000000000000000000000000000000003ca00000000000000000000000000000000000000000000000000000000000003ce00000000000000000000000000000000000000000000000000000000000003d200000000000000000000000000000000000000000000000000000000000003d600000000000000000000000000000000000000000000000000000000000003da00000000000000000000000000000000000000000000000000000000000003de00000000000000000000000000000000000000000000000000000000000003e200000000000000000000000000000000000000000000000000000000000003e600000000000000000000000000000000000000000000000000000000000003ea00000000000000000000000000000000000000000000000000000000000003ee00000000000000000000000000000000000000000000000000000000000003f200000000000000000000000000000000000000000000000000000000000003f600000000000000000000000000000000000000000000000000000000000003fa00000000000000000000000000000000000000000000000000000000000003fe00000000000000000000000000000000000000000000000000000000000004020000000000000000000000000000000000000000000000000000000000000406000000000000000000000000000000000000000000000000000000000000040a000000000000000000000000000000000000000000000000000000000000040e00000000000000000000000000000000000000000000000000000000000004120000000000000000000000000000000000000000000000000000000000000416000000000000000000000000000000000000000000000000000000000000041a000000000000000000000000000000000000000000000000000000000000041e00000000000000000000000000000000000000000000000000000000000004220000000000000000000000000000000000000000000000000000000000000426000000000000000000000000000000000000000000000000000000000000042a000000000000000000000000000000000000000000000000000000000000042e00000000000000000000000000000000000000000000000000000000000004320000000000000000000000000000000000000000000000000000000000000436000000000000000000000000000000000000000000000000000000000000043a000000000000000000000000000000000000000000000000000000000000043e00000000000000000000000000000000000000000000000000000000000004420000000000000000000000000000000000000000000000000000000000000446000000000000000000000000000000000000000000000000000000000000044a000000000000000000000000000000000000000000000000000000000000044e00000000000000000000000000000000000000000000000000000000000004520000000000000000000000000000000000000000000000000000000000000456000000000000000000000000000000000000000000000000000000000000045a000000000000000000000000000000000000000000000000000000000000045e00000000000000000000000000000000000000000000000000000000000004620000000000000000000000000000000000000000000000000000000000000466000000000000000000000000000000000000000000000000000000000000046a000000000000000000000000000000000000000000000000000000000000046e00000000000000000000000000000000000000000000000000000000000004720000000000000000000000000000000000000000000000000000000000000476000000000000000000000000000000000000000000000000000000000000047a000000000000000000000000000000000000000000000000000000000000047e00000000000000000000000000000000000000000000000000000000000004820000000000000000000000000000000000000000000000000000000000000486000000000000000000000000000000000000000000000000000000000000048a000000000000000000000000000000000000000000000000000000000000048e00000000000000000000000000000000000000000000000000000000000004920000000000000000000000000000000000000000000000000000000000000496000000000000000000000000000000000000000000000000000000000000049a000000000000000000000000000000000000000000000000000000000000049e00000000000000000000000000000000000000000000000000000000000004a200000000000000000000000000000000000000000000000000000000000004a600000000000000000000000000000000000000000000000000000000000004aa00000000000000000000000000000000000000000000000000000000000004ae00000000000000000000000000000000000000000000000000000000000004b200000000000000000000000000000000000000000000000000000000000004b600000000000000000000000000000000000000000000000000000000000004ba00000000000000000000000000000000000000000000000000000000000004be00000000000000000000000000000000000000000000000000000000000004c200000000000000000000000000000000000000000000000000000000000004c600000000000000000000000000000000000000000000000000000000000004ca00000000000000000000000000000000000000000000000000000000000004ce00000000000000000000000000000000000000000000000000000000000004d200000000000000000000000000000000000000000000000000000000000004d600000000000000000000000000000000000000000000000000000000000004da00000000000000000000000000000000000000000000000000000000000004de00000000000000000000000000000000000000000000000000000000000004e200000000000000000000000000000000000000000000000000000000000004e600000000000000000000000000000000000000000000000000000000000004ea00000000000000000000000000000000000000000000000000000000000004ee00000000000000000000000000000000000000000000000000000000000004f200000000000000000000000000000000000000000000000000000000000004f600000000000000000000000000000000000000000000000000000000000004fa00000000000000000000000000000000000000000000000000000000000004fe00000000000000000000000000000000000000000000000000000000000005020000000000000000000000000000000000000000000000000000000000000506000000000000000000000000000000000000000000000000000000000000050a000000000000000000000000000000000000000000000000000000000000050e00000000000000000000000000000000000000000000000000000000000005120000000000000000000000000000000000000000000000000000000000000516000000000000000000000000000000000000000000000000000000000000051a000000000000000000000000000000000000000000000000000000000000051e00000000000000000000000000000000000000000000000000000000000005220000000000000000000000000000000000000000000000000000000000000526000000000000000000000000000000000000000000000000000000000000052a000000000000000000000000000000000000000000000000000000000000052e00000000000000000000000000000000000000000000000000000000000005320000000000000000000000000000000000000000000000000000000000000536000000000000000000000000000000000000000000000000000000000000053a000000000000000000000000000000000000000000000000000000000000053e00000000000000000000000000000000000000000000000000000000000005420000000000000000000000000000000000000000000000000000000000000546000000000000000000000000000000000000000000000000000000000000054a000000000000000000000000000000000000000000000000000000000000054e00000000000000000000000000000000000000000000000000000000000005520000000000000000000000000000000000000000000000000000000000000556000000000000000000000000000000000000000000000000000000000000055a000000000000000000000000000000000000000000000000000000000000055e00000000000000000000000000000000000000000000000000000000000005620000000000000000000000000000000000000000000000000000000000000566000000000000000000000000000000000000000000000000000000000000056a000000000000000000000000000000000000000000000000000000000000056e00000000000000000000000000000000000000000000000000000000000005720000000000000000000000000000000000000000000000000000000000000576000000000000000000000000000000000000000000000000000000000000057a000000000000000000000000000000000000000000000000000000000000057e00000000000000000000000000000000000000000000000000000000000005820000000000000000000000000000000000000000000000000000000000000586000000000000000000000000000000000000000000000000000000000000058a000000000000000000000000000000000000000000000000000000000000058e00000000000000000000000000000000000000000000000000000000000005920000000000000000000000000000000000000000000000000000000000000596000000000000000000000000000000000000000000000000000000000000059a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006666666666666000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066335623961310000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000663666332616200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006363361306639000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063830376637650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000663616566663900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006353634386564000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063561343233660000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000662393138356300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006623837623131000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066666666466320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000634623439343900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006333433323335000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063166316432390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000630363839343000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006383637633164000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066165333230380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000639663231613000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006663938663330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066665353030630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000664323634353100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006666438623562000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063561363566610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000664323232303900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006653932363563000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066335346533380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000638306137326400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006346265613639000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063334616338300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000665656438313100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006363236313664000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066666363338640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000638626330633500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006633464613533000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063030303030300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666333332326300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006666661653161000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066666633131300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000635303561356300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006666665663136000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066666663637310000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666666634343900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006646238333233000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066466326333390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666393338643800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006356332356662000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063261383666640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000634356661666600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006333864643536000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066666336130650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000664333261303900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006393033373037000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063665333230360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000635353265303500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006653837303562000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066633386237630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000665346134393900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006363637616639000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063634386466390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000637636334663200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006393766326662000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066133656664300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000638376534643900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006373162646534000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066666316130620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666373861313800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006326238336636000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066436323134390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000638333433393800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006666663393235000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066439333931660000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000662643264323400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006666637323136000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063235346566620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000665356535646500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006303061353536000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066335303330650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000661626631333100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006666234363934000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066537613332630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666666630656500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006303039633539000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063033383565620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000630303439396300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006653131383333000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063236623166330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666666630626500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006643864616466000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066437643363640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000631393239663400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006656162313138000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063062353032370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666396635636200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006636663396238000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066665623964350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666386436383900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006356436303631000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063736383538620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000637353735373600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006666630653065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063061646334640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666646638666600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006373065383930000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066637393133640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666663161643200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006666638326164000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063533356131350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666613666653200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006666665393339000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066162333662650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000661646338636300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006363034363636000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066632303432320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000661626161613800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006346236356637000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066131396339610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000635383536356300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006646134326362000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063032376339320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000663656331383900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006393039623065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063734353830640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000630323765653600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006623239353864000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066566616438310000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000637643633356500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006656666326661000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063666353937610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000664346237623200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006643138363837000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066364393136640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000636623366333900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006346432373162000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063835363334660000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666396634653600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006663864646230000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066239326233630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000664303862313100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006323537636564000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066133626165640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000635666434666200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006633136373130000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066132386566340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000633613038356200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006363762316533000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063165333434350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666666430363700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006393632323336000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063736396361390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000635613662376200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006376535323433000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066138366636300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000638663738356500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006636330353935000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063432666662300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000664353633333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006623863656432000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066239316234330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666333937313300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006653865386532000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066563356234330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000632333534373600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006623261386135000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066436633362650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000634396233386200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006666363663235000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066635396233340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000633373564666300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006393965366465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063237613436330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000635353435343300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006623139653030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066434613031350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000639663462323700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006663965386464000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063662373231320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000639643865366500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006343234336638000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066661356532300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666383239303500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006353535333533000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063837366636390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000634313064363600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006353532643164000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066637313234380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666656533663300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006633136393233000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063262323833340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000630303739666300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006643331653134000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066638333030310000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000638646431323200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006666666646634000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066666613231650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000665346166613300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006666263333131000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066161393430630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000665656463303000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006666666303036000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063963623462380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000661333836353400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006616536633061000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063262623236620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000665326338633000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006663839383635000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066638363130300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000664636438643300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006303439643433000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066430616561390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666333964343400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006656562373863000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066639663565390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000635643335303000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006633361313939000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066161613661340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000663616132366100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006666465376635000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066664663030380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666646365663200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006663638316536000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063031383134360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000664313961353400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006396562356531000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066635666366660000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000633663933323300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006303066636666000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063461353335380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666626338303000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006643539366136000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066666623931330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000665396261313200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006373637633065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066639663664310000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000664323936303700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006663863653437000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063339356564310000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666666335663000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006636263316263000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066434636663300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000004e0000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000066000000000000000000000000000000000000000000000000000000000000006c00000000000000000000000000000000000000000000000000000000000000720000000000000000000000000000000000000000000000000000000000000078000000000000000000000000000000000000000000000000000000000000007e0000000000000000000000000000000000000000000000000000000000000084000000000000000000000000000000000000000000000000000000000000008a00000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000096000000000000000000000000000000000000000000000000000000000000009c00000000000000000000000000000000000000000000000000000000000000a200000000000000000000000000000000000000000000000000000000000000a800000000000000000000000000000000000000000000000000000000000000ae00000000000000000000000000000000000000000000000000000000000000b400000000000000000000000000000000000000000000000000000000000000ba00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c600000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000d200000000000000000000000000000000000000000000000000000000000000d800000000000000000000000000000000000000000000000000000000000000de00000000000000000000000000000000000000000000000000000000000000e400000000000000000000000000000000000000000000000000000000000000ea000000000000000000000000000000000000000000000000000000000000000370015171f090e020e020e020e02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b0200000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e030e030e030e03020301000b03020301000b03020301000b03020301000b03020301000b03020301000b03020301000b0300000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e040e040e040e04020401000b04020401000b04020401000b04020401000b04020401000b04020401000b04020401000b0400000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e050e050e050e05020501000b05020501000b05020501000b05020501000b05020501000b05020501000b05020501000b0500000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e060e060e060e06020601000b06020601000b06020601000b06020601000b06020601000b06020601000b06020601000b0600000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e070e070e070e07020701000b07020701000b07020701000b07020701000b07020701000b07020701000b07020701000b0700000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e080e080e080e08020801000b08020801000b08020801000b08020801000b08020801000b08020801000b08020801000b0800000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e090e090e090e09020901000b09020901000b09020901000b09020901000b09020901000b09020901000b09020901000b0900000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e030e030e030e03020301000b03020301000b03020301000b03020301000b03020301000b03020301000b03020301000b0300000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e0a0e0a0e0a0e0a020a01000b0a020a01000b0a020a01000b0a020a01000b0a020a01000b0a020a01000b0a020a01000b0a00000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e0b0e0b0e0b0e0b020b01000b0b020b01000b0b020b01000b0b020b01000b0b020b01000b0b020b01000b0b020b01000b0b00000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e0c0e0c0e0c0e0c020c01000b0c020c01000b0c020c01000b0c020c01000b0c020c01000b0c020c01000b0c020c01000b0c00000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e0d0e0d0e0d0e0d020d01000b0d020d01000b0d020d01000b0d020d01000b0d020d01000b0d020d01000b0d020d01000b0d00000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e0e0e0e0e0e0e0e020e01000b0e020e01000b0e020e01000b0e020e01000b0e020e01000b0e020e01000b0e020e01000b0e00000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e0f0e0f0e0f0e0f020f01000b0f020f01000b0f020f01000b0f020f01000b0f020f01000b0f020f01000b0f020f01000b0f00000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e100e100e100e10021001000b10021001000b10021001000b10021001000b10021001000b10021001000b10021001000b1000000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e110e110e110e11021101000b11021101000b11021101000b11021101000b11021101000b11021101000b11021101000b1100000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e120e120e120e12021201000b12021201000b12021201000b12021201000b12021201000b12021201000b12021201000b1200000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e130e130e130e13021301000b13021301000b13021301000b13021301000b13021301000b13021301000b13021301000b1300000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e140e140e140e14021401000b14021401000b14021401000b14021401000b14021401000b14021401000b14021401000b1400000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e150e150e150e15021501000b15021501000b15021501000b15021501000b15021501000b15021501000b15021501000b1500000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e160e160e160e16021601000b16021601000b16021601000b16021601000b16021601000b16021601000b16021601000b1600000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e170e170e170e17021701000b17021701000b17021701000b17021701000b17021701000b17021701000b17021701000b1700000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e180e180e180e18021801000b18021801000b18021801000b18021801000b18021801000b18021801000b18021801000b1800000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e190e190e190e19021901000b19021901000b19021901000b19021901000b19021901000b19021901000b19021901000b1900000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e1a0e1a0e1a0e1a021a01000b1a021a01000b1a021a01000b1a021a01000b1a021a01000b1a021a01000b1a021a01000b1a00000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e1b0e1b0e1b0e1b021b01000b1b021b01000b1b021b01000b1b021b01000b1b021b01000b1b021b01000b1b021b01000b1b00000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e1c0e1c0e1c0e1c021c01000b1c021c01000b1c021c01000b1c021c01000b1c021c01000b1c021c01000b1c021c01000b1c00000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e1d0e1d0e1d0e1d021d01000b1d021d01000b1d021d01000b1d021d01000b1d021d01000b1d021d01000b1d021d01000b1d00000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e1e0e1e0e1e0e1e021e01000b1e021e01000b1e021e01000b1e021e01000b1e021e01000b1e021e01000b1e021e01000b1e0000000000000000000000000000000000000000000000000000000000000000000000000000000089000000000000000000000000000000000000000000000000000000000000112000000000000000000000000000000000000000000000000000000000000011a00000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000126000000000000000000000000000000000000000000000000000000000000012c00000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000136000000000000000000000000000000000000000000000000000000000000013e0000000000000000000000000000000000000000000000000000000000000146000000000000000000000000000000000000000000000000000000000000014c0000000000000000000000000000000000000000000000000000000000000154000000000000000000000000000000000000000000000000000000000000015a0000000000000000000000000000000000000000000000000000000000000162000000000000000000000000000000000000000000000000000000000000016a00000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000176000000000000000000000000000000000000000000000000000000000000017c000000000000000000000000000000000000000000000000000000000000018a0000000000000000000000000000000000000000000000000000000000000190000000000000000000000000000000000000000000000000000000000000019600000000000000000000000000000000000000000000000000000000000001a200000000000000000000000000000000000000000000000000000000000001a800000000000000000000000000000000000000000000000000000000000001ae00000000000000000000000000000000000000000000000000000000000001b400000000000000000000000000000000000000000000000000000000000001ba00000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000001c800000000000000000000000000000000000000000000000000000000000001d600000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000001ea00000000000000000000000000000000000000000000000000000000000001f600000000000000000000000000000000000000000000000000000000000001fe00000000000000000000000000000000000000000000000000000000000002060000000000000000000000000000000000000000000000000000000000000214000000000000000000000000000000000000000000000000000000000000021e000000000000000000000000000000000000000000000000000000000000022800000000000000000000000000000000000000000000000000000000000002340000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000024c00000000000000000000000000000000000000000000000000000000000002520000000000000000000000000000000000000000000000000000000000000256000000000000000000000000000000000000000000000000000000000000025e000000000000000000000000000000000000000000000000000000000000026200000000000000000000000000000000000000000000000000000000000002680000000000000000000000000000000000000000000000000000000000000272000000000000000000000000000000000000000000000000000000000000027c0000000000000000000000000000000000000000000000000000000000000282000000000000000000000000000000000000000000000000000000000000028a00000000000000000000000000000000000000000000000000000000000002900000000000000000000000000000000000000000000000000000000000000294000000000000000000000000000000000000000000000000000000000000029a00000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000002a600000000000000000000000000000000000000000000000000000000000002ac00000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000002b600000000000000000000000000000000000000000000000000000000000002bc00000000000000000000000000000000000000000000000000000000000002c800000000000000000000000000000000000000000000000000000000000002ce00000000000000000000000000000000000000000000000000000000000002d400000000000000000000000000000000000000000000000000000000000002d800000000000000000000000000000000000000000000000000000000000002de00000000000000000000000000000000000000000000000000000000000002e400000000000000000000000000000000000000000000000000000000000002e800000000000000000000000000000000000000000000000000000000000002ec00000000000000000000000000000000000000000000000000000000000002fc000000000000000000000000000000000000000000000000000000000000030c00000000000000000000000000000000000000000000000000000000000003120000000000000000000000000000000000000000000000000000000000000316000000000000000000000000000000000000000000000000000000000000031c00000000000000000000000000000000000000000000000000000000000003220000000000000000000000000000000000000000000000000000000000000326000000000000000000000000000000000000000000000000000000000000032e0000000000000000000000000000000000000000000000000000000000000336000000000000000000000000000000000000000000000000000000000000033a00000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000346000000000000000000000000000000000000000000000000000000000000034c0000000000000000000000000000000000000000000000000000000000000352000000000000000000000000000000000000000000000000000000000000035a00000000000000000000000000000000000000000000000000000000000003620000000000000000000000000000000000000000000000000000000000000366000000000000000000000000000000000000000000000000000000000000036e00000000000000000000000000000000000000000000000000000000000003720000000000000000000000000000000000000000000000000000000000000378000000000000000000000000000000000000000000000000000000000000037c00000000000000000000000000000000000000000000000000000000000003820000000000000000000000000000000000000000000000000000000000000388000000000000000000000000000000000000000000000000000000000000038e0000000000000000000000000000000000000000000000000000000000000396000000000000000000000000000000000000000000000000000000000000039c00000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000003a600000000000000000000000000000000000000000000000000000000000003ac00000000000000000000000000000000000000000000000000000000000003b200000000000000000000000000000000000000000000000000000000000003b800000000000000000000000000000000000000000000000000000000000003be00000000000000000000000000000000000000000000000000000000000003c600000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000003d600000000000000000000000000000000000000000000000000000000000003da00000000000000000000000000000000000000000000000000000000000003e200000000000000000000000000000000000000000000000000000000000003ee00000000000000000000000000000000000000000000000000000000000003f600000000000000000000000000000000000000000000000000000000000003fa00000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000408000000000000000000000000000000000000000000000000000000000000040e0000000000000000000000000000000000000000000000000000000000000414000000000000000000000000000000000000000000000000000000000000041a00000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000426000000000000000000000000000000000000000000000000000000000000042a00000000000000000000000000000000000000000000000000000000000004300000000000000000000000000000000000000000000000000000000000000436000000000000000000000000000000000000000000000000000000000000043c00000000000000000000000000000000000000000000000000000000000004420000000000000000000000000000000000000000000000000000000000000448000000000000000000000000000000000000000000000000000000000000044e0000000000000000000000000000000000000000000000000000000000000456000000000000000000000000000000000000000000000000000000000000045e0000000000000000000000000000000000000000000000000000000000000466000000000000000000000000000000000000000000000000000000000000046e0000000000000000000000000000000000000000000000000000000000000474000000000000000000000000000000000000000000000000000000000000047a00000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000488000000000000000000000000000000000000000000000000000000000000048e0000000000000000000000000000000000000000000000000000000000000496000000000000000000000000000000000000000000000000000000000000049c00000000000000000000000000000000000000000000000000000000000004a400000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000000004bc00000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000004c600000000000000000000000000000000000000000000000000000000000004cc00000000000000000000000000000000000000000000000000000000000004d2000000000000000000000000000000000000000000000000000000000000000450017141e0d0100011f0500021f05000100011f0300011f01000100011f0200011f02000300011f03000200011f0200021f0100011f0200011f0100011f0400011f0100011f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000230018151a0d020003200100012001000100052002000120010001200100012001000220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000330017141d0e0101052101010421010001010321020001010121010001210200010102000121020003000121020003000121020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f0017121e0d0100012201000122010005000222010002220500022201000222050002220100012201000100012203000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f0018151a0d01000223020002230100012302000223020001230300022303000000000000000000000000000000000000000000000000000000000000000000290017131c0d0400012401000300022401000424012301250100042401000200032401000100012404000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004b0015141d0d0126050001260100012603000126010002000126010001260200030001260300030001260300020003260200030001260300010001260100012601000126010002000326020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000530015161e0b0127090001270100012707000127010002000127050001270200030001270300012703000400032704000500010d05000200020d052702000300020d032703000400030d04000300020d0327030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b0018141e0d040003260500022604000126010001260300012603000100022604000326040001000126050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000590015141e0c01260600012601000126040001260100020001260200012602000300022603000200012602000126020001000626010002000126012801260128012601000300042601000400012601280126010005000226010000000000000000000000000000000000000000000000000000000000000000000000000000003b0015141b0c0126060001260100012604000126010002000126020001260200030002260300010006290100010004260229010001000426022901000000000000000000000000000000000000000000000000000000000000000000000000004b0015141d0c01260600012601000126040001260100020001260200012602000300022603000200012602000126020001000126012804260100010006260100020004260200030002260300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005d0015141e0c01260600012601000126040001260100020001260200012602000300022603000100062601000100012601000226010001260100010006260100020004260200010001260100022601000126010001000126040001260100000000000000000000000000000000000000000000000000000000000000000000003f0017141d0d0300032a01000200012a0300012a0100032a0200012a012a0100012a0100012a0100012a012a0200032a0100012a0300012a02000100032a03000000000000000000000000000000000000000000000000000000000000000000370016131c0e012b0300012b012b0300012b0100012b0100012b01000100012b0100012b01000200012b0200022b0100022b022b0100022b000000000000000000000000000000000000000000000000000000000000000000000000000000003b0016141d0c010001260600032601000126020001260100012602000126030003000326020001000726030003260200040001260300040001260300000000000000000000000000000000000000000000000000000000000000000000000000ad0015171f09022c0223022c0223022c0223022c022c0223022c0223022c0223022c0223022d0223022d0223022d02230223022d0223022d0223022d0223022e01000123022e0223022e0223022e022e01000123022e0223022e0223022e02230100012f0223022f0223022f022302230100012f0223022f0223022f02230230010001230230022302300223023002300100012302300223023002230230022301000131022302310223023102230000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e320e320e330e33021101000b11021101000b11023401000b34023401000b34023501000b35023501000b35023601000b3600000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e320e320e240e24023701000b37023701000b37023701000b37023701000b37023801000b38023801000b38023901000b3900000000000000000000000000000000000000000000000000000000000000000000000000000000970015171f090e3a013a013b013a013b013a013b013a013b013a013b013a013b013a013b0e3b013b0104013b0104013b0104013b0104013b0104013b0104013b0104020401000b04020401000b04020401000b040104013c0100013c0104013c0104013c0104013c0104013c0104013c023c01000b3c013c013d0100013d013c013d013c013d013c013d013c013d013c013d023d01000b3d00000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e3e0e3e0e3f0e3f023f01000b3f023f01000b3f023c01000b3c023c01000b3c023c01000b3c023c01000b3c024001000b4000000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e410e410e420e42022a01000b2a022a01000b2a020f01000b0f020f01000b0f024301000b43024301000b43021201000b1200000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e440e440e440e09020901000b09020901000b09020901000b09020901000b09020901000b09024501000b45024501000b4500000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e460e460e460e25024201000b42021401000b14024701000b47024701000b47024801000b48024801000b48024801000b4800000000000000000000000000000000000000000000000000000000000000000000000000000000290018131d0e0200011d0100011d0300011d010002000249010001000249020001000149030001490400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000530018171c090126010003260100032601000326010001000126030001260300012603000126022602000326010003260100022601000126030001260300012603000126012602000226010003260100032601000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ad0015171f090224021c024a0224021c024a02240224021c024a0224021c024a0224024a0224021c024a0224021c024a024a0224021c024a0224021c024a021c0100014a0224021c024a0224021c021c0100014a0224021c024a0224021c02240100011c024a0224021c024a022402240100011c024a0224021c024a0224024a01000124021c024a0224021c024a024a01000124021c024a0224021c024a021c0100014a0224021c024a0224021c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007d0015171f09040003070100030701000207030701000307010003070300030701000307070003070700030701000600030701000307010003000207010003070100030701000107020002070100030705000107020002070700020701070700030701000207040003070100030701000207020702000307010003070300000000000000000000000000000000000000000000000000000000000000000000007d0015171f090400034b0100034b0100024b034b0100034b0100034b0300034b0100034b0700034b0700034b01000600034b0100034b01000300024b0100034b0100034b0100014b0200024b0100034b0500014b0200024b0700024b014b0700034b0100024b0400034b0100034b0100024b024b0200034b0100034b0300000000000000000000000000000000000000000000000000000000000000000000008b0015171f090400034c010003460100021403120100034c01000346030003120100034c0400031203120400034d01000312030003140100034d010003120246010003140100034d040002460100031404000346010002460400034c010003460100030002120100034c010003460100014d020002120100034c04000112014d020002120400034d01000112000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b0015171f0903000223040002230300030002230400022303000e0002230400022304000223022304000223040002230e0003000223040002230300030002230400022303000e0002230400022304000223022304000223040002230000000000000000000000000000000000000000000000000000000000000000000000005b0015171f0903000201040002010300030002010400020103000e0002010400020104000201020104000201040002010e0003000201040002010300030002010400020103000e000201040002010400020102010400020104000201000000000000000000000000000000000000000000000000000000000000000000000000ad0015171f09024e0243024f024e0243024f024e024e0243024f024e0243024f024e024f024e0243024f024e0243024f024f024e0243024f024e0243024f02430100014f024e0243024f024e024302430100014f024e0243024f024e0243024e01000143024f024e0243024f024e024e01000143024f024e0243024f024e024f0100014e0243024f024e0243024f024f0100014e0243024f024e0243024f02430100014f024e0243024f024e02430000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000730015171f09030f0300030f0300020f030f0300030f0300020f030f0300030f0300020f0300030f0300030f02000300030f0300030f02000300030f0300030f0200020f0400030f0300020f020f0400030f0300020f020f0400030f0300020f0300030f0300030f02000300030f0300030f02000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000730015171f09031903000319030002190319030003190300021903190300031903000219030003190300031902000300031903000319020003000319030003190200021904000319030002190219040003190300021902190400031903000219030003190300031902000300031903000319020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009f0015171f090200022302000223020002230200020002230200022302000223020002230200022302000223020002230223020002230200022302000223030001230200022302000223020003000123020002230200022302000223020002230200022302000223022302000223020002230200022303000123020002230200022302000300012302000223020002230200022302000223020002230200022300000000000000000000000000000000000000000000000000000000000000009f0015171f09024a0200024a0200024a0200024a024a0200024a0200024a0200024a0200024a0200024a0200024a02000200024a0200024a0200024a0200024a0200024a0200024a0200024a024a0200024a0200024a0200024a0300014a0200024a0200024a02000300014a0200024a0200024a0200024a0200024a0200024a0200024a024a0200024a0200024a0200024a0300014a0200024a0200024a020000000000000000000000000000000000000000000000000000000000000000009f0015171f090200022002000220020002200200020002200200022002000220020002200200022002000220020002200220020002200200022002000220030001200200022002000220020003000120020002200200022002000220020002200200022002000220022002000220020002200200022003000120020002200200022002000300012002000220020002200200022002000220020002200200022000000000000000000000000000000000000000000000000000000000000000002b0018131d0d030002470100020102000101015001000401010002000201020002000101030002000150030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110018131a0d02000301010001000501060100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000470017151e0d0200021d04000200031d03000100011d0100011d0100021d0100031d0100031d0100021d0100011d0100011d02000200031d03000200021d0100011d02000600021d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b00151717090e190e260e4200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000370018141c0d050001510100010003510123015101380151010001510123025101000151010001510238015101000200015102000151010000000000000000000000000000000000000000000000000000000000000000000000000000000000610015171f090e27020006270300032702000b270100010009270100022701000227010001270100032702000427022701000827030001270200012702000327050003000827030003000127040002270100022701000100012701000b2703000b270000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000690015171f090e27024106270341032702420b27014201420927014202270142022701000127012a0327022a0427022701000827032a0127010f01000127020f0327050f020f01000827030f024301000127044302270143022701430143012701000b27021201000b270000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f0017131d0d020003520100020001520100015201000200045202000352010001520100035201000652030001520200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000450015141e0c01260600012601260600012601000126040001260100020004260200030002260300020004260200020002260400040002260200020004260200030002260300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003f0017141e0d020f0100030f01000100030f0100020f020f0300010f01000300030f01000100020f0400010f0300020f01000100030f0200010f0200010f04000000000000000000000000000000000000000000000000000000000000000000190018131a0e01280100022801000100032801140100032801000000000000000000000000000000000000000000000000000000000000000000000000000000290018131d0e020001530200020001530200010001530154015301000554010003530100020001530200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000330018151c0d0200045402000100015401000254010001540100015402000254020001540100015404000154010002000454020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b0017151d0d0100010106000200020104000300030102000801020003010300040002010200060001010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f0017131d0e0126010a0126010a01260126010a0126010a012605550155032601550155022602550155012603550555000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000190018161a0d07230200032301000523032301000323010001230000000000000000000000000000000000000000000000000000000000000000000000000000210018161a0d0756020001560100015601000156010003560356010003560100015600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f0017141d0d07560156010002560100025602000256010002560700071d011d0100021d0100021d0200021d0100021d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000910016171e09015701000157010001570100015701000157010001570100015701000e00010001570100015701000157010001570100015701000157010001570e000157030001570100015701000157010001570100015701000e00010001570100015701000157010001570100015701000157010001570e0001570300015701000157010001570100015701000157010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000250018141d0d010002580100025801000758075801000558010002000358020003000158030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000250016121b0f010101000101010101000101010101000101010101000159010102000159020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110017151a1002000101020005260501050100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000350017141e0d0100020b0400010b0200010b0300010b06000100030b03000300030b01000600010b0300010b0200010b0400020b0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000390016131d0e0200015b02000100015b012b015b01000200015b02000100035b0100015b032b015b025b022b015b015b032b015b0100035b010000000000000000000000000000000000000000000000000000000000000000000000000000001f0018141d0d0300045c0200055c0200055c0200055c0200045c0100025c050000000000000000000000000000000000000000000000000000000000000000001d0017121c0e045d045d045d0100025d01000100025e01000100025e010000000000000000000000000000000000000000000000000000000000000000000000d10015171f090200010f0200010f0200010f0200010f0200015c0200015c0200015c0200015c0200015c01000100010f0200010f0200010f0200010f0200010f0200015c0200015c0200015c0200015c0200010f0200010f0200010f0200010f0200010f01000100015c0200015c0200015c0200015c0200015c0500010f0200010f0200010f0200015c0200015c0200015c0200015c0200015c01000100010f0200010f0200010f0200010f0200010f0500015c0200015c0200015c0200010f0200010f0200010f0200010f0200010f010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d10015171f090200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f01000100015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f01000100015f0200015f0200015f0200015f0200015f0500015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f01000100015f0200015f0200015f0200015f0200015f0500015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003f0016161e0d0300032303000100072301000100072301000323030103230323010101000101032303230301032301000723010001000723010003000323030000000000000000000000000000000000000000000000000000000000000000001d0018131d0e04000123022301000223030002230200032303000223052300000000000000000000000000000000000000000000000000000000000000000000270018131c0e010b0100010b0100010b0500010b0100010b0100010b0500010b0100010b0100010b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003b0017131d0e056001600100016001000160010001600100016001000160010001600100016001000160010001600100036001000160016001000360000000000000000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b0015171f090e610e610461075803610e6102620100026103580261015803610261010001610158036102580461026201000361015807610261010001610258016104580361026201000b6102610100016107580361026201000b61000000000000000000000000000000000000000000000000000000000000000000000000430015141d0c012606000126010001260400012601000200012602000126020003000226030003000226030002000426020002000426020001000626010001000626010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013001715191001000137030001000101030005630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000290018131d0e0400014301000143020001430100014303000300014301000143020001430100014304000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d0017171c090b000312070004180312030004140418031202460100041404180300024601000414070002460c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000330018151e0d030002640300020004640200020004640200010002650264025a01000465045a0465045a010002650200025a01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000210019171b0901230200012302000123020001230200012301000e00022301000b230000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000550015171f0b0413030005130413030005130413030005130413030005130100036603000566010003660300056601000366030005660100036603000566010003130300051301000313030005130100031303000513000000000000000000000000000000000000000000000000000000000000000000000000000000000000470015151f0c031c0300031c031c0300031c031c0300031c032303000323032303000323032303000323031c0300031c031c0300031c031c0300031c03230300032303230300032300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d0018121b0e016702000167010002670100010002670100016702000167000000000000000000000000000000000000000000000000000000000000000000004f0015151f0c09230523010003230223010002230200022301230200012301680300012303000223040003000223040003000223040003000223040003000123016804000300022304000300022304000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f0018121c0e0100025f0100035f0100025f02000100015f02200200012001000000000000000000000000000000000000000000000000000000000000000000370017121d0d0200014e0100014e014e0100024e01000100034e01000100024e0100014e014e0100014e02000300014e01000100014e0300000000000000000000000000000000000000000000000000000000000000000000000000000000001b001514170d012605000126010001260300012601000200032602000000000000000000000000000000000000000000000000000000000000000000000000003f0017141d0d010001010300010101000201010001010100020102000301020001000501010002000301020002010100010101000201010001010300010101000000000000000000000000000000000000000000000000000000000000000000330016151d0d050002190100020001190100041904000419050002190100011901000219040002000219040008000100011906000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000330017151e0d0100010f060008000200020f0400010f0100020f04000500020f01000400040f0200010f0100040f0500020f010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005f0015171f090e690e430e280e1c02010100012302010223020102230201020101000123020102230201022302010223010001010223020102230201022302230100010102230201022302010223026901000b69024301000b43022801000b280000000000000000000000000000000000000000000000000000000000000000230015171d090e240e240e240e000e000e00022401000b24022401000b24022401000b240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b0015171b090e5a0e5a0e5a0e00026a01000b6a0e00022a01000b2a0000000000000000000000000000000000000000000000000000000000000000000000002b0015171f090e430e000e430e00024301000b430e00024301000b430e00024301000b430e00024301000b43000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b0015171f090e350e000e350e00023501000b350e00023501000b350e00023501000b350e00023501000b35000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b0015171f090e6b0e000e6b0e00026b01000b6b0e00026b01000b6b0e00026b01000b6b0e00026b01000b6b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b0015171f090e190e000e190e00021901000b190e00021901000b190e00021901000b190e00021901000b1900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000250017141a0d030001260300010001260300012601000200032602000126010003260100012600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410017171a090266020d0266020d0266020d02660266020d0266020d0266020d0266020d01000166020d0266020d0266020d020d01000166020d0266020d0266020d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000770015171f0902280200012804000128030001280228030004280400012803280900022803280900022802280200012801000128030001280100022802280300012801000228010001280100022802280300012801000228030002280228080001280100022802280a00022802280a00022802280a00022800000000000000000000000000000000000000000000000000000000000000000000000000000000390017131d0d014e0100014e010002570100014e020002570100014e02000257060001570200024e010001570200024e010002570100024e01000000000000000000000000000000000000000000000000000000000000000000000000000000190018131c0e03010200030102000500020001010200040001010000000000000000000000000000000000000000000000000000000000000000000000000000430015121f0e0423014b0223014b014b0223014b014b0223014b014b0223014b014b0223014b014b0223014b014b0223014b014b0223014b014b0223014b014b0223014b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000930016151f0b0200023b0100016c0200016c0100013b0100033b0200016c02000100013b0300013b0200026c0300026d0100013b0100026c0200016d0100011c016d013b0100016c01000100016d0100011c016c013b0100016c0100011c0100016d0100011c0100026c03000100016d0200011c0300011c01000200016d0200031c0100011c0100016d0200016d0100021c02000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000430015121f0e046e014b026e014b014b026e014b014b026e014b014b026e014b014b026e014b014b026e014b014b026e014b014b026e014b014b026e014b014b026e014b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000170016111e0f02410241020002410241024102410241024100000000000000000000000000000000000000000000000000000000000000000000000000000000350017151d0d0200016f0500026f0600026f0100016f04000200036f03000300016f0100016f0100016f0500026f01000500026f0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000470017151d0c0100077001000170070001700170010002700100027001000170017001000170020001700200017001700100027001000270010001700170070001700100077001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000310017141c0d037101000371017103000171020001710300017102000171030001710200017103000171020003710100037100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000390017131d0d027201000272010001720200027201000272010002720100060002720100017201000172027201000272010001720200017202000000000000000000000000000000000000000000000000000000000000000000000000000000390018151b0c0223020001230200012301000123010002230100022301000123012301000523010001230223010001230100012301000123010000000000000000000000000000000000000000000000000000000000000000000000000000003f0016161d0b0200012308000323080001230100032306000100022301000323040003000223010003230200050002230100032308000123010001230a0001230000000000000000000000000000000000000000000000000000000000000000390017131d0d0100017302000173010002730100017301000173027302000173010006000273010001730200027301000273010001730200037300000000000000000000000000000000000000000000000000000000000000000000000000001f0019151b0d05230100022302230100022301000223012302000223010002230000000000000000000000000000000000000000000000000000000000000000230019171d09027401000b74027401000b74027401000b74027401000b74027401000b740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d0018131c0d015603000156010001560200015602000156010001560100025601000156020002560156030002560000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000390017131d0d013e0300023e013e0200023e0100023e0100013e020006000100013e0200023e013e0100013e0100023e013e0100013e0100023e000000000000000000000000000000000000000000000000000000000000000000000000000027001715190d010102000201010001010100010102000201010001010100020101000201010002010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000370016141c0d0600011407000214010001140200011401140100011401000114010001140700021402000314011401000114020001140100000000000000000000000000000000000000000000000000000000000000000000000000000000002f0018151a0d037501000175010001750100017501000175010001750100017501000175010001750100017501000275000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410017131e0d0100026901000169010001000169010002690100060002690100016901000169026901000369060001000269010001690100010001690100026901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410017131e0d0100023e0100013e01000100013e0100023e01000600023e0100013e0100013e023e0100033e06000100023e0100013e01000100013e0100023e01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410017131e0d010002170100011701000100011701000217010006000276010001140100011402760100031406000100020f0100010f01000100010f0100020f01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410016131d0d0100026c0100016c01000100016c0100026c01000600026c0100016c0100016c026c0100036c06000100026c0100016c01000100016c0100026c01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000270018131b0d0100051f011f0100011f0100011f01000200011f0100011f01000200011f0200011f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000290017131d0d022804000228040001280100022802000200022802000400022804000228040001280100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000330017131d0d0201020002770201020002770101010001010100027706000337010001260100023702000126010001370300022600000000000000000000000000000000000000000000000000000000000000000000000000000000000000004d0018151d0c0700011c0100040001560100011c0100011c02000156010001560100031c015601000156010001560100011c0200015601000156010001560200011c0100010001560100015605000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000370018151a0c0143010001430100011c0100014301000143010001430100031c010001430100010001430100011c0100011c010001430100000000000000000000000000000000000000000000000000000000000000000000000000000000004b0015171f090a00016203000a0001620300026201000b62040001620900040001620900026201000462010006620a00016203000a0001620300026201000b62040001620900040001620900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b0017151b0d010003560400025602000156030002000156020001560200020001560300025601000156060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000430018141e0d017802790178037902790178017a0178027902790178017a0178027903790178027901780100010401000104010001040100010001040500050001040100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000850015171f09037b010003140100037b0100027b0e00017b010003140100037b010003140100010001140300017b030001140300017b01140200027b010003140100037b01000e00027b020003140100037b01000214030001140300017b030001140200017b01140200037b010003140100027b0e00017b0200027b010003140100037b010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830015171f09037c0100037c0100037c0100027c0e00017c0100037c0100037c0100037c01000100017c0300017c0300017c0300017c017c0200027c0100037c0100037c01000e00027c0200037c0100037c0100027c0300017c0300017c0300017c0200027c0200037c0100037c0100027c0e00017c0200027c0100037c0100037c0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110018121b0e040d020d024b020d024b044b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e020e020e020e02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b0200000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e0b0e0b0e0b0e0b020b01000b0b020b01000b0b020b01000b0b020b01000b0b020b01000b0b020b01000b0b020b01000b0b00000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e0e0e0e0e0e0e0e020e01000b0e020e01000b0e020e01000b0e020e01000b0e020e01000b0e020e01000b0e020e01000b0e00000000000000000000000000000000000000000000000000000000000000000000000000000000370015171f090e060e060e060e06020601000b06020601000b06020601000b06020601000b06020601000b06020601000b06020601000b0600000000000000000000000000000000000000000000000000000000000000000000000000000000ea0000000000000000000000000000000000000000000000000000000000001d400000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000001fa000000000000000000000000000000000000000000000000000000000000020400000000000000000000000000000000000000000000000000000000000002120000000000000000000000000000000000000000000000000000000000000234000000000000000000000000000000000000000000000000000000000000024400000000000000000000000000000000000000000000000000000000000002580000000000000000000000000000000000000000000000000000000000000268000000000000000000000000000000000000000000000000000000000000027a000000000000000000000000000000000000000000000000000000000000028e000000000000000000000000000000000000000000000000000000000000029800000000000000000000000000000000000000000000000000000000000002ae00000000000000000000000000000000000000000000000000000000000002bc00000000000000000000000000000000000000000000000000000000000002c800000000000000000000000000000000000000000000000000000000000002d800000000000000000000000000000000000000000000000000000000000002e800000000000000000000000000000000000000000000000000000000000003060000000000000000000000000000000000000000000000000000000000000314000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003300000000000000000000000000000000000000000000000000000000000000344000000000000000000000000000000000000000000000000000000000000034e000000000000000000000000000000000000000000000000000000000000035a0000000000000000000000000000000000000000000000000000000000000366000000000000000000000000000000000000000000000000000000000000037c00000000000000000000000000000000000000000000000000000000000003840000000000000000000000000000000000000000000000000000000000000392000000000000000000000000000000000000000000000000000000000000039c00000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000003c200000000000000000000000000000000000000000000000000000000000003d800000000000000000000000000000000000000000000000000000000000003e200000000000000000000000000000000000000000000000000000000000003ea00000000000000000000000000000000000000000000000000000000000003f600000000000000000000000000000000000000000000000000000000000004040000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000041e0000000000000000000000000000000000000000000000000000000000000432000000000000000000000000000000000000000000000000000000000000044a000000000000000000000000000000000000000000000000000000000000045e000000000000000000000000000000000000000000000000000000000000047400000000000000000000000000000000000000000000000000000000000004820000000000000000000000000000000000000000000000000000000000000492000000000000000000000000000000000000000000000000000000000000049e00000000000000000000000000000000000000000000000000000000000004ac00000000000000000000000000000000000000000000000000000000000004b600000000000000000000000000000000000000000000000000000000000004c200000000000000000000000000000000000000000000000000000000000004d600000000000000000000000000000000000000000000000000000000000004e600000000000000000000000000000000000000000000000000000000000004f400000000000000000000000000000000000000000000000000000000000004fc000000000000000000000000000000000000000000000000000000000000050e000000000000000000000000000000000000000000000000000000000000051a000000000000000000000000000000000000000000000000000000000000052a0000000000000000000000000000000000000000000000000000000000000534000000000000000000000000000000000000000000000000000000000000054400000000000000000000000000000000000000000000000000000000000005500000000000000000000000000000000000000000000000000000000000000564000000000000000000000000000000000000000000000000000000000000057a00000000000000000000000000000000000000000000000000000000000005860000000000000000000000000000000000000000000000000000000000000592000000000000000000000000000000000000000000000000000000000000059c00000000000000000000000000000000000000000000000000000000000005a800000000000000000000000000000000000000000000000000000000000005b600000000000000000000000000000000000000000000000000000000000005c200000000000000000000000000000000000000000000000000000000000005d200000000000000000000000000000000000000000000000000000000000005e400000000000000000000000000000000000000000000000000000000000005f60000000000000000000000000000000000000000000000000000000000000604000000000000000000000000000000000000000000000000000000000000060c000000000000000000000000000000000000000000000000000000000000062c0000000000000000000000000000000000000000000000000000000000000638000000000000000000000000000000000000000000000000000000000000064c00000000000000000000000000000000000000000000000000000000000006580000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000066c000000000000000000000000000000000000000000000000000000000000067c000000000000000000000000000000000000000000000000000000000000068e000000000000000000000000000000000000000000000000000000000000069e00000000000000000000000000000000000000000000000000000000000006aa00000000000000000000000000000000000000000000000000000000000006ca00000000000000000000000000000000000000000000000000000000000006e600000000000000000000000000000000000000000000000000000000000006f20000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000070e000000000000000000000000000000000000000000000000000000000000071e000000000000000000000000000000000000000000000000000000000000072a00000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000750000000000000000000000000000000000000000000000000000000000000075a000000000000000000000000000000000000000000000000000000000000076e000000000000000000000000000000000000000000000000000000000000077a0000000000000000000000000000000000000000000000000000000000000786000000000000000000000000000000000000000000000000000000000000079200000000000000000000000000000000000000000000000000000000000007a000000000000000000000000000000000000000000000000000000000000007b000000000000000000000000000000000000000000000000000000000000007c200000000000000000000000000000000000000000000000000000000000007ce00000000000000000000000000000000000000000000000000000000000007de0000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000080e000000000000000000000000000000000000000000000000000000000000081a000000000000000000000000000000000000000000000000000000000000082a000000000000000000000000000000000000000000000000000000000000083400000000000000000000000000000000000000000000000000000000000008420000000000000000000000000000000000000000000000000000000000000850000000000000000000000000000000000000000000000000000000000000086400000000000000000000000000000000000000000000000000000000000008780000000000000000000000000000000000000000000000000000000000000888000000000000000000000000000000000000000000000000000000000000089c00000000000000000000000000000000000000000000000000000000000008ae00000000000000000000000000000000000000000000000000000000000008c200000000000000000000000000000000000000000000000000000000000008d000000000000000000000000000000000000000000000000000000000000008dc00000000000000000000000000000000000000000000000000000000000008e600000000000000000000000000000000000000000000000000000000000008f40000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000091e000000000000000000000000000000000000000000000000000000000000092a00000000000000000000000000000000000000000000000000000000000009360000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000000000000000000000000094c0000000000000000000000000000000000000000000000000000000000000956000000000000000000000000000000000000000000000000000000000000096800000000000000000000000000000000000000000000000000000000000009780000000000000000000000000000000000000000000000000000000000000984000000000000000000000000000000000000000000000000000000000000099600000000000000000000000000000000000000000000000000000000000009ac00000000000000000000000000000000000000000000000000000000000009ba00000000000000000000000000000000000000000000000000000000000009c800000000000000000000000000000000000000000000000000000000000009d600000000000000000000000000000000000000000000000000000000000009e600000000000000000000000000000000000000000000000000000000000009f20000000000000000000000000000000000000000000000000000000000000a060000000000000000000000000000000000000000000000000000000000000a160000000000000000000000000000000000000000000000000000000000000a200000000000000000000000000000000000000000000000000000000000000a2e0000000000000000000000000000000000000000000000000000000000000a3e0000000000000000000000000000000000000000000000000000000000000a540000000000000000000000000000000000000000000000000000000000000a620000000000000000000000000000000000000000000000000000000000000a6e0000000000000000000000000000000000000000000000000000000000000a760000000000000000000000000000000000000000000000000000000000000a840000000000000000000000000000000000000000000000000000000000000a960000000000000000000000000000000000000000000000000000000000000aa80000000000000000000000000000000000000000000000000000000000000ab40000000000000000000000000000000000000000000000000000000000000abe0000000000000000000000000000000000000000000000000000000000000ac60000000000000000000000000000000000000000000000000000000000000ada0000000000000000000000000000000000000000000000000000000000000ae40000000000000000000000000000000000000000000000000000000000000af80000000000000000000000000000000000000000000000000000000000000b040000000000000000000000000000000000000000000000000000000000000b120000000000000000000000000000000000000000000000000000000000000b2a0000000000000000000000000000000000000000000000000000000000000b3a0000000000000000000000000000000000000000000000000000000000000b460000000000000000000000000000000000000000000000000000000000000b540000000000000000000000000000000000000000000000000000000000000b660000000000000000000000000000000000000000000000000000000000000b700000000000000000000000000000000000000000000000000000000000000b860000000000000000000000000000000000000000000000000000000000000b960000000000000000000000000000000000000000000000000000000000000ba20000000000000000000000000000000000000000000000000000000000000bb00000000000000000000000000000000000000000000000000000000000000bba0000000000000000000000000000000000000000000000000000000000000bc60000000000000000000000000000000000000000000000000000000000000bd60000000000000000000000000000000000000000000000000000000000000be60000000000000000000000000000000000000000000000000000000000000bf40000000000000000000000000000000000000000000000000000000000000c0c0000000000000000000000000000000000000000000000000000000000000c140000000000000000000000000000000000000000000000000000000000000c220000000000000000000000000000000000000000000000000000000000000c2e0000000000000000000000000000000000000000000000000000000000000c360000000000000000000000000000000000000000000000000000000000000c460000000000000000000000000000000000000000000000000000000000000c560000000000000000000000000000000000000000000000000000000000000c660000000000000000000000000000000000000000000000000000000000000c6e0000000000000000000000000000000000000000000000000000000000000c7e0000000000000000000000000000000000000000000000000000000000000c900000000000000000000000000000000000000000000000000000000000000ca20000000000000000000000000000000000000000000000000000000000000cae0000000000000000000000000000000000000000000000000000000000000cc40000000000000000000000000000000000000000000000000000000000000cd20000000000000000000000000000000000000000000000000000000000000ce00000000000000000000000000000000000000000000000000000000000000cf20000000000000000000000000000000000000000000000000000000000000cfe0000000000000000000000000000000000000000000000000000000000000d0c0000000000000000000000000000000000000000000000000000000000000d1c0000000000000000000000000000000000000000000000000000000000000d2c0000000000000000000000000000000000000000000000000000000000000d3e0000000000000000000000000000000000000000000000000000000000000d4a0000000000000000000000000000000000000000000000000000000000000d5a0000000000000000000000000000000000000000000000000000000000000d660000000000000000000000000000000000000000000000000000000000000d740000000000000000000000000000000000000000000000000000000000000d820000000000000000000000000000000000000000000000000000000000000d980000000000000000000000000000000000000000000000000000000000000da40000000000000000000000000000000000000000000000000000000000000dbc0000000000000000000000000000000000000000000000000000000000000dc40000000000000000000000000000000000000000000000000000000000000dd80000000000000000000000000000000000000000000000000000000000000de60000000000000000000000000000000000000000000000000000000000000dfe0000000000000000000000000000000000000000000000000000000000000e120000000000000000000000000000000000000000000000000000000000000e220000000000000000000000000000000000000000000000000000000000000e300000000000000000000000000000000000000000000000000000000000000e400000000000000000000000000000000000000000000000000000000000000e4c0000000000000000000000000000000000000000000000000000000000000e5c0000000000000000000000000000000000000000000000000000000000000e6c0000000000000000000000000000000000000000000000000000000000000e7c0000000000000000000000000000000000000000000000000000000000000e900000000000000000000000000000000000000000000000000000000000000eb60000000000000000000000000000000000000000000000000000000000000ec40000000000000000000000000000000000000000000000000000000000000ed80000000000000000000000000000000000000000000000000000000000000ee80000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000f0a0000000000000000000000000000000000000000000000000000000000000f1c0000000000000000000000000000000000000000000000000000000000000f320000000000000000000000000000000000000000000000000000000000000f3e0000000000000000000000000000000000000000000000000000000000000f4c0000000000000000000000000000000000000000000000000000000000000f5a0000000000000000000000000000000000000000000000000000000000000f700000000000000000000000000000000000000000000000000000000000000f7e0000000000000000000000000000000000000000000000000000000000000f8c0000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000fb20000000000000000000000000000000000000000000000000000000000000fc40000000000000000000000000000000000000000000000000000000000000fd20000000000000000000000000000000000000000000000000000000000000fe20000000000000000000000000000000000000000000000000000000000000ff8000000000000000000000000000000000000000000000000000000000000100200000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000009100021e140605000137020001370f0004000237020002370e0003000337020003370d0002000437020004370c0003000337020003370d0004000237020002370e0005000137020001370f000d370b000d370b000d370b000d370b000d370b000d370b000d370600057d0d370600017d017e017d017e017d0b37097d017e017d017e017d0b370d7d0a370523097d0b370d7d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017900041a1405045c01000447010004470100017f01000114010001140100045c01230447012304470123017f01230114012301140123045c01230447012304470123017f01230114012301140123045c01230447012304470123017f01230114012301140123045c01230447012304470123017f012301140123011401230100142301230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601001323010001230154012301540123015401230407012304550123045501230154012301540123015401230407012304550123045501230154012301540123015401230107035401230455012304550123015401230154012301540123040701230455012304550123015401230154012301540123040701230455012304550000000000000000000000000000000000000000000000000000000000000000000000000000730005191406030004800c0002000980080001000e80040002000f80020001001080020002000f80020002000f800200020001800e810200020001800e810200020001800e810200020001800e81020003800e8102000180018101800f8101000180018103800d82018005800d810180020011800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b500031c140306000e3a050006000e3a05000400023a0e00023a03000400023a0e00023a03000400023a0e00023a030002000207023a0e07023a02070100020001070126023a040706260407023a01260107010001000126010702260607042606070226010701000100012608070626080701000100013a16070100013a0100013a15070100013a0100013a15070100013a0107013a1607013a0107013a1607010018070100070703760e0701001807020016070100000000000000000000000000000000000000000000000000000000000000000000000000000000000001e300011d19050a0001830d000a00030f0b000a0001830200010f0100018308000a00020f0300010f017a07000a000108010f017a020f0108017a010f06000a00020f017a020f0183017a020f050001000183080001830100017a010f010001080100020f018304000200010807000108040001080200010f017a010f030003000108060001080300010803000183017a010f0300040001080500010803000108020001080100017a010f0200010f0200017a030f017a030f010803000108020001080200020f017a01000100010f017a030f017a030f017a03000108010001080400010f017a010f0100010f017a030f017a030f017a010f01000108020001080400010f02000100010f017a030f017a030f017a020f01080100010808000100010f017a030f017a030f017a030f017a020f07000100010f017a030f017a030f017a030f017a030f017a050001000108017a030f017a030f017a030f017a030f017a010f0400010001080200020f017a030f0211020f017a030f017a010f0400010001080400017a030f017a030f017a030f017a010f0400010001080400017a030f017a030f017a030f017a0500010001080500030f017a030f017a030f017a0500010001080700010f017a030f017a020f070001000108160001000183160003831500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d100041d140304000523047903260a0005000323047905260900060001230479072608000700037909260700070002790226012b07260700070001790326012b0326022b0226070007000226012b0526022b02260700012606000826022b022606000126022605000826022b022605000226032604000c26040003260126012b022602000e26020004260226012b022601000e26010005260326012b1226012b032601001426012b0326010002000a26032b0926020003000626015706260157062603000400042603570526025704260400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010b00031c15040b00021f0b000900061f09000700031f0472031f07000500021f020c011f0472011f020c021f05000300021f020c031f0472031f020c021f03000100161f01000100167201000200031f0272041f0272041f0272031f02000200011f010c011f0272041f0272041f0272011f010c011f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200011f1272011f02000100161f0100021f1472021f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000db00041a17060800040b08000600080b0600040001240b0b04000300020b01240a0b0124010b02000200030b01240a0b0124010b02000200030b01240a0b0124010b02000100040b01240a0b0124020b01000100030b01240c0b0124010b0100040b01240c0b0124020b030b01240e0b0124010b030b01240e0b0124010b030b01240e0b0124010b0100030b01240c0b0124010b01000100030b01240c0b0124010b01000200030b01240a0b0124010b02000200040b0224060b0224020b02000300050b0624030b030004000c0b04000600080b06000800040b0800000000000000000000000000000000000000000000000000000000000000000000000000f100031a160607000542011a070005000442011a0242011a0242050003000242021a0542011a0442030002000542011a0442011a0442011a020002000142011a0442011a0342011a0342011a0142020001000842011a0242011a0242011a0342010001000142011a0742051a044201000c42011a07420c42011a07420c42011a0742141a0c42011a07420c42011a074201000b42011a0642010001000942051a04420100020004420166010e0166010e0166010e011a0242011a0242020002000642011a0342011a0342011a0142020003000442011a0442011a044203000500021a0542011a0242050007000542011a0700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011900031e14020900018408000184090009000184080001840900080003840600038408000400018402000284018501840600018401850284020001840400040005840185028404000284018505840400030001840185038401850a84018503840185018403000300058401850a84018505840300020001840185148401850184020002000184018514840185018402000100018401851684018501840100010001840185168401850184010001000184018516840185018401000100018401851684018501840100018401851884018501840184018518840185018407840185048402230162012301620223018401850784028403000284018503840323010101230101012302840185028403000284018405001084050001840000000000000000000000000000000000000000000000000000000000000000000000000000730005181508058606000586018602370286060002860237018610861086108610861086108610861086108610860208028602080223018701230187022301080286020802860208072301080286020802860208028602080286020802860208028602080286020802860208028601000e08010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012500021914060500028702000387070004000b87040003000f87010003000f870100020011870200018701420c87016d02870300024201680287016802470587016d018701000388024201680247016802470168014702870168016d0187010003880342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701420247016802470268016d0200028801000342024701420247016802470268016d020003880342024701420247016802470268016d0200010002880342024701420247014202470268016d020003000c420168016d02000300058807850288020003000e88020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a300021a14060400031d0200028009000400011d0119021d0280010c018008000400021d0119011d0180010c028008000500021d0119010c028009000600011d0119010c01800a00070002850b000200108902000100091901890119018901190189011903890100148903191089011914891489128902191489148902190f89031901000a8902200689010002000419018901190789011901890119020003000e8903000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008900011c14040b0002260b000b0002260b0008000826080007000226010107260700060002260101092606000500022601010b26050005000e26050005000e2605000400102604000400102604000400102604000400102604000400102604000400108a04000400108a0400020014260200020001260101122602000c26033709261826010016260100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c500021d14020d00047f0a000d00067f08000c00037f0156017f0156017f08000c00027f0156015a0156015a017f08000c00027f028b0156018b017f08000900057f018b0156015a0156017f080008000b7f080007000b7f090006000d7f080005000e7f018c07000400047f01000a7f038c05000300047f02000a7f058c03000200047f02000b7f078c0100047f03000c7f0300058c037f04000c7f0400018c0100018c010007000b7f09000700087f028d027f08000800028c0a7f07000700068c087f060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c500021d14020d0004340a000d00063408000c000334012b0134012b013408000c000234012b0136012b0136013408000c000234028e012b018e0134080009000534018e012b0136012b0134080008000b34080007000b34090006000d34080005000e34013607000400043401000a34033605000300043402000a34053603000200043402000b3407360100043403000c3403000536033404000c340400013601000136010007000b34090007000834021602340800080002360a340700070006360834060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001bb00011d17030e00018f0b000d00018f0c000400018f15000300018f0600015f0600015f0400018f03000300018f0500015f0600015f0600018f02000800015f0300045f0300015f06000800015f01190120015f0320031908000400015f0200015f01190220045f0220025f07000400015f0100015f01190120025f0490025f01200119015f06000400015f0100015f0120015f029004230290015f01200119015f0100015f03000200015f0200025f0120015f019006230190015f022001190300018f010005000119025f019008230190025f01190400018f018f0500025f019008230190015f0120015f01190300018f018f0400015f0120015f019008230190015f0120015f05000100018f0300015f0120015f019008230190015f0120015f05000500015f01190120015f019006230190015f02200119015f04000300015f0200035f029004230290025f02190100015f03000400025f02190120025f0490025f0220015f01190100015f03000700015f01190220045f0120015f01200119015f060006000219055f0320015f02190200015f04000200018f0700015f01000319015f0a000300018f0900015f0900018f02001600018f0300000000000000000000000000000000000000000000000000000000000000000000000000bf00041a1706070006430700050005430691040003000143019101560591035403910300020002430691015403770154039102000200014306910254047701540291020001000243079101540477015403910100010001430156089104540491010002431291034311910343119102431291024312910243129101000143039106770891010001000143049102920991014301910100020002430e910200020004430c910200040002430991014304000400054306910143040007000643070000000000000000000000000000000000000000000000000000000000000000008f00041c16070f00010d05000600060d0200030d028302000400040d0172090d0100018301000300020d02720a0d030001830200030d0272090d040001830100100d030001830100100d03000193120d02000141120d0300120d0300120d0300120d0300120d03000100100d04000100100d04000200060d0572030d050003000c0d060004000a0d07000600060d0900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cf00021e15030c00070f08000a00030f031c040f07000800050f031c010f021c020f06000600040f011c020f031c010f021c020f06000500100f060006000e0f0200030f02000a00080f0300020f011c020f01000100070f0600027c0300080f020f021c060f0400037c060f021c020f020f021c010f011c050f0400017c070f021c020f0b0f0400037c080f01000b0f0300097c04000100080f087c0a000200030f047c0300047c0b000a00067c0b000900087c0a00040012940500040005940d0e050004001294050006000e9407000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010f00041b1f06040002580f00060002580d00080002580b00020008950258079502000200019509000258040001950200020001950b0002580200019502000296136f0296016f011c016f0195016f090e016f0195016f0124016f0296136f0296036f030e026f0195016f0195026f030e036f0296026f050e056f050e026f0296016f070e016f0195016f070e016f0296016f070e036f070e016f0296016f070e016f0195016f070e016f0296026f050e056f050e026f0296036f030e026f0195016f0195026f030e036f0296136f1200020e01001300010e01001300010e01001300010e01001300010e01001300010e01001300010e01001300010e01001300010e01001300010e01001300010e01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006500061c140701000697030002970900010006970208010001970198090001000797020801970198090001000897010801970198090001000b97090001000b97090001000b9709000d9708000e9707001497010015971597049703260e971597010013830100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009900061c1403040003970f9901080200030004970f99010802000200049701080f99020801000200049701080f99020801000100049702080f9902080100059702080f990308040003080f990308040003080f990300040003080f9903000400029901080f9903000400029901080f99030004000299010805990a0203000400030805990a0203000400030805990a020300040003080f990300000000000000000000000000000000000000000000000000000000000000000000000000000085000418140504000d55020002000a55043802550100010012551355135513550255018901550607095502550189015506070955025501890155060709550255018901550607095502550189015506070955030001550607095503000f550100040003550b26010004000355012605010123010103260100040003550b26010004000e550100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012500051a14060600086a06000300036a0320016a0420036a03000200016a0320036a0120046a0320016a02000100016a0120026a0120016a0120016a0120016a0120026a0120026a0120016a01000100016a0120016a0120026a0120026a0120026a0120056a0100066a0120036a0120026a0120026a0120016a0120016a016a0120046a0120066a0120046a0120016a016a0120026a0120026a0120036a0120066a0120016a046a0120026a0120046a0120016a0220026a0120016a016a0120026a0120036a0120096a0120016a016a0120036a0120056a0120066a0120016a066a0120056a0220046a0120016a0100126a01000100016a0120036a0220026a0120056a0220016a01000200016a0120016a0120026a0220046a0220026a020003000e6a0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b00041b160504000e010400020012010200010014010100010014010100160116011601160116011601160101001401010001001401010002001201020004000f0103000f00030104000f00020105000e00020106000e0001010700000000000000000000000000000000000000000000000000000000000000000000000000b900021b170508000669080006000369029a0569060004000269029a046902010469040003000269019a056904010469030002000269019a066904010569020002000a690201026902010269020001000f690201036901000100026901011169010016691669166916691669166901001469010001001469010002000a69019a0769020002000b69019a0669020003000169019a0769019a0469019a0169030004000169039a0669039a0169040006000a9a06000800069a080000000000000000000000000000000000000000000000000000000000000000000000000000007d00071a14060600080a06000400060a0125050a04000300040a0125050a0125030a03000200020a01250d0a020002000e0a0125010a02000100120a01000100120a0100010012260100082601970626029701260197012601970226019704260c97029701260c97012604970100129701000200100a02000200100a0200000000000000000000000000000000000000000000000000000000000000000000010300021a140605000137040001370300013705000400013701290137020001370129013701000137012901370400040001370129012602000137012901260100013701290126040005000126040001260300012605000400033c0200033c0100033c040004000156023c02000156023c01000156023c0400020010200200010005200601072001000100042008010620010001000420080105200101010001000101032009010320020101000100020102200e0101000100020102200e0101000100020101200f01010001001201010001001201010001000120010102200201052002010220020101200100012001010120020102200501022002010220010101201420000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ed00051a16060200120302001203020001030488010303880103070701030200060303880103070701030200010304880d03020006030388010303880103038801030200010304880d03020006030388010303880103038801030200010304180d0302000103041801030388010303880103038801030200120302000103105c010302080103015c019b035c019b035c019b015c019b015c029b015c010302080103015c039b015c029b025c019b015c019b015c029b015c010302080103015c019b015c019b015c039b015c019b015c019b015c029b015c010302080103105c010302000103109c01030200120300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013300041a14050100029d0200029d0200029d0200029d0200029d02000201019d0301019d0301019d0301019d0301019d02011501010101230101012301010123010101230101012301010123010101230101059f01010f01029f0101029f010101010da00101019f0101019f0101019f0101020101a0010101a0010101a0010101a0010101a0010101a00201059f010101010da00101059f0101020101a0010101a0010101a0010101a0010101a0010101a00201059f010101010da00101059f0101020101a0010101a0010101a0010101a0010101a0010101a00201059f010101010da00101059f0101020101a0010101a0010101a0010101a0010101a0010101a00201059f010101010da00101059f0101020101a0010101a0010101a0062301a00101059f010101010da00101059f0101150100000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f00091c14050400047e0500047e060001230100117c030001230123017e017c01240f7c020002230123017e117c027e022301230100117c027e02230200117c027e02230200117c027e022302001123027e022302001123027e022302000e23027e0123027e0223020001230b7c0223027e012302000223020011230300012300000000000000000000000000000000000000000000000000000000000000005900041a14060f00017a04000c000383017a04000e00027a04000b00047a05000700067a030002390200097a0500053901001483148c148c148c148c14a2140714070507010e0151010e0151010e0151010e015107071407148300000000000000000000000000000000000000000000000000000000000000000000000000009500091c140605000855090004000155080401550800030003550804015507000200055508040155060001000755060401a30104015505000e5502a304550200145501570100145501570155035501230227095502270123045502a30155012702a30127015502230455012702a30127025502a302a30100012702a3012707a3012702a30127010002a3010004000227090002270500000000000000000000000000000000000000000000000000000000000000000000000000000000000000b700021a1408010004580d0001000158026201580d000100045802000a2701000161015801620258026101270843012701610161045802610127014306540143012701610161016f0262016f026101270843012701610161046f0261012701430354044301270161016104270261012708430127016112611261126112611261126112610f61022a0161016102870161028701610287016102870161042a0161016102870161028701610287016102870161042a01611261000000000000000000000000000000000000000000000000000000000000000000000000000000009d00071b14050100140e0100020e1201020e020e0101010e1001020e010e0101010e0101010e1001010e010e05a4010103a4020103a4010105a4010e010e04a4030103a4010102a4030104a4010e010e04a4030103a4010102a4030104a4010e010e05a4010103a4020103a4010105a4010e010e14a4010e010e1426010e010e1426010e060c0a1f060c050c021f0100061f0100021f050c040c0e1f040c00000000000000000000000000000000000000000000000000000000000000000000b500031a14060100020e0d00020e02000100040e0900040e02000100010e0106040e0500040e0106010e02000100010e0306020e0500020e0306010e02000100010e0406070e0406010e02000100010e0306090e0306010e02000100010e01060d0e0106010e02000100110e02000200100e02000200100e02000200100e02000200100e02000200100e02000200100e0200053c0506026c0406043c02000806019607060200053c030604960406043c0200100602000000000000000000000000000000000000000000000000000000000000000000000000000000000000011f00031b1805080006a40800060002a4066702a40600040002a40a6702a40400030001a40e6701a40300020001a401220f6701a40200020001a402220e6701a40200010001a405220b67024301a40100010001a40622016704080367044301a4010001a404200322010804a40108074301a401a40620010806a40108064301a401a40620010802a4020002a40108064301a401a40620010802a4020002a40108069a01a401a40626010806a40108069a01a401a40726010804a40108026e059a01a4010001a40426036704080167046e029a01a40100010001a402260b67056e01a40100020001a40d67036e01a40200020001a40f67016e01a40200030001a40e6701a40300040002a40a6702a40400060002a4066702a40600080006a4080000000000000000000000000000000000000000000000000000000000000000014b00051e160203000484010006840100068401000384030003000493018406930184069301840393030003000484010a0684010a0684010a0384030004000184010a0184010a018402000184010a0184010a018402000184010a0184010a018405000200038401930684019306840193068402000200039301840101059301840101059301840101059302000200038401000684010006840100068402001c001c001c001c000300068401000684010006840100048402000184010105930184010105930184010105930184010103930100018401930684010a0684010a06840193048401000184010a0184010a018402000184010a0184010a018402000184010a0184010a018402000184010a0184010a01840100048401930684019306840193068401930184010004930184069301840693018406930184020004840100068401000684010006840300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011300051d1604030003631300020001630300016312000200016303000163120008630200010d0200010d0200010d0200010d05000863010d0100020d0100020d0100020d0100020d04000863020d0263010d0263010d0263010d0263020d02000100010d06630e0d0163020d08630e0d0163010d01000100010d06630f0d020008630e0d0163020d0100010d06630e0d0163010d010008630f0d020008630e0d0163020d03630101010d0101010d01630e0d0163010d010001000263010d0101010d010101630f0d020002000863010d0263010d0263010d0263010d0263010d020003000563020d0100020d0100020d0100020d0100020d0300040004630100010d0200010d0200010d0200010d0200010d030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012100021c16040b00021d0b000b00021d0b000a00041d0a000900061d090005000184031d0184041d0184031d018405000300030f0184031d0484031d0184030f03000200010f0222020f0184011d0184041d0184011d0184050f02000100010f0423010f0184021d0484021d0184060f01000100010f012202230122020f0184061d0184050f022201000100020f0222030f0184061d0184040f032301000100070f0184061d0184040f0122022301000100070f0184061d0184050f022201000200040f0284081d0284040f0200030003840c1d038403000200141d02000100161d01000100041d048406230484041d0100021d03840e220384021d011d01840522010f0122060f0122010f05220184011d010016220100020003220e00032202000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a500041a1406100004730800041c040004730800041c040004730800041c0469047304000428041c0469047304000428041c0469047304000428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428011c06230169047304190428041c0469047304190428041c0469047300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cf00031a140605000226012b0226022908000500052602290800050005260329070004000226012902260229012b01290700040001260129022b01260129012b03290600040001260129022b01260129012603290600030005260329022602290500030005260729050003000526082904000200052609290400020005260a290300020005260a290300010005260c290200010005260c29020001000126012903260d29010001260129012b02260429012b012903230529010001260129012b02260229022607290126032905260f290000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009500051c1404050006010d0003000b010a000200090103a4080102000100060104a40c0101000100030103a41001010018010d0101a4060101a4030101000b0101a4050102a4030101000200030101a4060101a4030102a4040102000300030101a4050101a4020101a40501030005000e7c050005000ea4050005000ea40500050001010c550101050005000e01050005000e010500000000000000000000000000000000000000000000000000000000000000000000000000000000000000b900011b15050900030f0a000400010f0200070f080005000b0f06000500010f0100070f08000600010f0200030f0a000600010f0300010f0b000700010f0300010f0a000700010f0400010f090004000318010f01180400010f044104000200091809410200010009180b41010001000918094101010141010009180d4109180d4109180d4109180d4109180d4101000918064103180241010001000918054101180201034101000200091809410200040005180400054104000000000000000000000000000000000000000000000000000000000000000000000000000000610003181408050001550100035506000400075505000300085505000200028707550387020001000687045504870100010009870155048701001087108710871087108710871087108708870413048708870613028708870455048708870455048700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008300041c16050600081c090004000a1c09000200081c0d0001000a1c0c000100071c0224011c0c00041c07240c00011c0a240c0001000a240c0001000a240c0001000b240b0001000b240b0002000b240900012402000c240700022403000d2404000324040005240523092405001124010006000f24020007000c2404000a00072406000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010500061c140513a5040001a501a603a502a701a508a801a501a601a5040005a502a706a501a906a5030001a503aa01a502a701a50aab02a5030001a501aa01ab01aa02a501a906a501a907a501ac01a601a503aa01a501a904a501a903a501a905a501a902a605a501a903a501a905a501a903a501a901a501ac01a605a501a903a501a905a501a902a501a902a502a602a510a903a501ac01a601a501a903a501a90fa5020001a501a902a510a901a501ac01a601a501a901a501a910a501a902a603a501a901a502ab01a502ab01a502ab01a502ab01a502ab02a501ac01a601a501a601a501a901a502ab01a502ab01a502ab01a502ab01a502ab02a502a615a501ac01a600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000db00021c19040d0001230a000c000107022309000b000307022308000a000207010102070223070009000287050702230600080004870507022305000700028701010387050703420300060002870101058705070242030005000a87050701420123020004000c8705070223010003000e8705070223020001070f8705070123010003070f870407010005070f870207020006070f870300010006070d870200014201000200060703870214068702000242010003000607098702000342010004000607078707001800180015000342150002420100150001420200000000000000000000000000000000000000000000000000000000000000000000000000a3000319140701000185010e039701850397080001000185010e028501970385019708000100020e0985060001000185010e03970185039701850197060001000185010e028501970385019703850197018503000100020e0c85030001000185010e03970185039701850397018502970100038c0f06128c128c128c128c128c010002890e190100010010190100010010190100010003190c89011901000100101901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b00041c14040b000501080009000901060008000b01050007000d01040006000f0103000400110103000200140102000100150102000100150102001601020017010100180118010100170101001701020015010100040012010200000000000000000000000000000000000000000000000000000000000000000000000000f100041d16070400031d0500031c07000300051d0300051c06000300051d0300051c06000100031c051d0100061c021d0400041c061d041c051d0300051c051d031c061d0300061c010f021d031c010f061d03000100061c010f011d021c010f061d04000300051c010f011c010f051d06000400021d031c010f031c021d07000300051d010f011c010f051c06000100061d010f021c011d010f061c0400061d010f031c021d010f061c0300061d031c051d051c0300051d041c011d055c041c0100020f0100021d061c010f051d031c040f0300051c030f051d050f01000300051c0300051d06000400031c0500031d0700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008f00071b14030b0004120900020009760412097602000876015b0412015b087602000876065b087602000812015b04ad015b0812010001120876015b0412015b087601000112097604120976015b0100097604120976015b0100097604120976020009760412097602000976041209760200097601010123010101230101087602000976041209760200097604120976000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000df0005191608040004ae010004ae0400020005ae01340135013405ae0200010002ae013403ae01340123013406ae010002ae013404ae01340123013407ae01ae013405ae01340123013407ae01ae013405ae01340123013407ae01ae013405ae01340123013407ae07ae01340123013407ae07ae01340123013407ae07ae01340123013407ae07ae01340123013407ae07ae01340123013407ae07ae01340123013407ae04ae032301340123013407ae07ae01340123013407ae010006ae01340123013406ae0100020005ae01340135013405ae0200040004ae010004ae040000000000000000000000000000000000000000000000000000000000000000006d0003191407080002240800080002240800070004240700070004240700070004240700060006240600060006af0600060006af0600050008af050005000824050005000824050004000a24040004000aaf040004000aaf040003000caf030003000c24030004240c48022412240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cf00031914071203010310100103010301100f79010301030110077901b0077901030103011005790510017901b0011001b00179010301030110067903b00279011001b0011001790103010301100179021001790110017901b0017901b0027901b0011001b001790103010301100f790103010301100f790103010301100f790103010301100f790103010301100f790103010301100f7901031203020301b10f03010303b1020301b1010301b1010303b2010303240103020301b1020301b1010301b1020303b201030324010312030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009100031a160607000698070005000a98050003000e9803000200079801850898020002000d98018502980200010012980100010012980100149814981498149814980f980285039801000e98028502980100010003980285029801850a980100020002980285029805850598020002000698018509980200030004980185049801850498030005000a980500070006980700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010d000a1d1402020009030db10303020005030389010301b1028801b1028801b1028802b1018901b103030200020301b102030389010301b1028801b1028801b1028802b1018901b1030302000503038901030db1010301230103020005030389010301b1028801b1028801b1028804b10103012301030200010301b1010301b101030389010301b1028801b1028801b1028804b1010301230103020005030389010301b1028801b1028801b1028804b101030123010302230503038901030db10103012301030223020301b102030389010301b1028801b1028801b1028802b1018801b1010301230103020005030389010301b1028801b1028801b1028802b1018801b10303020009030db1030300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013900021c16040a0001010d0009000301014b02010200010106000400010102000201014b0701070005000501014b0401014b030102000101020004000101014b0401014b0501014b0401030004000201014b0a01014b0201040003000301014b0601014b0301014b0301030003000101014b0201014b0601014b0401014b0101030001000201014b0301014b0601014b0701020002000501014b0d01014b020002000401014b0f01020002001101014b02010100010101001201014b03010100010101000301014b0d01014b0201020003000101014b0d01014b0201030003000401014b0201014b0201014b0301014b0301030004000301014b0301024b070101000101020003000301014b0301014b0201014b0401014b010104000500014b0d01050007000801014b0101070009000101014b0301014b090000000000000000000000000000000000000000000000000000000000000000000000000000008d00061914060300017f0323057f052302000300017f0323057f052302000100037f0323057f0523017f01000c7f0523027f137f047f02230d7f030003230b7f020003000323047f0323047f02000300077f0323047f02000300077f0323047f02000300027f0e5f03000123017f045f0208035f0208035f030002230e5f03000223035f0908025f030002230e5f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009700021b1405040004130600041304000200071304000713020001000913020009130100031302b30c0002b303130a1302000a130913040009130213010005130600051301000213021307000123020001230700021302130100101301000213021301001013010002131613161316130300101303000300101303000300101303000300061304b306130300030010130300030010130300000000000000000000000000000000000000000000000000000000000000000000000000000000007900061f1405060005b40f0004000ab40c0003000cb40b00020003b4050106230a00010002b406010823090001b40801092308000901072304b606000a01052308b60300060109230bb6050107230e00040108230e00010002010a230d00020002010323040105230a00030002010d230800040002010c23080000000000000000000000000000000000000000000000000000000000000000000000000000008300061e150801000e23070001000e2307001023060001000e1d070001000e1d070001000e1d070001000e1d070001000e1d070001000e1d070001000e1d07000100151d0100151d0100031d0323021d0423021d0423031d0100051d0123021d0123021d0123021d0123021d0123031d0100051d0423021d0423021d0323011d0100151d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bd00041a14060100015b0700025b0700015b01000100015b0700025b0700015b01000100025b0500045b0500025b0100028b012b015b0300015b041d015b0300015b012b0241018b0154012b025b0100025b011d029b010f025b0100025b012b011801410254012b055b021d020f055b012b02180100125b01000100125b01000100125b01000100125b01000100125b01000100125b01000100125b01000100125b010002000135052b0435052b013502000100125b01000100125b0100000000000000000000000000000000000000000000000000000000000000000000008b00051a15040400120204001202020004020166025a01660a5a02020602025a01660b5a020206020166025a01660a5a020206020e5a020206020e5a020206020e5a020206020e5a020202b104020e5a020206020e5a020202b104020e5a020206020e5a020202b104020e5a02020d02012301020123060202000a020123010201230102012305020400120200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c300021a14060700062d07000500022d06b7022d05000400012d0ab7012d04000300012d07b7012d04b7012d03000200012d03b7012d0ab7012d02000100012d03b7012d01b7012d05b7012d04b7012d01000100012d04b7012d05b7032d03b7012d0100012d0cb7012d05b7012d012d07b7012d0ab7012d012d12b7012d012d12b7012d012d12b7012d012d12b7012d0100012d10b7012d01000100012d10b7012d01000200012d0eb7012d0200020010b80200020005b8072304b80200020010b80200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f500051a18060500024a0104044a0104024a05000400034a0104044a0104034a04000300034a0104064a0104034a03000200044a0104064a0104044a02000100044a0101084a0104044a01000204010101040301010401010b04054a0101084a0104054a054a0104084a0104054a054a0104084a0104054a054a0104084a0104054a14040100054a0104064a0104054a01000200044a0104064a0104044a02000300044a0104044a0104044a03000400034a0104044a0104034a04000500024a0104044a0104024a05000600024a0104024a0104024a06000700014a0104024a0104014a070008000104024a010408000900024a0900000000000000000000000000000000000000000000000000000000000000000000000000000000000000f500051a1806050002b9014204b9014202b90500040003b9014204b9014203b90400030003b9014206b9014203b90300020004b9014206b9014204b90200010004b9010108b9014204b901000242010101420301014201010b4205b9010108b9014205b905b9014208b9014205b905b9014208b9014205b905b9014208b9014205b91442010005b9014206b9014205b90100020004b9014206b9014204b90200030004b9014204b9014204b90300040003b9014204b9014203b90400050002b9014204b9014202b90500060002b9014202b9014202b90600070001b9014202b9014201b907000800014202b901420800090002b90900000000000000000000000000000000000000000000000000000000000000000000000000000000000000bf00051b150501000801040008010100014a01010372010103720101020001010372010103720101014a014a1401014a014a010103720101037204010372010103720101014a014a1401014a014a010103720101037204010372010103720101014a014a1401014a014a010103720d0102720101014a014a1401014a014a010103720d0102720101014a014a1401014a014a010103720d0102720101014a014a070106410701014a014a1401014a014a1401014a0a4a02010a4a0900044a090000000000000000000000000000000000000000000000000000000000000000004f00071d15080300061d0c000300061d0c00151d151d151d151d151d151d151d151d151d0100051d0301011d0301011d0301011d03010100051d0301011d0301011d0301011d03010100141d0100141d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d300091d160304431200045501000126010004430c00045501000151010001000126010001550100044308000355014301000126010001510100010001260100015501000143010001510243060002550143010001430100012601000151010001000126010001550100014301000151010002430400025501000143010001430100012601000151010001000126010001550100014301000151010003430200025501430100014301000143010001260100015101000100012601000155010001430100015101000143010002430255010001430100014301000143010001260100015101000100014301000151010001260100015501000143020002550200014301000143010001550100014301000155010001000143010001510100012601000155010001430100025502430100014301000143010001550100014301000155010001000143010001510100012601000155010001430255020003430100014301000155010001430100015501000100014301000151010001260100015501000255040002430100014301000155010001430100015501000100014301000151010001260100035506000343010001550100014301000155010001000143010005550a00054301000155010005551000054300000000000000000000000000000000000000000000000000000000000000000000000000000000000000008d00061a140603000e970300010004850d970185010005850d97028504850e97028504850e97028504850e97028504850e97028504850e9702850485049706380497028504850497063804970285048503970838039702850485019708380223020d013802850200039708380423013802000200039704380223010103230101012301380200020003970d38020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011900031a160607000156056c07000500026c0156046c01ba026c050003000a6c01ba036c03000200086c016d056c021902000200026c02ba016c0119036c016d066c02000100076c0119016c0138056c0156026c01000100076c0538026c0156036c0100046c016d026c013804000138066c011c016c021c016c016d016c013806000138026d036c011c066c013806000138066c066c013806000138066c026c0156036c013806000138036c02ba016c026c0156036c023804000138026c0156046c0100076c0538036c0156026c01000100046c01ba066c0219056c01000200026c01ba046c0156086c02000200076c0156040e016d036c02000300026c0119096c016d016c030005000119096c05000700016c021c036c070000000000000000000000000000000000000000000000000000000000000000000000000000008d00071c140502000e1401a4060001000f1401a4017e050001000f1401a4017e017c017e017c017e017c101401a4027e017c017e017c017e101401a4017e050001000f1401a4060001000f1401a4060002000e1401a406000500057e01a40c000500057e02a40b000500057e03a40a000500077e0b0004000114012301260123012601230814050004000e14050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005900041d1407070006010900050005010c001001060011010500110105001101050011010500110105001101050011010500110105001101050011010500050110460100050104460142014601420a460501114601000501104600000000000000000000000000000000000000000000000000000000000000000000000000008700031c14040c00082604000a000526045102260300090005260251022302510126030009000526025102230251012601140200090006260451022603140100022607000a26031401000100052605000a260300162602001726010018261826182601001726010017260200162602000b26018a0926010003000726038a092602000500102603000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c100031a160607000643070005000a43050003000343011c0543011c0243021c030002000243031c0543061c020002000243021c0543071c02000100011c0243031c0343091c01000100021c0243011c0443091c0100031c0843091c031c0d43041c041c0743091c051c0543091c0143061c0443081c0243061c0443071c03430100031c0643071c024301000100021c0843041c044301000200011c0943041c024302000200011c0443081c0343020003000e43030005000a4305000700064307000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e700011915070700040107000500020102af040105000400010101af010102af020102af0101040003000c0103000200010101af020101af020101af060102000200010101af060102af020101af010102000100010101af020101af040102af030101af010101000100010101af0c0101af010101000100010101af0b0101af02010100100101af0101050101af0a0101af0101020101af0a0101af020101af0101020101af0a0101af020101af0101120112010e0102af02010100100101000100030101af080101af0301010002000501021e0701020003000c0103000500050101af020105000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c9000119140608000326080005000126020701260107012602070126050005000207012603070126020705000400010f0407010f0407010f040003000d07030003000107012604070126040701260107030002000107012601890126020701260189012602070126018901260107020002000207012604070126040701260207020001001107010001001126010013260100118a010001001107010001001107010002000f07020002000f07020002000f07020003000d070300030006260323032604000500098a05000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009300031a14080300057c0a000100010e0300087c05000100020e0b00047c010002240f000100020e0400010e0300010e0300010e02000100020e0300020e0200020e0200020e0200040e0100030e0100030e0100030e0200100e0200100e0200100e0200100e0200100e0200100e0200100e0200100e0200020e0172010e026d010e026d010e0172050e0200100e0200100e02000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c900031a160607000651070005000351010001510200035105000300035102000151020001510200035103000200035102000151027e0151027e01510200025102000200025102000151027e0151027e0151027e015101000151020001000251020001510100017e0151027e0151027e0151017e010002510100010001510200015102000151027e0151027e0151017e01000151010001510100025101000151020001510100017e0262017e0151017e0100015102000251015101000151027e0151020004620200015102000151010001510251027e0151027e06620151027e01510200015101510100017e0151027e01510662027e0151017e01000251015101000151027e0151027e0462027e0151027e01510100015102510100017e0151027e0151017e0262027e0151027e0151017e02510100015101000151027e0151027e01510100017e0151027e0151027e01510100010002510100017e0151027e01510100017e0151027e0151027e025101000200015101000151027e015102000151027e0151017e010002510200020002510200015102000151027e015102000351020003000351020001510200015102000351030005000351020001510100035105000700065107000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019500041d1403020001bb060001bb060001bb060001340200010003bb0400013402bb040003bb040001bb013401bb010005bb020001bb013403bb020005bb020002bb013402bb05bb020001bb013403bb020003bb013401bb020002bb013402bb03bb013401bb020001bb013403bb020003bb013401bb020005bb03bb013401bb023401bb013403bb023403bb013401bb023402bb013402bb03bb013401bb023401bb013403bb023405bb023405bb03bb013401bb023401bb013403bb023405bb023405bb03bb013401bb020005bb020005bb020005bb013404bb020005bb020001bb013403bb020003bb013401bb013404bb020005bb020001bb013403bb020003bb013401bb013402bb013401bb023405bb023401bb013403bb023403bb013401bb013404bb023405bb023401bb013403bb023401bb013401bb013401bb013404bb023405bb023401bb013403bb023403bb013401bb013404bb020005bb02000585020003bb013401bb05bb020003bb013401bb02000585020003bb013401bb05bb020003bb013401bb020001bb013403bb020005bb0000000000000000000000000000000000000000000000000000000000000000000000000000000000009500031814050800062305000800062305000300102303420726078702260100014201000726078702260342072607870226034207260787022603420726078702260342072607870226034207260787022603420726078702260342072607870226034207260787022603420726078702260342072607870226010001420100022603ae022607870226034207260787022603001023000000000000000000000000000000000000000000000000000000000000000000000000000000000000af00051b140516bc010002bc010002bc010002bc010002bc010002bc010002bc010002bc010016bc02bd01bc10bd01bc02bd02bd01bc10bd01bc02bd02bd01bc10bd01bc02bd02bd01bc10bd01bc02bd01bd017b01bc10bd01bc02bd02bd01bc10bd01bc02bd02bd01bc10bd01bc02bd02bd01bc10bd01bc02bd02bd01bc10bd01bc02bd02bd01bc10bd01bc02bd16bc010002bc010002bc010002bc010002bc010002bc010002bc010002bc010016bc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b500011f18010e00020f0e000d00040f0d000c00060f0c000b00030f015c040f0b000a00030f015c060f0a000900030f015c040f015c030f090008000a0f015c030f080007000c0f015c030f07000600120f06000500140f05000400160f04000300180f030002001a0f020001001c0f01001e0f0600120f06000500140f05000400160f04000300060f065c0c0f030002001a0f02001e000700010f0e00010f07000600020f0e00020f06000500030f0e00030f0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000db00021c14040b0002be0b00090006be0900080002bf01be02bf01be02bf0800070003bf01be02bf01be03bf0700060003bf01be04bf01be03bf0600060003bf01be04bf01be03bf0600050003bf01be06bf01be03bf0500050003bf01be06bf01be03bf0500030012be0300030012be030005000ebf050005000ebf0500010002bf012310be012302bf0100010002bf012310be012302bf010001be02bf012310be012302bf01be01be02bf012310be012302bf01be010002bf012303be0b2302be012302bf0100010002bf012310be012302bf010005000ebf05000000000000000000000000000000000000000000000000000000000000000000000000008700031b14050c00042003ba03000a00062001ba012301ba012002000900072003ba022001000800042005000320025f070004200800035f070004200800025f010e070005200800020e080006200600020e090008200300010e01000a00092003000b00092002000d00082001000f00062001000100156a166a0b2006090520162001001420010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012300031b18050a00024f0a000900044f0900040002ba0200019a044f019a020002ba0400030005ba019a044f019a05ba0300020007ba019a024f019a07ba0200020007ba041307ba0200030004ba0213046d021304ba0300030003ba0113086d011303ba03000200029a02ba0113086d011302ba029a02000100034f019a01130a6d0113019a034f0100054f01130a6d0113054f054f01130a6d0113054f0100034f019a01130a6d0113019a034f01000200029a02ba0113086d011302ba029a0200030003ba0113086d011303ba0300030004ba0213016d0385021304ba0300020007ba041307ba0200020007ba019a024f019a07ba0200030005ba019a044f019a05ba0300040002ba0200019a044f019a020002ba04000900044f09000a00024f0a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d700031c1904050003011000040005010f000300014205010800022301000223020002000242050108000242010002420200010004420301090006420100074204000223064201110142011102420542070006010642044209000b01054209000a010100054209000901020004420a00080104000f4205010400104204010400114203010400124202010400054207010742010104000542062302010642010004000542090104420200040001420e0002420300010004420e00014204000100014211000242030001000123120002420223010001231600000000000000000000000000000000000000000000000000000000000000000000000000000000006d00061914070300051c0300041c03000200071c0100061c02000100041c020f0a1c01000100041c020f0a1c010001000d1c020f011c010001000d1c020f011c01000100101c01000100101c01000100020f0e1c0100011c020f0f1c121c121c126702670e5c026701001067010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010f00051914070700010b0100010b0100010b06000800030b07000800030b070007000157030b0157060003000157030b0157030b0157030b03000200010b0157030b0157030b0157030b015702000100020b0157030b0157030b0157030b0157010b0100030b0157030b0157030b0157030b0157020b030b0157030b0157030b0157030b0157020b030b0157030b0157030b0157030b0157020b030b0157030b0157030b0157030b0157020b030b0157030b0157030b0157030b0157020b030b0157010b01c0010b0157030b0157030b0157020b030b0157020b04c0010b0157030b0157020b0100020b0157030b0157030b0157030b0157010b01000200010b0157030b0157030b0157030b0157020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000081000419140108000f34010008000f34010009000d23020009000d26020009000126015d0b26020009000126015d0b260200013401000234010004340d26020002000134020004340d26020001000234010005340d26020009000d26020009000d26020009000d26020008000f34010008000f2301000700118e0700118e0700112300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008900051b16030c00028c0a000b00048c09000200028c0700058c0600028c0200048c0400028c0104018c0104018c0400048c0200068c0200068c0200068c0300148c01000300148c01000300148c01000300148c01000400128c02000400128c02000400118c03000400118c030005000f8c040003000f8c0600118c07000400028c12000200048c12000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008f00091c120204000a8002000a80040001800501048002000180050104800400018005010480020001800501048005800501078005010480058005010780050104800180030001800501048002000180050104800180030001800501048002000180050104800180030001800501048002000180050104800400018005010480020001800501048004000a8002000a80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b100011a140609000241090009000241090008000441080007000641070007000641070006000841060006000841060005000a41050003000ec1030001c2010001c10ec201c1010001c202c201c10ec201c102c202c201c10ec201c102c202c201c10ec201c102c20200104c02000200104c02000200104c02000200104c0200020003c20123010101230101012301010123010101230101012302c20200020003c20b4102c202000300088a018e078a010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000df00051d1805030001b10c00040d0400020002b10e0004b10200010002b10e0002b1017e022301b10100010002b10e0002b1017e04b101000fb1017e02b1017e02b1029802000eb1017e02b1017e01b1017e02b103000eb1027e02b1010002b1030010b1030001b10100030010b10500030010b10500030011b10400030011b10400020005b1017e0cb10400020005b1017e01230101012301010123010107b10300020004b1017e0ab1010003b10300020003b101000ab1040001b10300010002b1110001b1030003b1100002b1030001b1120001b1040001b1120001b104000000000000000000000000000000000000000000000000000000000000000000f100031a160607000626070005000326042b0326050003000326022b0426022b0326030002000226022b0826022b0226020002000126012b0c26012b0126020001000226012b0c26012b0226010001000126012b092603290226012b012601000226012b032603290826012b02260126012b1026012b01260126012b1026012b01260126012b1026012b01260126012b1026012b01260226012b112601000126012b1026010001000226012b0f26010002000126012b02260129012604290426012b0126020002000226022b0826022b0226020003000326022b0426022b0326030005000326042b03260500070006260700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008700051b1405020012210200030010950300010014210100162113210151022101211207015101070121012114070121012112070151010701210121140701210121140701210121140701210221080703250707022101000121070701140125012302250607012101000100022107070325060702210100020003210c070321020004000e2104000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d500061d16020900010801000108010001080100010801000108090007000c08080006000f08060001000208020004080e7a040004080200137a020001000408157a01000508157a010001000408117a0108047a02000308107a02c5047a010004080e7a02c5047a0282020003080d7a01c5047a02820200010004080c7a01c5047a018204000508057a0208047a010801c5037a018205c501000408047a0108057a020801c5027a018201c5047a010004080200077a040801c5077a0200010002080600027a0508027a01c5047a04000c0003080c00000000000000000000000000000000000000000000000000000000000000000000000000000000000001e300031e15020800068e0100058e08000700018e0626018e0526018e07000600018e0126068e0126058e0126018e06000300018e0100018e0126018e0626018e0526018e0126018e0100018e03000400018e0126018e0126068e0126058e0126018e0126018e04000400018e0126018e0126018e0500018e0400018e0126018e0126018e04000400018e0126018e0126018e0a00018e0126018e0126018e04000400018e0126018e0126018e0a00018e0126018e0126018e04000200018e0100018e0126018e0126018e0a00018e0126018e0126018e0100018e02000300018e0126018e0126018e0c00018e0126018e0126018e03000300018e0126018e0126018e0c00018e0126018e0126018e03000300018e0126018e0126018e0c00018e0126018e0126018e03000300018e0126018e0126018e0c00018e0126018e0126018e03000100018e0100018e0126018e0126018e0c00018e0126018e0126018e0100018e01000200018e0126018e0126018e0e00018e0126018e0126018e02000200018e0126018e0126018e0e00018e0126018e0126018e02000200018e0126018e0126018e0e00018e0126018e0126018e02000200018e0126018e0126018e0e00018e0126018e0126018e0200028e0100018e0100018e1000018e0100018e0100028e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b100041d1405050005c605c70900040006c701c605c70800030006c602c701c605c70700020007c701c602c701c605c70600020008c701c601c701c605c70600010009c701c602c705c601c70500010009c701c608c70500010009c701c608c70500010009c701c608c70500010009c701c608c70500010009c701c608c70500010009c701c608c70500010009c701c608c70500010003c70fc6050004c701c60d2301c605c704c701c60dc701c605c718c7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009700041c1704050005240400052405000300092401000824030002000624020106240201042402000100092401010524020101240101032401000100132401010224010014240101032418241824182401001624010001001624010002001424020002001424020003001224030004000724020101230624040005000e24050006000c24060007000a2407000900062409000b0002240b0000000000000000000000000000000000000000000000000000000000000000000000000000000000d100031d14020d0002230c000400016104620261062302610462016103000d0002230c000d0002230c000a000720075603000100022006000220019a0120019a0120019a0120085602000100032004000320019a0120019a0120019a012009560100010002620e200556030102560162022301620d200556030102560162022301620d200556030102560100026202000c200a5606000b2008560101015607000a2008560101015608000920065602010156010009000820085602000a000e2003000c000123020001230b0007000e230600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006700061b1405020003181100010005181000010006180f0008180e0008180e0008180e0008180e0009180d000b180b0001000c18090002000418020008180600030002180400091804000300021805000a1802000300021806000318042304180300025b07000a5b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a900051b150507000805070004000305081f03050400020002050e1f0205020001000105121f010501000105141f01050105141f01050105141f0105010d0105121f0105011f020d02050e1f0205010c011f040d0305081f0305020c021f070d0805060c011f040d030c020d010c010d090c021f070d0e0c011f0100030d030c020d0b0c011f01000200050d030c0105010d0205010d050c02000400030c020d090c04000700080c0700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bf00061b15050900018e0100028e0900040003ad0100068e010003ad04000200028e03ad068e020003ad04000200028e07ad018e06ad04000100038e06ad036d05ad04000200028e07ad016d06ad04000200028e07ad016d06ad04000100038e07ad016d06ad04000200028e07ad016d06ad04000200028e07ad016d06ad04000100038e128a0200028e0e8a0123018a0123018a0100038e028a016d0123016d0123016d0123016d098a048e128a0100038e128a0100018e0100018e0e8a0400000000000000000000000000000000000000000000000000000000000000000117000317140905000489050002000183013906890139018302000100028301390689013902830100028301390289016d0219038901390283028301390389026d0119028901390283028301390589016d0119018901390283028301390389026d0119028901390283028301390289016d0219038901390283028301390389026d0119028901390283028301390589016d0119018901390283028301390389026d0119028901390283028301390289016d0219038901390283028301390389026d0119028901390283028301390589016d0119018901390283028301390389026d0119028901390283028301390289016d0219038901390283028301390389026d0119028901390283028301390589016d0119018901390283000000000000000000000000000000000000000000000000000000000000000000000000000000011100031c1505080001830e000100027c04000183015101830d000100021103000183035101830c00010002110200018302510183025101830b0001000211010001830251018301c8018302510183071103000100021101830351038303510183071102000100011101830b51018307110100010001830d510183071101830f51078317510351051103510b8301510351051103510183031103c80311018301510351051103510183021105c80211018301510351051103510183011107c801110183015103510311012601110351018306c8017c02c801830151035105110351018305c8027c02c80183015103510111032301110351018304c8037c02c8018301510351051103510b8301510251077c0e5100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cf00071c19020500061c0893051902000400021c059b08010316031901000400011c019b051c08930319020102190400011c019b051c08930319020102190400071c089305190116011904c9071c089305190116011904c9071c0893071904c9071c089305190116011904c9071c0893071904c9071c089307190400071c089307190400011c029b041c089307190400011c029b041c01930201019301010393061901000500061c0893051902000800021c0c00021902000800011c0d00011903001600011903001a001600011903000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011b00051e1405080006010b0005000401013c0201023c0301080004000101033c0301013c0301023c0101070003000101013c0601013c0501013c0101060002000101033c0101043c0101013c0101053c0101050002000601013c0601013c0401050001000101013c1001013c0101040001000501053c0101063c030104000100140104001201013c0101013c020102000101023c0901063c0101013c040101000301013c0401013c0501013c0201013c0101013c0201013c010101000301013c0401013c0501013c0301013c0201023a013c01010101023c0101053c0101033c0201043c0201023a013c01010101013c0301013c0501013c0401013c0101013c0201033c010101000401013c0501013c0401013c0101013c05010100000000000000000000000000000000000000000000000000000000000000000000000000e700021b14060400040f0d000300060f0100061c05000700020f091c03000500080f031c01ca031c01000400040f01ca030f031c01ca0200031c0400020f020002ca0100010f021c02ca0300021c0400010f040002ca0100021c01ca0400021c090002ca0200011c01ca0500011c0400060f01ca020002ca06000300080f01ca010002ca06000300080f01ca010002ca06000300080f01ca010002ca06000300080f01ca010002ca060003000e26040002001026030001000d260146042602000226014601260229022602290226014603260146032601000626022906260146052601001426010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011b00031c1b050700055f016a035f07000400016a0e5f04000200065f016a0c5f02000200135f02000100085f0576055f016a025f01000100015f016a045f0976065f0100055f0d76055f015f016a025f0f76025f016a015f045f0f76045f035f1176035f035f1176035f0100015f1376015f01000100015f1376015f01000100015f1376015f01000100015f036e0176036e0176036e0176036e0176036e015f01000100156e01000100016a086e0690066e01000100016a0200016a0e6e016a0100016a01000100016a0200016a0e00016a0100016a01000100016a0200016a0e00016a0100016a0100016a0200016a0f00016a0200016a016a0200016a1000016a0100016a016a1300016a0100016a016a1500016a016a1500016a000000000000000000000000000000000000000000000000000000000000000000000000b500011d1a0309000882090007000c82070007000982037d07000400107d023704000300057d0f37030003000b3709380300010005370a3809370100010006380a37087d0100010009370f7d01000637147d0437167d1a7d1a7d1a7d187d0237167d0437147d0637010001370b7d0c37010001000e37042503370382010003000b370225022302250382030003000482083704250482030003001482030004001282040007000c8207000900088209000900088209000000000000000000000000000000000000000000000000000000000000000000000000000000000000009900051a1406037e0a00037e0400017e0238017e0800017e0238017e0400017e0338017e0600017e0338017e04000100017e0338017e0400017e0338017e05000200017e0238027e0200027e0238017e060003000a7e07000300087e09000300087e09000300087e09000300087e09000300067e088103230300067e088103230300067e0b810300067e022309810300067e0b810300067e0b81000000000000000000000000000000000000000000000000000000000000000000000000000063000218140807000224070007000224070006000424060006000424060005000689050005000623050001000224028902240289022402890224010001000e23010010241024102410241024102410241024022403890224038906240424048908241024000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a700061b1605161f011f010b013c120b011f011f1456011f011f1456011f011f1456011f011f1456011f011f1456011f011f1456011f011f1456011f011f1456011f011f1456011f011f1456011f031f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e021f021f130e011f021f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e031f011f130e021f161f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009100021e19050800031e0e000700081e0a0007000c1e060006000c1e070006000b1e080005000b1e090005000a1e0a0004000a1e0b000400091e0c000300091e0d000300081e0e000200171e0200161e01000100151e03000100131e0500121e070005000b1e090004000a1e0b000400081e0d000300071e0f000300051e11000200041e13000200021e15000100011e170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ab00021b16050a00018c0b000900018c0c00030001910600018c040001400600020001910300018c0200038c0140010002400600030002910200028c0191028c034004000291010005000340028c0191018c014001910240018c0200019102000100018c0200014001910340018c0191018c024001910240028c0300038c034001910340038c024001910140018c04000100018c0100018c024001910340018c0191028c014001910140028c03000300018c0191024001910240028c0191028c02400191028c010001910100028c0191018c024001910240028c0191028c0240038c010001910200018c0140028c014001910240058c0240028c0191018c01910100058c0740038c01400191038c010001910100038c01910840028c01400191028c020001910200018c01910a40018c0191028c03000200038c0140018c01910640018c0191038c01910200030001910140028c0191014004230140048c0100029101000200048c01910740028c0191028c03000200018c010002910740028c0191018c01910400050001910100014001000340018c0191018c0100018c0500090001400191010001910900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008300051d1503070004240400042407000500072402000724050004000d2402010324040003000e2403010324030002001324010102240200010018240100010006240c01062401000524100105240424120104240324140103241a240100182401000100182401000200162402000300082404010824030005001024050008000a2408000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009d000118140806000324070004000724050003000137092403000200012401370a240200020002240137062401370224020002000324043702010324020002000724023703240200020007240237032402000b2a0101042a0b2a0101042a0b2a0101042a0b0d0105040d0b0d0105040d0b0d0105040d0b0d0105040d0b0d0105040d0b0d0105040d060d0223030d0105040d0b0d0105040d0b0501010405000000000000000000000000000000000000000000000000000000000000000000006d00031814080400081f040003000a1f03000200031f0600031f02000200021f0800021f02000200011f010d0800011f010d02000200020d0800020d0200107a108a108a108a108a108a108a108a018a026d0a8a026d018a018a026d048a0223048a026d018a078a0223078a108a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008700081d1403010008290800082901000229060a022906000229060a022901260829012606000126082901260a2606000a26012601280826060008260128012601260128092604000826022801261726012802260100182601000100152601280226010002001626020003000626020a0126020a0126020a0626030004001226040006000e26060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007900071c1405070005890b00070005890b000a0002890b000a050289030508000a050289030508000a050289030508000a050289030508000a0502890305060102000a05028903050401013a010102000a0502890305060102000a0502890305060102000a050289030501010423010102000f050601020017050000000000000000000000000000000000000000000000000000000000000000000000000000fb00061b14050acb01000bcb01cb0b0001cb040001cb030001cb01cb01000bcb010001cb010004cb010001cb01cb010001cb030001cb070001cb040001cb010001cb01cb030001cb030007cb010004cb010001cb06cb010002cb030001cb080001cb01cb010001cb050001cb010001cb010001cb010006cb010001cb01cb010005cb010001cb010003cb080001cb01cb050001cb050001cb010008cb01cb010003cb010003cb010001cb080001cb010001cb01cb030001cb010001cb010001cb010008cb010001cb010001cb03cb010001cb100001cb01cb010001cb010004cb010007cb010005cb01cb030001cb080001cb070001cb14cb010001cb000000000000000000000000000000000000000000000000000000000000000000000000d900071a1f05010002950f06012102060100029501060e9201210143010e0100029501060e920121010e01430100029501060e92012102c80100029501060e92012102060100029501060e92012102c80100029501060e92012102060100029501060e92012102c80100029501060e92012102060100029501060e92012102c80100010e019501060e9201210206020e019501060e92012102c8020e01950f06012102c8010e02950f0601210206010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e140000000000000000000000000000000000000000000000000000000000000000000000000000008d00031b14080100014a0d7f04000100014a067f0524027f0400034a057f09240289034a097f05240289034a0d430300034a0143017f0143027f0143047f0143017f01430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d43030003c80d7f0300034a0d430300034a0d4303000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e500041a14061497019702060101010603010a0601010197019701060101010603010b060101019701970101010603010c06010101970197010603010d0601010197019703010106063c0106063c01010197019702010206013c0406013c0106013c0406013c0101019701970101043c0406033c0406013c0101019701970106013c0206013c0406013c0106013c0406013c0101019701970106013c0206013c0406013c0106013c0406013c0101019701970406063c0106063c0101019701971106010101970197110601010197019711060101019701971106010101970197120101971497000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013b00021a1406030002230300022403000224050002000172030001230172030001240172030001240300140c010c030f020c030f020c030f020c0123010c0123010c010c010f015c010f020c010f015c010f020c010f015c010f020c0124010c0123010c100c014e010c01b0010c020c0123040c0123030c0301020c014e010c014e010c020c0123040c0123030c0372020c014e010c014e010c020c0123040c0123040c0123070c020c0123040c0123040c0123070c020c0123040c0123040c0123050c011f010c020c0123040c0123040c0123070c020c0123040c0123040c0123050c011f010c020c0123040c0123040c0123070c020c0123040c0123040c0123050c011f010c010c0301030c0123040c0123070c010c0372020c0301030c0123040c021f010c020c0123030c0372030c0123040c021f010c140c000000000000000000000000000000000000000000000000000000000000000000000000a500031a160607000687070005000387035e0487050003000487035e0787030002000487025e0687015e0387020002000e87015e0187020001001287010001000587015e0887015e038701000287015e11870187025e11870187015e128714871487148701001287010001000f87015e028701000200058702230687025e0187020002000b87035e0287020003000687015e0387015e0387030005000a87050007000687070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a100051c15040383010002830c000283010003830383010002830c850283010003830383010002830c850283010003830383010002830c8502830100038307830b85068307830b85068307830b85068304000e85060004000f85050004000f85050004000f850500040005850d980200040005850d98020004000585069802840298028401980200040005850d9802000400058501980b840198020009000d9802000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a300011f14030c0002350e000a000235030002350b0009000135030002350d0008000135030001350f00080001350200013510000800013502000135100008000135020001351000040009110f0003000211014909110d000200021101490b110c000100021101490d110b00010011110a001311090002110149101109001411080001001b1102001511050003000a11078508000400021107850711080005000f110800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d300031c15040a0004010a0009000101028d0301090008000101018d0601080008000101018d0601080007000a01070007000101018d0601018d0101070006000c01060006000c01060005000e01050005000e0105000400021d0201021d0401021d0301011d04000400021d0101041d0201041d0101021d04000300021d0201051d0101041d0201021d03000300021d02010a1d0201021d03000200031d0201051d0101041d0201031d02000100021d01010f1d0101031d01000b1d0301071d0101021d0100161d01000300061d0600061d030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009500031e1407070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e050002000e05070002000e05070002000e05070002000e05070002000e050400030e02000e050400030e02000e050400030e02001205030002000e05011f0105011f0105030002000805024b0105024b050503000200120503000000000000000000000000000000000000000000000000000000000000000000000000000000000000010100031b14020900067f0200017f07000700037f0400017f0300027f0100017f03000600017f0200037f0300037f07000700027f0100017f0e0019000300160103000101016f014b1101014b010101000101014b0101016f014b1101014b0101020101000101016f024b1001014b0101010102000101016f024b1001014b0101010102000101016f024b1001014b0101020101000101016f024b1001014b010101000101014b0101016f024b120102000101014b0101016f014b1101010004000101016f014b1101010005000101016f014b040104370401014b0201020006000101016f014b040102370401014b0201030007000101016f024b0601024b020104000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c500021c150408000855080005000855025104550500030003550151045502510455025102550300020008550451055501510255020001000a5502510a5501000100035502510c5503510255010003550451065502510255055102550155015102550251035501510355025102550551025501550151105503510355185501001655010003001255030005000eaf050005000eaf050005000eaf050005000eaf050005000eaf0500050002af045508af0500050002af01550223015508af0500070004550d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006300021814080700022607000700022607000600042606000600042606000500068a050005000623050001000226028a0226028a0226028a0226010001000e230100104610461046104610461046104610460246038a0246038a06460446048a08461046000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb00051c1404040002ce01cd03ce01cd03ce01cd03ce01cd01ce0400020001cd03ce01cd03ce01cd03ce01cd03ce01cd03ce020002ce01cd04ce01cd03ce01cd03ce01cd03ce01cd04ce03ce01cd03ce01cd03ce01cd03ce01cd03ce01cd04ce03ce01cd03ce01cd03ce01cd03ce01cd03ce01cd04ce03ce120103ce01001601010001001601010002001401020001001601010001001601010002001401020001001601010001000a0103cf09010100020014010200030012010300000000000000000000000000000000000000000000000000000000000000000000000000dd00021e1402100001360b00100001360500013605000f000136040002360600050001d0010001d0010001d005000136020002360800040001d0015c01d0015c01d0015c01d002000298038803160700030001d0015c01d0025c03160398068802160600020001d0015c01d0025c02160419038803c20288011602980400020001d0015c01d0015c02160619018801c2034601c201880116039803001c0b01001a0b010001001a8901000200188902000200180b02000300168903000300160b03000400140b04000500070b0789040b05000600100b060008000c0b0800000000000000000000000000000000000000000000000000000000000000000000012b00041a14060a00019c09000800019c0100019c0100019c07000900039c080008000137039c013707000200029c0137039c0137039c0137039c0137019c02000100039c0137039c0137039c0137039c0137029c0100049c0137039c0137039c0137039c0137039c049c0137039c0137039c0137039c0137039c049c0137039c0137039c0137039c0137039c049c0137039c0137039c0137039c0137039c049c0137039c0137039c0137039c0137039c049c0137039c0137039c0137039c0137039c049c0137039c0137039c0137039c0137039c049c01c8019c0123019c0137039c0137029c01c80137039c0100039c0137029c0423019c0137039c0137029c01000200029c0137039c0137039c0137039c0137019c02000300019c0137039c0137039c0137039c0137030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b30002181406070001240a0004000b24030003000b24040003000c24030001000e2403000624070e0424010002000424070e04240100020002240c0e01240100020002240c0e01240100020002240c0e01240100020002240c0e01240100020002240c0e012401000200100e0200040e0a08020e0200030e0c08010e0200030e010801240208010e0108010e030801240108010e0200030e01240a080124010e0200030e01240a230124010e0200030e0c24010e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000008b00021b14010d00010d0c000d00020d0b000d00030d0a000d00040d09000d00050d08000d00060d07000b000b0d040009000e0d03000800100d02000100030d0300110d02000200030d0100130d01000200170d01000300160d01000200180d0200030d0100140d0100030d0200130d0100030d0400080d090b02000800060d090b03000900040d090b04000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057000918140704000b86020002000e86010002000f8602000f8602000f86010010861186118602000286047f0623037f020001d10486017f0623017f0286020002d1037f04d1012303d1027f020008d1012301d1012304d100000000000000000000000000000000000000000000000000000000000000000000000000000000a3000418160810511051045108a40451035102a4012304a4012302a40351035102a4012304a4012302a40351035101a4037c02a4037c01a40351035104a4022304a40351035104a4022304a40351045108a404511051045108a40451035102a4012304a4012302a40351035102a4012304a4012302a40351035101a4037c02a4037c01a40351035104a4022304a40351035104a4022304a40351045108a4045110511051000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f5000218140507000ad20200060001d20ad301d20100050001d201d304d402d304d401d301d2050001d201d30ad401d301d2050001d201d301d402d501d302d401d302d501d401d301d2050001d201d303d401d302d401d303d401d301d2050001d201d304d402d304d401d301d2050002d201d308d402d301d20400042b01d308d401d301d20300062b08d401d301d20300062b01d207d401d301d20200072b01d207d401d301d20200072b01d207d401d301d20200072b01d207d401d301d20200062b02d207d401d201000200052b03d206d401d202000200032b04d206d401d20300010001d2012b07d206d403000bd207d40100000000000000000000000000000000000000000000000000000000000000000000000000000000000000f300021d14040a0005810a000700048103820481070007000181098201810700050003810982038105000500018105820398058201810500020004810282099802820481020002000181058209980582018102000200018102820f980282018102000381018211980182038101810382119803820181018102821398028201810181048206980351079803820181010002810382049805510498038202810100030002810182039807510398018202810300050001810198025507510255019801810500040001810f550181040003000481035505810355048103000300018102d6058103d6058102d601810300040011d6040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009700091c18020700036d0572097502240600046d027201b10272097502240600046d0572087503240100096d0572087503240a6d0572087503240a6d0572087503240a6d0572077504240a6d0572077504240100096d0572077504240600046d0572077504240600036d0224017201b10272067505240700036d057206750524160001240100022418000224180001240100180001240100000000000000000000000000000000000000000000000000000000000000000000000000000000007900051914060100042309000423010006230700062306230901042305230b01032304230d010223010002230e010123010002001001010002001001010002001001010002001001010002001001010002001001010002000a0104230201010002000a010423020101000200070106230301010002001001010000000000000000000000000000000000000000000000000000000000000000000000000000005900091d14031ad701d7180001d701d7180001d701d7180001d701d7030010d7050001d701d7030001d7140001d701d7030001d7140001d701d7030001d7140001d701d7030001d7140001d701d7030016d701d7190014d7060000000000000000000000000000000000000000000000000000000000000000000000000000010100041b1605040005d80d00020002d8036004d80b00010002d8016003c9036002d80a00010002d8016001c902d8016002c9016001d80a0002d8026003d8016002d8016002d8090001d8016002c9036001d8046002d8080001d8016002d8016003d8016001d802c9016005d8040001d801600bd8016006d8020002d8016012d80100010001d8016010d8016001d80100010002d8016012d8020002d801600dd8026002d803000fd802c9016001d8040005d8036005d8016002d8016001d8050002d8016002d802c9056001d8026002d8060002d8026002d8016004c9016002c901d80100080002d8036004d8016003d801000a0003d8046003d802000d0005d8040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007300031714090600022306000600022306000500042305000500042305000400062304000400022301570323040003000223035703230300030007570123030002000a57020002000a57020001000c57010001000c5701000e570e57025704260557032601570626035704260326083703260e2600000000000000000000000000000000000000000000000000000000000000000000000000000000000000010f00021e14030a0001d9020001da020001d90a000a0001d901db010001da010001db01d90a00080001d9020001db01dc01da01dc01db020001d90800090002db05dc02db0900050001d9010002aa01dd02aa03dd02aa01dd02aa010001d90500040002d902aa01dd04aa01dd04aa01dd02aa02d90400050002aa01dd02aa02d901aa01dd01aa02d902aa01dd02aa0500040002aa01dd02aa02d902aa01dd02aa02d902aa01dd02aa0400030002aa01dd0faa01dd02aa0300020017aa020001d9010017aa010001d9010001d917aa01d9010002d917aa02d9010001d917aa01d9010001d9010017aa010001d9020002aa01da11aa01da02aa0200030001aa13da01aa0300030015aa0300050011aa05000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008500041b15080400050e0a000200020e010501590105040e08000100020e0105080e070001000b0e07000d0e06000d0e06000e0e05000e0e05000f0e0400110e0200130e130e130e130e010e0159070e0159050e0159030e010e0159010e0159010e0159010e0159010e0159010e0159010e0159010e0159010e0159010e010e1159010e130e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b700031b15050400040f0e000200080f0c000100030f01c0060f0b000100030f015c030f01c0020f0b00020f01c0060f015c020f0a00020f015c030f01c0070f0800060f015c040f01c0015c050f0400010f01c0120f0200010f015c130f0100150f0100160f0100150f0100130f01c0010f0100020f01c0100f015c010f0200010f015c120f02000b0f012302c0015c040f01000300030f01c0015c010f01c0040f025c050f01000500050f015c090f020007000b0f0400000000000000000000000000000000000000000000000000000000000000000000000000000000014100011c14040b0002cc0b00050002cc030002cc050002cc0500060002cc030002cc030002cc0600050002cc030002cc050002cc0500060002cc080002cc0600050002cc04000209040002cc0500060002cc0200020901190109020002cc0600090001de040901de0900050002de010903de020903de010902de0500030012de0300020001de010910de010901de0200010016de0100010001de04bb01de04bb01de04bb01de04bb01de01bb010018bb18bb03bb029503bb0196019503bb0195019603bb029504bb01bb01950196029501960295019202950196029501960295019602950196029501bb010001950196029501960295099201960295019602950100020001960295019602950192029501960295019602950196029501960195020002000196029501960295019602950196029501960295019602950196019502000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cf00041d14020c0003420c000b000142039301420500027604000800036c012503930125026c02000176016c0176040006000276026c017605120176026c0176026c0176040005000176106c01760400020001760100036c01010f6c01760300010001760259146c01760200010001760159136c0112016c03760100017601590176166c0176015901000276166c017603000176146c037603000276156c0176030001590176146c0176010004000376106c02760200050013760300060006760112020101120676050008000c7607000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008500061d140305000924071d050003000c24081d03000200062401010724081d02000100032402010a24091d01000100032402010b24081d01001124091d1124091d1124091d1124091d1124091d01001024061d010f011d010001000f24071d010f011d010002000a2403230124061d010f011d020003000c24081d030005000924071d050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a5000319160702df0e0002e00ddf05e0010002df0ee00100010003df0de00100010003df08e003df02e00100010003df0de00100010003df02e002df09e00100010003df0de00100010003df0de00100010003df0de00100010003df0de00100010003df0de00100010003df0de00100010003df0de00100010003df0de00100010003df05e004df04e00100010003df0de00100010002df0ee001000ddf05e002df0e0002e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff00031914070600010f010002e10100010f0600040001e10100020f02e1020f010001e10400040003e1010f02e1010f03e10400060006e1060004000228022602280226022804000200022802260228022602280226022802000200022802260228022602280226022802000100012802260228022602280226022802260128010001000128022602280226022802260228022601280100010001260228022602280226022802260228012601000100012602280226022802260228022602280126010001001126010010260100010010260100122601000226034201260442012603420226010001000226034201260442012603420226010002000e26020000000000000000000000000000000000000000000000000000000000000000007500061c150509160e0009980e0009980e000100030804980f000100030804980f000100030804980f000100030804980f000100030804980c0003160100030804980c1603980100030813980100030813980100040812980100060801230101012301010123080803980200150803001408140003080000000000000000000000000000000000000000000000000000000000000000000000000000000000012f00011f14030c0002230e000d0001980e0005000198030008230b00040002230400082302000223060005000198050001230151012302510123015101230200019806000300025501980500032302510323010003550500030003550500042301510323020003550400030004550300022301510423015101230100035505000200065501000923030001980600050001980700019807000198060005000198070001980700019806000d2601980700019806000c97012601980700019806000197022309970126089701980100052601970223099701260198010001970100019701000197010001980126049701000c970a2603970300020004970123109705000300029703230197012301970123019701230197012301970123049706000400029701230e97070005000f970800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c5000319140708000237080008000237080007000137022801370700070001370228013707000600013704280137060006000137012802370128013706000500013702280237022801370500050001370628013705000400013708280137040004000137082801370400030001370a2801370300030001370a2801370300020001370c2801370200020001370c280137020001000137032803370828013701000100013701280137012803370528023701280137010001370828032305280137013710280137000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008300041e14030d0002010c000c0005010a0009000901090007000b01090005000c010a001b001b0006000bc80a0006000bc80a0006000bc80a0006000cc8090006000cc8090002c8040012c80200010102c8040005c8060107c8020001010ac8090105c8010001c801010924020106230201052402000101010007c80b0105c802000101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a3000318140802000ca302000100061405280314010005140128031404280314022802140128011401280314042802140214012802140128041405280114021401280814042801140228051401280314042801140a14052801140a1404280214091405280214091404280314081404280414071404280514051405280614031404280914021403280314012801230201012301280214010002280c14010002000ca302000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007900051914070500025701000257010002570500050002570183025701830257050004000257018302570183025701830157040004000157018302570183025701830257040002000e57020002000e57020001001057010001001057010001001057010012571257125712570957037d0657125701001057010000000000000000000000000000000000000000000000000000000000000000000000000000008300061d15040f0001c909000d00077a05000b00037a01c9077a030008000b7a02c9027a020005000f7a01c9027a02000200167a01000100177a0100187a0100187a0100187a01c9187a0100107a02c9057a02000100097a01230101012301010123017a02c9057a02000200057a02c90d7a03000300047a02c90b7a050006000a7a0900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c100041c160509000168020001680a000600016801000668010001680700034903000568014904680700054902680349076806000449036803490368024903680500034904680349036802490468040003491068040002001268030002001268030002001268030005490d6805490149046801930b680193046801490549029309680293054901490a68044907680149054902930468014902350149026801930549030006930268044901680393040004000e93050005000c9306000700089308000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d500051b1406080003b001c501b00800080003b001c501b00800080003b001c501b008000300072401b0072403000300072401480724030002240148072401480724014802240224014807240148072401480224022401480724014807240148022402240148072401480724014802240224014807240148072401480224022401480724014807240148022402240148072401480724014802240224014807240148072401480224022401480585016d0385016d05850148022402240148072401480724014802240224014807240148072401480224000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab00031e14030800018601b111000800028601b110000700038602b10f000700038603b10e000600058603b10d000600058604b10c00050002860284028601b1028602b10b000500078605b10a000400088606b109000400088607b1080003000a8607b1070003000a8608b1060002000b8609b1050002000c8606b1028601b1040001000d860ab1030001000186038401860184078607b1038601b102000986032303860bb101000f860cb1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015300021b14050a00025b0a000900015b01180141015b09000900015b01410118015b09000500035b0200025b0200035b05000400015b0300015b0100025b0100015b0300015b04000100035b0500045b0500035b0100015b0200015b03000241015b018b0154015b02410300015b0200015b015b0200015b01000441015b0254015b04410100015b0200015b015b01000141015b0541015b0154018b015b0541015b01410100015b0100015b0141015b0541045b0541015b0141015b01000100015b0141015b0641025b0641015b0141015b01000100015b0241015b0441045b0441015b0241015b01000200015b0241015b0341015b028a015b0341015b0241015b02000200015b0241015b0341015b028a015b0341015b0241015b02000100025b0141035b0241015b028a015b0241035b0141025b01000200125b02000300103503000200055b0841055b02000200125b020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004900041715090372080003720372080003720372080003720372080003720372080003720e720e720e720e720e720e720e720e050e0502050b230105030502010405020103050e050e05000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000af00041a140608000c1807000d18060003180b14050004180b140400021803140b460300031803140b4602000118031403460b0f01000218031403460b0f031803140346030f0854031803140346030f0854031803140346030f03540512031803140346030f03540512031803140346030f035403120200031803140346030f035403120200031803140346030f032303120200031803140346030f035403120200031803140346030f0354031202000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009300061b1405020002050100020501000d72010501050b7203050172020e0101010e017201050105027201050372020c037203050172040e0172010501050172020511720105010e010c0205110c010e010e140c010e010e140c010e010e140c010e010e140c010e010e140c010e010e140c010e010e120c0205010e010e080c0505050c0205010e010e140c010e01051472010500000000000000000000000000000000000000000000000000000000000000000000000000000000000000005f00041e14080100080e0d000400070e0b0001000c0e090002000c0e080001000e0e070001000e0e070001000f0e0600100e0600100e0600100e0600100e0600090e070d0600080e0c0d0200070e0f0d070e0f0d070e0d0d0200080e090d05000000000000000000000000000000000000000000000000000000000000000000c500091d150504000320110004000120011906200c0004000320011906200a0003000520011902200119042008000300092001190620050003000220011903200119062001190320040002000220021903200119032002190120031901200400020002200f19022003000100022011190120030001000120031904a4011904a4011904a40119022002a402200219012001a40120011901a4011901a4021901a4011901a40119012001a40320010001a4052001a4022003a4022003a4022006a4030003a4120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d900011c160409000664090007000a64070006000c64060005000e64050005000e640500040010640400040001640628026406690164040003000165072802010769015a030002000265062804010669025a020001000365052806010569035a010001000365052806010569035a01000565032808010369055a0565032808010369055a0665022808010269065a0765012808010169075a086501e2060101e2085a086508e2085a0100086506e2085a01000100086506e2085a01000200086504e2085a02000300086502e2085a0300050006650200065a05000000000000000000000000000000000000000000000000000000000000000000000000000000d100021a15060600084f06000600024f0101024f016c024f06000700034f016c024f07000500032a044f032a05000300022a021e022a024f022a021e022a03000200012a021e0a2a021e012a02000100052a011e0700052a01000100032a011e0b00032a0100032a021e0c00032a012a0101012a011e0d00032a032a011e0d00032a032a011e0d00032a032a011e0d00012a0101012a032a011e0d00012a0101012a032a011e0d00032a0100032a021e0a00032a01000100052a081e052a01000200102a020003000e2a030005000a2a0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b00061c1403020017e3020017e3020017d4020017e3020017e3010017e30100010017e30100010017e30100010017e30100010017e3010018e3010017e4020017e3020001e303e403e303e403e303e403e303e401e3020017e30200000000000000000000000000000000000000000000000000000000000000000000000000d900031c140405000e1f050005000e1f050003001205030003000105011f0205011f0205011f0205011f0205011f0205011f0105030003001205030003001205030003000105101f01050300010001050100120503000100010501001205010001050100031f1205010001050100010e021f1205031f031f1205021f010e010e021f1205031f031f1205021f010e03000105010e0259010e0259010e0259010e0259010e0259010e0105031f03000105010e020b010e020b010e020b010e020b010e020b010e0105030003000105100e010503000300120503000000000000000000000000000000000000000000000000000000000000000000000000000000e700031b14050b00030c08000a00010c031f020c06000900010c011f010c041f020c04000800020c021f010c051f020c02000300050c051f010c061f010c01000200010c121f010c0100010c051f040c0a1f010c0100010c091f010c091f010c0100010c021f010c101f010c0100010c071f020c011f070c021f010c0100010c051f020c0c1f010c010c141f010c010c041f010c0e1f020c010c041f010c081f020c011f030c02000100010c041f010c041f030c021f010c021f010c02000200010c051f030c041f010c021f010c03000300050c041f030c031f010c03000400010c0c1f010c04000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e300021c14040c0001940b000a000119010002940a000900021904940900070004190694070006000419089406000500051909940500040006190a940400040005190b940400030006190394011d08940300030006190394011d08940300011d020006190294021d08940200011d0100011d010007190194021d08940100011d01000100041d05190194021d0694041d01000200051d03190194021d0494051d02000300051d0219041d0294051d03000400041d0119011d0123021d0123011d0194041d04000500031d0119021d0223021d0194031d050006000c1d060006000c1d06000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009900021c1508019a1300019a014f1200029a014f1100019a034f1000019a044f0f00029a044f0e00019a064f0d00019a074f0c00029a074f0b00019a094f0a00019a034f0100064f0900029a024f0200064f0800019a034f0300064f0700019a034f0400064f0600029a024f0500064f0500019a034f0600064f0400019a104f0300029a094f049a034f0200019a0a4f049a044f0100019a134f00000000000000000000000000000000000000000000000000000000000000000000000000012500031c14040c00047908000c00057907000300047905000579070003000479020002790100057907000300047902000279010005790700027901000479020002790100057907000279010004790200017902b0057902000279010002790100017901b004790500057902000279010002790300047905000579010003790100027904000379050004790200037901b001790100027902000479020001790100047902000379030002790200047902000179010004790200027904000279020004790200017901b00479020002790400037901000479030001b004790100037904000100027901b0047904b004790100037904000200017901b0077902b00379010002790500040002790323037901b0037901b0027905000500077901b0037901b00279050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bf00011c14040d0001010a000c0002010100010108000b0003010100010108000a0004010100020107000900020102df01010100020107000800030102df010101000301060007000701010003010600060008010100040105000500090101000401050004000a0101000501040003000b0101000501040002000c0101000601030001000d010100060103000e0101000701020018001883010001831498018301000200018301981083019801830200030001831098018303000400108304000000000000000000000000000000000000000000000000000000000000000000b300041d14030d0001880c000c0003e10b000c0002e1011a0b000c0003e10b000500088301880783050003000783017d028301880483017d0483030002000283017d088301880183017d0883020001000883017d0a83017d04830100010018830100010018e501000100185501000100016d0655016d0855016d07550100011c186d011c031c066d081c056d041c0100041c0298051c0398051c0298011c0100011c0100030006980823069803000400129804000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e700051c16030b0004e60a00090008e6080007000ce60200023a0200010005510ee60100023a0200015105000ee605000151040002140de6011404000151040003140ce601140400010001510200025503140be6021403000200015101000255041409e603140300030001510355061405e6041403000400015102550f1403000500015104550b140151020001e60500015502510555061402550100015102000600025502510a55030001510100030002e60100045503510755040001510200013a02e60200065503510355050001510200023a050007550351050001510b00045504000551010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009700091e15020c9710a301000b9710a3020003970100069710a3020002970300059710a3020002970300059710a3020002970300059710a3020002970300059710a302000297030005970ea3010001a302000297030005970ca3010001a302000200039701000297012602970ba3010001a304000100099703a3025105a3010001a30600099702a3025105a3010001a30800080008a30c0000000000000000000000000000000000000000000000000000000000000000000000000000000000ad00031e1403060008e70d00060008e70d00060008e70d00030004e7050003e70c00030004e7020003e803e70c00030004e7020001e8010002e802e70c00010003e7070003e80d00010003e71700010003e7170003e7180003e7180003e7180003e703000de8080003e7020010e80300039f05e710e803e7019f0200010004e702e802e902e802e902e802e901e807e70200010004e704e802e902e802e904e806e7020006000ee8010003e7039f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd00031c14030a0004ec0b000b0005ec09000c0005ec08000c0005ec080001ec0b0006ec0700010001ec08000b430400010002ec05000e430300010003ec020011430200020003ec010012430100020004ec1343030003ec1343030003ec104301ec01430100030003ec104301ec01430100020003ec010011430200020002ec020011430200020001ec0300034301ec014301ec0243023c0101013c0101013c0101013c0300010001ec0400024301ec014301ec0243023c0101013c0101013c0101023c030006000643093c04000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cb00011c19040b00020d0b000b00020d0b000800080d080006000c0d060005000e0d05000400101f04000400081f010b011f030b031f04000400101f040005000e43050005000e430500040010430400040010430400040010430400030012430300030012430300030012430300020014430200020014430200020014430200010016430100010001430100014310000143010001430100010004430e0004430100014301000143010001430e0001430100014301000143180001000143010001431000014301000143010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f900091e1402030016c00300010003c0016a0369016a0ac0016a0369016a03c00100010001c0011b01c0016a0369016a0ac0016a0369016a01c0011b01c0010002c0011b01c0016a0369016a0ac0016a0369016a01c0011b02c002c0011b03c0017c0ec0017c03c0011b02c002c0011b03c0017c0ec0017c03c0011b02c002c0011b03c0017c0ec0017c03c0011b02c002c0011b03c0017c0ec0017c03c0011b02c002c0011b01c0016a0369016a0ac0016a0369016a01c0011b02c0010001c0011b01c0016a0369016a05c0030e02c0016a0369016a01c0011b01c00100010003c0016a0369016a0ac0016a0369016a03c00100030016c00300000000000000000000000000000000000000000000000000000000000000000000000000000091000519150704000a43040001001043010001001043010012431243010010af0100010010af0100010010af0100010010af0100010010af0100010010af0100010010af0100010007af01b101af01b106af010003000caf0300030002af01b101af016d01af01b101af01b101af01b101af0300030003af01b101af01b101af01b101af01b101af01b1030004000baf030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c900011e1403010001230100142301000123010001230800012301000123100001230200152301000123010006000123140006000123140006000223130006000423110007000b230900030014880400020001880a770188097701880300020001880a77018807770166017701880300020001880a77018807770166017701880300020001880a77018807770166017701880300020001880a7701880977018803000200163303000200168803000200163303000200063306230a3303000200163303000400123305000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009100051d14030600042406000424060004000824020008240400012402001424020001240724020108240201072401240101162401010124012404011024040101240224160102240324140103240100032412010324010001000424100104240100020004240e0104240200020006240a010624020003001424030004000a2402010624040005001024050007000c24070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b700051914080600048c07000300038c0151038c0151038c03000100018c0151058c0151068c015101000100048c0151018c0351028c0151038c0100038c0151018c0197025101970251038c0151028c0151048c025103970251058c048c025105970251038c0151038c0251039701260197012601970251038c048c0997048c048c04970126019701260297048c048c09970151038c038c015109970251028c11510100045104110751010001000f08010001000f08010000000000000000000000000000000000000000000000000000000000000000000000000000000000a100071e15050c0001040c000c0001040c0008000305010002040b000b00010502040b000b00010502040b000b000123010402260a000a0003230426080003230600032302260155052605000c23012603550104052603000b23022602550804020002230901022602550804020005010123110102000601032301010b05030001040a010a050300010401000100012301050123010501230105012301000e04020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012300041a1c060c000384050005000384030001840385018404000400038401850484028501d00284030003000184028501d001840485028404850200030004850184048501840585020003000f8502000300015503850255028501d002550385015502000200105502000200105502000100037d0c55027d02000100127d0100147d147d017d0201017d0101017d0701017d0301017d0101017d017d0401017d0701017d0301017d0101017d017d0c01017d0501017d017d010010010100017d017d0100017d0e00017d0100017d017d0100017d0e00017d0100017d017d0100017d0e00017d0100017d017d0100017d0e00017d0100017d017d0100017d0e00017d0100017d0200017d0e00017d02000200017d0e00017d02000200017d0e00017d0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000870004191408010003290200022902000429030001290222032901220929010001290222092903220229010007290222022903220229010003290222022902220229032202290100032902220a2901001029010010290100112911291129112910290100012902220d29010001290222032905230429020001000d2901220129010001000e29020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014100011c1a020d00026a0b000c00046a0a000b00036a01ed026a09000a00056a01ed026a08000900076a01ed026a070008000c6a060007000e6a05000600014f0e6a014f04000500024f0e6a024f03000400024f106a024f02000300034f106a034f01000200044f106a014f01ed024f0200044f106a024f01ed014f0200044f106a044f0200044f106a044f0300034f106a034f01000100014f0200034f0e6a034f0200014f016a014f03000245014f0123010101230101012301010123010101230101014f02450400014f016a014f020003450c4f03450300014f016a014f0100144502000100014f014501000145010002450100024506000245010002450100024501000200034501000145020001450800014502000145020001450100030001451300014f014501001700014f014501001700014f014501001700014f020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004300081c140407000d24040004001224020002001624010017240100172401001724010017240518127201000618117201000418012402181100051812240100181818180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011500021b17050a0002ad0a0006000129020001ad022901ad0900090001ad022901ad0900080001ad042901ad0300012901000129020003000129040001ad042901ad04000129030002000329020001ad062901ad0200012901000129020003000129030001ad062901ad0700050002ad082902ad0500030002ad0c2902ad0300010002ad102902ad010001ad142901ad01ad142901ad010002ad102902ad0100030002ad0c2902ad0300050001ad0a2901ad0500050001ad0a2901ad050001000129020001ad072903ad022901ad0400040001ad0c2901ad0400030001ad062902ad062901ad0300030001ad042902ad020002ad042901ad0300030001ad022902ad060002ad022901ad0300040002ad0a0002ad0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000bd00071b160504000e51040002000251061803380518025102000100015109180138081801510100010001510918013808180151010001510a1801380918015101510a1801380918015101510a1801380918015101510a1801380918015101510a1801380918015101510138091801380918015102510238051803380118035105180151010003510838011801510138015104180251020008510238011803510418015101000400075102380518035101000a000a5102000b0007510400000000000000000000000000000000000000000000000000000000000000000000014700031d1403090008490900070004490142024901420449070005000549014201490242014901420549050004000149014201490c420149014201490400030001490142014904420126014202260142012604420149014201490300020001490142014903420a2603420149014201490200020002490342032601280126022801260128032603420249020001000249034203260828032603420249010001000249024203260a2803260242024901000349024202260c280226024203490249024202260e28022602420249014901420149024202260d28012602420149014201490249024202260e280226024202490249024202260e28022602420249014901420149024202260c280226024201490142014902490242022606280201012605280226024202490349024202260c2802260242034901000349024202260a28022602420349010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011100051d14030a00038e0167028e0a000800038e0167018e0167048e08000600038e0167018e015701670157018e0167028e0167018e06000500018e0267018e0367011102570367038e05000500028e026708500157038e05000300018e0167018e015702110150018a0350018a025002110267028e03000300028e01670650018a0750038e03000300018e01110d50018a02500167018e03000200018e015701110150018a0e5001110157018e020001000167018e1450018e0200020001670450018a0c50018a02500267010002000111145001110200016701000350018a0d50018a0150018a025002000100016716500167010002000550018a0550018a0750018a025001000167030014500167020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d100041c170405000ee60500050001e603c8040105c801e60500040001e603c8040107c801e60400040001e602c8040108c801e60400030001e602c8040104c8034303c801e60300030001e601c8040104c8014303c8014302c801e60300010016e60100010016e60100010016e60100010016e60100010016e60100010016e60100010016e60100010002e6011f10e6011f02e60100011f0137141f0137011f091f061d091f010008e6061d08e601000200020e0500061d0500020e02000200020d1000020d02000200020d1000020d020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb00011a14050a00012b02e608000a0001e6012b02e607000a0001e6012b02e607000a00012b03e60700090005e60700080006e60700070006e60800060006e6012b07e60100030008e6012b07e6012b01e60be6012b07e6012b01e60de6012b06e6012b0de6072b01000ae6012b0ae60ae6012b08e6012b01e60ae6012b09e6012b0ce6082b010001e6022b05e6012b02e6012b08e6010008e6042b06e6012b01e60100030004e6012b03e6012b07e6012b0100040008e6072b0200000000000000000000000000000000000000000000000000000000000000000000000000df00031a1f0504000e840300030002840cd8028402000300018403d8089903d801840200040001840cd8018403000400018402d8089902d8018403000300010b0e72010b02000300010b0e72010b02000300010b0e72010b020d0300010b0e72010b020d0300010b0e72010b02000300010b0e72010b02000300010b0e72010b02000300010b0e72010b02000300010b0e72010b02000300010b0e72010b02000200120d0100021f120d0100011f0100120d0100011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f140000000000000000000000000000000000000000000000000000000000000000008f00071a1605010002ee11010100010002ee1101010004ee110104ee110104ee110101ee017c010d01ee110101ee017c010d01ee110101ee017c010d01ee110101ee017c010d01ee110104ee110104ee110104ee1101010002ee027c01ee010101ee010101ee010101ee010101ee010101ee010101ee01010200010002ee017c1001010004000c010500050008010800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d300041917060a0005570400030004570100025705010257020002000157040101570301015705010157010001000157060103570701015701000157100101570157110101570157110101570157110101570157110101570157110101570157110101570100015710010157020001570e0101570100020001570e0101570100030001570201097c020101570100030001570d01015701000400015704010357040101570200040001570301015703000157030101570200050001570201015704000157020101570200060002570600025703000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c700021914011000016707000f000167011c016706000f000167021c046702000f000167061c016701000c000667021c0101011c0167010009000367081c0101011c01670100080001670d1c01670100080001670d1c0167010008000101011c0101011c0101011c0101011c0101011c0101011c0101011c0101010008000f01010008000f01010008000f01010008000f01010008000f0101000143010002430100134302000143020013430100024301000543012301460123014601230a4307001143070011430000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c100031c150406000c81060003000281017c0281047e057c0381040002000281027c0b81017c03810300020003810f7c038101000200168103000b7c0181017c078101000500118102000700047c0181017c0181017c0581040006000c81060005000d81060004000b81090002000b810b00010009810e0002000a810800018103000500088106000181040001000181010001810100017c049c0281017c0681010001810300018101000481067c088104000300128103000300048108000481050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010900031b14050900050508000700020504000105080007000105020009050300020011050300020008050723010d04000300010d08230a0d020006050323030d0505010d020002000205031f0205031f0205031f02050100010d010001000305031f0205031f0205031f03050200010501000205031f0205031f0205031f020501000105010002000205031f0205031f0205031f0205030002000205031f0205031f0205031f0205030002000205031f0205031f0205031f0205030002000205031f0205031f0205031f0205030002000205031f0205031f0205031f0205030002000205011f0523021f0205031f0205030002000205031f0205031f0205031f020503000200110503000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023500041d19031500018904000300126101890161030002000289016101cc01820161018201cc01610282016101cc0182016101cc0182016101820189016103000100018901940261028201610282016101cc018201610282016102820161018201cc028902000100018901941461018902000100018901000261018201cc016102820161018201cc0161018201cc016102820161028201610189020001000189010002890282016101cc01820161028201610282016101cc0182016101cc018201610189020002890194016101891261018901940100038901610189018201cc01610282016101cc01820161018201cc016102820161018201cc0161018901000189018901000189016101890282016101cc018201610282016102820161018201cc01610282016101890100018901890100018901610189126101890100018901890100018901610189018201cc016102820161028201610282016101cc018201610282016101890100018901890100038902820161018201cc0161018201cc0161018201cc01610282016101cc018201610189010001890189010001891461018901000189018901000189026102010161020101610201016102010161020101610201016102000189018901000189026102010161020101610201016102010161020101610201016101890100018901890100018914610189010001890189010001890194110001940100028901000189020002891100018903000100018901000289150001000189010001941600020002891600000000000000000000000000000000000000000000000000000000000000000000000000000000000000b500021e15020e00014f0d000d00034f0c000e00014f0d000b00064f0b0009000a4f090007000e43070006000a430106014302060243060006000c430206024306000500124305000500124305000500124305000400144304000400144304000400144304000400144f04000200184f02000100054f026d014f026d014f026d014f026d014f026d014f026d044f0100064f026d014f026d014f026d014f026d014f026d014f026d054f0400144f040009000a4f09000000000000000000000000000000000000000000000000000000000000000000000000000000000000011700021b16050600027903260b00060004790200027903260500020001260300027903000579060002000126017902000279020003790900020001260179020002790200037909000200027902000279020002790200018003000126030002000279020003790100027905000179022602000200027903000579050004790100018002000279020005790600037901000280010002790200057907000279010003000a7904000479010004001079020004000f7902000180018005000a79040002800700087907000300018003000879070006000180017901230125012301250123027901800300018002000500038006790380050004000e8004000500018001000380020002800100018006000800018009000180030000000000000000000000000000000000000000000000000000000000000000000000000000000000df00041b16040b00021c0a000800011c0300021c0600012602000900021c0100021c040002260300050003660100051c0200032604000200031c0366071c032601660400011c0100031c0766011c0426026604000100031c012007660426036604000200011c02200766032604660400020003200766022605660400010004200766012606660400020003200e660400020003200e66040002000320125f01000220023a0e5f0120015f0120015f0100043a035f012001660123016601230166012301660120065f0200033a125f0200033a125f0300023a12000400013a120000000000000000000000000000000000000000000000000000000000000000015b00081c140418011801030101230101012301010123010101230201012301010123010101230101012305010301011f0101011f0101011f0101011f0201011f0101011f0101011f0101011f05010301011f0101011f0101011f0101011f0201011f0101011f0101011f0101011f0101012303010301011f0101011f0101011f0101011f0201011f0101011f0101011f0101011f0101012303010101011f0101011f0101011f0101011f0101011f0201011f0101011f0101011f0101011f010101230101011f01010301011f0101011f0101011f0101011f0201011f0101011f0101011f0101011f0101012303010301011f0101011f0101011f0101011f0201011f0101011f0101011f0101011f0101020202010301011f0101011f0101011f0101011f0201011f0101011f0101011f0101011f050103010102010101020101010201010102020101020101010201010102010101020501180118010000000000000000000000000000000000000000000000000000000000000000000000006d00051b140501230200012302000123020001230200012302000123020001230200012316001600012314000123160016000123140001231600160001231400012316001600012314000123160016000123020001230200012302000123020001230200012302000123020001230000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f700031c15040800081f08000800011f0641011f08000700021f0642021f07000700011f014106280141011f07000600021f0341031f0241021f06000600021f0141041f0141021f0141011f06000500021f01410b1f05000500041f010c051f010c031f05000400051f010c051f010c041f04000400051f010c051f010c041f04000300051f010c071f010c041f03000300051f010c071f010c041f03000200061f010c071f010c051f02000200051f010c091f010c041f02000100021f020c0f1f010c021f01000100021f020c051f010c0c1f01000a1f010c0341010c041f020c031f061f010c021f010c091f020c031f0200141f0200000000000000000000000000000000000000000000000000000000000000000000000000000000013500031b1505090004d40900060001d401ef02d4020102d401ef01d40600040003d401ef02d4020102d401ef03d40400030001d401ef03d401ef04d401ef03d401ef01d40300020003d401ef02d401ef04d401ef02d401ef03d40200020004d40aef02d4010101d40200010004d401ef0ad401ef04d40100010003d401ef0cd401ef01d4010101d40100010003d401ef0cd401ef01d4010101d4010004d401ef0cd401ef01d4010102d404d401ef0cd401ef02d4010101d404d401ef0cd401ef02d4010101d404d401ef0cd401ef04d4010003d401ef0cd401ef04d4010003d401ef0cd401ef03d40100010001d4010102d401ef0ad401ef04d40100020001d4010102d40aef04d40200020003d401ef02d401ef04d401ef02d401ef03d40200030001d401ef03d401ef04d401ef03d401ef01d403000000000000000000000000000000000000000000000000000000000000000000000000000000000000009700031a15060237041a01830237011a0137091a061a01830d1a061a01830d1a061a01830d1a0100128301000237011a0137091a01830237041a0d1a0183061a0d1a0183061a0d1a0183061a0100128301000237041a018301370c1a061a01830d1a061a01830d1a061a01830d1a0100128301000237011a0137091a01830237041a071a0337031a0183061a0d1a0183061a0d1a0183061a00000000000000000000000000000000000000000000000000000000000000000000000000000000bb00081d1403020008a40e8c0200029701a408510ec801970197012301a408510ec801970d9701080c9701970ba40197010801970a430197019701a4057c05a4019701080c97019701a4017c03a4017c05a40197010801970a260197019701a4017c03a4017c05a4019701080c97019701a4027c01a4027c05a40197010801970a980197019701a4017c03a4017c05a40197010801970a980197019701a4057c01a4034701a4019701080c9701970ba4019701080c970d9701080c97000000000000000000000000000000000000000000000000000000000000000000000000bd00091d140419080108117e0108052401080108017e0f08017e0108052401080108017e0f08017e07080108017e0f08017e01080124010801240108012401080108017e0f08017e07080108017e0f08017e01080124010801240108012401080108017e010801a40d08017e07080108017e01a4010801a40c08017e01080124010801240108012401080108017e010801a40208010101230101012301010123010101230308017e07080108117e010801a401080124010801a401081908000000000000000000000000000000000000000000000000000000000000000000012d0003191f0402000fee0400020002ee017201ee017201ee017401ee017201ee015101ee0155017402ee0300020002ee017401ee017401ee017201ee017403ee0143017402ee03000200037210510200037206510472065102000372045102720475027204510200037203510172087501720351020003720351017208750172035102000372025101720a750172025102000372025101720a750172025102000372025101720a750172025102000372025101720a750172025102000372035101720875017203510200037203510172087501720351020003720451027204750272045102230372015102430351047206510123010003721051012301000372105101231400012314000123140001231400012314000123140001231400012314000123140001231400012314000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bd00041a150802000c0a040001000826011e0126021e0226030001260e51012602000126065102780651012602000126035101780651017803510126020001260e51012602000126015101780a51017801510126020001260e5101260100010a01260e510126010a012601260e510126020a01260e510126010a012601260e5101260100010a0126045101780451017804510126020001260e510126020001260651027806510126020001260e510126020001000e26030002000c0a040000000000000000000000000000000000000000000000000000000000000000000000b300031b15050400051d0d000300051d02240c000200051d0124011802240b000200041d0224012303240a000100041d082409000100031d06240123011802240800041d02240123011807240700031d0d240600031d0e240500031d0f240400031d10240300031d112402000100021d122401000100031d1124011d0200021d1024011d01000300021d042401230118012301180624011d02000400031d0a24021d03000500041d0624021d05000800071d070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011300021c1401120004df05000e000adf03000c0002df014a0adf02000b0005df024a0243014a02df014a02df01000a0002df024a01df024a0143054a02df014a01df090002df024a01df024a01df034a01df0143024a03df090001df034a01df024a01df024a01df064a01df080002df024a01df024a01df034a01df024a0300014a01df080001df034a01df024a01df054a040001df0100070001df0d4a0600070001df0d4a0600060002df0d4a0600060001df0e4a0600050001df0f4a0600050001df0f4a0600040001df074a0143024a0143034a0143014a0600040001df044a01df024a0143034a0143034a0143014a050001df020001df044a01df044a0143034a0243054a0300010002df164a0100014a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e300011d15020d00010f0d000c00020f0d000c00020f0100010f0b000b00040f0c000400010f0600040f0700010f04000400020f0600030f0100010f0400020f04000400030f0100010f0200050f0400030f04000500040f0200060f0100040f05000500050f0200040f0100050f05000600050f0100040f0100040f0600010f06000d0f0600010f0100020f0100010f03000b0f0500020f01000100040f0200130f01000200170f02000400130f040005000f0f07000900030f015c030f015c010f09000800050f035c030f080006000f0f06000500110f05000400020f0f00020f0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e900021a1405060001270896019505000600012701960727019505000600012701960600012701950500020003270d9601950200020003270396010e0196010e0196020e049601950200020003270396020e0296010e059601950200020003270396010e0196010e0196010e0196010e039601950200020003270396010e0196010e0296020e039601950200010003270f9601950100010003270f9601950100010003270f9601950100010003270f9601950100010003270f9601950100010003270f960195010003271196019503271196019503270496092704960195032711960195032711960195000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b500061c1404030005970700059704000300059707000597040003000597070005970400030011260400030011070400030011260400030002970e8101970400030002970e8101970400020003970e8101970400010004970e810197040005971181029703000297018101d6018101d60f8102000397018101d6018101d60181042301010123010103230381010001000497018101d6018101d602230101062301010223018102000597018101d6018101d60c820300000000000000000000000000000000000000000000000000000000000000000000000000000000000000c700021e15021100044a07001000064a06000f00084a05000e000a4a04000d00064a010e054a0300014a0400014a0600064a010e014a010e054a0200024a0200024a05000f4a01560100064a05000f4a015601000100044a07000d4a03560200034a07000c4a04560200054a05000b4a055602000156134a065603000156114a0756030003560e4a07560100040005560a4a0856010004000656084a0856020005000556014a030e034a0856030006000356074a0856040007000156064a085606000a000956090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012b00041a1606080009d6030007000cd60100060005d6080d0100050005d6010d097c040005d6010d037c0281017c0281017c0181030005d6010d017c0281017c0281017c0281017c0181020005d6010d0481017c0281017c0281017c0181010005d6010d0581017c0281017c0281017c018106d6010d0581017c0281017c0281017c018106d6010d0581017c0281017c0281017c018106d6010d0581017c0281017c0281017c018106d6010d0481017c0381017c0281017c018106d6010d0381017c0381017c0381017c018103d6010d02d6010d0281017c0381017c0381017c028102d6030d01d602980181017c0281017c0381017c038103d6010d02d60398017c0281017c0281017c0381010006d60398017c0281017c0281017c02810200060003980b00060003980b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007100051b1405166f166f136f0101026f136f0101026f136f0101026f016f129401190194016f016f1494016f016f1494016f016f1494016f016f1494016f016f1494016f026f1294026f0100016f1294016f01000100026f069404190694026f01000200036f0c94036f020004000e6f040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b700041b1404030008ec0c00020006ec014604ec0a00020001ec020002ec034604ec090002000146030002ec014606ec08000546020004ec014604ec070001000346040002ec014601ec014601ec014602ec06000100014601000146050002ec014606ec050009000aec0400080008ec014602ec0400080001ec014605ec034602ec0300080008ec014603ec0300080004ec014607ec030007000dec030006000eec0300050007ec050e02ec04000300125402000100165400000000000000000000000000000000000000000000000000000000000000000000000000000000cb00061b14060a0001010123090001000223035e0101012301010123010102230100035e040001000201035e0101012301010123010101230200035e040001000223055e0123035e0123045e040001000201065e0323055e040001000223065e0323055e040001000201075e0123065e040001000223075e0123065e040001000201075e0123065e0400010002230e5e0400010002010c5e0623010002230d5e012301010123010101230301025e0101012301010123010101230101035e062303230d5e052303010d5e0523000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000004c00000000000000000000000000000000000000000000000000000000000000560000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000006a0000000000000000000000000000000000000000000000000000000000000072000000000000000000000000000000000000000000000000000000000000007c00000000000000000000000000000000000000000000000000000000000000860000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000000000000a400000000000000000000000000000000000000000000000000000000000000ae00000000000000000000000000000000000000000000000000000000000000b800000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000000000000000d600000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000ea0000000000000000000000000000000000000000000000000000000000000005b000b171007030006200100062003000120020102230120010001200201022301200420020102230320020102230120042002010223032002010223012001200200012002010223012001000120020102230120030006200100062000000000000000000000000000000000000000000000000000000000000000000000000063000b171007030006230100062303000123020102640123010001230201026401230423020102640323020102640123012302000123020102640123010001230201026401230123020001230201026401230100012302010264012303000623010006230000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004b000b171007030006230100062303000323016402230100032301640223102301230200012301650223015a01230100012301650223015a01230123020006230100062303000623010006230000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000053000b171007030006230100062303000123020103230100012302010323042302010523020103230123020001230201032301000123020103230123020001230201032301000123020103230300062301000623000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063000b1710070300064301000643030001430201022301430100014302010223014304430201022303430201022301430143020001430201022301430100014302010223014301430200014302010223014301000143020102230143030006430100064300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063000b1710070300060701000607030001070201022301070100010702010223010704070201022303070201022301070107020001070201022301070100010702010223010701070200010702010223010701000107020102230107030006070100060700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063000b171007030006c0010006c0030001c00201022301c0010001c00201022301c004c00201022303c00201022301c001c0020001c00201022301c0010001c00201022301c001c0020001c00201022301c0010001c00201022301c0030006c0010006c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043000b171007030006230100062303000423010101230100042301010123072301010623010101230123020006230100062301230200062301000623030006230100062300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069000b1710070300060f0100068b0300010f02010223010f0100018b02010223018b034a010f02010223010f014a018b02010223018b018b0200010f02010223010f0100018b02010223018b018b0200010f02010223010f0100018b02010223018b0300060f0100068b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063000b171007030006c8010006c8030001c80201022301c8010001c80201022301c804c80201022303c80201022301c801c8020001c80201022301c8010001c80201022301c801c8020001c80201022301c8010001c80201022301c8030006c8010006c800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063000b1710070300063701000637030001370201022301370100013702010223013704370201022303370201022301370137020001370201022301370100013702010223013701370200013702010223013701000137020102230137030006370100063700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063000b171007030006de010006de030001de0201022301de010001de0201022301de04de0201022303de0201022301de01de020001de0201022301de010001de0201022301de01de020001de0201022301de010001de0201022301de030006de010006de00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063000b1710070300060901000609030001090201022301090100010902010223010904090201022303090201022301090109020001090201022301090100010902010223010901090200010902010223010901000109020102230109030006090100060900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063000b1710070300061401000614030001140201022301140100011402010223011404140201022303140201022301140114020001140201022301140100011402010223011401140200011402010223011401000114020102230114030006140100061400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069000b171007030006200100069a030001200201022301200100019a02010223019a036e0120020102230120016e019a02010223019a019a020001200201022301200100019a02010223019a019a020001200201022301200100019a02010223019a030006200100069a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063000b1710070300062401000624030001240201022301240100012402010223012404240201022303240201022301240124020001240201022301240100012402010223012401240200012402010223012401000124020102230124030006240100062400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063000b1710070300065901000659030001590266022301590100015902660223015904590266022303590266022301590159020001590266022301590100015902660223015901590200015902660223015901000159026602230159030006590100065900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063000b1710070300061c0100061c0300011c02010223011c0100011c02010223011c041c02010223031c02010223011c011c0200011c02010223011c0100011c02010223011c011c0200011c02010223011c0100011c02010223011c0300061c0100061c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063000b1710070300063701000637030001370201022301370100013702010223013704370201022303370201022301370137020001370201022301370100013702010223013701370200013702010223013701000137020102230137030006370100063700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069000b1710070300062601000613030001260201022301260100011302010223011303420126020102230126014201130201022301130126020001260201022301260100011302010223011301260200012602010223012601000113020102230113030006260100061300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063000b171007030006280100062803000128020102230128010001280201022301280428020102230328020102230128012802000128020102230128010001280201022301280128020001280201022301280100012802010223012803000628010006280000000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/packages/nouns-contracts/test/foundry/files/descriptor_v2/accessoriesPage.abi b/packages/nouns-contracts/test/foundry/files/descriptor_v2/accessoriesPage.abi new file mode 100644 index 0000000000..253a20e194 --- /dev/null +++ b/packages/nouns-contracts/test/foundry/files/descriptor_v2/accessoriesPage.abi @@ -0,0 +1 @@ +0x00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000004aa000000000000000000000000000000000000000000000000000000000000000890000000000000000000000000000000000000000000000000000000000000ed5bd5b5b731bb715060eb0a4e815494b9644c9a224da944545aae3b88e233bbec956e2c4719d3477374e5bc94dd2ba759b8b7b499b74469d3e743a7deebb66fa47f4de3fa19fd2ef1c60c925232d76576d31fa78cec1013e5c168b05b02ba5324327dbadfe9eed9e08e49fd80df80fb2fd939b01ff5ec01fe03f15e03f15e09fea04fcbbd9fee96cb79ade0ef8f7b3fd339b01ff5eb6bf95ed56aded6cff6ca0fcd940f97381f2e7f6b3fda73b01ff6ec07f90ed9fdf0cf8f7b2fded4eb67f21dbad1602fc8b9bd9fea500ffd26eb6bf13c8df39c8f69f09f09f0d147036c0dfddcbf62f6f07fcfbd9fe73d96e752ec07f6e2fdbbf12e05fd9cdf6f73a017f28ff41b67f7533e00ff0af06f89f0bf03fb797ed5fcb76abb500ffda6ec07f90ed5fdf0bf803f9bfd709f8b703fefd6cfff900fff900fff9bd6cfff301ff8580ff856cb77a6133e00ff05f0cf05f0cf05fdccff67fbf13f06f07fc01fe4b01fe4bbb017f80ffc5cd807f2fe03fc8f65f0ef05fde0df803fc2f7502fe00ff4b01fe8dcd807f3fdb7f25dbadae04f8afec65fbaf06f8af6e07fcfbd9fe973b01ff6eb6ff5a20ffb550fefd6cfff500fff5836cff8dcd807f37e00ff0df0cf0dfdccbf6dfca76ab5bdb01ff7eb67fb313f007f837f7b2fdb7b3ddea7680fff67eb6ff4e27e0df0df80fb2fd5b9b01ff5eb6ff956cb77a653be0dfcff6bfda09f8f7b2fd77b3ddeaee6ec07f90ed7f6d33dbff7aa0fcd7f702fe40f9f702e5df0bf0bf91edc604a05a538b75adf452a468a9026900f2883c083eede3585a2f43ecd840a9d9e9d37552a683f41d5211a04577a04e98232b5c40fd171a9aa2339aec19709239831248b32e1a7026f2a0c2fcebaa3529fd73965151044967a321a9cfa28cb3a654fd97a47fc0d5451f77c125127c5d0319e6ecaad6a9761dd763d92a5ad6ca2eebae3ec7d228b34c127f9c70434d4f2dd4f50a7a6f05b55b311eac735c45a411ddfa7897ceace4e9ed2d353db318eb5e4de91ef2f5aa00f87b91879138c3fe7a55513d422cd50dc7896d7ae5fa3d093d358bf16fa505d46f8191d6b0ed5a1695e6bf87fe5b1c77fda47d1f313b092b093b495cc5f5ebaa8355d6f5f92ae725e42d172ea2fcf98cf2adaa3c47288bfc6fd172647ce46a1fb70525483badf8f25cb90781fe43fd45d7d247bacf6f86e292b1593c6cf0fc52c7685e03a34043c73d0aa93d08b611dda5e1b479c3053573aaddd0ebb8db01bdae3dc84b233a41b700ad17adff2535c3d747ee54d3ef8d44729c5155b95bb987abd2bb45c2bfd4746ba946dfc39ce56153bae07c029bd281e765b67b9e0476c862c0be004d60872ce00549fd0209ec90c5807d119a47d13e4b87f3d2bef6f7db976842ab3a104fd08bd080f845ba0c0d882fd34bf87da938ff7ac2bf4c1be04a21dea02bd080f80a5dc56f68af7468f8abf0375fd6d7f4a138794d5b7d288c45e91ee3565f479f5ed7761406f1e3d7f50d786fe8eba330888f6f94a977129e73fd7373f1166a02c4b70825d65388afd3267e37cbf1fbeb7bbb7d87efe83a10af51131a1037690b1a106fd1247e278bf3f7847fed959335308d20aed1abd080f8d572b54feabf76b7718eee80e70e4de1778a5e032f10bf46af43f38843abd5434257cd9e5a6860ae58c0155e3002ba8719e91e74c1f1d6170fd46cab5de319c9f4913c2f4c7f1d91f868680d829ac047a9bcc5839fbf96a94d6fb85f9bd2f13bd0daf68d743a6aa32efd183b64e1176b319de24c5bcc0a3bc59bb64699a97d9cfe7d26edc33aa6aa059197a66abcaca6c036d63dfd34a84795bc1d797d9096aa035e0b5fc25baa7ef7b520f2d2dc375e5653601bf5eba741fdee93b723af0fd2d2fd01af852fe12d12fe96d4ef07c87b179c53063381b35043d1b10699448a07d02711873bd0e984f4ce429d45b78ee36ec287f83e1bdaf280bc8dd5caa4b31caf2e31f3b8f040eacf7b0994d5ad7839e12556995e0ee2b2d21ca37c427eaa7839e125b8bd1cc465a5295ebebfbfdfa42d7acbfdda948edf81b665df4aa7e3b95ff763ec9085df3761a738d316b3c24ef1a6ad5166da2adeaa41f8d4f56f13e30e88462479699ad188c4d86a5ad1ed88fc6e9e12dd3e5abf39f000d188242fcd5c342251bf392bba1d91dfcd739cfafdd38d0fbfff263fcee950d821dbf4f7ead48d52faf1f314b9cf7cfddf402e0f9bd287618f881fcd63f8e9e3f528a5e7cd53e47af4fbbf93c0a6f461d8211b25f6f528a51f3f4f9133a973bc3ec2fe90575c4472f2f4433c6dc8cd789a50ca0f8f73425107bf9c9f813b2e31d06fa8d6f422f2d302f67a0bd6afe35057c078908fd3f09b85c8db639061fe18d7af556bcc35561a778ad78ef7a7b353ed3a7ae96db4f16dddd56feb2b006cdc1d4eb20f7146d2b05d247c28e3abd12355e961ae808c815a0fadf6e07327237eadc6e4bc8904a637061bbbe29ef56949d2c64813f7f296bf93947f1be5df46397750fe1d947f871c98730df16bbefc35d84d8ec53cdcab36254ef621a8c716d203b0a41eb227c95d93c3c3ba6a61fca2b5efa0e5efa01448fb0edb5a6c9615f1959b652ff7cf6f68e40cc7faf3212b276d63729693ff5c68c0cfe7d7bc63e3e79481b47866697996b9679c96671a89ad0545762c2dbeff1a7a15d77f151cab9ad773abf9c7607ffff42e6af22e6af6ae7e0f50d17be011fb384f2f3e3f9a9d6ee3fad9f7c0054e02b400ad079c8eb2e1b7ef152fab8bf96381cfbf095788aa320f8d11cf4755d8633cdf1dabfee778fc35302e4e30c84b8c97f7b1ef7b1f63e17dbd32f67e797e5cbf99d3f52a9eaaa68b7b093072ca9e37ff92cbff017af203dd470530a287f2afcbf9e118d29280bcacaa313ff3d2027959a67d7f5733adc59afe10753914278f88673400f35fca537614a07ff9fd82a2870e0d207a8899fa219e090fc333c1929a999c6ff228a414f48fe4bdcf8fc2e3bd89f17dfaa47b4f14ad9c287c835cf0efcf28c63d8607b48ed13b31ee9318cf5b4867733c66b9b8782ff1f9b0cc1f8fc0f348af3b89fe79a459ae9b47b44e90f0495cd1e0fa1f73c3c7687f0af663b4e9e3f07b8f69d59a6c37c67f8cd43fc638fe09a3482dfeedd77fba39828f0fc1689ac3d2e5498376152f2b0af8cbdd01fdf6fff4ff89e87f90a75cfb2fa99999457ebf827d17cfd25599a10d55ba7c4f6b48433c633b9f655f21fe3979fe5a99f549dea9927054733e017ac8df6e68dcb90e913a5c2fd174091bf2fcab6c8323070c4022f3f25795d2f25732bc25e3b3b3537d38b1438f51fa8e79483bfa61b4831a419a1d7a68c56360d52416f3f88e650f62eb1253f556bc53b4fccb81f78b95fe1ad2ca3b547eff57a4b51398ffe74e827983776b46453f2b56bf9e1f5f7a4b4e80bcac8cd8e5cfc8cfab56ab5d8b9599ac2a3bcbe78b768a259f278aa69c86d5d8ddf152fcb3d37cffd127e8c54fd08b9f40ff943ea18fc0faa9fd88a13946714cf1b0a4e65af3352d5f34a4d194af1de2e05d28e32fb6a78caaa5109dc278fb0cf2b30c99a41b9245eb7f554d4f2f8d9b36c6960774cc1f150fe887fa4ccef9655ecd4ece37f4cfd1273f473f4312a4b3f3e4bf21f56ba02fa3aef6b31bf7affe85f1df905487c09ec4ca332a17503fcc7f8a30bf9b9fb2343cdffbaf78c281bf9fe1fda57e137905a82140ded66f467c360a943b2599c3fcd0facef729f9be3de1704dd6e75aeefd6415e924ef71306200def30ce20769f384753583fd5324a7967a4ecb29a69d635b8b4d7398c1e6ead02ba5dabf2ee73be06a9ef4bb5d70366b00ee67bf2eb1d0a9e4fae4913bbf78d2d86aac36dad2fa2efa4660872c06f74d62d9210b7882fbfd09b9b7a9d841c7ab79ca6fa1fc85dadaf29a7cdd54f78897f3d69ff3cfd7d63e6a28fa25f2fdb2215f6ec4a1ffbbe807f77e1ead570c57fba3645ece43f82f831f20f996e028790cfe5f811fa05f81e748790cfe39f0033caae3236519fe33b83f4fd74deac96ffc1b62edbf6729c33a0837f07c3d5da3cfa89ec0a67406cae85b76c8a27a98ff676e7dbf8a1aafa205aba83d60a1dbd59a8a002b3e2d3e96d64b92b8b4cdf9c67cdc893e28d77d7454b82ae77f5a666294f1a1bca94a49ac643e74b37522d9c7325f3825eb6723b3698dd7f34091fa5d54d3934b0dcc25f73183e480be5facfdffc0fcbc84fd395d430b9fe24a3c85846eaeb18e9ebfc6801f3afddaf988d3b1dec66f92cfd94f9d2d7a1287f4b8f2bf461aac1004d04d3b49e3f252bbdc39a0ef9fdfa07f7e433950b47f623533b1d8b4b7498d87be853f345c90f343b4f1733c833ec7b3ee73b419d2005a743de42b1a6e31ff38f6875f80e70bac6a20d3d05f9060381eeba02f5c9e1cf59f6ad7cd97b8e7bec495fb126c47484e63be2c5affcbeefcfd2bd40ad05f914a74faaaeae3c09bf2338af0cf4ecf8f537fddad059442d43f131d207fb88afdfb029f6f75c7c03226b98dac2e0f9363be8413b94f605dff20cf3394f10c357ea6451ab1abde2691896e9ee5afffbc9a9b9eaf731f58df1fc67f899def2d2cf2637d42bfc5ba6404f16ff3e45fe7f9b1ae3f30fe6c993cdc3933f938033f05cf9a0f0b175cffddc473e726da75530bf44dccc5b08de8ba2fe96651fe1eef9feb3ab542d623ab65873275e7c0dfafb6eb982b78873b05d629f23201c71376c0cec77145c205f9fedefc0eb973807e57b4fe7cbe23e7c358fdea27a8df13d6abde46cf0baa23fefc6de8f3cb15247f15abde7657d6f4edc49f9fff6ac2df42fe16f2b75807dfef93fe67cdf055e0b7967ec7917fb7b1c1e7dbccff74f0fca5a7556f8359501df1e7afff19dc5ff3e0afc8ffab68ffff2d3af57f2eb9a90e0de7dcfc8df51cc9fa4e2ba757543aae7cb8e4f8f99efa83fbd5c9bdf5073c4537b4fbce7dc3ad88f5067f135984ff1ec6ffc2389e87edc8cd3ab22e19cc4058a7a4de7ba53d324ff5edb2ff21c1cfa7d3e3ee94cc97be3580ac929253b4f6c09f3f6cc9fa1bcf9bc7d8633f46eff029e463ebed9ad816a83c3e3acd7102cf8f3cfecc0756defe714fb9191efc32ab73ef95dbfb73b82affbfa2bfa63feaaf2340ff497f6dbd649be351824d8092ed09d1f385bfb8efb7bef15f3242d2370da553b691591777d337c64b99a3fb299ad069907bcaa452934f9df03bee74eee3bd5d56eacfaefedf82cb83be451929db7c8b5a7c6bfa20d8d4f735c51ee435a9b434e26bf8b8017738d4e5fcaf52c7dabc5e29b836e7d095f6bdacb1e63802255e3a7e971f24f52310977ef791e26f80eb08c48dff027f055c4720cebef9fe030000000000000000000000 \ No newline at end of file diff --git a/packages/nouns-contracts/test/foundry/files/descriptor_v2/bodiesPage.abi b/packages/nouns-contracts/test/foundry/files/descriptor_v2/bodiesPage.abi new file mode 100644 index 0000000000..1796648bc2 --- /dev/null +++ b/packages/nouns-contracts/test/foundry/files/descriptor_v2/bodiesPage.abi @@ -0,0 +1 @@ +0x00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000f40000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000140b5d7cb8d83501044d167196c4319fff1df1e2467312b427128844228844228530954378b1ea45a5de9aca02552329fc6cee96de7f960f7ccf1b3cee9a3ddf3d6e9bddd17764e8bafd307bb2f1ba7774e1fedbe6a9ddedbbdb0732abe4e1fec5e364eef9c3eda1dadd37bbbafed9cd65fa70f76af1aa7774e1fedbe699ddedb3d7d527df9297e67b3548961e61053fc392d31cc03fc8c9618b2003fa725863cc05fd0128377a3a6f84b5a625806f82b5a625805f8052d3178376c8affdfef67494b0c6580cf8fb4120302fc352d317837748a5fd1124315e06f68896113e06f6989611be0ef68896117e0ef6989611fe01f6889e110e01f6989e118e09f6889e114e0d7b4c45007f8675a623807f8175a62b804f8575a62b806f8375a62b805f8775a62b807f80f5a627804f84f5a627806f82f5a627805f86f5a62b07f71ff00 \ No newline at end of file diff --git a/packages/nouns-contracts/test/foundry/files/descriptor_v2/glassesPage.abi b/packages/nouns-contracts/test/foundry/files/descriptor_v2/glassesPage.abi new file mode 100644 index 0000000000..547d66c2b8 --- /dev/null +++ b/packages/nouns-contracts/test/foundry/files/descriptor_v2/glassesPage.abi @@ -0,0 +1 @@ +0x00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000da000000000000000000000000000000000000000000000000000000000000000150000000000000000000000000000000000000000000000000000000000000278c555318a1b4110dceed6dc6aad833348c68902c18a433f506430279c1c3874208333cbe0e4dee05c3f50e49fc8995e21f0535caad188f3cddcb6d70ebcb0b5ddd5dd5533b38b54559dd7acbb5cbdea2eebf7eeba39fae6cc0f9cf981331f9cf9e0cc5f39f357dfbaebb5335f3bfe43677ee8cc37ce7ce3ccbf78ebd47f74d747cefcc899bf76e6af7f76d7ab0fd5e8f5cbdaf02205b7553253d55690c528102d8b75a659afcc928e63fae8fa94fc5bccb5f06fa1f45990c528108d08d7ac5ee2a44d7abeffbb27fed60a3485cf31b56583fc63548ff1c933f5ffa9cf73d7fbc2feedbc931af769ff83f31e13ff34b77f58c7e5fc57985fc17fc537892c468168445d69562f71b24a7a3dfc6bf4e329351590c528108da8b566f5122717bd1efe7bf4efe1bfa702b21805a21175af59bdc4c93ee9f9fe6f9ebcff412b7afad64ecf216ef09abeb7fa2fbebb4dd2bf41ff16fbbbe10a91c996d1d6ee2fdc7de474ab595f89c3ec59d75f877bfe07e81cb0be039591c528108da807cdea254e0e49af87ff12fd4bf82fa9802c468168445d6a562f71b24c7a3dfc8fe83fc2ff480564310a4423ea51b37a899363d2ebe1dfa0bf817f430564310a44236aa359bdc44993f47af84fd03f81ff840ac862148846d48966f5122793a4e7fb6f1effffed7efbffdb31dad9c3857b889cee34eb2b71983debfaeb70cf670e9d39d637a732b21805a21175ae59bdc4c93ce9f5f05fa37f0dffb57e8102b21805a21175ad59bdc4c93ae9f5f09fa27f0aff2977802c468168449d6a562f71324d7a3dfcffd3efc3d7e47f8bfe31fc6fa9804cc68cc67677e1ee1207a6d0596693b6bf96cef359406381f52da88a2c468168445d68562f71b2487a30f8050000000000000000 \ No newline at end of file diff --git a/packages/nouns-contracts/test/foundry/files/descriptor_v2/headsPage.abi b/packages/nouns-contracts/test/foundry/files/descriptor_v2/headsPage.abi new file mode 100644 index 0000000000..7bb2a31c7f --- /dev/null +++ b/packages/nouns-contracts/test/foundry/files/descriptor_v2/headsPage.abi @@ -0,0 +1 @@ +0x0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000ebc000000000000000000000000000000000000000000000000000000000000000ea0000000000000000000000000000000000000000000000000000000000004f45ccbd7b941dd57927babf6fef5daf73aace39dda75bdda25bdd709a0342e3b959b18c3021f74aea310e7212b92734b281b178d80814646e94802345ef074258c6562468193f82111e87188312df38c60e016eec083b93d80e13633b315692119e194fee5df96356d6acbb66adfbfbbeaad37dbad53aa7bb71d6bd67ad5f7dcffda8aa5d7b7ffb54d52e633afe463b9bcd7fed6c1e5edbd9bea24bf6234f74b68f8e76b65fda25ffcbce75b6375eea6c1feb92fef22ee99b5dec5774c9ffcadb3adb573ed1d97e5597f4ab3a9bcdaa739dedffeaa5cef67fbdafb3fd7fb9adb3fd673a9bcdcf9ceb6cffd92ee97f765f67fb5bd776b17729ff6da35dec5dcabfba4bf9577729ff9ace66f3f6d1cef66b6feb6cffb92ef9ffdcbecef6ebd676b6ff7c97fc7ffea5cef6ffb54bf9ffdb139dedebba94bf7e6d67fbf86d9dedffa64bfa778c76b1bfd4d97efdbecef67776369b773ed1d9fe0be73adb6f78a9b37dc3becef67775369b5fec66ef52fe2f75b1fff2dacef68da35dec5df29fe86c36ffb64bf9fff65c67fbafeceb6cbf71b48bfda5cef6c9273adb6f5adbd9bea94bf9efe9627f6f17fbcd9dcde6e6db3adb6f5ddbc57eaeb3fd7d5dca7fdf139ded9b47bbd85fea6cbfad4bfeb777b1dfb1afb3fdceb59ded1f18ed6cbfeb5c67fb96273adbefbeadb3fd9e2ee56fed6c365bbb94ffab2f75b6dfdbc5be6d6d67fb076feb6cbfafb3d9dcf74467fbffde25ff5f1bed6cdfdec5feebddec2f75b6ff4617fb035dec1fdad7d9fe9ba39ded3b3a9bcd8e2ef9ef5cdbd9fe5b5dcadfd525fdeedb3adbf77449bf775f67fbbe2ef6fd4f74b61fb8adb3fde068177b97fc0f75c9ff7067b379f0a5cef6235df27fa84bfe0fedeb6c3f3adac5fe5267fbc35dec1fee623fb6afb3fd235dec8f74c9ffa35dd27f6c6d67fbf1ce6673fc5c67fb6f3fd1d97ee2a5cef6935dd23f3adad9fe5867b379ec5c67fba92ef99fea92fee3fb3adb1fef6c368f3fd1d9fe89973adb3fd9c5fea97d9ded9fee6c369fee92fe779ee86c7f62b4b3fd336bbbd8cf75b63ff95267fb539dcde6a92ef97f765f67fbbf5fdbd9feb9db3adb7fb7b3d93cdd25ffdf1bed627fa9b3fdf3fb3adb9fe96c36cf3cd1d9fe852ef93f7b5b67fb73a39ded67bae47fe65c67fbefbfd4d9fe07b775b177c9ff8b5df2ff3f9ee86cffc37d9ded5fea6c365f3ad7d9fe475dec5fee627ffe89cef6af7449ffd52ee9fff8b6cef617bad8ff64b48bfd5c67fb8b2f75b6bfb4afb3fde5273adbffcfb59ded7f3adac5fe5267fbd7ba94fff5db3adbff6c5f67fbd9d1cef657bae4ffca4b9deddf38d7d9fecd2ee9ffc36867fb5faced6cffcb2ee9fff25c67fbb7bad8bffd4467fb77f675b6ffd56d9dedafaeed6cff8f5dd27ff789cef6d7baa4ffdebecef6ef77b1ff4d67b3f99b273adbffb68bfd87e73adb5fdfd7d9fea3db3adbcfaded6cffbb273adbffbe4bf9ffd025ffff745b67fbf92ee9dfe862fff16867fb7fee6c36ffe5b62ef6739dedfff5892e051c36bca21e78436b18e8350cca6b6ac682da3515e3401d682ed70a7b6fe15f31e99ad2451018bf5bb6b49bf6e428ad89dbf87477b2c63762e5ba54f2e23ffa9071cbebdedd4ac6bd3307ed05ea39a06f40a780be019de2a7a527d3d7a0f7500ee8ddf54041ff85f5a617a5437be30c5c084ce658889e427be3e252cce8177a82fe9df183f5c01ab72f33f1bed864fb0253d9674d759f03cd41fbb2fd176ed1de744bfb683fedabec27e5ecbef440b02f85864d6d5ff7f24f1b3b54b781c9ae2d01b1e16b33209c43bde1101cc0a135145293af7561d074d0509342d442b6cd207400179a081e9170d7f687a8ddb582beb95ca8d61635034018da0732e5d988ee4dfce87943c3833e31747099b1953e50d4a782920ff618ae58e177d60c4542b902ba932a5558543a285b5ca107230069766aca88c47e10fa2804703622cd1356d1096c8e83a2131f5fe858538b5652003b6d45316de5bc6ccdcfb690a792922a451ddaac799db8b0db5936dd2358e2d9f9a925ba402790da5fa8a58a9fae9bad708d67e99d99cf7bae36d0e33057134ed7426b142dc351eb37f660df024ff01f1a375cb7cef886db619be887413d28aec11da1c83be2265af00eb4c95521388217adb24d5ec5a207ef95473d9a8189940f8c6dfa82f7c6379d29030ebedc64930181f2049ee047ab7a344f3275a5d6244dbb2a465af86dca1122bddd84b23639e4b5f0df7fc1f5d9e74a8647ea2618a91a3be2b6db9132642e137802e59148e5dc26b233fd23b876b65bf8f3765700764323847433ba5c7617f8fd4bcb34d283b22dea49b26fdb7964299737269018df96059171a5cc44255ce763a5127aad128d25009550f2bc3c7adc82e712abbeac7a52bdf01ec80037878acf8c7f7b5a3bab2c57e2b100e012da502918b3a85719358c5053578a16b87faf1abbbc3f088d5f4fcbcbc661cb0a9cf1f5bc5cb46ebd37392d60a8e06c015a6f4d349d5274ac3ee17a2f7ea60cbeb740b8bebebc3ccd93298106f08fd5d74a0deea26c1a459ece04b3caf366ba365253ad27af2f6b3dc3459ddfff61ec8a3aa3ff3a84dee1504f41117f1dc2557aa80c1ebdd2213a4c900994218b8f57dea9cd1f0ad56681a4a0e2ef0bd91ff26aafabdeb5f156f97ee579013c293fa065e73402dc216ed01d8810ee00851c235fd67ad806312958d3a005a12e55adcfc28e0fe28781bec83f1898e041c49ea00cfa9907396241838e20ff23a0b90c846dfcc581be2d5ac0c84b7d8607253ee623b8128e944ce948682a4710b71cb1a6061dca5f5f3e42db1832dacadd7c0478a7870616631f52dd3b73d03bc5dab2a095beb3656368719e1f82fea7a35ddf5d5bd4a04d873d98d1adcf755eae1ea5fea1f0303fe44df6102fa27d7f1857473d40cf348c7aec4b11add0200ff33ef4cafbd0cb43820692d8540257512ff1c07ce3706aaa47ad8907e9284dc31ec55874d40e56c15f7b9407af042a90c92447793480bf53bfb0f047ada15bca6f8ba1a1ba8c4fcd7ea017a3614546550e9ba9d2b859525a6a26182d05b1a936a30bf1b020c008ea2496e41e8cb2e5a65d732946d5fee6d263c0cfe2a8d539356eef3213ecad1bbb976e2245ddb0d09b152af187c17f98f6d68cdf4b1f2e6c7baba6b4b7a248f7a626db4bc74ac80d4772af3d8671672f83f3c7bc72a5bde1318c207bad2903fe98dd8bd801206809de25e416ede58f30281f4bf666263816ed0d96bc776dfbb71afbb71afbb79a5691027b24f46a854afc08f8476835f66f353d52d85663ff565714e96aecdf6aba1afbb71afbb7da5e8dfd5b8dfd5bedaff6ca9556875763ff5663ff007fb55d8dfd03901380fd436ed16aee6750be3a598dfdbb3a5afd26f68f3e8ab6becc226efbe800502d28fafacd0297f31ff5852c3c6280cd68df006d46bacd68e1a3d08cda418c169b59353cea36f3286f2e8954f8f066f731de0cdf41da9cb4f448c91f730dfe181516d17acd477d37d3c78206c1cab0dabc3683b07c2c8216741023106ad7d2e4398a277fd415f9b75ba4fe761e7d32bd1fede5d1e6506b628b3af2661e94fa21fe11aed823d612459f4cefbbe6a439a08f19f4383ac867908b2318eadea3b7d88cfee8a3187b37c7c5715f7c1ff1398dcf42138c63f41f0f8e23ef713a4e37f9e3f6467b1c47063abad17e08388e2302896f7490f8388ed178089b531b4bba9ba2e3ee46771c11e378cf713b5e5308df02f672dc1e0f3e14a9bf3bcebf1d1f97f224af0cf9bbf1f2718c90e3a28db43e345e42dd161793b4ff761b37d41fa2474e914f8a73913266862ea5ed712ab34c9cff94b727a9d59927acd03b9d4d565557d0133d484beb7ac0cf86831d11418af13df5db6d1a99729a98244d21c70ba8dfe70dafe8b36513567a30f7b243ae52311e14b3cf21ae20a2ac10684b2e992a741966a61634c26c92d5ce488fe3b60b331bf805158c57bb02700ec0fc6dc84343bb4248a9da22cc494b481defc23caa12ed2a233f87d46e579f0976d54db42b333d2763e34fa6590cae64b2934b3b07ff64dc2523183ff93d7d0552133dcaef091f458d1e8d210b15601c7a0f8ef1a3b8721febbd8f1fa3fb68087894ee8bb39c226ebf2fb7d9fb6cc6b9ee51066fa1e3fb7ce601d6b4619146682edb36beddd69e6ebe7c7befeb319cd50d2d088b1d097fc50443f5904c308573399580b2fc233045a712130aaf5c344505579a6a2136e95464b2a9d0d4a7c8fceb29db6c80f61e5c5c0d0e4af9989fdba9cac765feef94e24a4489958f7364a73906c7ca91f1ca59f8d9361a165bfe385d40fdc71312fb5c8ad48b3c62b37ff7183750f7cea493ce2493ee1a9e64f34b9388992683b0d485c693b8b20b5a99f4c64e969ab2a5a6d7a8df365bba6c7289110e958c47fc1898686b6cec56f4e35bdda8dd8a110abcdd4aa34e75a8077806a80d3cad63335727f05bd16e40ed2cdf9c3a2028687b1a5be87d9b1ff2bfc0276ee37d9126549e8b34647a8a7ad922bdd85afb92d7437cc58623b87569e7f9e7d07ff4e3fc661c981eb6a6ce0c90791cc879f4c2b05518fd27f71a56e04ae485f557270c5fb2cc4726b82733f61e7edcdf93180675f730bb7bd076ef21e81c78af7c001eb249606705da0e28d28a9d6bf7903904d421d7614b9026847f49d3e2bcab4cc89f1e27e44ff758e82d788c1a8f231e7b7ca1ff3ce4bf7b4c98b7af047d474297fb24344e295d6e13d419344d70fc4029c1b14a3847fecfd854d0e429c4f30acc03a65c33035f0670dd9b1ef44a55a4ae268b9933b5fffe4ee74f727f067dfc1ab48d358855d6d0cafcfe8b502a6894d366a16f167acc4748e71c480bde5e87b1ef3a443fd7c1ff2686245bd26d60aaa3887a47030e47d15b8d461c14d48f12da0aaee8d118c059431be1d16c16a5d10a684f019214f0f4e23d2a56521da9ec5587d6ce7da34b3c30c5ef1fd13ff40728d3e620eb1e226b813024c8411b2fb6745ad74247fd405a509a63cbcbaade0a3e224bb7d2276c0152b0d0c26655e6796d2d9dfd04cd63d7fca59c4fe6652efaf0509fde1f4344f929be104c9fb2733050fc5f333ffca7abcc9fc699fd3473fa3bd07dba05a415f902a00514befeff331fcc2854d7b2f52fe262dc61e221191fdd1e8ced7b02b9e3666a88f4b8417b68178d5576e17a025fdbc57bacda780f37f842da984d33502a786a9476712e9bdc07d76a6361f57b879cdf00f1f9ceaab107692762ad9d15e376964db013b57c3b9b78a737feede8510fbefb58fd336f0911634db4e392b07e70d1ed6afa77448e0ffaa7681273a9c9c8d1640963be5044bf4a43134e068e9e24f01209f0930e31467d9236916ee57e225f114ff215725f919fa449ba02db2b6892e55ea3f23ce99e44ffa17cf8646137fc24fae72b10035fe1975cff47a57f4544e6de83b9f47bf80e027588a313e44fb7d37be80e44d5b7d315d1384abddd298f59dc8da432e2df3b8019fb7db9dddee872f98a96ed91dbf92abe9d8fd02cb87975bdb72fe6f88797c8f55d47e4cc590fbb0c2d3eabb2559af39cf9d3e8bb4f639405f5a73973a7adf20ceae691e7fad7054d016541391929957904b193dedb88cbd9882b2ff5f87fc258b45fa97b0a205ac67cc981a2ee81cb70cd8192ca3640bdc4a7905d10022d5b3cada7202dd2d4328cbcf3828dbfce077caf0b1c46c028a0c7c2407436708fe5ba6ab0b04ee27f187bc980c43fa733c3a7832d7c1af1cfe90414b1c9e96c0b9dc6d87d9a2eab80c3287c9a2f131dea79da5f56dac2e3d0800f2ea32d2eb25bd06a4ea3dd9d468c7b196611a7290ac791eb284501f8a0e01969783ef971c8cdc2177cd8ccf3e00ffac78b7c9b282342591fe4c7f392b959dae23f98d728dd623f98d712b5fd605e73a96d58ec5152ec21a2acd30b8cb2e86dc6afe8478ce90ea1bd14907b1bee041d0a0ad81381d893a080cdef672439f8223c663f87e844300dcca19017daebacad13afe9928343f7b7f1b8eaf31ce7a4912df212cb8960a65e275c7effa34bbdda7929a1bd8e7442756dfb2ee059472738b488619e10af0df73b6bec9d7d86eec459bcb35ed01e13dd89baa4ed403f7d27a5b8da66c18967cab0cc80e55f9b34b8334b097ca434cf23b8b3021a15169af6927ca359367b27fa9f54319d5e722fb4f0755a1f9e038c5777f205b5445c7e27cdd91fc19b9bfffe4fc343fdf2fffe703f806869b8d704c3180b0ed9613ae486731ac97d7d704e252bf7ff2b7c194347859750af4f27b80641cff065e8027d12822e43bca0fe81fa21ad616c6da17115db90ffa05a92f8cfc8e28f2ba8c287a26186d5cb9dc161b993561fb6a67f18ed07a5050d2735c15ed843d965566bea2f93b203802ae0a596a61f79d9cb305bbb6c213ddc6735bea81af7eb9171436e2ebdc7fd3af82b3b70833f2d8e8610c75dc4bef4f3ff451d7fbc3e29c14d5e991a5f6ced4abdb3b352b4b48a209148ab644babeccaa45d8677ac69c43b0217ea365a19601beb3659e975ebb02dafb4c55652db66ba924c9e2f379d96661bbe4dc7c837d4527cb3b27231fbf75bc60fd59d3701574d89cb06f3b7d311fae300e37c19f33419f7ab4ce672c62804206e861ffa7e8d05d052a6f57c1a3377953dc04a2393ed4a4c763a0771799218bc626131d9a70c5dd2e7312fad64fac45058494da952d26798c242672bd5e2c99f9e82d6e43a03526307e03920bc5b179878205e67b12dad63e5d1cbac2370e9bab9106db0ce0eb07afa7534806847d3c6c8c72347bf6e21cfb1ac430deaf2fcd324c6b5c904b16e84581823e69170d21ec1713ee226dd1194718440c93c74c4f5968f04bd09f465b52de66c5ef8fb55f97fde07261a4a4d325402cd4053130ef1180d95610dc7ca86869231d80b94a029298d0d8db1298fa1be63d6a463182d013fe61bf1983735e82bf0298f65261c5bd25d2ef2f2ffa8ef7d0a67e829faac7d8aff3d3d157d4e7882ce430e9ea2df0d9ec2597dca3e4d6a4f7e8f55a6a7e9f7e869563bfd6ef8147d5e528917fdae032ce001feac6f938492fab66b59c19fe5a7aaa2d39c726be52996b27e572c346d115435ef3c3ffebdb9e0966fe13f9f077fb64fbd967e7eff08e3d3a0c3dcaad16f28e446dd586c31cb0b11ad83aba2a57950cc5a949621237a016fd7c7ca7bd1af8f4c024aeba91198b27a3a9329c5de8715b161f66ac1b9908c0745ee261019db549e74588fd61cda235c0f20e93331612c4f45acc7390ec323bf08ae0f7ad473fdc227d8478c1d94ffefe93022f6293a6ca762e5f9304d5900fb90c587c3363bb8a970968f800e3b7896b16df714f014f6eb5825b8f918c6c6a3d92062fb0276b07c94945ffafdf777e20a93e7033cd7d0b766dac7a6e8ff2a1c9a1afa40f97fb54fc1a61f5886fef56780650a86deebff654bfdfd10637f7f28cf57a06f1e4a100d6264198a0b8a1879c863cc0f86108fa0a6c1b01bca2dd842c219953b63c3727f0c36956898550ae125f7be10390c2726f7b1c847ca28f4c81ff189dc23c33640542092f88884bc87a5743f2431aa838fbf155bb9e386dc02cd57eed7496d10510dcb3db6dc37915a638f16f20ff44764fe6b4bc6f5944cfc80eb891f40fcf900dde27ae89648f920a790dd33d0f5a0adf5cc788894a7a35bc8cce5781e3af36f5874817df1e7ef65e307fbe57ed117302ff802469e2fd06a7a1badf65fb086c15b911bb43a805d6457c8d117c4a7339f2d9296be601bb335214a0da66b60db6a1714355eccb39ef3fd7e49afff08e30f7ab2b18a71186b72a426c038153c2bc0b8f66c62a231418c310cbdd9b382d0949f457f86b1cb8d957fa13eb6f8f2bfa0e5f7da6a952d552b3b641beea0e742e5fc0e5f254854055413ecb0cff10e95abb9065bf1c9fd009ee55fe9b2edb374a66aed19486748617f1f18b3e05b3a2e74bd4b98eadc573c5f199c2a9be414e2b553de84a7e87074ca9914944f59d3738a0132bf7e8a0f5bd00c94a1b34ae970021f56de1ff648174017231f079a03e702f907a7167d8f9b10910ccb7da8d8a667ac65e3ad3daafbfc500b7c868e92da383f1617b5e7695339660d9a372f376da399e37d519f0ee91b73ca6a5cb46e0f5187fc72bbd43ddfff459f5e793e11f35789bdfb25367f17eb7d1a91f5fffd7785188f10afbfcb01566d0190cbb93e54bf44d3869a47a0be82dc970b9da42176eadff20b214b3ea9d88d7854a0a9e5a924354637f556de169e8c518fa6f940d37181bce4bc26a8314a90b4be90739fbc2688149043d9442a553547f158c87323addf6e13e8fb29b41733aebdbee1a739cc7d0a4ede282a830eeee546ba17fa4669af9727f1f70a703dcda1bc3793a7b390ce6de6c82ae48e41a65bbb398eb890bbd7ef43862fd1fb0fbd8122ec7500e629bd6833bd38a2bdfc0788f9fe2085dc0b5b093a0f3f0fea7a1127e9fd85103c99aaea72fa6f9047157e2d04bdee0f826979e10df11e138cd431fff05fec35c9172ba6fc45ccc9bee8396860f6fcc580a306ced217238e1b11e2a3b0e1fe303009fb46f48732078d1ba53ff4d0a2bf8767052d2bd12d8e237c5270a944b45c6e2ceeaeeeccefd74cb0a22f429f861c321c872a900d4717451fa225811db60dc44c0a0b19310ff8d9c8f5aef0c3d8a9691757bffcff15b4f05b701d02740bcfe2f916f4b3002326e10fd32aba052deb16379c535ac5ebe8c37423a8d86f41ecf609c46339bf8a06681dc3e66fe161ae78f11ec0f5885c2f0ee4fa36bfca01f4365be8decc1b4a3b8c5fdee79ce921011b477417df4c7725374724b4043aa3c9668189cfb80e7c85708d0101f24d0a5ee0b5ac85d5efb4de5fc7f8f816b4b3b7045fe2b7a0bdbe25f912bd05c7ff2d21a803d02bbcc57e29d7db8227d117769cb3dcef4b36b7412eabcc9a4702da330bb94fb5485b2df2cd243f53fd23f4a97f846be58f845ffadc407eafe1f80fc8ff5b1bc8398037c4c616bcdd102a1f288f7656f06e83159ea3dccfb043cfead0b382969c2f2c09301ff51bea0ed7459197cff32af2cdcbc811b6d5236eab5f49f91c98f7163c6da8989cab19d98745efff9769bd03f8cbd8ff82b75f0e950f9447dd0ade7dd90acf51ee27cff5333c00ecff7a5f5812603eeabf5c5f8ffd2ff2f2795e45be791939c2b67ac46df52b299f03fb5ff0f4e58ac939ecff9717beffa78dbfa4cf13c64827e3a41c4fb6db73e8131d2d7e03a2b0699b5b843e655e901c72b02e2cf4752e6d405f8ff3e816712ee7fbfdbc0987fb22996b5680b27941fb649cab76cca3a90f0bba664f2f9878b8dfbaf11ee326f5ff5879c636e727f4ad50fde7cf8d47f2dcdb78eed16e51dd048f078673fb457de4a95f275ea69b9f1de7f6dc3a780ae5f15979b67bb7bca65349be3ce3d74a37399f2f896f7bae1dbd255fbb004f9ec431e8e26727833caf39763f99185fe8fd64157cf7f673bf09964bfc974d21c63a9ccabf4bc6830687b379e0a6826b5c1bb553d135169440310748e91acc928c685d83ae91a7421df4b80af27f0c54935eb3981efdff29e66f7493bf1723d4bd7493bb979ee77b31e302b5f77a13dd4bdbfcbd2c4fe2dfcbcfd3bd3468a109eeb526040ff91a8f54b041f6d7480eb01be4b20d3c6a44d704f7d210ddcb006d137f44fdd7f036780d0585542e6894a756dea234ab326b2e45ddb4145b9428750d50378fdac0fe3ce49ba27b9dd4ec2697d136a93ff483b1961c19e1ca46ea62ef5dd85cf243261caa7b36595dee5357b0a53d414169570b55c83c2d57dbbcf23491a62f19bf874ed7b0e5d3683d7bece98a09f7548cbee9dfcc11d563f82efc79934df2fe6e88f88233cc93caa68ad98efc2fb81078ae5e8fd6c8ee7af4ff4072bde79a6aaad72fb4fcfbe5fd778739523393377d27b859963b5c1368ad13348ba77ac904ea61ebb80e9ba1bce55bc7acb5e98533fd4d36cb70f5fd02b04cc1aa2b35e9e1b88973dab4a088b09b8b99c69e6efd3f815e35915e749c86700d0fa1d71a92b7272c24f96751e5f1700851d29068ed783c84de0a3c0d39f0e81586a2f1f2503a1e0d85e3197ca19394905929d28e8b57008ea5a783bf835e728cc149ef4bea6fc7bdc9509704757a33ef4ec8ef4fd1a6fb70fe1dcb3c869f75326b657a1623e2b322cb73b6e57c360c394780b19a94b2cae83fa6ed0e3a9ba7575db98d2fe53e686392969ec59c5e7d93226d3bffd63c6ff8ca3d407a3652bb45dbe21521ea53e648e6f5cff202efe35decf739ec7f3dc0796d2296697228eb28e434917b184dab92bcbfefc21ca149c340d760700528f42ad3d12287364aa1d37c5abeb27e432d6453430bed056a0f732e435f816f0eaf65044ddbb0cdd8c40f2f7d1f3f2cf78f117ff85d25790ec944bb30d26725e37651fe9f66e64cf18c9282153c0df482c64e83f5d9a44ee08cb653c6db72d076df665bc28f3ed7bafe26cac64ee471819dc0f992f8a0809df02d794f01c31338eeb3757b747c9eb0851e7cbb650fb5fc5b68b3e429c5a3884c3435df41d3766ed54e4b7777f0b49f2d720aee98a9db4cd9c11dad32dad2ef7177ccd4d8b6794b9933f5e28956cddaf66fcfeca3d096b6cdc6380a6d294dfb3170edc761cf9ce33be7f84bedd0074d2cb90fa283ba7e04f2fa4a3083d5d6d8afa05dae666c95fb0aad068cff0a2b6f418567f0619bceaa5faef7053fd716e57475a15f5de857b7a599b6a18cd573fddb745a871cb4da15fcecf22eaee7225f7f415d34cd2c7db1fff3dae696e30fe765046dfb3c9f6ee6382ef5e4c9efb83c5f20cf1736522032d5865d1f36c323b23a07a20293f32ddd4f8be67943fe02cfb6a3fcc5d5ff53987fd67dff57915b07f47f95ff98be5a05dc45a8fd63faadce1e7329ff71f752bbd7ffc386460628335cb9c4b8caa0092ab2ce0eddea2a7d4a834a6f21d3adb6523389d28a292b4d4d4fa564ea95d8f4635c1ba878b3bc62cd5085cc8a4a30cb1654825bcb6abf026361a6cfb67045ca2de9b331f2ccd9527e5f459ca3efafbf5037c10b35c37f422fe4a8185bf0f64f52e59df2e536bea47ca07cd2c647a6e705d4ff05c4cdd0677f1248be8dea0bd4e03fe1361eede885364b1b4f2f90fad9174a0dbe205d803c17b6bfbf6e2cda1766e4a3f6795c21a3f43ce2f4e769b464426878348605bdeb286f0ee54d16630bca9b290b8d172ec3d5352aa3766ca25119a54b261ecd800ae4aa917760566d2d8d06f125a364eaa38bfb37f47feaf3c1887536f61ab711e7f479f40c8fbb8df438f6f779d4e0f95cf2cf7b138267f0e1f388a69f77bd2174ee79ee75db80e731e77d9e7aa36dd46ba1e7c7b99090e3e3e8cf918e7a13c8f43878e337e6525250c8737cec9c3c7c5bfe81968bf9d96129d917b5716d35f46d350fe7ec558a3dedc51e270b383e2f23221f747277a78e78b307fd8e3c558639b39127543897a42fd2b5592ca2e7407abdf5b035c0d5d04fd5c2f532bf4ad6c7a6c41edb44fef1018d11dbbaf589fef755414ece54d73bb93b857c9ce959cf72ef6a7dc8e17a522e683007bada4ccc6e3dc6c9f5993ee7e24065cd17fdef0d32c9f337eb59d75feb5f546bb8f0b749ee3f85fa0c847198f18443f2b486f05c4930c369d17448df549ea6d502e8239042de617eeb507d4b762b6f414cbf65e16df4bfcbfa6c989fc8aa3f39d0d794d03780d2265ba24d71417378f16a9301598d6896a658416896ceff1464e4fb22cdd171c94deb508f79ea622fa8f16222e52dc60dd6293295d5319098b4513269539f05fd77a5698ad6bf9a643d0ae356a74d8dac94b3aaf3ab25c50c923c378ce6b547c21c8b1c55677ef7617cedb7985b1eeb33ee18faf963e8538ea1373b861a1cc355728c1c29d08ea10ba6614d1dba1978d38374821af2a81dc33e835654967ceb48dfb3e8fa1d36f1500faeae641f03b2b21faec37d5cd0d9720c846dd4efb3b3ecdde4b9f9899c97bbd4a36bcc470d2daf07b1e175b8e6d7d58c5b5731c1ba0c484db4ae0c944cb20ee3e04ba8cbcbb87e5eca5ea697d0fe5fce393787f2cbb86e7fd1cd027ce77ddf8e5f165b691dbfec4df4303d123ebcf83b71678d1f1ef0a8db198c9129dac599ccb83356299fc11ca74167785a7267c85444ab906740b24222a516328b6c84af9e917cb10f672245ed0cdacd99c078f8960bdabe47e1198c67d025486fc15bd004e9250f3e5303c53876a6aa79d3991ed5b7e8527fdf6acd6f9b886b9a6e956dca7f11bcca01f27e3a83e62be1e9ba3cabca80bc2bcb052f2be2893ed667bbc5466ab390a37c55bc55d57cb5bc79a9d8e5bf085299356d45dfc5559f95d4742b9de6ebdaeae2dbea1815f5c63cb0b9f879e0368dbfd9f45cea4df5515ce7979259792966e997f684985f867c691d68e773d84ba3d05e1e8247dd2f0d43aad3e568919707215d8abd80c682e74b71c62e2dc31b11dba54b394b5f37c170bffc27a6eb38b6a36aca51662a11a20b593b21ca76a20703d7bb13a363d4b713fd2ab662a9eda4c881b35175277fcdc122dec2f101d1a63b49794957569e0e60bc8ffc4e463a94f6350b8dff9aa41359f4f435868e8adcd8843b1d74a1bc5319e12adae923d69caac87fc92fbf617e8ef867451f629ce011eccf2315438f044d7ac40329786a42dff4003d128bacba191fe1451716fa767f4134ad873f78d726b7db9205e883b6f2e7da44efdbe4f2dc743f05bd9b537e794ef9b64dcee6a6fb29e8d1eaf3f2816aab2ed02dfde4cbef84fc3fe311737eddff19e62f7f46a025137c9d958b4d089af391894049f9d0c4aaf79003e5a32550fb6795afa347869436e8eba24d81e13f5b4cfdef4784ba0cf1bbd7f70622138f9189c6bc09c6104b036ecc8a8e3d7802b563b88241197e75d07781f643d70fbf3af2a8236dcf586842f16f0463b1c9c64aa6ac6f2e602e3656370c79e1bfaf1aabeb87c993f274bbbb836f47940f4ab7639c690c02fd98298637a1f79539e0286648d3886e42ef368a31789636be092de18e6cd4df64996fd2350fef48e797e0c7a63c9adc14981272c3287853689282c3b11a0d6ec25ede84190a7465938d568ae7b57a4cd658d8fb16ef3581f6ef76a0c7f8819a0906306b1dc866211e484d69a06cca0325e306183ac433030e7af4ad03de24000fa03d0cb8861bb0faec5172cbc28eefc7f5f982d044be64ac8f46acc751f4d9084bcce17b46c8e33af175c83920a7857e84d3dc5357684df3d4b2ba6b98463ec875654e614d63d566d02172506da92cabab7af09223f2487d197b004b5c2e99a8bcd091f2f3387ef2fe517e2da7c63e43da17db67b01f8f608beb3ee7c367d0373d8391195bbbcdb774db82364eac7375b3ad3d0f4b3f923d8c78280774fc306d033f8df861073f52ef568f933dbcb418e89f8d5d568f71951f0d6535aeb70747e9ed7410e7b8e04195e7a3b48d655dc5b73b48f6286fa3412e240f9baea3388fedff9fe978c12b1afc93ac3fec65fdeb8ae15dba72d9041d44345c93d5cb2c78f41d3596d5cd267260ae55a342a6b3390d6b4eb4f0b79a2694d4904bca4bea54399432111e5c3ee16b76a274d02945aa9a3d6b616bc95cf367b94da65a78965486579354179ca55d7c76c607290a19f646eee3ceda369f126a16eecaba7df175ceef45130e0db2bcc5159df08368cb43fe1311db7e3b88f17e883ee1a1b783ccf2fcc15c39d434d44f83ee95b97cd84117166943cd933fe166f174027de60979433b407df27a25a897acf48798640871d3e020f05623eb1076f91166cb2bf4ff75aeca53c8d7a1e6d7592ecb9351a004f075f9f3d4745d00788010af899dd85d472afbebe43e6e50f8b8fcb9e9ebaab9cd78b507c84bde0772f244b4a6cb9fd5e6eb62d848d3e913d242b51c9ef6533acb66f3f4d7e635ce6b60c1bb696deee38b34793e56f37173f4e017d728da7edf91e7930344e6158cce15f9ef0ae7a1120f45b2bade107d43dee471155095d097cabdfc0afac06f90d135f9be81be6848dfdf541dc30bdc10462878a3457d43da9993bcbf21a962e44be2d795cb9a81a962569536e97a97cfbcae277d935640d7db1c9855f14ac4d3d7fb7c7df345eebff41f9760fcf39b69ab95f536b7669bd12a2195373bd3bbd99a68b37f40ac9cafcdb9d56d8e1f801d2952a1d0571e60500f1a6eae41577bc0ea3a9cbd0fe4eb79cea5f683f4c01c40dff741594d2cfa60f0b1403941f64159672ce75536f3cb2d5d45292b5f553d6fed2d689f82ba7db176ceef238686975b9c970398cf1d402c72c0ee2e99ea6e5e8363b6bbb20691d19af81ac48e6b926be2356c826b9235d16e36f19aca6e9c9b35f5dd6ecd2e78f783d67707bada556977199ed91a77b95d6331932bade1cb1973537b2030ee4004bd03573f109a9e03881d517274a00758ca93864775fd39bb2731768f937bd2d7d09ea8a022db6be449a29cfa82b6f4a1faf11e1c51f58f4d827ca23de55908f644fb6dc3b6d1d27ed97223de3f2395f62fa1f246de4fe681bacca1c730a6218a76636500338ca389091063f2181f6d03e24e3207c630ae02c9983b3ab08477aada7f47105ff5fb652354a2eb7a4a3c52bf69217023945117b891decc2ed06f6089abefcbffbfbc6210e30366e9265a5133e51588a357209e56642651544cac404b0396adc07c06e85b811e6005e6334823fee227f6700562f515bdc6214f5ed16f68c5b2a5568f3e8afeb75fbeff71ac0ee0fa3d8ed6780c2d702d5ae9714421c7d0e71ea3b5b882d7a24f3dcef28ff0713e66d7a29785af5d2b3289c7715e2bdead54a2b1d08895d58a54c8cbaadeaa0e3ec77cb1fa334ffbb3e646f097ba68be9a5a2cca8bbfac723b2befdc6ad5c6926e2d17b5f2c7b8554ba4f2c7c2b5ba47c76d910fe8f1a8e5ad7ba0e98f27456d7c7e04c007ba157f6ff21acad63500793b187b0e7a3c2c6a93ef1917b2a48cb53c399aad23237b9ee9b192ba2cbe87d962fc709f0d714d3abd3631ef05629362fe6b310fcec62ca82fe6ccd60cc01e8c9531b7c69118ab723cd6c3e1589d87218b6d003efdf08fc61c47988f5775e6bcd4b767e4fd2842ff8176823e231c933506656500cce4d7a07740ef416b5093359caf1cb046eaec641fd6cc5036a5ab882b05dc5525ccff2af32049b9610bdea5250fdf05dc02dea8eb2f38138d60ce3a82333d12c837444cfecd10fd1e481ae956562a8e64b56253ddf96b0ff3b60460c03dcc0d605b04baece1c51e9ffb4d345cb764a295887856a2b5ac0c12a0a0d4840e7188d01268a9495746fa1d16ba1231c895f2dc64d4e42b0772d90c204ee9535e9eb794efab704205e4dfdf1e5d617e312b31dcafcfc762ac3d8a3ee728fa9ba32593783e8ad976171a203acd39c489d7d2b414ccc3e15c35c4a3a2ba658b7854e147faff45f24d32e56f227afa26ced8371111422e010438809547bff4cdb0f0119d555d58f884d3baa8f0f7ead74250e4e30bd9aa9f9ff68b559743f2982963268fa8ad4ef4cd6a51ce4cf94151bed4b34f6dddf6fffb265c3e22eb333e5a09e8529695d01ea520fb6dba94c66535e46929d327ee0b09b3ba193e78737ae43c6de119feacf05aa7b3944dd76ec1eb38d71778fe3f2ccf6fc8fffd1bd2bd380f1b82bd7e8cf7a237d9e0f7c68849ec865834a0e9b8953786c6692f8d33e0f6e6bc68d3a56ccfeabb9c6d9aa5fcbeaeefeff54de1d83005169729ae83292aa4522e295f2e2c9653e5303b0b30ef1340c2ac2dc08c0ca016d5940ebc9d9141e7f5bb88deb595500be6dff670dfd492765d7e34a8efcfe97badba860c63cca2edfaf6ab6cc7f2ad357d655be169c00a8056e856aacc43c7c45e2bd32f833e67c13bc096311bcf75bfdca6db3e5727882fc27bf9df708936d49d5bf648cb6dc9ace9a42e2db96f8137850eb6ee4f1e291b7bc4becf1d898c030d8f60de7c84df171ca1f7d923b2560bbd8f8e58d373848d071fa99e648597f74107d0fb7e19b2d82be0e57b34fe083702d808e94bc89391679e9f405684c1ece3c89b7bbefda0f1437dceeabf8865f927d104397fb8139f1c2c1d4e0b0407b177871353391c4fc31f4e4f05d3dbe0141f6280da7474aa04b964d2536feefdc8c3880deaf2fcc4db0600b4dfb7a1f752daa794deb60c403c09fb6c5a3771ad47fef5bb21ae5594966aa9d2b45636b55a627a6bb1ca55d03a70490da37b0dc7bd161e967f11c3c32152546a4b8fce74fd321cffc438ee95ff923e62b926ff3d7d24c8df8707ad9884b382a78f10a7a6cc98c370a958a70b751c46ef33ec00793b2e92eff0b083ce81f270a8765fe878385039515e566999b1d961ab692b80bc1b5d427ea1e641a65f5697415a59736671e7c7aea88761866832f3667114d1b38fe7c0e953f673698ff7e049ef4a10f8c8f3bb08f0e07bfc9b5961f0c732bec9536b7bd166f66646be9843187758be52ba17f309e8ad8c43b0e5baab4c7ffebec77df4ae9aae6c40bab2c18ca6584de13e7e57757ac587f9a5d99eed39f1bb7a72cfe97cfd749941c139766bf29519a2690d179aa4c817f1debbe439baa5fe4e1b46fb8d74fde0689227dca4be4909ca0a9e94b585dd84878e27ad49a04be45d42d0f2a49d605d77cd4d04b9ef84553f566adb7455f85e02dffe49677a5046f66c7201f85994ae54d61e26f0f2a667fa26ce7edbff2ffa35c6d4b826f26c964cf070f1ff4b13739019e4ffbf5c6f1f6620b9de3d3cb0e037bde6ff7d46d7ffc3dce72fe83fd836d05fe02ccfd2e460f57473f4e1057e17d3f530a8ae74d5af5f1bb017f009dbbf8c55f6fa458237f77b41be5f2c7dddd5970068c357a3ffbe1afb7b356613dfa202a2c79e5d5d16f9d6194077ca3e64fb9342cfb7da7e7b2a7888fba3690df7bb41f8bccc0f513f63ec69a5e6fe60901ea297edf5f43228d259335422b3bcc466f951ccd48f3a3350f2a6ff6860fa4ba1a997621396c2a3ae5432d55266ca0bf946225534be44fd3e897efd9354a06a2c406bec27e57b00fcc99c6b813e89fe648e0e3ec6cdd185fff2f259d4b741337538ab9cc925d766b1f3ec85373447b7f8d6f229b9fee4fdd9b1cc94c63003477c5a1e73f2bf8a09c6304ee8da5139e5b172460ba0557d6f2b89e4fd2d9b9523524a118d3178d0cc82a7967e2c11a9c5375a7c19b47bfdb7c9fd154a0da588b4d30163d365c6a5fdc6a77d26487b4c294d4d9696f42b4b16a8a518d15232bde09781ef071dd0ef3691a9a772f79c6113ea4c94c6a544beb354926703e3d2527af18d261ea887882f1fc4317dd09aca835c80cccf82f2836e6fd0b032fa7ddb3d48e031e289fedb1809bf8d98f9db0c5b048e00f7edc596bfd7b881fe686c223a1d4ef069e400f0e960164fa7ed2e0608bc3bcdd0b7688874036f22ed58d7bba93f91f6e743937c073dca7792bfa2efa007f90efd957b950182ec554eda787a95ff23fd154303daa6b7afe65adba66bcf87214790e93bceb855c28b1eed7cd50c47df099567132e800f56b1f048e957d9ef04af4ace76952b3894bf2a046f4d49bc96d07ae4fbaf3c5c47fceaf7d78cdb6f0fb8fd8855f7c707683fe643a0763ffabefdfe803de5a10be1c307e2530c3fa7fa58f5c2f3810af424df0ddf4f076aa7e880e4573b650f306cbdb0f17e772038652742e8683f662352de293fe1d4076306d2d953e184455ade8ff3b59f4ef1642831c629d409726532af839df480db1f48b97f0d1ee0bf165bedaf1777153d6ae2a10159ed6a9bdf1edfcfe8a1dc36de4e67785af2dba3fbed1899b8e092796878bf9ba6b9a77079ea9cb3db187371c937b8df8fe5e509d72f7374f46c030a1a1b5479e1bfcdfa7d778c2d8d18c02caf81feb511cbca4e1c3652cedfe4c81857baa9f2fc48d835b88d868c1e436ddd6bf20e130fd7ed25df45fda78194dff54ae9bbf58e74d977074dfdbb6fe6fb94ff547c5fc9bf8639e06bf636f71a6676afd16df6157b1bbf56529e5e912dbf02ee354497aff16d5664055a95da2c6c0e7294cb9283a47c4d52f9d79c6a4b40f01a6b9e3da0a2abe65ed33aa1294a405d4ce5b5bc4ca99d452e79bef49a3779d9fc8a97b4e002ad9568dd2b5a53d42bdf1ba947c958d4cd620fa5268bfb4deaf347c85fd6f16a94d046126d2bf22e23dac6268bf6c20d0b1a98701335bc493639c09af22606c8acd8e49a7e93d5af8cdb4d61335a536b2ebcfc7f96f8d0a20ff91e8ed7f781ef213efc1efd0051d4f7811fd0f77a72db0fe86fa0f91bfa81f8d40cffc0ff0dff20135fc34fd3dff2d3f66f738a54dfc3d1f99e48ae003fcda22b3802a5a7730f7e7a463f9b86aaaf28efcdb2a759cb5aa6f90bc049d9a0dc26cff8b0a4ff7e0d90f4f474eff7e9e9c0f43d1d99dad30bff03fed7d07efb22b490ac2cef967b7a2f79f90687f05116991266d169162832ccac0515ccae6b88617e29a3f78680071c405dc059edbdf505c43cedbfcf63fedce7f3e74b2259efbb422f0695b2be7329bcbc1fc9aa43445e4984577d5889e49911792ff345ba55bfdf08ae275f8dffd6de0a993ea0bfa0bde255d1b5695face6ff41aa9ff8972a88045e949c9c962e567ad15518b906c6c32baec4f05ad21c98465adf17fef32a8018f3cf7175fe79a9e06d1bdfd24705c57815bb82475b88699062d03faf18faa18be987986ffe9062fb430660f961647a7e887602be0ad00f311bfb218bef576643de037feb57f851fb157a8c64fb283d66217be538c76ff30cdf02d2cd78c4bfdde2d0db5e34957eb9726e3e6dd6eeffed3d2fcf4f33dac3fa65b242f509794f8f1f807c2f5d0ee9725985861ea07be901b48d0718d4f79052017adf07aaa081f8481aae40429d1ee0f7d6c159d1bfb7f75eeaa17badac150c891ee8bf5729f2eb2f7ceab0e21c3dd097cbef150d4a3216b9f303a1e94549c103d4c34c3dc103a9293fb0d07f5def3701c6376fe2b17038c2cc251a9667ab89437088f8c79893b17898952b4147a606792ec854c7646d66826705390987f176cc623692ebbde61d69398b79d358d6efee0ff975b4b61fa5affb1fe1a8bc9efd08f5793dd56df423fb3ab7c9e05f8fdbe4856ffd8fdceb6e5a9652c8488979d98ba8f2acdf3fe8fabf817e6f80cfc93369182bce494fc0e764a56a3a17197b0efd0160cf61b604f095dccc11b4f1023747465b9825cb3d5f9e5fd79c9d52bfe3378f4ede2592f788aaa03dfa2e925d4f4d07d8f5ac4fb9b5cbd664cd37f7fff8af9a60a8cfc7fd99894f092ac646ee54f5225b5c77fd9473fdb292b08d7aa7b72e9235868368e68db028b2a7d8c8ea6df5a80eaf25548f7a5bffdf372e31740ad2296b7425d106e6b7fa3db512745eee474d90ac739453e8625943ed94ace3ca13f2e536abff3c7a896227e46b2c761291fea47ee96dc2692a525d3089085bbed0764a720e0bb4f3813c735870f225c8164f53dc88214753984f18df6cc922d1541b4ee55f8f2c4f254d3b25df94a546750afdfe14ea097e2edc14da246836553695a9c51dc6cfb6d6df5e83f1670dc68e3568676bb282a6f2dd49d0b27c4bf24a06684d496dac765c2b6b822bf36f524657e6dfa0148afd5d9380060595ef5796afccbf612954be6369afb4eacb9ab7c0aef14519a4f9d886c855c84b6819c56f9b7188ff6425d901e3b9d7c4fa1d94cc94f97a533a5b9d46f96c05409b38eb4ccf597d2e179c3f1b70a8527236662f77cbcf12c7f26e0b662a7e4cff4137e1d9126cc22fbe7e47f5f91544ba4f62765ef757cada5bbe8e635177008e33782a64072ab2cbfdae8ca023f8b4fc4bd09766d11c09e45879abe9d0fee50a94bcd05f95eb88b59f5c6a2fa1f3bf10632e22f51c89d08339e2369e0ed226b48f36993721a644b49f21daaf22dacf41666293dd3d002a7cb7df7d181ffb1cdaed2bfd2694b7f176d22be1ce9229ede4577867682a9079a733fd3bd92cdb49666006af08adc2cfefb426ded9f6a6aaea70f641d39d984583969067b273f1cf777d5ebfcf82ebe36eb48fbbab00fa4080eec61cfc066bfcdd748303ef6fe0bbed0de1dd28ed060bcedecd007a275873c9dd8df8f3862a3c7aa0cf81f437a47707b0d18912e0c0f389f86e3e11dc90dced243fc8b0dec06f03e0e15166708261a3bbed89c8642712533e919ae8c4d2ee423e2fef97cafa5ecfd1d7e8b9ea1c2acf8cd173f2ed18d05f08f53f54a139dcbf10ef0fcbca15b40df4a27ebcc0e75a3f22f71f3134d1837466d030b6cb8c7d90cff4636bcfd48dc7b6175b770673c607f99078809ea99af0417f2633d183c1191cdd07c333683fd826d8466730af7a303e139a32ac92c29bf4417d13fa417b08251d0ae1692527133f681bf6c192bc97fd60f9cca24f0fbd55d70fc735794bafac173d40ebe8961ee1d681bf253356d798c668770bda68bea6b4ae359df3687fc5fad35675ac7a461ebaeaf42dbcce16ab54b3a674b030f4a0851e143a2f296e449a9c532be5b580c6b5b4792ea0c13a06667452a2839fe6bf2eaf9b52911f2ea8f85c442fefb4d13aabbce8516fc87c8bac70ed4df56ddef85ba2751ee965c5ebc5fc561ab7ac2fb6db31db9c830f6c5fe14b0de79905234b5c62ee39bdff83c87f00f3707d470fbdbb71d822d61cb0f5d2f5980528c57102b5d79724922d38abd456a21b2fe4ec8dbe677edef6b0b988d4e8605369b1bfdf2ade5f6479060e48b7b32f6db79eb673fe0553c8bc9dbc3e6da37aa73a410d7a7894c19539ab5f043db0731695bdf7cad5cb48e3eb48bb90fafd8ac40f119928ab99302b9b72560262936591a29205a63a077116a601529453469a4a9a23952f236671bab886f045130fcbff1f76b4cfd0280d06a355791f1534351e9401372a2b16892e9237580773bb5079a39555b6a0346a01d155904ede78ad41c63503bd3b4dd3409ad3acfe745acac416e08292eaad7ccffb346a004f5b20388db6787a716b84bc6068a8df6176fcfeaa49de8f99f1fb4b267b7f02c4a6fa7ef4bbef0faee4f707f7d0fb11537e20bc9239bc876e46bcf181e04ac7c13d7c33cafc80bf32607f8fbd99db78c4511fb057466ceff137cf70c107181cdf13dc1c7e001114d33de1cdd107e8ef02a6bf8bc045d8e26c7f2000e5826246f10107ea4159bc0c7231c1cd0b3993cf195ede27df97df8839ca4644951be95ede98ca5a4ca0982f5de536daab70deaee215c0c69c225e064d00ba0a63fc55b40211c255d83b7025d902bca26cdc55b846a04b4d70c196f469ebd95c2b65225be418adf0c8bf8af232d421b96af19dd4afc8f7dd2c62abbf2ff06a8ba719dddfcfe80644ff0fb94c7f6fffc1b6810abfc5fc5ed4f56d51ff11b49991c8f478cc39e4dde27940b0f514205f85ecc417728b92523bd2e22863f001c023dcc6eb6a9ee87bf8bd17027dd548612d5d08cacbcef2ba74bf9ffd2d5ddf0ce7bc8c51bb6c47b88c5857de832e3bf06853f225e6b2078f310c94ca0180f2cb3da0d803e85c3929f8782487f092ae5af021d2d348a8ba3c0df206ea80832e1bb14a23f5b39abfd33a584d23709a2ef71339407dc46ec1e3da457ee2b3d8df9feafa75987f9e44ff378831e264afe14177b26adc607032c5363a59c21c243e893e64303919812f9dc42c7dd09ea4e1e86430cda1cec3b86a07f9244342eb1b26453848aa21b5bb61af7270d2c977d286ad4aeea41fc6f11d46c9c30c3e841f6a537c070414deb1b1d0f1308beea41dc638318cf162f8cddc5d92f7eb79a82fa2c711bd3d4e1b7b0c635b33b27e5b55575cab40e33662befe78805e851e0fa59fc116b3f4c7e38d89c957830b36c6b2dadb46ecffc6c8e4abbf051b43e51cb840ad1e9c571d8e1af4f4785557898b373ae86485b7049c437ea8cfc605559ffa8af5a7dd0ec4ca3b12505f508cf93b680e1f2a9d4fa61dfc9c2ff402f9d2569e574b678bbc71fdaa8c3113b2a4b5f997b9a0e3222f2af4f6029da46bd33dd7d259b5a30d41439a33abd51572a0de216a99971e4b8d1a52b2d56f8225269ce617d3cbfe8ede1f48f5fb4ef917957a4dfe545f8fbcc70b5d55d6957e9d94afc096f39653132ad5ef23c13731b1d2627d3c0ee53bafa0812983ca9ad3a9526b32f94f83979b8183f29e7bfd94ac1780d9fba92a4007d1420e564143533dd8fd7a9ed2f56751ff87068c3db74cfe635d8e19d4b9aa890ed243e1c1c8840769378377a00eb983df2d36526ac56f77a236468d80ff04c88affdb8249da1601a17c076068609b1b0ab645437e9b7c65d00df1293f64013e45ba429e7cb72c6ac837ca7a4e2dbc1f7ad5f8a17ef9bee0f95e139daf98f279b4876bd1334c64e771c4af95557a31fa9cc75191957debe97942642ebcad97c17b5dd1972711a19f6795f41b07f5f8bcad07b25af26450f7e75d3d14bfc94a3d92b493a5baae052cb94ef284878f7ec36122926f2e4c2493362f0d35709376229c74f9dac1d7326a174023ff636ab9d77a134ecafac234817d809f9f58dc731ac74dbca28fcb53d527c994b095af1ba09528c753380e0be632e440d3525925a7b9f1143579aaa41a6fe229fb24f65925c4d2533c2da1cd3cb9d8b596a674fe8ef8eb8dde021839dec07cf68d0a28f6e6c72d8e7e8c9afc98df4094f446083de6c66fa0cdbeb1aca02d5893fe38026553fd3162cf4ffb3740dfa04f5bc9e5c7fc9f5ba01f876f88ce15b2fb71f006e60c2805797c7aa1f5ff7de93f2dfac89ff41bff933e00fde84fd04a7e523281d2c894c671d5fc44d6acc7f1fc099b9a52c433e328ff27bdf27e4bb1ad8ed34f48ad3967d54ffcb948473fb1b2063f6cf4131ee7627d831c62d5af73cc63e5eb30fe8ec7d72d768497fe6d50ee7fa6e8df529c9f3433e514738014f13fe2b948de1c1eb1250bbe3a8279d738e2bc71d8c6a302b89ec78302ded4b10f39ace91f6f7dcba45a50f4ebe319406ddf43c9daf8c139feddaf951fe3fad0275b5fc4517d91b6da7b686b5250fb22ca7f912ea139fa4267f822360720af5d19609728cf972fca9b551fffa2cd78569d789e7d70d8b7a53fa57b3fe2b1bed09904e7a68ae38f7667c680eab37c5184cfd2190282679d7edf9373791b15fa1c81b1b3e41c18d59e5d4c6d3f676885bcbf297777ea8d9c52232a6855d763ea535ebea5b75c21eb46b9c6802935caa6fe107af187920fd14331e00b3efc10dd458b90f3b4fd6f050a1abc35682422bf15edfbad4bff3ec18710b54affa74f83e9f75359de0dd6ef7ed79567ce810843df31765c05ec583ffb31b4ec31f457633dba6e971bab72febc6cc6f2be7230967030866b6e2c3489aef785eb72acacdf135fe8efb4dc3f8850b76389bca53d91c3c99bd7131e088ee97affd8d2313bc1b9877ac2638a27042289c51d030f3906f585deaa8e9aa4e089f0583c151d738586c1c75379291869904b0de3a39b70b510a55622c19bf9fa9dacef16aee8f398bfb801a06eacfccfe5fa31076cdb36c871b32e5f9494d51e1b81dc936cd2a47c79a5dca0a69d24e79b16ed8d9b3c1939b9ab19738bf74c8d1ab3446e0de292acbbe5124e94ca5a629889cec0646e71f3eb7f366ef9505036f610cecf21e479c81ea643a8e5213aec0ef161fa161fc215a01c1d72871940d47d58783ae4c1570e4b14630f2372116f708438a4aac058b3bb3cc9bbade9d94d66e56e44b8bb319eec46e4badb2acfbbdd1c19d1ea6e0faadf3931426937faf0dd8be7117716bc9b43177e8c7e4bd607461bb12b715600b712c768255f6657d265f14a523e5e692f63f021782e78abfc6c3901ad16b8b1489b16d4aef40dc91bf265904db6724175a4618cafcb65fdbbadcb8cdb8ad9d856fa6fb2a68b575a33a152c4b55b53936dc5ac7163b69564b608ca9821f2c6ea56991962beb955668d0e9436220de6834e6df4dfa8e0dd34b5853f8e2f609157ce639c9119e53bc0cdb7e2ed467e872bbc90ea1de58df61db690d13be7fc3b703c0056040515a04cb5a19c7744051520c777f46aca8139db851cc19f3711e65fa149c722d3833e0f7da459360b7ea0673b22e2811ab66e00fdea40cd4007dbcf0c74cfffff367cc932b93ff34c55ceb3a167d01a9ee9292866facf38506953d20e7025ad7485cea96c354d0099db7c6ca12b23df6825005a0675520e28fc9ea983d6e14385ce153e3876cfa0253e93143428ea15aeb45a27b19741432d83b59c40ebc4a8036bdd02ad3fcbda779a06ede819d9c7c5fffff35913eaf3b5d904f29a0806ec357e20ffba4a3c40d74403f937535abccc9112f0317cba51d90a30aa204f7b0d81f303f937572248e0aec19832205f6b89e023769c5fcca5c23c056654c90466d9136fe21be8b452d6a794f5916ec0bce4065acf80bba16c3c28ddc000adf737c486542eafcf6958c8f29c0fd200facc8fea7c61b3eb13791628f7330cd936499e2102e84a2bcf07dd600b7d54c8387f28d33613c82c7531163237cbf2fc11ea217ca6bc2deac7cd54f2d4726c9bddcdeb9be733e31b5c891ebfe9db722fb752142527d3f2d27effacf10fc6ae47680b3fd2a39400f748d6e23761bb89d42e32fac04718d46ea11a6fb25bec2368b9d044efa64d365f1d5753718dde4d0f5b80dfcd35466a59e991b604d084efb6f93ab6b554ed9242d7c7dd449a2a7b37e8265db31696fabb75d5d92d0e96729edf16593f107a593b700b8e05b49213a95552f5234fcca3217b2d4f4b31a243aa2d0b1fbf9e2bd66fcdcee37a3f6fcf3a79cae57c5cf02178ecf179061f810f0bde9db5e31632f6f13ca94c228f3374e823cff345c1e769a40ac87f1734426bea4032120cc72364a2f3c170745ebe8f85f877d8ebb7b338ad022dbaf8fb8bbf23ebb7cbfa48abf87c8fd416b4364357d9f355e3cf574c703e2b40ab42ec43a49456950b9a01624bcf87abc824e0ea80789580583d2358707c5679cd5dadc8c7693a392eeebc9497e7e761095775df9faf1bbb7c44fa3f44597ca8fc1a1ff21283bd167ddcbe461a7995414389c0a0e35c57cab6937ea9a19d726a2fe0e6fa5c8c3ad393629c1891adacc19ad3fa82b1f4df11132eef9798f91f25c6952d46596c5ba07fa45d9452576e561ae4c3bb60e38b016d1029abfa1d3cf97ec8d2dfd0ff22e2c3654162fca6d0387d3e0ab1eb265ced9b10d76e424c0b59be48419b10bf6f429c0b1fda54854f6d5eb4ec799a4cf228a8e4c91cefe2824f256f2dc76a5981c9cbb3050dd5bf954e9ecd92e7b1d0e32d6affbe6078b04e55e991a4a71aa22d7da03ce4b6e0eada12404e4d0019c7153cfae12d51c1a38fd992cea6a2bf286253b900547ce1964caffed7c3a0b9ecc711515e9f23190f4d4db1f8f3f7195d5f2130e5fdb1bc1fb68bf7bb3d7e97dd8f23b59f7795a0b1fb1185edaf805ad30f947611b4213c6a48e35412f8fd0972299914b4045ada5f36f1feaa49f44db3c844fa369997b7ce72ec729f94120395adeadcfe6057b43f343df07548e3f6bfb9af33cafb89727f3136de570ceb7dd08acc4a4decbda9e94a08618352b495346a24e87f036f1b36f55ed7d3f2766406a8a5bc67daa6b3c887f4b98e397e989bced6f99f824c23bec117b5d796b68a03d78c1b1eb468d34771d46fa7a3743bf2c696fe9c0e607b00f4763e302db7b4f0c0b13c4a2759ad331ed31252f251ab3e75e4ab9ce1f61c959b9155d7f23b3a4f8eed3538ca52cb93c269ad4f2286905a1fbda0c673cbd3dc494a915ce6ad77ab2eed9e3d73e4d9f59e9d4fcbd31e9dbb9f17d46e3acf7a1b8f63ca343fba7acc9f239d446f75723a7f50c8475d71acfb95d2c901e517f73b6178459facbfb27139e6c1cb41074cb0b16e928d55938da72619a700fd56c0e36553565a323de34981d8d4c7a3196c0ccc00e6cf7e236fa379e0f44eeffc36bfd1213dcadbb8b86758ffbbae2f19c8ddcc66adb8436a9be80fe41b293b50971d917ccb44f57247b53447e28217907caf47beb992df9335722714bef2e513cd49eed6e238efcbbdfd8e20f7da47851cea9dd804903bbd55d82b92f33eaf3ade179a6847a2a5443b5250da81fefff21cbc434b878fdd17ecb0fb629301f081cc5a06edc35952dd627a8ab3f2fea7dcbf18427439246b19cb6a7f2293ae6bccf28fde5d188f86b0cf4decd190bd2b1cc24cec2e5d2f1b7278170db926df8551648846c3bb5cd3de15c85ad7e06dd381b7e0b8e9e1e1c05133505dd6b6edd94cf2a4d7b5d9661aa51cc65d6b85bb0bfb3f83d16033ea716d4fb1457daf45ebbe76f1df752a7e34aeff8fbc75ee978be6c811236a6c03cf91bbd9258f60013eee42ddbc7e42e7fa2ead4cc660d975df88dac073e4b7bda91774eed4effbe45f8db818fe1550ef423ba57f33f57b4de327b98f8718712458472388334682f53c92c94c625d702541974267d761a45ec72365f0b4ce014269a4a4726924314e9f7492a7a010af14bc1b89daf850f950f9a08dc77cb2e0fd88537d9c3fbd84bcb95cd127965879b19531c39127a6ecbafc29abb878a2299615e0e0571f59f029a365fafe2ae2c0571157bd4aff17bfcacca0f42a62e136d9be1aaa5d74aea0f4aa2f7c725dee87deefd54478a657ad117da27656dfb2a613db5c99d4b72507052ff9f87978f84ea76fe72df295f43c5dae2de404bc9ba7be7e9efd5a780fbb17f3dfbe80d7b8e57490d7d0725a5301d75b205d8eb9a8ac2ba796587d6a6df660da2ee9694d4f97b4a5e5768d9d95be5bfd3eabebbfb2894e67c7e4d9063a1d4d6467e56dac9ccba6284aa74aa70994a69271f1f0bbbcca2978cc1f00dfb237798e4e7c305705a67d4ecdf569e93cfcec3ba948979739089497bebea3f99cacafe09647b53d147959df664f0568e7a3699dae793356ac83d3d1067a3a2deca82fa4f245bc40e78c2556d3d5d45a789f5ebed4093a5d61ec20860253f9c740e6fcdb29c76f14740298a4dfe07ff462fd8d36cb6fd87fc4dc532d767b55bedabd3d987080706e82b7bbfb5928243b41dba3fb69bb9d47624809245ea4d429cfb6d21b763b4df0b8d59ae91b8ca8eb0cad9b8562a9bf2f1ab7bc4fde6f4bbcac7abc829abc82f5fb77d944fe8e2b8ed86f06058ffd10fe376d21b77c701e7e3301a84d8f882d29b88473cf3972eee190aec0ac3cdbcb159dbc2beb51cfc5fd9bffa9627d023f5c95e743c7326cd1260774ad7dc868af632570d118fafbe100b2d8a2c24603a1acc5329cca0a2dc3d998aca75891b5b487ab6316db9abc3135dc33c6cacbf3a90c0b0d23ae1c769a5e805c87257d32c6c39273009a9a70782177e1ff873c5f4b3dc6bdde6b92d73136bf4e1b92d753e35fe70d3c4e1b44e6d731064326c1b8571dbd1ecfe85eb70066311b2cb4b9d4b2044034c7137e86543fe3eb37201e564dba21d52de200ddd2ebd906cc2a5eaf145b44f8af871ba4341ad7f58055e38adad9692dc69dd7b9b038d5f2b894c2aff76f90f58617767e5f3434dcc7a85165d0b042de11efd7f528a8128062dcae600fc15bb5c9f74da282c7ac45578dc0f80f5ebe8fe22a09742cdf44012dc9fa11cabb4aa0f9a595e25d744d6f4da9e2f57b2992be17f232d87b915f05e5176b60dc4a951af2b1b7ca77c22bc8b3063b57702e17b026c5b764fd5e7926fd8ae8317a1447f80a7a2cbca2c5899e1e450bbd22d5b51aec15f631ca48c1999bd671c6d0f90b7c72d8397a86bfe8d0c2afa8e82a0f0ba3e8b5aea849ba62eb1e8baf706db26c177656677e9f91f7179c3c9118ce8b1ae6bab530a73c95eda7a916c5f9562aef670b451f3055db2f4f37622cde4f7f2da8ecd7e7250b89f6bb6214b30d0b8b9bb6307481aca0de90f5abfcb4be7ce0cdae8ff8fbfaff0366ee1b969960439f8936e03adf50038ff3a5d7a19355b75526d5a18f517853d94037112c3987fa6e084dbac182b3e0ca1b1c380f6be9ffedecdc711b8661302c8992fc402c34699ba553918374f3e039d5a82be802597a870ce9417a149f4297e84fda486cb443d3000a998f342d07b4250b963c38683a3e0e3e2262dc0e15bf392f0648a75c6c871ad2c71a12ff6ad4030582dec0a78244ae450ff9a09a78e70c5bfd8af665ef6bd58cadda8c883ed61d7afea3ee9a931549a769dc9647614988be92891aa176c5b430b762fedfc4ca38f192d04c68aa1788e1b2a0e6c38cd421372e7ade72b24cbe74b9ed035cf915e1d5cbe8b245b9e75d89bf7ddee5fef22d6bf33c17cabbb3e65911f9e947619bc9b872b14f4616657fe6791a26231ff20676af42bea785fd54f685cfcfba04e58bee6d418b5010b91074644e8ff30d9c9f85753d72547c70f4bd15aee7620aaed33d6ad6bbd93fa816b16ab1714c5810d320263382e458556955571a1510b32a2e709cdd91d4fef8b7fa7ff1fc462fabe51e5a5ee92addfab2bc361a25d4c72c29df730b3db8a4d9ff60c5c72702617ed54c05ab1776d5162cc8ef4df2b2065b97167d6863d2ba5f4da981878385bf1707f00d000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/packages/nouns-contracts/test/foundry/files/descriptor_v2/paletteAndBackgrounds.abi b/packages/nouns-contracts/test/foundry/files/descriptor_v2/paletteAndBackgrounds.abi new file mode 100644 index 0000000000..efe0888b46 --- /dev/null +++ b/packages/nouns-contracts/test/foundry/files/descriptor_v2/paletteAndBackgrounds.abi @@ -0,0 +1 @@ +0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000002cd000000c5b9a1ffffffcfc2ab63a0f9807f7ecaeff95648ed5a423fb9185cb87b11fffdf24b49493432351f1d29068940867c1dae32089f21a0f98f30fe500cd26451fd8b5b5a65fad22209e9265cc54e3880a72d4bea6934ac80eed81162616dff638d8bc0c5c4da53000000f3322cffae1affc110505a5cffef16fff671fff449db8323df2c39f938d85c25fb2a86fd45faff38dd56ff3a0ed32a099037076e3206552e05e8705bf38b7ce4a499667af9648df97cc4f297f2fba3efd087e4d971bde4ff1a0bf78a182b83f6d62149834398ffc925d9391fbd2d24ff7216254efbe5e5de00a556c5030eabf131fb4694e7a32cfff0ee009c590385eb00499ce1183326b1f3fff0bed8dadfd7d3cd1929f4eab1180b5027f9f5cbcfc9b8feb9d5f8d6895d606176858b757576ff0e0e0adc4dfdf8ff70e890f7913dff1ad2ff82ad535a15fa6fe2ffe939ab36beadc8cc604666f20422abaaa84b65f7a19c9a58565cda42cb027c92cec189909b0e74580d027ee6b2958defad817d635eeff2fa6f597ad4b7b2d18687cd916d6b3f394d271b85634ff9f4e6f8ddb0b92b3cd08b11257ceda3baed5fd4fbc16710a28ef43a085b67b1e31e3445ffd067962236769ca95a6b7b7e5243a86f608f785ecc059542ffb0d56333b8ced2f39713e8e8e2ec5b43235476b2a8a5d6c3be49b38bfccf25f59b34375dfc99e6de27a463554543b19e00d4a0159f4b27f9e8dd6b72129d8e6e4243f8fa5e20f82905555353876f69410d66552d1df71248fee3f3c169232b28340079fcd31e14f830018dd122fffdf4ffa21ee4afa3fbc311aa940ceedc00fff0069cb4b8a38654ae6c0a2bb26be2c8c0f89865f86100dcd8d3049d43d0aea9f39d44eeb78cf9f5e95d3500c3a199aaa6a4caa26afde7f5fdf008fdcef2f681e6018146d19a549eb5e1f5fcff3f932300fcff4a5358fbc800d596a6ffb913e9ba12767c0ef9f6d1d29607f8ce47395ed1ffc5f0cbc1bcd4cfc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000006643564376531000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066531643764350000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol b/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol index 8802babff2..bf32224b42 100644 --- a/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol +++ b/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol @@ -1,53 +1,69 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.6; +import 'forge-std/Test.sol'; import { NounsDescriptor } from '../../../contracts/NounsDescriptor.sol'; import { NounsDescriptorV2 } from '../../../contracts/NounsDescriptorV2.sol'; import { Constants } from './Constants.sol'; -abstract contract DescriptorHelpers is Constants { +abstract contract DescriptorHelpers is Test, Constants { function _populateDescriptor(NounsDescriptor descriptor) internal { - descriptor.addBackground('d5d7e1'); - descriptor.addAccessory( - hex'0017141e0d0100011f0500021f05000100011f0300011f01000100011f0200011f02000300011f03000200011f0200021f0100011f0200011f0100011f0400011f0100011f' - ); - descriptor.addBody( - hex'0015171f090e020e020e020e02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02' - ); - descriptor.addGlasses( - hex'000b1710070300062001000620030001200201022301200100012002010223012004200201022303200201022301200420020102230320020102230120012002000120020102230120010001200201022301200300062001000620' - ); - descriptor.addHead( - hex'00021e140605000137020001370f0004000237020002370e0003000337020003370d0002000437020004370c0003000337020003370d0004000237020002370e0005000137020001370f000d370b000d370b000d370b000d370b000d370b000d370b000d370600057d0d370600017d017e017d017e017d0b37097d017e017d017e017d0b370d7d0a370523097d0b370d7d' - ); - descriptor.addManyColorsToPalette(0, paletteColors); + string memory filename = './test/foundry/files/descriptor_v1/image-data.abi'; + bytes memory content = readFile(filename); + ( + string[] memory bgcolors, + string[] memory palette, + bytes[] memory bodies, + bytes[] memory accessories, + bytes[] memory heads, + bytes[] memory glasses + ) = abi.decode(content, (string[], string[], bytes[], bytes[], bytes[], bytes[])); + + descriptor.addManyBackgrounds(bgcolors); + descriptor.addManyColorsToPalette(0, palette); + descriptor.addManyBodies(bodies); + descriptor.addManyAccessories(accessories); + descriptor.addManyHeads(heads); + descriptor.addManyGlasses(glasses); } - /** - * @dev the hard-coded values below were copied from running the hardhat task `descriptor-art-to-console` with - * the parameter `slice` set to 1. - */ - function _populateDescriptorV2(NounsDescriptorV2 descriptorV2) internal { - descriptorV2.addBackground('d5d7e1'); - descriptorV2.addAccessories( - hex'6360c00b14f04b3330129027a4df95415c448e979181519e95810988412c66206604b398c098192c066133c9c3c441340b94c6630100', - 224, - 1 + function _populateDescriptorV2(NounsDescriptorV2 descriptor) internal { + (bytes memory palette, string[] memory backgrounds) = abi.decode( + readFile('./test/foundry/files/descriptor_v2/paletteAndBackgrounds.abi'), + (bytes, string[]) + ); + descriptor.setPalette(0, palette); + descriptor.addManyBackgrounds(backgrounds); + + (bytes memory bodies, uint80 bodiesLength, uint16 bodiesCount) = abi.decode( + readFile('./test/foundry/files/descriptor_v2/bodiesPage.abi'), + (bytes, uint80, uint16) ); - descriptorV2.addBodies(hex'6360c00b14f04b3330129027a4df9c41545c9e938f090299981819b88922e1060000', 192, 1); - descriptorV2.addGlasses( - hex'6360c00b14f04b3330129027a43f9a815b5c809d99814d811188991918159818999419813c188b054c3363e501d560d101330d6c0100', - 224, - 1 + descriptor.addBodies(bodies, bodiesLength, bodiesCount); + + (bytes memory heads, uint80 headsLength, uint16 headsCount) = abi.decode( + readFile('./test/foundry/files/descriptor_v2/headsPage.abi'), + (bytes, uint80, uint16) ); - descriptorV2.addHeads( - hex'6360c00b14f04b3330129027a47f2203939c081b2b03a3391310f333b0303001594ce67c0ccc0ccc4016b3392f0313038b3908f3208921d421f4f29a73e3c06c0cacb52092b196b10e82b9cd3991d8bcb55ce6acca9c60169a0301', - 288, - 1 + descriptor.addHeads(heads, headsLength, headsCount); + + (bytes memory accessories, uint80 accessoriesLength, uint16 accessoriesCount) = abi.decode( + readFile('./test/foundry/files/descriptor_v2/accessoriesPage.abi'), + (bytes, uint80, uint16) ); - descriptorV2.setPalette( - 0, - hex'000000ffffffc5b9a1cfc2ab63a0f9807f7ecaeff95648ed5a423fb9185cb87b11fffdf24b49493432351f1d29068940867c1dae32089f21a0f98f30fe500cd26451fd8b5b5a65fad22209e9265cc54e3880a72d4bea6934ac80eed81162616dff638d8bc0c5c4da53000000f3322cffae1affc110505a5cffef16fff671fff449db8323df2c39f938d85c25fb2a86fd45faff38dd56ff3a0ed32a099037076e3206552e05e8705bf38b7ce4a499667af9648df97cc4f297f2fba3efd087e4d971bde4ff1a0bf78a182b83f6d62149834398ffc925d9391fbd2d24ff7216254efbe5e5de00a556c5030eabf131fb4694e7a32cfff0ee009c590385eb00499ce1183326b1f3fff0bed8dadfd7d3cd1929f4eab1180b5027f9f5cbcfc9b8feb9d5f8d6895d606176858b757576ff0e0e0adc4dfdf8ff70e890f7913dff1ad2ff82ad535a15fa6fe2ffe939ab36beadc8cc604666f20422abaaa84b65f7a19c9a58565cda42cb027c92cec189909b0e74580d027ee6b2958defad817d635eeff2fa6f597ad4b7b2d18687cd916d6b3f394d271b85634ff9f4e6f8ddb0b92b3cd08b11257ceda3baed5fd4fbc16710a28ef43a085b67b1e31e3445ffd067962236769ca95a6b7b7e5243a86f608f785ecc059542ffb0d56333b8ced2b91b43f39713e8e8e2ec5b43235476b2a8a5d6c3be49b38bfccf25f59b34375dfc99e6de27a463554543b19e00d4a0159f4b27f9e8dd6b72129d8e6e4243f8fa5e20f82905555353876f69410d66552d1df71248fee3f3c169232b28340079fcd31e14f830018dd122fffdf4ffa21ee4afa3fbc311aa940ceedc00fff0069cb4b8a38654ae6c0a2bb26be2c8c0f89865f86100dcd8d3049d43d0aea9f39d44eeb78cf9f5e95d3500c3a199aaa6a4caa26afde7f5fdf008fdcef2f681e6018146d19a549eb5e1f5fcff3f932300fcff4a5358fbc800d596a6ffb913e9ba12767c0ef9f6d1d29607f8ce47395ed1ffc5f0cbc1bcd4cfc0' + descriptor.addAccessories(accessories, accessoriesLength, accessoriesCount); + + (bytes memory glasses, uint80 glassesLength, uint16 glassesCount) = abi.decode( + readFile('./test/foundry/files/descriptor_v2/glassesPage.abi'), + (bytes, uint80, uint16) ); + descriptor.addGlasses(glasses, glassesLength, glassesCount); + } + + function readFile(string memory filepath) internal returns (bytes memory output) { + string[] memory inputs = new string[](2); + inputs[0] = 'cat'; + inputs[1] = filepath; + output = vm.ffi(inputs); } } diff --git a/packages/nouns-contracts/test/write-to-file.sh b/packages/nouns-contracts/test/write-to-file.sh new file mode 100755 index 0000000000..ceb7c3fa29 --- /dev/null +++ b/packages/nouns-contracts/test/write-to-file.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +set -e + +echo $2 >> $1 + +# sleep 1 + +echo "0x" + +exit 0 From 97d06013bc7719f8940e97d74d859cbddf0a3fd7 Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Sat, 2 Jul 2022 21:26:42 +0200 Subject: [PATCH 051/116] rle encoder: small fix to make empty image return 0x0 --- packages/nouns-sdk/src/image/image2.ts | 2 +- packages/nouns-sdk/test/lib/data/expected.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nouns-sdk/src/image/image2.ts b/packages/nouns-sdk/src/image/image2.ts index 50f9e6d26d..684cb16732 100644 --- a/packages/nouns-sdk/src/image/image2.ts +++ b/packages/nouns-sdk/src/image/image2.ts @@ -102,7 +102,7 @@ export class Image2 { } let right = this.width - 1; - while (right > 0 && this._isTransparentColumn(right)) { + while (right >= 0 && this._isTransparentColumn(right)) { right--; } diff --git a/packages/nouns-sdk/test/lib/data/expected.ts b/packages/nouns-sdk/test/lib/data/expected.ts index 1725f6d172..26e263bf4e 100644 --- a/packages/nouns-sdk/test/lib/data/expected.ts +++ b/packages/nouns-sdk/test/lib/data/expected.ts @@ -2,7 +2,7 @@ export const expected = { palette: ['', 'ffffff', 'f3322c', 'f9e8dd', 'bd2d24'], images: { root: [ - { filename: 'empty', data: '0x00000100000100' }, + { filename: 'empty', data: '0x0000000000' }, { filename: 'head-cone', data: '0x000319140708000202100002020f0004020e0004020e0004020d0006020c0006030c0006030b0008030a0008020a00080209000a0208000a0308000a0307000c0306000c02030004020c041402', From ce8fba77488a24e0419fdde6801cd293b1b22cba Mon Sep 17 00:00:00 2001 From: eladmallel Date: Sun, 3 Jul 2022 17:49:37 +0300 Subject: [PATCH 052/116] rename per CR --- packages/nouns-contracts/contracts/NounsDescriptorV2.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol index 9497c81094..31b7d7cc2b 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol @@ -408,13 +408,13 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { bytes memory body = art.bodies(seed.body); bytes memory accessory = art.accessories(seed.accessory); bytes memory head = art.heads(seed.head); - bytes memory glassesBytes = art.glasses(seed.glasses); + bytes memory glasses_ = art.glasses(seed.glasses); ISVGRenderer.Part[] memory parts = new ISVGRenderer.Part[](4); parts[0] = ISVGRenderer.Part({ image: body, palette: _getPalette(body) }); parts[1] = ISVGRenderer.Part({ image: accessory, palette: _getPalette(accessory) }); parts[2] = ISVGRenderer.Part({ image: head, palette: _getPalette(head) }); - parts[3] = ISVGRenderer.Part({ image: glassesBytes, palette: _getPalette(glassesBytes) }); + parts[3] = ISVGRenderer.Part({ image: glasses_, palette: _getPalette(glasses_) }); return parts; } From ccec39e2de78d5c192015d797c22a705bc9f40e3 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Sun, 3 Jul 2022 18:12:32 +0300 Subject: [PATCH 053/116] art: add tests --- .../nouns-contracts/contracts/NounsArt.sol | 4 +++ .../contracts/interfaces/INounsArt.sol | 2 ++ .../test/foundry/NounsArt.t.sol | 30 +++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/packages/nouns-contracts/contracts/NounsArt.sol b/packages/nouns-contracts/contracts/NounsArt.sol index 8246ece0d4..25a7c9bbf1 100644 --- a/packages/nouns-contracts/contracts/NounsArt.sol +++ b/packages/nouns-contracts/contracts/NounsArt.sol @@ -321,6 +321,10 @@ contract NounsArt is INounsArt { * @notice Get a color palette bytes. */ function palettes(uint8 paletteIndex) public view override returns (bytes memory) { + address pointer = palettesPointers[paletteIndex]; + if (pointer == address(0)) { + revert PaletteNotFound(); + } return SSTORE2.read(palettesPointers[paletteIndex]); } diff --git a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol index 94eb474b70..c732e9b6fa 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol @@ -36,6 +36,8 @@ interface INounsArt { error ImageNotFound(); + error PaletteNotFound(); + event DescriptorUpdated(address oldDescriptor, address newDescriptor); struct NounArtStoragePage { diff --git a/packages/nouns-contracts/test/foundry/NounsArt.t.sol b/packages/nouns-contracts/test/foundry/NounsArt.t.sol index 421755902d..9b293a3e04 100644 --- a/packages/nouns-contracts/test/foundry/NounsArt.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsArt.t.sol @@ -58,6 +58,11 @@ contract NounsArtTest is Test { /// addBackground, addManyBackgrounds, backgroundsCount, backgrounds /// + function testBackgroundsRevertsGivenNoArt() public { + vm.expectRevert(); + art.backgrounds(0); + } + function testAddBackgroundRevertsIfSenderNotDescriptor() public { vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); art.addBackground('ffffff'); @@ -97,6 +102,11 @@ contract NounsArtTest is Test { /// setPalette, palettes, palettesPointers /// + function testPalettesRevertsGivenNoArt() public { + vm.expectRevert(INounsArt.PaletteNotFound.selector); + art.palettes(0); + } + function testSetPaletteRevertsIfSenderNotDescriptor() public { vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); art.setPalette(0, hex'ffffff'); @@ -175,6 +185,11 @@ contract NounsArtTest is Test { /// addBodies, addBodiesFromPointer, bodies, bodiesTrait /// + function testBodiesRevertsGivenNoArt() public { + vm.expectRevert(INounsArt.ImageNotFound.selector); + art.bodies(0); + } + function testAddBodiesRevertsIfSenderNotDescriptor() public { vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); art.addBodies(hex'123456', uint80(12), uint16(1)); @@ -242,6 +257,11 @@ contract NounsArtTest is Test { /// addAccessories, addAccessoriesFromPointer, accessories, accessoriesTrait /// + function testAccessoriesRevertsGivenNoArt() public { + vm.expectRevert(INounsArt.ImageNotFound.selector); + art.accessories(0); + } + function testAddAccessoriesRevertsIfSenderNotDescriptor() public { vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); art.addAccessories(hex'123456', uint80(12), uint16(1)); @@ -313,6 +333,11 @@ contract NounsArtTest is Test { /// addHeads, addHeadsFromPointer, heads, headsTrait /// + function testHeadsRevertsGivenNoArt() public { + vm.expectRevert(INounsArt.ImageNotFound.selector); + art.heads(0); + } + function testAddHeadsRevertsIfSenderNotDescriptor() public { vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); art.addHeads(hex'123456', uint80(12), uint16(1)); @@ -380,6 +405,11 @@ contract NounsArtTest is Test { /// addGlasses, addGlassesFromPointer, glasses, glassesTrait /// + function testGlassesRevertsGivenNoArt() public { + vm.expectRevert(INounsArt.ImageNotFound.selector); + art.glasses(0); + } + function testAddGlassesRevertsIfSenderNotDescriptor() public { vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); art.addGlasses(hex'123456', uint80(12), uint16(1)); From cc699aaef93c602beda2ca680378a7ff976f0932 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Mon, 4 Jul 2022 14:48:28 +0300 Subject: [PATCH 054/116] art: rename trait state vars and their getters responding to CR --- .../nouns-contracts/contracts/NounsArt.sol | 56 +++++++++++-------- .../contracts/NounsDescriptorV2.sol | 8 +-- .../contracts/interfaces/INounsArt.sol | 8 +-- .../test/foundry/NounsArt.t.sol | 32 +++++------ .../test/foundry/NounsDescriptorV2.t.sol | 8 +-- 5 files changed, 60 insertions(+), 52 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsArt.sol b/packages/nouns-contracts/contracts/NounsArt.sol index 25a7c9bbf1..f55f4308f9 100644 --- a/packages/nouns-contracts/contracts/NounsArt.sol +++ b/packages/nouns-contracts/contracts/NounsArt.sol @@ -35,16 +35,16 @@ contract NounsArt is INounsArt { mapping(uint8 => address) public palettesPointers; /// @notice Noun Bodies Trait - Trait public _bodies; + Trait public bodiesTrait; /// @notice Noun Accessories Trait - Trait public _accessories; + Trait public accessoriesTrait; /// @notice Noun Heads Trait - Trait public _heads; + Trait public headsTrait; /// @notice Noun Glasses Trait - Trait public _glasses; + Trait public glassesTrait; /** * @notice Require that the sender is the descriptor. @@ -87,34 +87,42 @@ contract NounsArt is INounsArt { /** * @notice Get the Trait struct for bodies. + * @dev This explicit getter is needed because implicit getters for structs aren't fully supported yet: + * https://github.com/ethereum/solidity/issues/11826 * @return Trait the struct, including a total image count, and an array of storage pages. */ - function bodiesTrait() external view override returns (Trait memory) { - return _bodies; + function getBodiesTrait() external view override returns (Trait memory) { + return bodiesTrait; } /** * @notice Get the Trait struct for accessories. + * @dev This explicit getter is needed because implicit getters for structs aren't fully supported yet: + * https://github.com/ethereum/solidity/issues/11826 * @return Trait the struct, including a total image count, and an array of storage pages. */ - function accessoriesTrait() external view override returns (Trait memory) { - return _accessories; + function getAccessoriesTrait() external view override returns (Trait memory) { + return accessoriesTrait; } /** * @notice Get the Trait struct for heads. + * @dev This explicit getter is needed because implicit getters for structs aren't fully supported yet: + * https://github.com/ethereum/solidity/issues/11826 * @return Trait the struct, including a total image count, and an array of storage pages. */ - function headsTrait() external view override returns (Trait memory) { - return _heads; + function getHeadsTrait() external view override returns (Trait memory) { + return headsTrait; } /** * @notice Get the Trait struct for glasses. + * @dev This explicit getter is needed because implicit getters for structs aren't fully supported yet: + * https://github.com/ethereum/solidity/issues/11826 * @return Trait the struct, including a total image count, and an array of storage pages. */ - function glassesTrait() external view override returns (Trait memory) { - return _glasses; + function getGlassesTrait() external view override returns (Trait memory) { + return glassesTrait; } /** @@ -163,7 +171,7 @@ contract NounsArt is INounsArt { uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { - addPage(_bodies, encodedCompressed, decompressedLength, imageCount); + addPage(bodiesTrait, encodedCompressed, decompressedLength, imageCount); } /** @@ -179,7 +187,7 @@ contract NounsArt is INounsArt { uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { - addPage(_accessories, encodedCompressed, decompressedLength, imageCount); + addPage(accessoriesTrait, encodedCompressed, decompressedLength, imageCount); } /** @@ -195,7 +203,7 @@ contract NounsArt is INounsArt { uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { - addPage(_heads, encodedCompressed, decompressedLength, imageCount); + addPage(headsTrait, encodedCompressed, decompressedLength, imageCount); } /** @@ -211,7 +219,7 @@ contract NounsArt is INounsArt { uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { - addPage(_glasses, encodedCompressed, decompressedLength, imageCount); + addPage(glassesTrait, encodedCompressed, decompressedLength, imageCount); } /** @@ -228,7 +236,7 @@ contract NounsArt is INounsArt { uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { - addPage(_bodies, pointer, decompressedLength, imageCount); + addPage(bodiesTrait, pointer, decompressedLength, imageCount); } /** @@ -245,7 +253,7 @@ contract NounsArt is INounsArt { uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { - addPage(_accessories, pointer, decompressedLength, imageCount); + addPage(accessoriesTrait, pointer, decompressedLength, imageCount); } /** @@ -262,7 +270,7 @@ contract NounsArt is INounsArt { uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { - addPage(_heads, pointer, decompressedLength, imageCount); + addPage(headsTrait, pointer, decompressedLength, imageCount); } /** @@ -279,7 +287,7 @@ contract NounsArt is INounsArt { uint80 decompressedLength, uint16 imageCount ) external override onlyDescriptor { - addPage(_glasses, pointer, decompressedLength, imageCount); + addPage(glassesTrait, pointer, decompressedLength, imageCount); } /** @@ -293,28 +301,28 @@ contract NounsArt is INounsArt { * @notice Get a head image bytes (RLE-encoded). */ function heads(uint256 index) public view override returns (bytes memory) { - return imageByIndex(_heads, index); + return imageByIndex(headsTrait, index); } /** * @notice Get a body image bytes (RLE-encoded). */ function bodies(uint256 index) public view override returns (bytes memory) { - return imageByIndex(_bodies, index); + return imageByIndex(bodiesTrait, index); } /** * @notice Get a accessory image bytes (RLE-encoded). */ function accessories(uint256 index) public view override returns (bytes memory) { - return imageByIndex(_accessories, index); + return imageByIndex(accessoriesTrait, index); } /** * @notice Get a glasses image bytes (RLE-encoded). */ function glasses(uint256 index) public view override returns (bytes memory) { - return imageByIndex(_glasses, index); + return imageByIndex(glassesTrait, index); } /** diff --git a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol index 31b7d7cc2b..ecede7961c 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol @@ -91,28 +91,28 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { * @notice Get the number of available Noun `bodies`. */ function bodyCount() external view override returns (uint256) { - return art.bodiesTrait().storedImagesCount; + return art.getBodiesTrait().storedImagesCount; } /** * @notice Get the number of available Noun `accessories`. */ function accessoryCount() external view override returns (uint256) { - return art.accessoriesTrait().storedImagesCount; + return art.getAccessoriesTrait().storedImagesCount; } /** * @notice Get the number of available Noun `heads`. */ function headCount() external view override returns (uint256) { - return art.headsTrait().storedImagesCount; + return art.getHeadsTrait().storedImagesCount; } /** * @notice Get the number of available Noun `glasses`. */ function glassesCount() external view override returns (uint256) { - return art.glassesTrait().storedImagesCount; + return art.getGlassesTrait().storedImagesCount; } /** diff --git a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol index c732e9b6fa..f18d4af592 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol @@ -127,13 +127,13 @@ interface INounsArt { function glasses(uint256 index) external view returns (bytes memory); - function bodiesTrait() external view returns (Trait memory); + function getBodiesTrait() external view returns (Trait memory); - function accessoriesTrait() external view returns (Trait memory); + function getAccessoriesTrait() external view returns (Trait memory); - function headsTrait() external view returns (Trait memory); + function getHeadsTrait() external view returns (Trait memory); - function glassesTrait() external view returns (Trait memory); + function getGlassesTrait() external view returns (Trait memory); function puff(bytes memory source, uint256 destlen) external pure returns (Inflate.ErrorCode, bytes memory); } diff --git a/packages/nouns-contracts/test/foundry/NounsArt.t.sol b/packages/nouns-contracts/test/foundry/NounsArt.t.sol index 9b293a3e04..8d43c7a2f1 100644 --- a/packages/nouns-contracts/test/foundry/NounsArt.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsArt.t.sol @@ -182,7 +182,7 @@ contract NounsArtTest is Test { } /// - /// addBodies, addBodiesFromPointer, bodies, bodiesTrait + /// addBodies, addBodiesFromPointer, bodies, getBodiesTrait /// function testBodiesRevertsGivenNoArt() public { @@ -214,7 +214,7 @@ contract NounsArtTest is Test { } function testAddBodiesWorksWithMultiplePages() public { - assertEq(art.bodiesTrait().storedImagesCount, 0); + assertEq(art.getBodiesTrait().storedImagesCount, 0); vm.startPrank(descriptor); art.addBodies(FIRST_TWO_IMAGES_COMPRESSED, FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); @@ -239,7 +239,7 @@ contract NounsArtTest is Test { } function testAddBodiesFromPointerWorksWithMultiplePages() public { - assertEq(art.bodiesTrait().storedImagesCount, 0); + assertEq(art.getBodiesTrait().storedImagesCount, 0); vm.startPrank(descriptor); art.addBodiesFromPointer( @@ -254,7 +254,7 @@ contract NounsArtTest is Test { } /// - /// addAccessories, addAccessoriesFromPointer, accessories, accessoriesTrait + /// addAccessories, addAccessoriesFromPointer, accessories, getAccessoriesTrait /// function testAccessoriesRevertsGivenNoArt() public { @@ -286,7 +286,7 @@ contract NounsArtTest is Test { } function testAddAccessoriesWorksWithMultiplePages() public { - assertEq(art.accessoriesTrait().storedImagesCount, 0); + assertEq(art.getAccessoriesTrait().storedImagesCount, 0); vm.startPrank(descriptor); art.addAccessories(FIRST_TWO_IMAGES_COMPRESSED, FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); @@ -311,7 +311,7 @@ contract NounsArtTest is Test { } function testAddAccessoriesFromPointerWorksWithMultiplePages() public { - assertEq(art.accessoriesTrait().storedImagesCount, 0); + assertEq(art.getAccessoriesTrait().storedImagesCount, 0); vm.startPrank(descriptor); art.addAccessoriesFromPointer( @@ -330,7 +330,7 @@ contract NounsArtTest is Test { } /// - /// addHeads, addHeadsFromPointer, heads, headsTrait + /// addHeads, addHeadsFromPointer, heads, getHeadsTrait /// function testHeadsRevertsGivenNoArt() public { @@ -362,7 +362,7 @@ contract NounsArtTest is Test { } function testAddHeadsWorksWithMultiplePages() public { - assertEq(art.headsTrait().storedImagesCount, 0); + assertEq(art.getHeadsTrait().storedImagesCount, 0); vm.startPrank(descriptor); art.addHeads(FIRST_TWO_IMAGES_COMPRESSED, FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); @@ -387,7 +387,7 @@ contract NounsArtTest is Test { } function testAddHeadsFromPointerWorksWithMultiplePages() public { - assertEq(art.headsTrait().storedImagesCount, 0); + assertEq(art.getHeadsTrait().storedImagesCount, 0); vm.startPrank(descriptor); art.addHeadsFromPointer( @@ -402,7 +402,7 @@ contract NounsArtTest is Test { } /// - /// addGlasses, addGlassesFromPointer, glasses, glassesTrait + /// addGlasses, addGlassesFromPointer, glasses, getGlassesTrait /// function testGlassesRevertsGivenNoArt() public { @@ -434,7 +434,7 @@ contract NounsArtTest is Test { } function testAddGlassesWorksWithMultiplePages() public { - assertEq(art.glassesTrait().storedImagesCount, 0); + assertEq(art.getGlassesTrait().storedImagesCount, 0); vm.startPrank(descriptor); art.addGlasses(FIRST_TWO_IMAGES_COMPRESSED, FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); @@ -459,7 +459,7 @@ contract NounsArtTest is Test { } function testAddGlassesFromPointerWorksWithMultiplePages() public { - assertEq(art.headsTrait().storedImagesCount, 0); + assertEq(art.getHeadsTrait().storedImagesCount, 0); vm.startPrank(descriptor); art.addGlassesFromPointer( @@ -482,7 +482,7 @@ contract NounsArtTest is Test { /// function _assertBodiesStoredOK() internal { - assertEq(art.bodiesTrait().storedImagesCount, 4); + assertEq(art.getBodiesTrait().storedImagesCount, 4); // These hard-coded values are copied from image-data.json -> images -> BODIES -> the first items assertEq(art.bodies(0), IMAGE_0); @@ -494,7 +494,7 @@ contract NounsArtTest is Test { } function _assertAccessoriesStoredOK() internal { - assertEq(art.accessoriesTrait().storedImagesCount, 4); + assertEq(art.getAccessoriesTrait().storedImagesCount, 4); // These hard-coded values are copied from image-data.json -> images -> BODIES -> the first items assertEq(art.accessories(0), IMAGE_0); @@ -506,7 +506,7 @@ contract NounsArtTest is Test { } function _assertHeadsStoredOK() internal { - assertEq(art.headsTrait().storedImagesCount, 4); + assertEq(art.getHeadsTrait().storedImagesCount, 4); // These hard-coded values are copied from image-data.json -> images -> BODIES -> the first items assertEq(art.heads(0), IMAGE_0); @@ -518,7 +518,7 @@ contract NounsArtTest is Test { } function _assertGlassesStoredOK() internal { - assertEq(art.glassesTrait().storedImagesCount, 4); + assertEq(art.getGlassesTrait().storedImagesCount, 4); // These hard-coded values are copied from image-data.json -> images -> BODIES -> the first items assertEq(art.glasses(0), IMAGE_0); diff --git a/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol b/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol index dc7bfb3792..46a23484eb 100644 --- a/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol @@ -114,7 +114,7 @@ contract NounsDescriptorV2Test is Test { function testBodyCountUsesArt() public { vm.mockCall( address(art), - abi.encodeWithSelector(NounsArt.bodiesTrait.selector), + abi.encodeWithSelector(NounsArt.getBodiesTrait.selector), abi.encode(INounsArt.Trait({ storedImagesCount: 42, storagePages: new INounsArt.NounArtStoragePage[](0) })) ); assertEq(descriptor.bodyCount(), 42); @@ -124,7 +124,7 @@ contract NounsDescriptorV2Test is Test { function testAccessoryCountUsesArt() public { vm.mockCall( address(art), - abi.encodeWithSelector(NounsArt.accessoriesTrait.selector), + abi.encodeWithSelector(NounsArt.getAccessoriesTrait.selector), abi.encode(INounsArt.Trait({ storedImagesCount: 42, storagePages: new INounsArt.NounArtStoragePage[](0) })) ); assertEq(descriptor.accessoryCount(), 42); @@ -134,7 +134,7 @@ contract NounsDescriptorV2Test is Test { function testHeadCountUsesArt() public { vm.mockCall( address(art), - abi.encodeWithSelector(NounsArt.headsTrait.selector), + abi.encodeWithSelector(NounsArt.getHeadsTrait.selector), abi.encode(INounsArt.Trait({ storedImagesCount: 42, storagePages: new INounsArt.NounArtStoragePage[](0) })) ); assertEq(descriptor.headCount(), 42); @@ -144,7 +144,7 @@ contract NounsDescriptorV2Test is Test { function testGlassesCountUsesArt() public { vm.mockCall( address(art), - abi.encodeWithSelector(NounsArt.glassesTrait.selector), + abi.encodeWithSelector(NounsArt.getGlassesTrait.selector), abi.encode(INounsArt.Trait({ storedImagesCount: 42, storagePages: new INounsArt.NounArtStoragePage[](0) })) ); assertEq(descriptor.glassesCount(), 42); From 110f7c8401ca4adde3ec6d80c9532391e2a5fc5c Mon Sep 17 00:00:00 2001 From: eladmallel Date: Mon, 4 Jul 2022 14:49:44 +0300 Subject: [PATCH 055/116] art: remove puff from interface --- packages/nouns-contracts/contracts/NounsArt.sol | 2 +- packages/nouns-contracts/contracts/interfaces/INounsArt.sol | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsArt.sol b/packages/nouns-contracts/contracts/NounsArt.sol index f55f4308f9..c6a0a66824 100644 --- a/packages/nouns-contracts/contracts/NounsArt.sol +++ b/packages/nouns-contracts/contracts/NounsArt.sol @@ -344,7 +344,7 @@ contract NounsArt is INounsArt { * @return Inflate.ErrorCode 0 if successful, otherwise an error code specifying the reason for failure. * @return bytes the decompressed bytes. */ - function puff(bytes memory source, uint256 destlen) public pure override returns (Inflate.ErrorCode, bytes memory) { + function puff(bytes memory source, uint256 destlen) public pure returns (Inflate.ErrorCode, bytes memory) { return Inflate.puff(source, destlen); } diff --git a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol index f18d4af592..b49b08a55e 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol @@ -134,6 +134,4 @@ interface INounsArt { function getHeadsTrait() external view returns (Trait memory); function getGlassesTrait() external view returns (Trait memory); - - function puff(bytes memory source, uint256 destlen) external pure returns (Inflate.ErrorCode, bytes memory); } From d98306591c26ff91d61110af51ea10f92f73d98a Mon Sep 17 00:00:00 2001 From: eladmallel Date: Mon, 4 Jul 2022 15:15:09 +0300 Subject: [PATCH 056/116] art: add events on storage updates --- .../nouns-contracts/contracts/NounsArt.sol | 22 +++++++ .../contracts/interfaces/INounsArt.sol | 12 ++++ .../test/foundry/NounsArt.t.sol | 57 +++++++++++++++++++ 3 files changed, 91 insertions(+) diff --git a/packages/nouns-contracts/contracts/NounsArt.sol b/packages/nouns-contracts/contracts/NounsArt.sol index c6a0a66824..aa0dbc7d02 100644 --- a/packages/nouns-contracts/contracts/NounsArt.sol +++ b/packages/nouns-contracts/contracts/NounsArt.sol @@ -133,6 +133,8 @@ contract NounsArt is INounsArt { for (uint256 i = 0; i < _backgrounds.length; i++) { _addBackground(_backgrounds[i]); } + + emit BackgroundsAdded(_backgrounds.length); } /** @@ -141,6 +143,8 @@ contract NounsArt is INounsArt { */ function addBackground(string calldata _background) external override onlyDescriptor { _addBackground(_background); + + emit BackgroundsAdded(1); } /** @@ -156,6 +160,8 @@ contract NounsArt is INounsArt { revert BadPaletteLength(); } palettesPointers[paletteIndex] = SSTORE2.write(palette); + + emit PaletteSet(paletteIndex); } /** @@ -172,6 +178,8 @@ contract NounsArt is INounsArt { uint16 imageCount ) external override onlyDescriptor { addPage(bodiesTrait, encodedCompressed, decompressedLength, imageCount); + + emit BodiesAdded(imageCount); } /** @@ -188,6 +196,8 @@ contract NounsArt is INounsArt { uint16 imageCount ) external override onlyDescriptor { addPage(accessoriesTrait, encodedCompressed, decompressedLength, imageCount); + + emit AccessoriesAdded(imageCount); } /** @@ -204,6 +214,8 @@ contract NounsArt is INounsArt { uint16 imageCount ) external override onlyDescriptor { addPage(headsTrait, encodedCompressed, decompressedLength, imageCount); + + emit HeadsAdded(imageCount); } /** @@ -220,6 +232,8 @@ contract NounsArt is INounsArt { uint16 imageCount ) external override onlyDescriptor { addPage(glassesTrait, encodedCompressed, decompressedLength, imageCount); + + emit GlassesAdded(imageCount); } /** @@ -237,6 +251,8 @@ contract NounsArt is INounsArt { uint16 imageCount ) external override onlyDescriptor { addPage(bodiesTrait, pointer, decompressedLength, imageCount); + + emit BodiesAdded(imageCount); } /** @@ -254,6 +270,8 @@ contract NounsArt is INounsArt { uint16 imageCount ) external override onlyDescriptor { addPage(accessoriesTrait, pointer, decompressedLength, imageCount); + + emit AccessoriesAdded(imageCount); } /** @@ -271,6 +289,8 @@ contract NounsArt is INounsArt { uint16 imageCount ) external override onlyDescriptor { addPage(headsTrait, pointer, decompressedLength, imageCount); + + emit HeadsAdded(imageCount); } /** @@ -288,6 +308,8 @@ contract NounsArt is INounsArt { uint16 imageCount ) external override onlyDescriptor { addPage(glassesTrait, pointer, decompressedLength, imageCount); + + emit GlassesAdded(imageCount); } /** diff --git a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol index b49b08a55e..7f14ca2a93 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol @@ -40,6 +40,18 @@ interface INounsArt { event DescriptorUpdated(address oldDescriptor, address newDescriptor); + event BackgroundsAdded(uint256 count); + + event PaletteSet(uint8 paletteIndex); + + event BodiesAdded(uint16 count); + + event AccessoriesAdded(uint16 count); + + event HeadsAdded(uint16 count); + + event GlassesAdded(uint16 count); + struct NounArtStoragePage { uint16 imageCount; uint80 decompressedLength; diff --git a/packages/nouns-contracts/test/foundry/NounsArt.t.sol b/packages/nouns-contracts/test/foundry/NounsArt.t.sol index 8d43c7a2f1..ae986fb1f1 100644 --- a/packages/nouns-contracts/test/foundry/NounsArt.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsArt.t.sol @@ -7,6 +7,18 @@ import { INounsArt } from '../../contracts/interfaces/INounsArt.sol'; import { SSTORE2 } from '../../contracts/libs/SSTORE2.sol'; contract NounsArtTest is Test { + event BackgroundsAdded(uint256 count); + + event PaletteSet(uint8 paletteIndex); + + event BodiesAdded(uint16 count); + + event AccessoriesAdded(uint16 count); + + event HeadsAdded(uint16 count); + + event GlassesAdded(uint16 count); + NounsArt art; address descriptor = address(1); @@ -70,6 +82,9 @@ contract NounsArtTest is Test { function testAddBackgroundWorks() public { vm.prank(descriptor); + vm.expectEmit(true, true, true, true); + emit BackgroundsAdded(1); + art.addBackground('ffffff'); assertEq(art.backgroundsCount(), 1); @@ -90,6 +105,9 @@ contract NounsArtTest is Test { bgs[0] = 'ffffff'; bgs[1] = '000000'; + vm.expectEmit(true, true, true, true); + emit BackgroundsAdded(2); + vm.prank(descriptor); art.addManyBackgrounds(bgs); @@ -113,6 +131,11 @@ contract NounsArtTest is Test { } function testSetPaletteWorks() public { + vm.expectEmit(true, true, true, true); + emit PaletteSet(0); + vm.expectEmit(true, true, true, true); + emit PaletteSet(1); + bytes memory palette0 = hex'ffffffc5b9a1'; bytes memory palette1 = hex'cfc2ab63a0f9'; vm.startPrank(descriptor); @@ -131,11 +154,15 @@ contract NounsArtTest is Test { bytes memory paletteV1 = hex'ffffffc5b9a1'; bytes memory paletteV2 = hex'cfc2ab63a0f9'; + vm.expectEmit(true, true, true, true); + emit PaletteSet(0); vm.prank(descriptor); art.setPalette(0, paletteV1); assertEq(art.palettes(0), paletteV1); assertEq(SSTORE2.read(art.palettesPointers(0)), paletteV1); + vm.expectEmit(true, true, true, true); + emit PaletteSet(0); vm.prank(descriptor); art.setPalette(0, paletteV2); assertEq(art.palettes(0), paletteV2); @@ -215,6 +242,10 @@ contract NounsArtTest is Test { function testAddBodiesWorksWithMultiplePages() public { assertEq(art.getBodiesTrait().storedImagesCount, 0); + vm.expectEmit(true, true, true, true); + emit BodiesAdded(2); + vm.expectEmit(true, true, true, true); + emit BodiesAdded(2); vm.startPrank(descriptor); art.addBodies(FIRST_TWO_IMAGES_COMPRESSED, FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); @@ -240,6 +271,10 @@ contract NounsArtTest is Test { function testAddBodiesFromPointerWorksWithMultiplePages() public { assertEq(art.getBodiesTrait().storedImagesCount, 0); + vm.expectEmit(true, true, true, true); + emit BodiesAdded(2); + vm.expectEmit(true, true, true, true); + emit BodiesAdded(2); vm.startPrank(descriptor); art.addBodiesFromPointer( @@ -287,6 +322,10 @@ contract NounsArtTest is Test { function testAddAccessoriesWorksWithMultiplePages() public { assertEq(art.getAccessoriesTrait().storedImagesCount, 0); + vm.expectEmit(true, true, true, true); + emit AccessoriesAdded(2); + vm.expectEmit(true, true, true, true); + emit AccessoriesAdded(2); vm.startPrank(descriptor); art.addAccessories(FIRST_TWO_IMAGES_COMPRESSED, FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); @@ -312,6 +351,10 @@ contract NounsArtTest is Test { function testAddAccessoriesFromPointerWorksWithMultiplePages() public { assertEq(art.getAccessoriesTrait().storedImagesCount, 0); + vm.expectEmit(true, true, true, true); + emit AccessoriesAdded(2); + vm.expectEmit(true, true, true, true); + emit AccessoriesAdded(2); vm.startPrank(descriptor); art.addAccessoriesFromPointer( @@ -363,6 +406,10 @@ contract NounsArtTest is Test { function testAddHeadsWorksWithMultiplePages() public { assertEq(art.getHeadsTrait().storedImagesCount, 0); + vm.expectEmit(true, true, true, true); + emit HeadsAdded(2); + vm.expectEmit(true, true, true, true); + emit HeadsAdded(2); vm.startPrank(descriptor); art.addHeads(FIRST_TWO_IMAGES_COMPRESSED, FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); @@ -388,6 +435,10 @@ contract NounsArtTest is Test { function testAddHeadsFromPointerWorksWithMultiplePages() public { assertEq(art.getHeadsTrait().storedImagesCount, 0); + vm.expectEmit(true, true, true, true); + emit HeadsAdded(2); + vm.expectEmit(true, true, true, true); + emit HeadsAdded(2); vm.startPrank(descriptor); art.addHeadsFromPointer( @@ -435,6 +486,10 @@ contract NounsArtTest is Test { function testAddGlassesWorksWithMultiplePages() public { assertEq(art.getGlassesTrait().storedImagesCount, 0); + vm.expectEmit(true, true, true, true); + emit GlassesAdded(2); + vm.expectEmit(true, true, true, true); + emit GlassesAdded(2); vm.startPrank(descriptor); art.addGlasses(FIRST_TWO_IMAGES_COMPRESSED, FIRST_TWO_IMAGES_DEFLATED_LENGTH, uint16(2)); @@ -460,6 +515,8 @@ contract NounsArtTest is Test { function testAddGlassesFromPointerWorksWithMultiplePages() public { assertEq(art.getHeadsTrait().storedImagesCount, 0); + vm.expectEmit(true, true, true, true); + emit GlassesAdded(2); vm.startPrank(descriptor); art.addGlassesFromPointer( From 8cdb65cae2df11f3aab845228cc99b1e560e6f94 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Mon, 4 Jul 2022 15:39:01 +0300 Subject: [PATCH 057/116] art: add a test with 5 pages of art --- .../test/foundry/NounsArt.t.sol | 23 ++++++++++++++++++- .../foundry/helpers/DescriptorHelpers.sol | 11 +++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/packages/nouns-contracts/test/foundry/NounsArt.t.sol b/packages/nouns-contracts/test/foundry/NounsArt.t.sol index ae986fb1f1..222d9046a1 100644 --- a/packages/nouns-contracts/test/foundry/NounsArt.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsArt.t.sol @@ -5,8 +5,9 @@ import 'forge-std/Test.sol'; import { NounsArt } from '../../contracts/NounsArt.sol'; import { INounsArt } from '../../contracts/interfaces/INounsArt.sol'; import { SSTORE2 } from '../../contracts/libs/SSTORE2.sol'; +import { DescriptorHelpers } from './helpers/DescriptorHelpers.sol'; -contract NounsArtTest is Test { +contract NounsArtTest is Test, DescriptorHelpers { event BackgroundsAdded(uint256 count); event PaletteSet(uint8 paletteIndex); @@ -534,6 +535,26 @@ contract NounsArtTest is Test { _assertGlassesStoredOK(); } + function testAddGlassesWorksWithSeveralPages() public { + uint256 pageCount = 5; + (bytes memory glasses, uint80 glassesLength, uint16 glassesCount) = getGlassesPage(); + vm.startPrank(descriptor); + for (uint256 i = 0; i < pageCount; i++) { + art.addGlasses(glasses, glassesLength, glassesCount); + } + vm.stopPrank(); + + assertEq(art.getGlassesTrait().storagePages.length, 5); + + for (uint256 i = 0; i < glassesCount; i++) { + bytes memory glassesPage0 = art.glasses(i); + for (uint256 j = 1; j < pageCount; j++) { + bytes memory sameGlassesDifferentPage = art.glasses(i + glassesCount * j); + assertEq(sameGlassesDifferentPage, glassesPage0); + } + } + } + /// /// INTERNAL /// diff --git a/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol b/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol index bf32224b42..77e4261542 100644 --- a/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol +++ b/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol @@ -66,4 +66,15 @@ abstract contract DescriptorHelpers is Test, Constants { inputs[1] = filepath; output = vm.ffi(inputs); } + + function getGlassesPage() + public + returns ( + bytes memory glasses, + uint80 glassesLength, + uint16 glassesCount + ) + { + return abi.decode(readFile('./test/foundry/files/descriptor_v2/glassesPage.abi'), (bytes, uint80, uint16)); + } } From fed6162478bd8b8329f0cea978952f1e6570b598 Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Tue, 5 Jul 2022 09:15:50 +0200 Subject: [PATCH 058/116] lil natspec love --- packages/nouns-contracts/contracts/NounsArt.sol | 2 ++ packages/nouns-contracts/contracts/NounsDescriptorV2.sol | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/nouns-contracts/contracts/NounsArt.sol b/packages/nouns-contracts/contracts/NounsArt.sol index aa0dbc7d02..ceb3b26d64 100644 --- a/packages/nouns-contracts/contracts/NounsArt.sol +++ b/packages/nouns-contracts/contracts/NounsArt.sol @@ -150,6 +150,8 @@ contract NounsArt is INounsArt { /** * @notice Update a single color palette. This function can be used to * add a new color palette or update an existing palette. + * @param paletteIndex the identifier of this palette + * @param palette byte array of colors. every 3 bytes represent an RGB color. max length: 256 * 3 = 768 * @dev This function can only be called by the descriptor. */ function setPalette(uint8 paletteIndex, bytes calldata palette) external override onlyDescriptor { diff --git a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol index ecede7961c..47d6682866 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol @@ -62,7 +62,7 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { /** * @notice Set the Noun's art contract. - * Only callable by the owner when not locked. + * @dev Only callable by the owner when not locked. */ function setArt(INounsArt _art) external onlyOwner whenPartsNotLocked { art = _art; @@ -134,6 +134,8 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { /** * @notice Update a single color palette. This function can be used to * add a new color palette or update an existing palette. + * @param paletteIndex the identifier of this palette + * @param palette byte array of colors. every 3 bytes represent an RGB color. max length: 256 * 3 = 768 */ function setPalette(uint8 paletteIndex, bytes calldata palette) external override onlyOwner whenPartsNotLocked { art.setPalette(paletteIndex, palette); From fe6a08cff0f9d5f638b3b40312609d8279fc5223 Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Tue, 5 Jul 2022 09:21:30 +0200 Subject: [PATCH 059/116] reverting spacing to minimize diff --- .../nouns-contracts/contracts/NounsSeeder.sol | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsSeeder.sol b/packages/nouns-contracts/contracts/NounsSeeder.sol index 07a385eeee..5351bec8be 100644 --- a/packages/nouns-contracts/contracts/NounsSeeder.sol +++ b/packages/nouns-contracts/contracts/NounsSeeder.sol @@ -37,11 +37,21 @@ contract NounsSeeder is INounsSeeder { uint256 glassesCount = descriptor.glassesCount(); return Seed({ - background: uint48(uint48(pseudorandomness) % backgroundCount), - body: uint48(uint48(pseudorandomness >> 48) % bodyCount), - accessory: uint48(uint48(pseudorandomness >> 96) % accessoryCount), - head: uint48(uint48(pseudorandomness >> 144) % headCount), - glasses: uint48(uint48(pseudorandomness >> 192) % glassesCount) + background: uint48( + uint48(pseudorandomness) % backgroundCount + ), + body: uint48( + uint48(pseudorandomness >> 48) % bodyCount + ), + accessory: uint48( + uint48(pseudorandomness >> 96) % accessoryCount + ), + head: uint48( + uint48(pseudorandomness >> 144) % headCount + ), + glasses: uint48( + uint48(pseudorandomness >> 192) % glassesCount + ) }); } } From a532d13707e56a7e5b1c41768b23d43ddf0b4b17 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 6 Jul 2022 16:17:40 +0300 Subject: [PATCH 060/116] add hardhat task that deploys descriptor v2 and submits an upgrade prop --- .../tasks/deploy-and-configure.ts | 17 +-- ...deploy-descriptorv2-and-propose-upgrade.ts | 113 ++++++++++++++++++ packages/nouns-contracts/tasks/index.ts | 1 + packages/nouns-contracts/tasks/types/index.ts | 5 + packages/nouns-contracts/tasks/utils/index.ts | 18 +++ 5 files changed, 139 insertions(+), 15 deletions(-) create mode 100644 packages/nouns-contracts/tasks/deploy-descriptorv2-and-propose-upgrade.ts diff --git a/packages/nouns-contracts/tasks/deploy-and-configure.ts b/packages/nouns-contracts/tasks/deploy-and-configure.ts index 1e3c7ce207..b17bdc37f6 100644 --- a/packages/nouns-contracts/tasks/deploy-and-configure.ts +++ b/packages/nouns-contracts/tasks/deploy-and-configure.ts @@ -1,5 +1,5 @@ import { task, types } from 'hardhat/config'; -import { DeployedContract } from './types'; +import { printContractsTable } from './utils'; interface ContractRow { Address: string; @@ -76,19 +76,6 @@ task('deploy-and-configure', 'Deploy and configure all contracts') }); } - console.table( - Object.values(contracts).reduce( - (acc: Record, contract: DeployedContract) => { - acc[contract.name] = { - Address: contract.address, - }; - if (contract.instance?.deployTransaction) { - acc[contract.name]['Deployment Hash'] = contract.instance.deployTransaction.hash; - } - return acc; - }, - {}, - ), - ); + printContractsTable(contracts); console.log('Deployment Complete.'); }); diff --git a/packages/nouns-contracts/tasks/deploy-descriptorv2-and-propose-upgrade.ts b/packages/nouns-contracts/tasks/deploy-descriptorv2-and-propose-upgrade.ts new file mode 100644 index 0000000000..e4cbdbd1d5 --- /dev/null +++ b/packages/nouns-contracts/tasks/deploy-descriptorv2-and-propose-upgrade.ts @@ -0,0 +1,113 @@ +import { task } from 'hardhat/config'; +import { + NFTDescriptorV2__factory, + NounsArt__factory, + NounsDAOLogicV1__factory, + NounsDescriptorV2__factory, + SVGRenderer__factory, +} from '../typechain'; +import { ContractName, DeployedContract } from './types'; +import { printContractsTable } from './utils'; + +task( + 'deploy-descriptorv2-and-propose-upgrade', + 'Deploy NounsDescriptorV2, populate it with art and submit an upgrade proposal to the DAO', +) + .addParam('tokenAddress', 'The NounsToken address, used in the descriptor upgrade proposal') + .addParam('daoAddress', 'The DAO proxy address, where the upgrade proposal is submitted') + .addParam('executorAddress', "The DAO's deployed timelock address") + .setAction(async ({ executorAddress, daoAddress, tokenAddress }, { ethers, run }) => { + const contracts: Record = {} as Record< + ContractName, + DeployedContract + >; + const [deployer] = await ethers.getSigners(); + console.log(`Deploying from address ${deployer.address}`); + + const nonce = await deployer.getTransactionCount(); + const expectedNounsArtAddress = ethers.utils.getContractAddress({ + from: deployer.address, + nonce: nonce + 3, + }); + + console.log('Deploying contracts...'); + const library = await new NFTDescriptorV2__factory(deployer).deploy(); + contracts.NFTDescriptorV2 = { + name: 'NFTDescriptorV2', + address: library.address, + instance: library, + constructorArguments: [], + libraries: {}, + }; + + const renderer = await new SVGRenderer__factory(deployer).deploy(); + contracts.SVGRenderer = { + name: 'SVGRenderer', + address: renderer.address, + instance: renderer, + constructorArguments: [], + libraries: {}, + }; + + const nounsDescriptorFactory = new NounsDescriptorV2__factory( + { + 'contracts/libs/NFTDescriptorV2.sol:NFTDescriptorV2': library.address, + }, + deployer, + ); + const nounsDescriptor = await nounsDescriptorFactory.deploy( + expectedNounsArtAddress, + renderer.address, + ); + contracts.NounsDescriptorV2 = { + name: 'NounsDescriptorV2', + address: nounsDescriptor.address, + constructorArguments: [expectedNounsArtAddress, renderer.address], + instance: nounsDescriptor, + libraries: { + NFTDescriptorV2: library.address, + }, + }; + + const art = await new NounsArt__factory(deployer).deploy(nounsDescriptor.address); + console.log(`actual art address: ${art.address}`); + contracts.NounsArt = { + name: 'NounsArt', + address: art.address, + constructorArguments: [nounsDescriptor.address], + instance: art, + libraries: {}, + }; + + console.log('Deployment complete:'); + printContractsTable(contracts); + + console.log('Verifying contracts on Etherscan...'); + await run('verify-etherscan', { + contracts, + }); + console.log('Verify complete.'); + + console.log('Populating Descriptor...'); + await run('populate-descriptor', { + nftDescriptor: contracts.NFTDescriptorV2.address, + nounsDescriptor: contracts.NounsDescriptorV2.address, + }); + console.log('Population complete.'); + + console.log('Transferring ownership of the descriptor to the executor...'); + await contracts.NounsDescriptorV2.instance!.transferOwnership(executorAddress); + console.log('Transfer complete.'); + + console.log('Submitting the upgrade proposal to the DAO...'); + const dao = NounsDAOLogicV1__factory.connect(daoAddress, deployer); + const propTx = await dao.propose( + [tokenAddress], + [0], + ['setDescriptor(address)'], + [contracts.NounsDescriptorV2.address], + 'Upgrade NounsToken to use DescriptorV2.', + ); + await propTx.wait(); + console.log('Submission complete.'); + }); diff --git a/packages/nouns-contracts/tasks/index.ts b/packages/nouns-contracts/tasks/index.ts index 8ae20017b5..89834e1278 100644 --- a/packages/nouns-contracts/tasks/index.ts +++ b/packages/nouns-contracts/tasks/index.ts @@ -11,3 +11,4 @@ export * from './verify-etherscan'; export * from './update-configs'; export * from './descriptor-art-to-console'; export * from './descriptor-v1-export-abi'; +export * from './deploy-descriptorv2-and-propose-upgrade'; diff --git a/packages/nouns-contracts/tasks/types/index.ts b/packages/nouns-contracts/tasks/types/index.ts index 867b6e047f..479a8ca8ca 100644 --- a/packages/nouns-contracts/tasks/types/index.ts +++ b/packages/nouns-contracts/tasks/types/index.ts @@ -24,3 +24,8 @@ export interface DeployedContract { constructorArguments: (string | number)[]; libraries: Record; } + +export interface ContractRow { + Address: string; + 'Deployment Hash'?: string; +} diff --git a/packages/nouns-contracts/tasks/utils/index.ts b/packages/nouns-contracts/tasks/utils/index.ts index 07ffbcc498..94cbaeb77a 100644 --- a/packages/nouns-contracts/tasks/utils/index.ts +++ b/packages/nouns-contracts/tasks/utils/index.ts @@ -1,5 +1,6 @@ import { ethers } from 'ethers'; import { deflateRawSync } from 'zlib'; +import { ContractName, ContractRow, DeployedContract } from '../types'; export function dataToDescriptorInput(data: string[]): { encodedCompressed: string; @@ -20,3 +21,20 @@ export function dataToDescriptorInput(data: string[]): { itemCount, }; } + +export function printContractsTable(contracts: Record) { + console.table( + Object.values(contracts).reduce( + (acc: Record, contract: DeployedContract) => { + acc[contract.name] = { + Address: contract.address, + }; + if (contract.instance?.deployTransaction) { + acc[contract.name]['Deployment Hash'] = contract.instance.deployTransaction.hash; + } + return acc; + }, + {}, + ), + ); +} From e118f7176e3e4274472080357db5ee4975c50c2f Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 6 Jul 2022 16:34:48 +0300 Subject: [PATCH 061/116] fix descriptor v2 deploy script --- ...deploy-descriptorv2-and-propose-upgrade.ts | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/packages/nouns-contracts/tasks/deploy-descriptorv2-and-propose-upgrade.ts b/packages/nouns-contracts/tasks/deploy-descriptorv2-and-propose-upgrade.ts index e4cbdbd1d5..fc8831579f 100644 --- a/packages/nouns-contracts/tasks/deploy-descriptorv2-and-propose-upgrade.ts +++ b/packages/nouns-contracts/tasks/deploy-descriptorv2-and-propose-upgrade.ts @@ -1,11 +1,4 @@ import { task } from 'hardhat/config'; -import { - NFTDescriptorV2__factory, - NounsArt__factory, - NounsDAOLogicV1__factory, - NounsDescriptorV2__factory, - SVGRenderer__factory, -} from '../typechain'; import { ContractName, DeployedContract } from './types'; import { printContractsTable } from './utils'; @@ -31,7 +24,7 @@ task( }); console.log('Deploying contracts...'); - const library = await new NFTDescriptorV2__factory(deployer).deploy(); + const library = await (await ethers.getContractFactory('NFTDescriptorV2', deployer)).deploy(); contracts.NFTDescriptorV2 = { name: 'NFTDescriptorV2', address: library.address, @@ -40,7 +33,7 @@ task( libraries: {}, }; - const renderer = await new SVGRenderer__factory(deployer).deploy(); + const renderer = await (await ethers.getContractFactory('SVGRenderer', deployer)).deploy(); contracts.SVGRenderer = { name: 'SVGRenderer', address: renderer.address, @@ -49,12 +42,11 @@ task( libraries: {}, }; - const nounsDescriptorFactory = new NounsDescriptorV2__factory( - { - 'contracts/libs/NFTDescriptorV2.sol:NFTDescriptorV2': library.address, + const nounsDescriptorFactory = await ethers.getContractFactory('NounsDescriptorV2', { + libraries: { + NFTDescriptorV2: library.address, }, - deployer, - ); + }); const nounsDescriptor = await nounsDescriptorFactory.deploy( expectedNounsArtAddress, renderer.address, @@ -69,7 +61,9 @@ task( }, }; - const art = await new NounsArt__factory(deployer).deploy(nounsDescriptor.address); + const art = await ( + await ethers.getContractFactory('NounsArt', deployer) + ).deploy(nounsDescriptor.address); console.log(`actual art address: ${art.address}`); contracts.NounsArt = { name: 'NounsArt', @@ -100,7 +94,7 @@ task( console.log('Transfer complete.'); console.log('Submitting the upgrade proposal to the DAO...'); - const dao = NounsDAOLogicV1__factory.connect(daoAddress, deployer); + const dao = (await ethers.getContractFactory('NounsDAOLogicV1', deployer)).attach(daoAddress); const propTx = await dao.propose( [tokenAddress], [0], From 534c88b942e420a05ea1eab030f0c91816897b68 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 6 Jul 2022 16:44:19 +0300 Subject: [PATCH 062/116] increase javascript heap max memory want to see this working ok first then will un-skip the v2 tokenURI test that we're skipping due to heap overutilization --- .github/workflows/contracts.yaml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/contracts.yaml b/.github/workflows/contracts.yaml index a8cd1c1f77..a701636aca 100644 --- a/.github/workflows/contracts.yaml +++ b/.github/workflows/contracts.yaml @@ -6,10 +6,13 @@ on: - master pull_request: paths: - - "packages/nouns-contracts/**" - - "packages/nouns-subgraph/**" + - 'packages/nouns-contracts/**' + - 'packages/nouns-subgraph/**' branches: - - "**" + - '**' + +env: + NODE_OPTIONS: --max_old_space_size=4096 jobs: build_and_test: From 71f7c80691e2c8b1ce81e0803444d5b93cdb11a4 Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Wed, 6 Jul 2022 16:03:21 +0200 Subject: [PATCH 063/116] upgrade solidity compiler to 0.8.15 --- packages/nouns-contracts/foundry.toml | 1 + packages/nouns-contracts/hardhat.config.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/nouns-contracts/foundry.toml b/packages/nouns-contracts/foundry.toml index 3ad1c161c1..2d051c48aa 100644 --- a/packages/nouns-contracts/foundry.toml +++ b/packages/nouns-contracts/foundry.toml @@ -3,3 +3,4 @@ src = 'contracts' libs = ['lib', '../../node_modules'] cache_path = 'foundry-cache' out = 'foundry-out' +solc_version = '0.8.15' \ No newline at end of file diff --git a/packages/nouns-contracts/hardhat.config.ts b/packages/nouns-contracts/hardhat.config.ts index 493b2e43e4..6d469b0503 100644 --- a/packages/nouns-contracts/hardhat.config.ts +++ b/packages/nouns-contracts/hardhat.config.ts @@ -14,7 +14,7 @@ dotenv.config(); const config: HardhatUserConfig = { solidity: { - version: '0.8.6', + version: '0.8.15', settings: { optimizer: { enabled: true, From f4c1e4a86d011dc8efbc7348d05fbd204496f4c2 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 6 Jul 2022 17:06:15 +0300 Subject: [PATCH 064/116] unskip descriptor test that failed bc of low JS heap in a previous commit we increased JS heap mem allocation, so this commit should work! --- packages/nouns-contracts/test/descriptorV2.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/nouns-contracts/test/descriptorV2.test.ts b/packages/nouns-contracts/test/descriptorV2.test.ts index 834d18ec78..cac68c9fd3 100644 --- a/packages/nouns-contracts/test/descriptorV2.test.ts +++ b/packages/nouns-contracts/test/descriptorV2.test.ts @@ -66,8 +66,7 @@ describe('NounsDescriptorV2', () => { expect(tokenUri).to.equal(`${BASE_URI}0`); }); - // Skipping until we resolve the CI memory issue - it.skip('should generate valid token uri metadata when data uris are enabled', async () => { + it('should generate valid token uri metadata when data uris are enabled', async () => { const tokenUri = await nounsDescriptor.tokenURI( 0, { From b71a14b6ee8987d4c25e43aed8950b3941b0e167 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 6 Jul 2022 18:08:17 +0300 Subject: [PATCH 065/116] increase tokenURI test timeout bc CI tests failing due to timeout --- packages/nouns-contracts/test/descriptorV2.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nouns-contracts/test/descriptorV2.test.ts b/packages/nouns-contracts/test/descriptorV2.test.ts index cac68c9fd3..11d73e3ed8 100644 --- a/packages/nouns-contracts/test/descriptorV2.test.ts +++ b/packages/nouns-contracts/test/descriptorV2.test.ts @@ -86,7 +86,7 @@ describe('NounsDescriptorV2', () => { expect(name).to.equal('Noun 0'); expect(description).to.equal('Noun 0 is a member of the Nouns DAO'); expect(image).to.not.be.undefined; - }).timeout(100_000); + }).timeout(500_000); // Unskip this test to validate the encoding of all parts. It ensures that no parts revert when building the token URI. // This test also outputs a parts.html file, which can be visually inspected. From aa18199f6c6f28849cf8b591afe588a0d4ea2b79 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 6 Jul 2022 19:08:44 +0300 Subject: [PATCH 066/116] hardhat task: deploy with no constraints on gov times so we can deploy to rinkeby with faster prop times to save precious testing time --- .../tasks/deploy-and-configure-short-times.ts | 76 +++++ .../tasks/deploy-short-times.ts | 300 ++++++++++++++++++ packages/nouns-contracts/tasks/index.ts | 2 + .../nouns-contracts/tasks/verify-etherscan.ts | 1 + 4 files changed, 379 insertions(+) create mode 100644 packages/nouns-contracts/tasks/deploy-and-configure-short-times.ts create mode 100644 packages/nouns-contracts/tasks/deploy-short-times.ts diff --git a/packages/nouns-contracts/tasks/deploy-and-configure-short-times.ts b/packages/nouns-contracts/tasks/deploy-and-configure-short-times.ts new file mode 100644 index 0000000000..7bc44e18ec --- /dev/null +++ b/packages/nouns-contracts/tasks/deploy-and-configure-short-times.ts @@ -0,0 +1,76 @@ +import { task, types } from 'hardhat/config'; +import { printContractsTable } from './utils'; + +task('deploy-and-configure-short-times', 'Deploy and configure all contracts') + .addFlag('startAuction', 'Start the first auction upon deployment completion') + .addFlag('autoDeploy', 'Deploy all contracts without user interaction') + .addFlag('updateConfigs', 'Write the deployed addresses to the SDK and subgraph configs') + .addOptionalParam('weth', 'The WETH contract address') + .addOptionalParam('noundersdao', 'The nounders DAO contract address') + .addOptionalParam( + 'auctionTimeBuffer', + 'The auction time buffer (seconds)', + 5 * 60 /* 5 minutes */, + types.int, + ) + .addOptionalParam('auctionReservePrice', 'The auction reserve price (wei)') + .addOptionalParam( + 'auctionMinIncrementBidPercentage', + 'The auction min increment bid percentage (out of 100)', + ) + .addOptionalParam('auctionDuration', 'The auction duration (seconds)', 600, types.int) + .addOptionalParam('timelockDelay', 'The timelock delay (seconds)') + .addOptionalParam('votingPeriod', 'The voting period (blocks)', 5760, types.int) + .addOptionalParam('votingDelay', 'The voting delay (blocks)', 1, types.int) + .addOptionalParam('proposalThresholdBps', 'The proposal threshold (basis points)') + .addOptionalParam('quorumVotesBps', 'Votes required for quorum (basis points)') + .setAction(async (args, { run }) => { + // Deploy the Nouns DAO contracts and return deployment information + const contracts = await run('deploy-short-times', args); + + // Verify the contracts on Etherscan + await run('verify-etherscan', { + contracts, + }); + + // Populate the on-chain art + await run('populate-descriptor', { + nftDescriptor: contracts.NFTDescriptorV2.address, + nounsDescriptor: contracts.NounsDescriptorV2.address, + }); + + // Transfer ownership of all contract except for the auction house. + // We must maintain ownership of the auction house to kick off the first auction. + const executorAddress = contracts.NounsDAOExecutor.address; + await contracts.NounsDescriptorV2.instance.transferOwnership(executorAddress); + await contracts.NounsToken.instance.transferOwnership(executorAddress); + await contracts.NounsAuctionHouseProxyAdmin.instance.transferOwnership(executorAddress); + console.log( + 'Transferred ownership of the descriptor, token, and proxy admin contracts to the executor.', + ); + + // Optionally kick off the first auction and transfer ownership of the auction house + // to the Nouns DAO executor. + if (args.startAuction) { + const auctionHouse = contracts.NounsAuctionHouse.instance.attach( + contracts.NounsAuctionHouseProxy.address, + ); + await auctionHouse.unpause({ + gasLimit: 1_000_000, + }); + await auctionHouse.transferOwnership(executorAddress); + console.log( + 'Started the first auction and transferred ownership of the auction house to the executor.', + ); + } + + // Optionally write the deployed addresses to the SDK and subgraph configs. + if (args.updateConfigs) { + await run('update-configs', { + contracts, + }); + } + + printContractsTable(contracts); + console.log('Deployment Complete.'); + }); diff --git a/packages/nouns-contracts/tasks/deploy-short-times.ts b/packages/nouns-contracts/tasks/deploy-short-times.ts new file mode 100644 index 0000000000..964b7a9eac --- /dev/null +++ b/packages/nouns-contracts/tasks/deploy-short-times.ts @@ -0,0 +1,300 @@ +import { default as NounsAuctionHouseABI } from '../abi/contracts/NounsAuctionHouse.sol/NounsAuctionHouse.json'; +import { ChainId, ContractDeployment, ContractName, DeployedContract } from './types'; +import { Interface } from 'ethers/lib/utils'; +import { task, types } from 'hardhat/config'; +import promptjs from 'prompt'; + +promptjs.colors = false; +promptjs.message = '> '; +promptjs.delimiter = ''; + +const proxyRegistries: Record = { + [ChainId.Mainnet]: '0xa5409ec958c83c3f309868babaca7c86dcb077c1', + [ChainId.Rinkeby]: '0xf57b2c51ded3a29e6891aba85459d600256cf317', +}; +const wethContracts: Record = { + [ChainId.Mainnet]: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', + [ChainId.Ropsten]: '0xc778417e063141139fce010982780140aa0cd5ab', + [ChainId.Rinkeby]: '0xc778417e063141139fce010982780140aa0cd5ab', + [ChainId.Kovan]: '0xd0a1e359811322d97991e03f863a0c30c2cf029c', +}; + +const NOUNS_ART_NONCE_OFFSET = 3; +const AUCTION_HOUSE_PROXY_NONCE_OFFSET = 8; +const GOVERNOR_N_DELEGATOR_NONCE_OFFSET = 11; + +task('deploy-short-times', 'Deploys NFTDescriptor, NounsDescriptor, NounsSeeder, and NounsToken') + .addFlag('autoDeploy', 'Deploy all contracts without user interaction') + .addOptionalParam('weth', 'The WETH contract address', undefined, types.string) + .addOptionalParam('noundersdao', 'The nounders DAO contract address', undefined, types.string) + .addOptionalParam( + 'auctionTimeBuffer', + 'The auction time buffer (seconds)', + 30 /* 30 seconds */, + types.int, + ) + .addOptionalParam( + 'auctionReservePrice', + 'The auction reserve price (wei)', + 1 /* 1 wei */, + types.int, + ) + .addOptionalParam( + 'auctionMinIncrementBidPercentage', + 'The auction min increment bid percentage (out of 100)', + 2 /* 2% */, + types.int, + ) + .addOptionalParam( + 'auctionDuration', + 'The auction duration (seconds)', + 60 * 2 /* 2 minutes */, + types.int, + ) + .addOptionalParam('timelockDelay', 'The timelock delay (seconds)', 3600 /* 1 hour */, types.int) + .addOptionalParam( + 'votingPeriod', + 'The voting period (blocks)', + 240 /* 1 hour (15s blocks) */, + types.int, + ) + .addOptionalParam('votingDelay', 'The voting delay (blocks)', 1, types.int) + .addOptionalParam( + 'proposalThresholdBps', + 'The proposal threshold (basis points)', + 100 /* 1% */, + types.int, + ) + .addOptionalParam( + 'quorumVotesBps', + 'Votes required for quorum (basis points)', + 1_000 /* 10% */, + types.int, + ) + .setAction(async (args, { ethers }) => { + const network = await ethers.provider.getNetwork(); + const [deployer] = await ethers.getSigners(); + + // prettier-ignore + const proxyRegistryAddress = proxyRegistries[network.chainId] ?? proxyRegistries[ChainId.Rinkeby]; + + if (!args.noundersdao) { + console.log( + `Nounders DAO address not provided. Setting to deployer (${deployer.address})...`, + ); + args.noundersdao = deployer.address; + } + if (!args.weth) { + const deployedWETHContract = wethContracts[network.chainId]; + if (!deployedWETHContract) { + throw new Error( + `Can not auto-detect WETH contract on chain ${network.name}. Provide it with the --weth arg.`, + ); + } + args.weth = deployedWETHContract; + } + + const nonce = await deployer.getTransactionCount(); + const expectedNounsArtAddress = ethers.utils.getContractAddress({ + from: deployer.address, + nonce: nonce + NOUNS_ART_NONCE_OFFSET, + }); + const expectedAuctionHouseProxyAddress = ethers.utils.getContractAddress({ + from: deployer.address, + nonce: nonce + AUCTION_HOUSE_PROXY_NONCE_OFFSET, + }); + const expectedNounsDAOProxyAddress = ethers.utils.getContractAddress({ + from: deployer.address, + nonce: nonce + GOVERNOR_N_DELEGATOR_NONCE_OFFSET, + }); + const deployment: Record = {} as Record< + ContractName, + DeployedContract + >; + const contracts: Record = { + NFTDescriptorV2: {}, + SVGRenderer: {}, + NounsDescriptorV2: { + args: [expectedNounsArtAddress, () => deployment.SVGRenderer.address], + libraries: () => ({ + NFTDescriptorV2: deployment.NFTDescriptorV2.address, + }), + }, + NounsArt: { + args: [() => deployment.NounsDescriptorV2.address], + }, + NounsSeeder: {}, + NounsToken: { + args: [ + args.noundersdao, + expectedAuctionHouseProxyAddress, + () => deployment.NounsDescriptorV2.address, + () => deployment.NounsSeeder.address, + proxyRegistryAddress, + ], + }, + NounsAuctionHouse: { + waitForConfirmation: true, + }, + NounsAuctionHouseProxyAdmin: {}, + NounsAuctionHouseProxy: { + args: [ + () => deployment.NounsAuctionHouse.address, + () => deployment.NounsAuctionHouseProxyAdmin.address, + () => + new Interface(NounsAuctionHouseABI).encodeFunctionData('initialize', [ + deployment.NounsToken.address, + args.weth, + args.auctionTimeBuffer, + args.auctionReservePrice, + args.auctionMinIncrementBidPercentage, + args.auctionDuration, + ]), + ], + waitForConfirmation: true, + validateDeployment: () => { + const expected = expectedAuctionHouseProxyAddress.toLowerCase(); + const actual = deployment.NounsAuctionHouseProxy.address.toLowerCase(); + if (expected !== actual) { + throw new Error( + `Unexpected auction house proxy address. Expected: ${expected}. Actual: ${actual}.`, + ); + } + }, + }, + NounsDAOExecutor: { + args: [expectedNounsDAOProxyAddress, args.timelockDelay], + }, + NounsDAOLogicV1: { + waitForConfirmation: true, + }, + NounsDAOProxy: { + args: [ + () => deployment.NounsDAOExecutor.address, + () => deployment.NounsToken.address, + args.noundersdao, + () => deployment.NounsDAOExecutor.address, + () => deployment.NounsDAOLogicV1.address, + args.votingPeriod, + args.votingDelay, + args.proposalThresholdBps, + args.quorumVotesBps, + ], + waitForConfirmation: true, + validateDeployment: () => { + const expected = expectedNounsDAOProxyAddress.toLowerCase(); + const actual = deployment.NounsDAOProxy.address.toLowerCase(); + if (expected !== actual) { + throw new Error( + `Unexpected Nouns DAO proxy address. Expected: ${expected}. Actual: ${actual}.`, + ); + } + }, + }, + }; + + for (const [name, contract] of Object.entries(contracts)) { + let gasPrice = await ethers.provider.getGasPrice(); + if (!args.autoDeploy) { + const gasInGwei = Math.round(Number(ethers.utils.formatUnits(gasPrice, 'gwei'))); + + promptjs.start(); + + const result = await promptjs.get([ + { + properties: { + gasPrice: { + type: 'integer', + required: true, + description: 'Enter a gas price (gwei)', + default: gasInGwei, + }, + }, + }, + ]); + gasPrice = ethers.utils.parseUnits(result.gasPrice.toString(), 'gwei'); + } + + let nameForFactory: string; + switch (name) { + case 'NounsDAOExecutor': + nameForFactory = 'NounsDAOExecutorTest'; + break; + case 'NounsDAOLogicV1': + nameForFactory = 'NounsDAOLogicV1Harness'; + break; + default: + nameForFactory = name; + break; + } + + const factory = await ethers.getContractFactory(nameForFactory, { + libraries: contract?.libraries?.(), + }); + + const deploymentGas = await factory.signer.estimateGas( + factory.getDeployTransaction( + ...(contract.args?.map(a => (typeof a === 'function' ? a() : a)) ?? []), + { + gasPrice, + }, + ), + ); + const deploymentCost = deploymentGas.mul(gasPrice); + + console.log( + `Estimated cost to deploy ${name}: ${ethers.utils.formatUnits( + deploymentCost, + 'ether', + )} ETH`, + ); + + if (!args.autoDeploy) { + const result = await promptjs.get([ + { + properties: { + confirm: { + pattern: /^(DEPLOY|SKIP|EXIT)$/, + description: + 'Type "DEPLOY" to confirm, "SKIP" to skip this contract, or "EXIT" to exit.', + }, + }, + }, + ]); + if (result.operation === 'SKIP') { + console.log(`Skipping ${name} deployment...`); + continue; + } + if (result.operation === 'EXIT') { + console.log('Exiting...'); + return; + } + } + console.log(`Deploying ${name}...`); + + const deployedContract = await factory.deploy( + ...(contract.args?.map(a => (typeof a === 'function' ? a() : a)) ?? []), + { + gasPrice, + }, + ); + + if (contract.waitForConfirmation) { + await deployedContract.deployed(); + } + + deployment[name as ContractName] = { + name: nameForFactory, + instance: deployedContract, + address: deployedContract.address, + constructorArguments: contract.args?.map(a => (typeof a === 'function' ? a() : a)) ?? [], + libraries: contract?.libraries?.() ?? {}, + }; + + contract.validateDeployment?.(); + + console.log(`${name} contract deployed to ${deployedContract.address}`); + } + + return deployment; + }); diff --git a/packages/nouns-contracts/tasks/index.ts b/packages/nouns-contracts/tasks/index.ts index 89834e1278..7585fe0dbb 100644 --- a/packages/nouns-contracts/tasks/index.ts +++ b/packages/nouns-contracts/tasks/index.ts @@ -12,3 +12,5 @@ export * from './update-configs'; export * from './descriptor-art-to-console'; export * from './descriptor-v1-export-abi'; export * from './deploy-descriptorv2-and-propose-upgrade'; +export * from './deploy-short-times'; +export * from './deploy-and-configure-short-times'; diff --git a/packages/nouns-contracts/tasks/verify-etherscan.ts b/packages/nouns-contracts/tasks/verify-etherscan.ts index c80dff0fbb..3dfe5bb94d 100644 --- a/packages/nouns-contracts/tasks/verify-etherscan.ts +++ b/packages/nouns-contracts/tasks/verify-etherscan.ts @@ -15,6 +15,7 @@ interface VerifyArgs { const nameToFullyQualifiedName: Record = { NounsAuctionHouseProxy: 'contracts/proxies/NounsAuctionHouseProxy.sol:NounsAuctionHouseProxy', NounsAuctionHouseProxyAdmin: 'contracts/proxies/NounsAuctionHouseProxyAdmin.sol:NounsAuctionHouseProxyAdmin', + NounsDAOLogicV1Harness: 'contracts/test/NounsDAOLogicV1Harness.sol:NounsDAOLogicV1Harness' }; task('verify-etherscan', 'Verify the Solidity contracts on Etherscan') From 723f134530c2c164b970931d788ef7eb612be433 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 6 Jul 2022 19:09:10 +0300 Subject: [PATCH 067/116] cleanup --- packages/nouns-contracts/tasks/deploy-and-configure.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/nouns-contracts/tasks/deploy-and-configure.ts b/packages/nouns-contracts/tasks/deploy-and-configure.ts index b17bdc37f6..8b889dfe64 100644 --- a/packages/nouns-contracts/tasks/deploy-and-configure.ts +++ b/packages/nouns-contracts/tasks/deploy-and-configure.ts @@ -1,11 +1,6 @@ import { task, types } from 'hardhat/config'; import { printContractsTable } from './utils'; -interface ContractRow { - Address: string; - 'Deployment Hash'?: string; -} - task('deploy-and-configure', 'Deploy and configure all contracts') .addFlag('startAuction', 'Start the first auction upon deployment completion') .addFlag('autoDeploy', 'Deploy all contracts without user interaction') From 05c7f1386daf4e3cf9d6d608c0c78c960798495f Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 6 Jul 2022 19:10:49 +0300 Subject: [PATCH 068/116] hardhat task: populate descriptor via proposal --- ...ata-example-for-populate-via-proposal.json | 333 ++++++++++++++++++ packages/nouns-contracts/tasks/index.ts | 1 + .../tasks/populate-descriptor-via-proposal.ts | 125 +++++++ 3 files changed, 459 insertions(+) create mode 100644 packages/nouns-contracts/files/image-data-example-for-populate-via-proposal.json create mode 100644 packages/nouns-contracts/tasks/populate-descriptor-via-proposal.ts diff --git a/packages/nouns-contracts/files/image-data-example-for-populate-via-proposal.json b/packages/nouns-contracts/files/image-data-example-for-populate-via-proposal.json new file mode 100644 index 0000000000..14bac67819 --- /dev/null +++ b/packages/nouns-contracts/files/image-data-example-for-populate-via-proposal.json @@ -0,0 +1,333 @@ +{ + "palette": { + "1": [ + "", + "c5b9a1", + "ffffff", + "cfc2ab", + "63a0f9", + "807f7e", + "caeff9", + "5648ed", + "5a423f", + "b9185c", + "b87b11", + "fffdf2", + "4b4949", + "343235", + "1f1d29", + "068940", + "867c1d", + "ae3208", + "9f21a0", + "f98f30", + "fe500c", + "d26451", + "fd8b5b", + "5a65fa", + "d22209", + "e9265c", + "c54e38", + "80a72d", + "4bea69", + "34ac80", + "eed811", + "62616d", + "ff638d", + "8bc0c5", + "c4da53", + "000000", + "f3322c", + "ffae1a", + "ffc110", + "505a5c", + "ffef16", + "fff671", + "fff449", + "db8323", + "df2c39", + "f938d8", + "5c25fb", + "2a86fd", + "45faff", + "38dd56", + "ff3a0e", + "d32a09", + "903707", + "6e3206", + "552e05", + "e8705b", + "f38b7c", + "e4a499", + "667af9", + "648df9", + "7cc4f2", + "97f2fb", + "a3efd0", + "87e4d9", + "71bde4", + "ff1a0b", + "f78a18", + "2b83f6", + "d62149", + "834398", + "ffc925", + "d9391f", + "bd2d24", + "ff7216", + "254efb", + "e5e5de", + "00a556", + "c5030e", + "abf131", + "fb4694", + "e7a32c", + "fff0ee", + "009c59", + "0385eb", + "00499c", + "e11833", + "26b1f3", + "fff0be", + "d8dadf", + "d7d3cd", + "1929f4", + "eab118", + "0b5027", + "f9f5cb", + "cfc9b8", + "feb9d5", + "f8d689", + "5d6061", + "76858b", + "757576", + "ff0e0e", + "0adc4d", + "fdf8ff", + "70e890", + "f7913d", + "ff1ad2", + "ff82ad", + "535a15", + "fa6fe2", + "ffe939", + "ab36be", + "adc8cc", + "604666", + "f20422", + "abaaa8", + "4b65f7", + "a19c9a", + "58565c", + "da42cb", + "027c92", + "cec189", + "909b0e", + "74580d", + "027ee6", + "b2958d", + "efad81", + "7d635e", + "eff2fa", + "6f597a", + "d4b7b2", + "d18687", + "cd916d", + "6b3f39", + "4d271b", + "85634f", + "f9f4e6", + "f8ddb0", + "b92b3c", + "d08b11", + "257ced", + "a3baed", + "5fd4fb", + "c16710", + "a28ef4", + "3a085b", + "67b1e3", + "1e3445", + "ffd067", + "962236", + "769ca9", + "5a6b7b", + "7e5243", + "a86f60", + "8f785e", + "cc0595", + "42ffb0", + "d56333", + "b8ced2", + "f39713", + "e8e8e2", + "ec5b43", + "235476", + "b2a8a5", + "d6c3be", + "49b38b", + "fccf25", + "f59b34", + "375dfc", + "99e6de", + "27a463", + "554543", + "b19e00", + "d4a015", + "9f4b27", + "f9e8dd", + "6b7212", + "9d8e6e", + "4243f8", + "fa5e20", + "f82905", + "555353", + "876f69", + "410d66", + "552d1d", + "f71248", + "fee3f3", + "c16923", + "2b2834", + "0079fc", + "d31e14", + "f83001", + "8dd122", + "fffdf4", + "ffa21e", + "e4afa3", + "fbc311", + "aa940c", + "eedc00", + "fff006", + "9cb4b8", + "a38654", + "ae6c0a", + "2bb26b", + "e2c8c0", + "f89865", + "f86100", + "dcd8d3", + "049d43", + "d0aea9", + "f39d44", + "eeb78c", + "f9f5e9", + "5d3500", + "c3a199", + "aaa6a4", + "caa26a", + "fde7f5", + "fdf008", + "fdcef2", + "f681e6", + "018146", + "d19a54", + "9eb5e1", + "f5fcff", + "3f9323", + "00fcff", + "4a5358", + "fbc800", + "d596a6", + "ffb913", + "e9ba12", + "767c0e", + "f9f6d1", + "d29607", + "f8ce47", + "395ed1", + "ffc5f0", + "cbc1bc", + "d4cfc0" + ] + }, + "images": { + "glasses": [ + { + "filename": "glasses-hip-rose", + "data": "0x000b1710070300062001000620030001200202022301200100012002020223052002020223032002020223052002020223032002020223022002000120020202230120010001200202022301200300062001000620" + }, + { + "filename": "glasses-square-black-eyes-red", + "data": "0x000b17100703000623010006230300012302020264012301000123020202640523020202640323020202640223020001230202026401230100012302020264022302000123020202640123010001230202026401230300062301000623" + }, + { + "filename": "glasses-square-black-rgb", + "data": "0x000b1710070300062301000623030003230164022301000323016413230200012301650223015a01230100012301650223015a022302000623010006230300062301000623" + }, + { + "filename": "glasses-square-black", + "data": "0x000b171007030006230100062303000123020203230100012302020723020205230202042302000123020203230100012302020423020001230202032301000123020203230300062301000623" + }, + { + "filename": "glasses-square-blue-med-saturated", + "data": "0x000b17100703000643010006430300014302020223014301000143020202230543020202230343020202230243020001430202022301430100014302020223024302000143020202230143010001430202022301430300064301000643" + }, + { + "filename": "glasses-square-blue", + "data": "0x000b17100703000607010006070300010702020223010701000107020202230507020202230307020202230207020001070202022301070100010702020223020702000107020202230107010001070202022301070300060701000607" + }, + { + "filename": "glasses-square-frog-green", + "data": "0x000b171007030006bf010006bf030001bf0202022301bf010001bf0202022305bf0202022303bf0202022302bf020001bf0202022301bf010001bf0202022302bf020001bf0202022301bf010001bf0202022301bf030006bf010006bf" + }, + { + "filename": "glasses-square-fullblack", + "data": "0x000b1710070300062301000623030004230102012301000423010208230102062301020223020006230100072302000623010006230300062301000623" + }, + { + "filename": "glasses-square-green-blue-multi", + "data": "0x000b1710070300060f0100068b0300010f02020223010f0100018b02020223018b034a010f02020223010f014a018b02020223028b0200010f02020223010f0100018b02020223028b0200010f02020223010f0100018b02020223018b0300060f0100068b" + }, + { + "filename": "glasses-square-grey-light", + "data": "0x000b171007030006c7010006c7030001c70202022301c7010001c70202022305c70202022303c70202022302c7020001c70202022301c7010001c70202022302c7020001c70202022301c7010001c70202022301c7030006c7010006c7" + }, + { + "filename": "glasses-square-guava", + "data": "0x000b17100703000637010006370300013702020223013701000137020202230537020202230337020202230237020001370202022301370100013702020223023702000137020202230137010001370202022301370300063701000637" + }, + { + "filename": "glasses-square-honey", + "data": "0x000b171007030006dd010006dd030001dd0202022301dd010001dd0202022305dd0202022303dd0202022302dd020001dd0202022301dd010001dd0202022302dd020001dd0202022301dd010001dd0202022301dd030006dd010006dd" + }, + { + "filename": "glasses-square-magenta", + "data": "0x000b17100703000609010006090300010902020223010901000109020202230509020202230309020202230209020001090202022301090100010902020223020902000109020202230109010001090202022301090300060901000609" + }, + { + "filename": "glasses-square-orange", + "data": "0x000b17100703000614010006140300011402020223011401000114020202230514020202230314020202230214020001140202022301140100011402020223021402000114020202230114010001140202022301140300061401000614" + }, + { + "filename": "glasses-square-pink-purple-multi", + "data": "0x000b171007030006200100069a030001200202022301200100019a02020223019a036e0120020202230120016e019a02020223029a020001200202022301200100019a02020223029a020001200202022301200100019a02020223019a030006200100069a" + }, + { + "filename": "glasses-square-red", + "data": "0x000b17100703000624010006240300012402020223012401000124020202230524020202230324020202230224020001240202022301240100012402020223022402000124020202230124010001240202022301240300062401000624" + }, + { + "filename": "glasses-square-smoke", + "data": "0x000b17100703000659010006590300015902660223015901000159026602230559026602230359026602230259020001590266022301590100015902660223025902000159026602230159010001590266022301590300065901000659" + }, + { + "filename": "glasses-square-teal", + "data": "0x000b1710070300061c0100061c0300011c02020223011c0100011c02020223051c02020223031c02020223021c0200011c02020223011c0100011c02020223021c0200011c02020223011c0100011c02020223011c0300061c0100061c" + }, + { + "filename": "glasses-square-watermelon", + "data": "0x000b17100703000637010006370300013702020223013701000137020202230537020202230337020202230237020001370202022301370100013702020223023702000137020202230137010001370202022301370300063701000637" + }, + { + "filename": "glasses-square-yellow-orange-multi", + "data": "0x000b17100703000626010006130300012602020223012601000113020202230113034201260202022301260142011302020223011301260200012602020223012601000113020202230113012602000126020202230126010001130202022301130300062601000613" + }, + { + "filename": "glasses-square-yellow-saturated", + "data": "0x000b17100703000628010006280300012802020223012801000128020202230528020202230328020202230228020001280202022301280100012802020223022802000128020202230128010001280202022301280300062801000628" + } + ] + } +} diff --git a/packages/nouns-contracts/tasks/index.ts b/packages/nouns-contracts/tasks/index.ts index 7585fe0dbb..5c6d5e60fa 100644 --- a/packages/nouns-contracts/tasks/index.ts +++ b/packages/nouns-contracts/tasks/index.ts @@ -14,3 +14,4 @@ export * from './descriptor-v1-export-abi'; export * from './deploy-descriptorv2-and-propose-upgrade'; export * from './deploy-short-times'; export * from './deploy-and-configure-short-times'; +export * from './populate-descriptor-via-proposal'; diff --git a/packages/nouns-contracts/tasks/populate-descriptor-via-proposal.ts b/packages/nouns-contracts/tasks/populate-descriptor-via-proposal.ts new file mode 100644 index 0000000000..f7058c3b30 --- /dev/null +++ b/packages/nouns-contracts/tasks/populate-descriptor-via-proposal.ts @@ -0,0 +1,125 @@ +import { task } from 'hardhat/config'; +import { dataToDescriptorInput } from './utils'; +import { readFileSync } from 'fs'; + +// see image-data-example-for-populate-via-proposal.json for an example input file +task( + 'populate-descriptor-via-proposal', + 'Populates the descriptor with color palettes and Noun parts; accepts an input JSON with missing properies.', +) + .addParam('nounsDescriptor', 'The `NounsDescriptor` contract address') + .addParam('daoAddress', 'The `NounsDAOProxy` contract address') + .addParam('imageDataPath', 'The path to the image data JSON file') + .setAction(async ({ nounsDescriptor, daoAddress, imageDataPath }, { ethers }) => { + const ImageData = JSON.parse(readFileSync(imageDataPath, 'utf-8')); + + const targets = []; + const values = []; + const signatures = []; + const calldatas = []; + + if (ImageData.bgcolors) { + targets.push(nounsDescriptor); + values.push(0); + signatures.push('addManyBackgrounds(string[])'); + calldatas.push(ethers.utils.defaultAbiCoder.encode(['string[]'], [ImageData.bgcolors])); + } + + if (ImageData.palettes) { + for (const [index, colors] of Object.entries(ImageData.palettes)) { + targets.push(nounsDescriptor); + values.push(0); + signatures.push('setPalette(uint8,bytes)'); + calldatas.push( + ethers.utils.defaultAbiCoder.encode( + ['uint8', 'bytes'], + [parseInt(index), `0x000000${(colors as string[]).join('')}`], + ), + ); + } + } + + if (ImageData.images) { + const { bodies, accessories, heads, glasses } = ImageData.images; + + if (bodies) { + const bodiesPage = dataToDescriptorInput( + (bodies as [{ data: string }]).map(({ data }) => data), + ); + + targets.push(nounsDescriptor); + values.push(0); + signatures.push('addBodies(bytes,uint80,uint16)'); + calldatas.push( + ethers.utils.defaultAbiCoder.encode( + ['bytes', 'uint80', 'uint16'], + [bodiesPage.encodedCompressed, bodiesPage.originalLength, bodiesPage.itemCount], + ), + ); + } + + if (heads) { + const headsPage = dataToDescriptorInput( + (heads as [{ data: string }]).map(({ data }) => data), + ); + + targets.push(nounsDescriptor); + values.push(0); + signatures.push('addHeads(bytes,uint80,uint16)'); + calldatas.push( + ethers.utils.defaultAbiCoder.encode( + ['bytes', 'uint80', 'uint16'], + [headsPage.encodedCompressed, headsPage.originalLength, headsPage.itemCount], + ), + ); + } + + if (glasses) { + const glassesPage = dataToDescriptorInput( + (glasses as [{ data: string }]).map(({ data }) => data), + ); + + targets.push(nounsDescriptor); + values.push(0); + signatures.push('addGlasses(bytes,uint80,uint16)'); + calldatas.push( + ethers.utils.defaultAbiCoder.encode( + ['bytes', 'uint80', 'uint16'], + [glassesPage.encodedCompressed, glassesPage.originalLength, glassesPage.itemCount], + ), + ); + } + + if (accessories) { + const accessoriesPage = dataToDescriptorInput( + (accessories as [{ data: string }]).map(({ data }) => data), + ); + + targets.push(nounsDescriptor); + values.push(0); + signatures.push('addAccessories(bytes,uint80,uint16)'); + calldatas.push( + ethers.utils.defaultAbiCoder.encode( + ['bytes', 'uint80', 'uint16'], + [ + accessoriesPage.encodedCompressed, + accessoriesPage.originalLength, + accessoriesPage.itemCount, + ], + ), + ); + } + } + + const dao = (await ethers.getContractFactory('NounsDAOLogicV1')).attach(daoAddress); + const propTx = await dao.propose( + targets, + values, + signatures, + calldatas, + 'Adding art to NounsDescriptorV2.', + ); + await propTx.wait(); + + console.log('Proposal submitted!'); + }); From e0336c9279a30e153119d7c7d4fd6ee3088bf33e Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 6 Jul 2022 19:11:00 +0300 Subject: [PATCH 069/116] cleanup --- packages/nouns-contracts/tasks/populate-descriptor.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/nouns-contracts/tasks/populate-descriptor.ts b/packages/nouns-contracts/tasks/populate-descriptor.ts index 5fee9ae3df..428c1f73cd 100644 --- a/packages/nouns-contracts/tasks/populate-descriptor.ts +++ b/packages/nouns-contracts/tasks/populate-descriptor.ts @@ -2,6 +2,9 @@ import { task, types } from 'hardhat/config'; import ImageData from '../files/image-data_v2.json'; import { dataToDescriptorInput } from './utils'; +// sometimes block limits are below 30M, taking a safety buffer to avoid the exceeding gas limit error +const maxGas = { gasLimit: 29_000_000 }; + task('populate-descriptor', 'Populates the descriptor with color palettes and Noun parts') .addOptionalParam( 'nftDescriptor', @@ -38,25 +41,25 @@ task('populate-descriptor', 'Populates the descriptor with color palettes and No bodiesPage.encodedCompressed, bodiesPage.originalLength, bodiesPage.itemCount, - { gasLimit: 30_000_000 }, + maxGas, ); await descriptorContract.addHeads( headsPage.encodedCompressed, headsPage.originalLength, headsPage.itemCount, - { gasLimit: 30_000_000 }, + maxGas, ); await descriptorContract.addGlasses( glassesPage.encodedCompressed, glassesPage.originalLength, glassesPage.itemCount, - { gasLimit: 30_000_000 }, + maxGas, ); await descriptorContract.addAccessories( accessoriesPage.encodedCompressed, accessoriesPage.originalLength, accessoriesPage.itemCount, - { gasLimit: 30_000_000 }, + maxGas, ); console.log('Descriptor populated with palettes and parts.'); From 62ac5155a279bda7fd2e81d5b7dd90694a591cf1 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 6 Jul 2022 19:13:25 +0300 Subject: [PATCH 070/116] increase node heap max memory again with the previous 4GB tests passed but coverage ran out of memory hoping this setting will suffice --- .github/workflows/contracts.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/contracts.yaml b/.github/workflows/contracts.yaml index a701636aca..c924f6bec1 100644 --- a/.github/workflows/contracts.yaml +++ b/.github/workflows/contracts.yaml @@ -12,7 +12,7 @@ on: - '**' env: - NODE_OPTIONS: --max_old_space_size=4096 + NODE_OPTIONS: --max_old_space_size=5120 jobs: build_and_test: From 2f95961aa13c44965ad97480e2263ac701c7620e Mon Sep 17 00:00:00 2001 From: eladmallel Date: Wed, 6 Jul 2022 19:55:44 +0300 Subject: [PATCH 071/116] bump the descriptor v2 test timeout again 500 seconds wasn't enough for the coverage test trying a 20-minute timeout hoping to get the build working! --- packages/nouns-contracts/test/descriptorV2.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nouns-contracts/test/descriptorV2.test.ts b/packages/nouns-contracts/test/descriptorV2.test.ts index 11d73e3ed8..0447b21cf7 100644 --- a/packages/nouns-contracts/test/descriptorV2.test.ts +++ b/packages/nouns-contracts/test/descriptorV2.test.ts @@ -86,7 +86,7 @@ describe('NounsDescriptorV2', () => { expect(name).to.equal('Noun 0'); expect(description).to.equal('Noun 0 is a member of the Nouns DAO'); expect(image).to.not.be.undefined; - }).timeout(500_000); + }).timeout(1_000_000); // Unskip this test to validate the encoding of all parts. It ensures that no parts revert when building the token URI. // This test also outputs a parts.html file, which can be visually inspected. From 68917fa24bb10f7650b9c2b20d01f8d2790df3c1 Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Thu, 7 Jul 2022 12:34:46 +0200 Subject: [PATCH 072/116] Revert "unskip descriptor test that failed bc of low JS heap" This reverts commit f4c1e4a86d011dc8efbc7348d05fbd204496f4c2. --- packages/nouns-contracts/test/descriptorV2.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/nouns-contracts/test/descriptorV2.test.ts b/packages/nouns-contracts/test/descriptorV2.test.ts index 0447b21cf7..30aec26024 100644 --- a/packages/nouns-contracts/test/descriptorV2.test.ts +++ b/packages/nouns-contracts/test/descriptorV2.test.ts @@ -66,7 +66,8 @@ describe('NounsDescriptorV2', () => { expect(tokenUri).to.equal(`${BASE_URI}0`); }); - it('should generate valid token uri metadata when data uris are enabled', async () => { + // Skipping until we resolve the CI memory issue + it.skip('should generate valid token uri metadata when data uris are enabled', async () => { const tokenUri = await nounsDescriptor.tokenURI( 0, { From 0780d4e9f5088652a0b80bdefe639308cdcc2350 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Thu, 7 Jul 2022 15:09:32 +0300 Subject: [PATCH 073/116] only skipping the URI test when using coverage it works fine under regular testing it keeps failing under coverage due to timeouts and memory issues --- packages/nouns-contracts/.solcover.js | 4 ++++ packages/nouns-contracts/test/descriptorV2.test.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/nouns-contracts/.solcover.js b/packages/nouns-contracts/.solcover.js index 40aa1cd5d6..7607b31b33 100644 --- a/packages/nouns-contracts/.solcover.js +++ b/packages/nouns-contracts/.solcover.js @@ -4,4 +4,8 @@ module.exports = { 'test/WETH.sol', ], configureYulOptimizer: true, + mocha: { + grep: "@skip-on-coverage", // Find everything with this tag + invert: true // Run the grep's inverse set. + } }; diff --git a/packages/nouns-contracts/test/descriptorV2.test.ts b/packages/nouns-contracts/test/descriptorV2.test.ts index 30aec26024..7b35f9c8f2 100644 --- a/packages/nouns-contracts/test/descriptorV2.test.ts +++ b/packages/nouns-contracts/test/descriptorV2.test.ts @@ -67,7 +67,7 @@ describe('NounsDescriptorV2', () => { }); // Skipping until we resolve the CI memory issue - it.skip('should generate valid token uri metadata when data uris are enabled', async () => { + it('should generate valid token uri metadata when data uris are enabled [ @skip-on-coverage ]', async () => { const tokenUri = await nounsDescriptor.tokenURI( 0, { From 5beda4293a42db19be48192904f6c29271fbaa0f Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Fri, 8 Jul 2022 14:51:31 +0200 Subject: [PATCH 074/116] added test minter which uses descriptor v2 this is to mint some test nfts and see that they look ok on marketplaces also removed the proposal part from deploy-descriptor-v2 task because it will be in 2 steps --- .../contracts/test/NounsTestMinter.sol | 20 +++++++ .../contracts/test/NounsTokenHarness.sol | 24 +++++++++ ...ose-upgrade.ts => deploy-descriptor-v2.ts} | 53 +++++++++---------- .../tasks/deploy-test-minter.ts | 35 ++++++++++++ packages/nouns-contracts/tasks/index.ts | 3 +- .../tasks/populate-descriptor.ts | 7 --- 6 files changed, 105 insertions(+), 37 deletions(-) create mode 100644 packages/nouns-contracts/contracts/test/NounsTestMinter.sol create mode 100644 packages/nouns-contracts/contracts/test/NounsTokenHarness.sol rename packages/nouns-contracts/tasks/{deploy-descriptorv2-and-propose-upgrade.ts => deploy-descriptor-v2.ts} (65%) create mode 100644 packages/nouns-contracts/tasks/deploy-test-minter.ts diff --git a/packages/nouns-contracts/contracts/test/NounsTestMinter.sol b/packages/nouns-contracts/contracts/test/NounsTestMinter.sol new file mode 100644 index 0000000000..5198a5b2f7 --- /dev/null +++ b/packages/nouns-contracts/contracts/test/NounsTestMinter.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.15; + +import { INounsToken } from '../interfaces/INounsToken.sol'; +import { NounsTokenHarness } from './NounsTokenHarness.sol'; + +contract NounsTestMinter { + NounsTokenHarness public nouns; + + constructor(NounsTokenHarness nouns_) { + nouns = nouns_; + } + + function mintMany(address to, uint256 amount) public { + for (uint256 i = 0; i < amount; i++) { + nouns.mintTo(to); + } + } +} diff --git a/packages/nouns-contracts/contracts/test/NounsTokenHarness.sol b/packages/nouns-contracts/contracts/test/NounsTokenHarness.sol new file mode 100644 index 0000000000..f49d4a5d28 --- /dev/null +++ b/packages/nouns-contracts/contracts/test/NounsTokenHarness.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.15; + +import { NounsToken } from '../NounsToken.sol'; +import { INounsDescriptorMinimal } from '../interfaces/INounsDescriptorMinimal.sol'; +import { INounsSeeder } from '../interfaces/INounsSeeder.sol'; +import { IProxyRegistry } from '../external/opensea/IProxyRegistry.sol'; + +contract NounsTokenHarness is NounsToken { + uint256 public currentNounId; + + constructor( + address noundersDAO, + address minter, + INounsDescriptorMinimal descriptor, + INounsSeeder seeder, + IProxyRegistry proxyRegistry + ) NounsToken(noundersDAO, minter, descriptor, seeder, proxyRegistry) {} + + function mintTo(address to) public { + _mintTo(to, currentNounId++); + } +} diff --git a/packages/nouns-contracts/tasks/deploy-descriptorv2-and-propose-upgrade.ts b/packages/nouns-contracts/tasks/deploy-descriptor-v2.ts similarity index 65% rename from packages/nouns-contracts/tasks/deploy-descriptorv2-and-propose-upgrade.ts rename to packages/nouns-contracts/tasks/deploy-descriptor-v2.ts index fc8831579f..544c20ae5f 100644 --- a/packages/nouns-contracts/tasks/deploy-descriptorv2-and-propose-upgrade.ts +++ b/packages/nouns-contracts/tasks/deploy-descriptor-v2.ts @@ -2,14 +2,12 @@ import { task } from 'hardhat/config'; import { ContractName, DeployedContract } from './types'; import { printContractsTable } from './utils'; -task( - 'deploy-descriptorv2-and-propose-upgrade', - 'Deploy NounsDescriptorV2, populate it with art and submit an upgrade proposal to the DAO', -) - .addParam('tokenAddress', 'The NounsToken address, used in the descriptor upgrade proposal') - .addParam('daoAddress', 'The DAO proxy address, where the upgrade proposal is submitted') - .addParam('executorAddress', "The DAO's deployed timelock address") - .setAction(async ({ executorAddress, daoAddress, tokenAddress }, { ethers, run }) => { +async function delay(seconds: number) { + return new Promise(resolve => setTimeout(resolve, 1000 * seconds)); +} + +task('deploy-descriptor-v2', 'Deploy NounsDescriptorV2 & populate it with art').setAction( + async ({}, { ethers, run, network }) => { const contracts: Record = {} as Record< ContractName, DeployedContract @@ -73,15 +71,16 @@ task( libraries: {}, }; + console.log('Waiting for contracts to be deployed'); + for (const c of Object.values(contracts)) { + console.log(`Waiting for ${c.name} to be deployed`); + await c.instance.deployTransaction.wait(); + console.log('Done'); + } + console.log('Deployment complete:'); printContractsTable(contracts); - console.log('Verifying contracts on Etherscan...'); - await run('verify-etherscan', { - contracts, - }); - console.log('Verify complete.'); - console.log('Populating Descriptor...'); await run('populate-descriptor', { nftDescriptor: contracts.NFTDescriptorV2.address, @@ -89,19 +88,15 @@ task( }); console.log('Population complete.'); - console.log('Transferring ownership of the descriptor to the executor...'); - await contracts.NounsDescriptorV2.instance!.transferOwnership(executorAddress); - console.log('Transfer complete.'); + if (network.name !== 'localhost') { + console.log('Waiting 1 minute before verifying contracts on Etherscan'); + await delay(60); - console.log('Submitting the upgrade proposal to the DAO...'); - const dao = (await ethers.getContractFactory('NounsDAOLogicV1', deployer)).attach(daoAddress); - const propTx = await dao.propose( - [tokenAddress], - [0], - ['setDescriptor(address)'], - [contracts.NounsDescriptorV2.address], - 'Upgrade NounsToken to use DescriptorV2.', - ); - await propTx.wait(); - console.log('Submission complete.'); - }); + console.log('Verifying contracts on Etherscan...'); + await run('verify-etherscan', { + contracts, + }); + console.log('Verify complete.'); + } + }, +); diff --git a/packages/nouns-contracts/tasks/deploy-test-minter.ts b/packages/nouns-contracts/tasks/deploy-test-minter.ts new file mode 100644 index 0000000000..68f6c2ec60 --- /dev/null +++ b/packages/nouns-contracts/tasks/deploy-test-minter.ts @@ -0,0 +1,35 @@ +import { task } from 'hardhat/config'; + +task('deploy-test-minter', 'Deploy NounsTestMinter given a descriptor') + .addParam('descriptorAddress', 'Address of a deployed descriptor contractor') + .addParam('seederAddress', 'Address of a deployed seeder contract') + .setAction(async ({ descriptorAddress, seederAddress }, { ethers, run, network }) => { + const [deployer] = await ethers.getSigners(); + console.log(`Deploying from address ${deployer.address}`); + + const nonce = await deployer.getTransactionCount(); + const expectedTokenAddress = ethers.utils.getContractAddress({ + from: deployer.address, + nonce: nonce + 1, + }); + + const proxyRegistryAddress = '0xa5409ec958c83c3f309868babaca7c86dcb077c1'; + + const minter = await ( + await ethers.getContractFactory('NounsTestMinter', deployer) + ).deploy(expectedTokenAddress); + console.log(`NounsTestMinter deployed to ${minter.address}`); + + const token = await ( + await ethers.getContractFactory('NounsTokenHarness', deployer) + ).deploy( + deployer.address, + minter.address, + descriptorAddress, + seederAddress, + proxyRegistryAddress, + ); + console.log(`NounsTokenHarness deployed to: ${token.address}`); + + console.log('Done'); + }); diff --git a/packages/nouns-contracts/tasks/index.ts b/packages/nouns-contracts/tasks/index.ts index 5c6d5e60fa..d67477730a 100644 --- a/packages/nouns-contracts/tasks/index.ts +++ b/packages/nouns-contracts/tasks/index.ts @@ -11,7 +11,8 @@ export * from './verify-etherscan'; export * from './update-configs'; export * from './descriptor-art-to-console'; export * from './descriptor-v1-export-abi'; -export * from './deploy-descriptorv2-and-propose-upgrade'; +export * from './deploy-descriptor-v2'; export * from './deploy-short-times'; export * from './deploy-and-configure-short-times'; export * from './populate-descriptor-via-proposal'; +export * from './deploy-test-minter'; diff --git a/packages/nouns-contracts/tasks/populate-descriptor.ts b/packages/nouns-contracts/tasks/populate-descriptor.ts index 428c1f73cd..784d62cae5 100644 --- a/packages/nouns-contracts/tasks/populate-descriptor.ts +++ b/packages/nouns-contracts/tasks/populate-descriptor.ts @@ -2,9 +2,6 @@ import { task, types } from 'hardhat/config'; import ImageData from '../files/image-data_v2.json'; import { dataToDescriptorInput } from './utils'; -// sometimes block limits are below 30M, taking a safety buffer to avoid the exceeding gas limit error -const maxGas = { gasLimit: 29_000_000 }; - task('populate-descriptor', 'Populates the descriptor with color palettes and Noun parts') .addOptionalParam( 'nftDescriptor', @@ -41,25 +38,21 @@ task('populate-descriptor', 'Populates the descriptor with color palettes and No bodiesPage.encodedCompressed, bodiesPage.originalLength, bodiesPage.itemCount, - maxGas, ); await descriptorContract.addHeads( headsPage.encodedCompressed, headsPage.originalLength, headsPage.itemCount, - maxGas, ); await descriptorContract.addGlasses( glassesPage.encodedCompressed, glassesPage.originalLength, glassesPage.itemCount, - maxGas, ); await descriptorContract.addAccessories( accessoriesPage.encodedCompressed, accessoriesPage.originalLength, accessoriesPage.itemCount, - maxGas, ); console.log('Descriptor populated with palettes and parts.'); From 8b16ca7f9735789d43ffbb753cb7b1465a9266f9 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Sun, 10 Jul 2022 13:05:41 +0300 Subject: [PATCH 075/116] add setPalettePointer function --- .../nouns-contracts/contracts/NounsArt.sol | 15 ++++++ .../contracts/NounsDescriptorV2.sol | 13 +++++ .../contracts/interfaces/INounsArt.sol | 2 + .../interfaces/INounsDescriptorV2.sol | 2 + .../test/foundry/NounsArt.t.sol | 47 ++++++++++++++++++- .../test/foundry/NounsDescriptorV2.t.sol | 20 ++++++++ 6 files changed, 98 insertions(+), 1 deletion(-) diff --git a/packages/nouns-contracts/contracts/NounsArt.sol b/packages/nouns-contracts/contracts/NounsArt.sol index ceb3b26d64..09bcd84bda 100644 --- a/packages/nouns-contracts/contracts/NounsArt.sol +++ b/packages/nouns-contracts/contracts/NounsArt.sol @@ -238,6 +238,21 @@ contract NounsArt is INounsArt { emit GlassesAdded(imageCount); } + /** + * @notice Update a single color palette. This function can be used to + * add a new color palette or update an existing palette. This function does not check for data length validity + * (len <= 768, len % 3 == 0). + * @param paletteIndex the identifier of this palette + * @param pointer the address of the contract holding the palette bytes. every 3 bytes represent an RGB color. + * max length: 256 * 3 = 768. + * @dev This function can only be called by the descriptor. + */ + function setPalettePointer(uint8 paletteIndex, address pointer) external override onlyDescriptor { + palettesPointers[paletteIndex] = pointer; + + emit PaletteSet(paletteIndex); + } + /** * @notice Add a batch of body images from an existing storage contract. * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data diff --git a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol index 47d6682866..feeec03e2b 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol @@ -201,6 +201,19 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { art.addGlasses(encodedCompressed, decompressedLength, imageCount); } + /** + * @notice Update a single color palette. This function can be used to + * add a new color palette or update an existing palette. This function does not check for data length validity + * (len <= 768, len % 3 == 0). + * @param paletteIndex the identifier of this palette + * @param pointer the address of the contract holding the palette bytes. every 3 bytes represent an RGB color. + * max length: 256 * 3 = 768. + * @dev This function can only be called by the owner when not locked. + */ + function setPalettePointer(uint8 paletteIndex, address pointer) external override onlyOwner whenPartsNotLocked { + art.setPalettePointer(paletteIndex, pointer); + } + /** * @notice Add a batch of body images from an existing storage contract. * @param pointer the address of a contract where the image batch was stored using SSTORE2. The data diff --git a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol index 7f14ca2a93..51af7d5afe 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol @@ -109,6 +109,8 @@ interface INounsArt { uint16 imageCount ) external; + function setPalettePointer(uint8 paletteIndex, address pointer) external; + function addAccessoriesFromPointer( address pointer, uint80 decompressedLength, diff --git a/packages/nouns-contracts/contracts/interfaces/INounsDescriptorV2.sol b/packages/nouns-contracts/contracts/interfaces/INounsDescriptorV2.sol index f8c2269714..1276814fae 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsDescriptorV2.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsDescriptorV2.sol @@ -95,6 +95,8 @@ interface INounsDescriptorV2 is INounsDescriptorMinimal { uint16 imageCount ) external; + function setPalettePointer(uint8 paletteIndex, address pointer) external; + function addBodiesFromPointer( address pointer, uint80 decompressedLength, diff --git a/packages/nouns-contracts/test/foundry/NounsArt.t.sol b/packages/nouns-contracts/test/foundry/NounsArt.t.sol index 222d9046a1..5a65b2af93 100644 --- a/packages/nouns-contracts/test/foundry/NounsArt.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsArt.t.sol @@ -118,7 +118,7 @@ contract NounsArtTest is Test, DescriptorHelpers { } /// - /// setPalette, palettes, palettesPointers + /// setPalette, palettes, palettesPointers, setPalettePointer /// function testPalettesRevertsGivenNoArt() public { @@ -131,6 +131,12 @@ contract NounsArtTest is Test, DescriptorHelpers { art.setPalette(0, hex'ffffff'); } + function testSetPalettePointerRevertsIfSenderNotDescriptor() public { + address pointer = SSTORE2.write(hex'ffffff000000'); + vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); + art.setPalettePointer(0, pointer); + } + function testSetPaletteWorks() public { vm.expectEmit(true, true, true, true); emit PaletteSet(0); @@ -151,6 +157,26 @@ contract NounsArtTest is Test, DescriptorHelpers { assertEq(SSTORE2.read(art.palettesPointers(1)), palette1); } + function testSetPalettePointerWorks() public { + vm.expectEmit(true, true, true, true); + emit PaletteSet(0); + vm.expectEmit(true, true, true, true); + emit PaletteSet(1); + + address pointer0 = SSTORE2.write(hex'ffffffc5b9a1'); + address pointer1 = SSTORE2.write(hex'cfc2ab63a0f9'); + vm.startPrank(descriptor); + art.setPalettePointer(0, pointer0); + art.setPalettePointer(1, pointer1); + vm.stopPrank(); + + assertEq(art.palettes(0), hex'ffffffc5b9a1'); + assertEq(art.palettes(1), hex'cfc2ab63a0f9'); + + assertEq(art.palettesPointers(0), pointer0); + assertEq(art.palettesPointers(1), pointer1); + } + function testSetPaletteUpdatesAnExistingPalette() public { bytes memory paletteV1 = hex'ffffffc5b9a1'; bytes memory paletteV2 = hex'cfc2ab63a0f9'; @@ -170,6 +196,25 @@ contract NounsArtTest is Test, DescriptorHelpers { assertEq(SSTORE2.read(art.palettesPointers(0)), paletteV2); } + function testSetPalettePointerUpdatesAnExistingPalette() public { + address paletteV1Pointer = SSTORE2.write(hex'ffffffc5b9a1'); + address paletteV2Pointer = SSTORE2.write(hex'cfc2ab63a0f9'); + + vm.expectEmit(true, true, true, true); + emit PaletteSet(0); + vm.prank(descriptor); + art.setPalettePointer(0, paletteV1Pointer); + assertEq(art.palettes(0), hex'ffffffc5b9a1'); + assertEq(art.palettesPointers(0), paletteV1Pointer); + + vm.expectEmit(true, true, true, true); + emit PaletteSet(0); + vm.prank(descriptor); + art.setPalettePointer(0, paletteV2Pointer); + assertEq(art.palettes(0), hex'cfc2ab63a0f9'); + assertEq(art.palettesPointers(0), paletteV2Pointer); + } + function testCannotSetEmptyPalette() public { vm.prank(descriptor); vm.expectRevert(INounsArt.EmptyPalette.selector); diff --git a/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol b/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol index 46a23484eb..56b3de5aed 100644 --- a/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol @@ -185,12 +185,32 @@ contract NounsDescriptorV2Test is Test { descriptor.setPalette(1, '654321'); } + function testSetPalettePointerUsesArt() public { + vm.expectCall(address(art), abi.encodeCall(art.setPalettePointer, (0, address(42)))); + descriptor.setPalettePointer(0, address(42)); + + vm.expectCall(address(art), abi.encodeCall(art.setPalettePointer, (1, address(1337)))); + descriptor.setPalettePointer(1, address(1337)); + } + function testCannotSetPaletteWhenPartsLocked() public { descriptor.lockParts(); vm.expectRevert(bytes('Parts are locked')); descriptor.setPalette(0, '000000'); } + function testCannotSetPalettePointerWhenPartsLocked() public { + descriptor.lockParts(); + vm.expectRevert(bytes('Parts are locked')); + descriptor.setPalettePointer(0, address(42)); + } + + function testCannotSetPalettePointerIfNotOwner() public { + vm.prank(address(1)); + vm.expectRevert(bytes('Ownable: caller is not the owner')); + descriptor.setPalettePointer(0, address(42)); + } + function testAddBodiesUsesArt() public { bytes memory someBytes = 'some bytes'; uint80 decompressedLen = 123; From a015e8a51b2b08ff0fdb45043aeba484e19eaba3 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Sun, 10 Jul 2022 13:09:44 +0300 Subject: [PATCH 076/116] add some dev natspec --- packages/nouns-contracts/contracts/NounsDescriptorV2.sol | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol index feeec03e2b..8906429447 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol @@ -136,6 +136,7 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { * add a new color palette or update an existing palette. * @param paletteIndex the identifier of this palette * @param palette byte array of colors. every 3 bytes represent an RGB color. max length: 256 * 3 = 768 + * @dev This function can only be called by the owner when not locked. */ function setPalette(uint8 paletteIndex, bytes calldata palette) external override onlyOwner whenPartsNotLocked { art.setPalette(paletteIndex, palette); @@ -147,6 +148,7 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { * and finally compressing it using deflate. * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. * @param imageCount the number of images in this batch; used when searching for images among batches. + * @dev This function can only be called by the owner when not locked. */ function addBodies( bytes calldata encodedCompressed, @@ -162,6 +164,7 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { * and finally compressing it using deflate. * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. * @param imageCount the number of images in this batch; used when searching for images among batches. + * @dev This function can only be called by the owner when not locked. */ function addAccessories( bytes calldata encodedCompressed, @@ -177,6 +180,7 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { * and finally compressing it using deflate. * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. * @param imageCount the number of images in this batch; used when searching for images among batches. + * @dev This function can only be called by the owner when not locked. */ function addHeads( bytes calldata encodedCompressed, @@ -192,6 +196,7 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { * and finally compressing it using deflate. * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. * @param imageCount the number of images in this batch; used when searching for images among batches. + * @dev This function can only be called by the owner when not locked. */ function addGlasses( bytes calldata encodedCompressed, @@ -221,6 +226,7 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. * @param imageCount the number of images in this batch; used when searching for images among batches. + * @dev This function can only be called by the owner when not locked. */ function addBodiesFromPointer( address pointer, @@ -237,6 +243,7 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. * @param imageCount the number of images in this batch; used when searching for images among batches. + * @dev This function can only be called by the owner when not locked. */ function addAccessoriesFromPointer( address pointer, @@ -253,6 +260,7 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. * @param imageCount the number of images in this batch; used when searching for images among batches. + * @dev This function can only be called by the owner when not locked. */ function addHeadsFromPointer( address pointer, @@ -269,6 +277,7 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { * RLE-encoded images, abi encoding it as a bytes array, and finally compressing it using deflate. * @param decompressedLength the size in bytes the images bytes were prior to compression; required input for Inflate. * @param imageCount the number of images in this batch; used when searching for images among batches. + * @dev This function can only be called by the owner when not locked. */ function addGlassesFromPointer( address pointer, From dd10cbdae2f73767381d5f06f092c651eb5d886d Mon Sep 17 00:00:00 2001 From: eladmallel Date: Sun, 10 Jul 2022 13:13:15 +0300 Subject: [PATCH 077/116] add ownable tests to descriptor v2 functions --- .../test/foundry/NounsDescriptorV2.t.sol | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol b/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol index 56b3de5aed..caf937720a 100644 --- a/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol @@ -225,6 +225,12 @@ contract NounsDescriptorV2Test is Test { descriptor.addBodies('00', 1, 1); } + function testCannotAddBodiesIfNotOwner() public { + vm.prank(address(1)); + vm.expectRevert(bytes('Ownable: caller is not the owner')); + descriptor.addBodies('00', 1, 1); + } + function testAddAccessoriesUsesArt() public { bytes memory someBytes = 'some bytes'; uint80 decompressedLen = 123; @@ -239,6 +245,12 @@ contract NounsDescriptorV2Test is Test { descriptor.addAccessories('00', 1, 1); } + function testCannotAddAccessoriesIfNotOwner() public { + vm.prank(address(1)); + vm.expectRevert(bytes('Ownable: caller is not the owner')); + descriptor.addAccessories('00', 1, 1); + } + function testAddHeadsUsesArt() public { bytes memory someBytes = 'some bytes'; uint80 decompressedLen = 123; @@ -253,6 +265,12 @@ contract NounsDescriptorV2Test is Test { descriptor.addHeads('00', 1, 1); } + function testCannotAddHeadsIfNotOwner() public { + vm.prank(address(1)); + vm.expectRevert(bytes('Ownable: caller is not the owner')); + descriptor.addHeads('00', 1, 1); + } + function testAddGlassesUsesArt() public { bytes memory someBytes = 'some bytes'; uint80 decompressedLen = 123; @@ -267,6 +285,12 @@ contract NounsDescriptorV2Test is Test { descriptor.addGlasses('00', 1, 1); } + function testCannotAddGlassesIfNotOwner() public { + vm.prank(address(1)); + vm.expectRevert(bytes('Ownable: caller is not the owner')); + descriptor.addGlasses('00', 1, 1); + } + function testAddBodiesFromPointerUsesArt() public { address somePointer = address(1337); uint80 decompressedLen = 123; @@ -284,6 +308,12 @@ contract NounsDescriptorV2Test is Test { descriptor.addBodiesFromPointer(address(1337), 1, 1); } + function testCannotAddBodiesFromPointerIfNotOwner() public { + vm.prank(address(1)); + vm.expectRevert(bytes('Ownable: caller is not the owner')); + descriptor.addBodiesFromPointer(address(1337), 1, 1); + } + function testAddAccessoriesFromPointerUsesArt() public { address somePointer = address(1337); uint80 decompressedLen = 123; @@ -301,6 +331,12 @@ contract NounsDescriptorV2Test is Test { descriptor.addAccessoriesFromPointer(address(1337), 1, 1); } + function testCannotAddAccessoriesFromPointerIfNotOwner() public { + vm.prank(address(1)); + vm.expectRevert(bytes('Ownable: caller is not the owner')); + descriptor.addAccessoriesFromPointer(address(1337), 1, 1); + } + function testAddHeadsFromPointerUsesArt() public { address somePointer = address(1337); uint80 decompressedLen = 123; @@ -318,6 +354,12 @@ contract NounsDescriptorV2Test is Test { descriptor.addHeadsFromPointer(address(1337), 1, 1); } + function testCannotAddHeadsFromPointerIfNotOwner() public { + vm.prank(address(1)); + vm.expectRevert(bytes('Ownable: caller is not the owner')); + descriptor.addHeadsFromPointer(address(1337), 1, 1); + } + function testAddGlassesFromPointerUsesArt() public { address somePointer = address(1337); uint80 decompressedLen = 123; @@ -335,6 +377,12 @@ contract NounsDescriptorV2Test is Test { descriptor.addGlassesFromPointer(address(1337), 1, 1); } + function testCannotAddGlassesFromPointerIfNotOwner() public { + vm.prank(address(1)); + vm.expectRevert(bytes('Ownable: caller is not the owner')); + descriptor.addGlassesFromPointer(address(1337), 1, 1); + } + function testBackgroundsUsesArt() public { vm.mockCall( address(art), From 9fda3f8a159dba098d3a542b7545a23650812fb6 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Sun, 10 Jul 2022 13:31:49 +0300 Subject: [PATCH 078/116] descriptorv2: add a function to set art's pendingDescriptor --- .../nouns-contracts/contracts/NounsDescriptorV2.sol | 9 +++++++++ .../test/foundry/NounsDescriptorV2.t.sol | 11 +++++++++++ 2 files changed, 20 insertions(+) diff --git a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol index 8906429447..0028cf34ec 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol @@ -80,6 +80,15 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { emit RendererUpdated(_renderer); } + /** + * @notice Set the art contract's `pendingDescriptor`. + * @param pendingDescriptor the address to set. + * @dev Only callable by the owner. + */ + function setArtDescriptor(address pendingDescriptor) external onlyOwner { + art.setDescriptor(pendingDescriptor); + } + /** * @notice Get the number of available Noun `backgrounds`. */ diff --git a/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol b/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol index caf937720a..e4710d29f4 100644 --- a/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol @@ -56,6 +56,17 @@ contract NounsDescriptorV2Test is Test { assertEq(address(descriptor.renderer()), address(2)); } + function testCannotSetArtDescriptorIfNotOwner() public { + vm.prank(address(1)); + vm.expectRevert(bytes('Ownable: caller is not the owner')); + descriptor.setArtDescriptor(address(2)); + } + + function testSetArtDescriptorUsesArt() public { + vm.expectCall(address(art), abi.encodeCall(art.setDescriptor, address(42))); + descriptor.setArtDescriptor(address(42)); + } + function testDataURIEnabledByDefault() public { assertEq(descriptor.isDataURIEnabled(), true); } From 5840d969e1636f889340fffd7522cca3356b6a60 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Sun, 10 Jul 2022 13:41:07 +0300 Subject: [PATCH 079/116] art: change setDescriptor to single-step per CR since this would happen as part of a proposal, we expect sufficient diligence such that a two-step process is unnecessary --- .../nouns-contracts/contracts/NounsArt.sol | 17 ++--------- .../contracts/interfaces/INounsArt.sol | 6 +--- .../test/foundry/NounsArt.t.sol | 29 ++++--------------- 3 files changed, 9 insertions(+), 43 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsArt.sol b/packages/nouns-contracts/contracts/NounsArt.sol index 09bcd84bda..0f25cbf5c2 100644 --- a/packages/nouns-contracts/contracts/NounsArt.sol +++ b/packages/nouns-contracts/contracts/NounsArt.sol @@ -65,22 +65,9 @@ contract NounsArt is INounsArt { * by calling `confirmDescriptor`. * @dev This function can only be called by the current descriptor. */ - function setDescriptor(address _pendingDescriptor) external override onlyDescriptor { - pendingDescriptor = _pendingDescriptor; - } - - /** - * @notice Confirm the pending descriptor. - * @dev This function can only be called by the pending descriptor. - */ - function confirmDescriptor() external override { - if (msg.sender != pendingDescriptor) { - revert SenderIsNotPendingDescriptor(); - } - + function setDescriptor(address _descriptor) external override onlyDescriptor { address oldDescriptor = descriptor; - descriptor = pendingDescriptor; - delete pendingDescriptor; + descriptor = _descriptor; emit DescriptorUpdated(oldDescriptor, descriptor); } diff --git a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol index 51af7d5afe..eee9f3a967 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol @@ -22,8 +22,6 @@ import { Inflate } from '../libs/Inflate.sol'; interface INounsArt { error SenderIsNotDescriptor(); - error SenderIsNotPendingDescriptor(); - error EmptyPalette(); error BadPaletteLength(); @@ -67,9 +65,7 @@ interface INounsArt { function pendingDescriptor() external view returns (address); - function setDescriptor(address pendingDescriptor) external; - - function confirmDescriptor() external; + function setDescriptor(address descriptor) external; function addManyBackgrounds(string[] calldata _backgrounds) external; diff --git a/packages/nouns-contracts/test/foundry/NounsArt.t.sol b/packages/nouns-contracts/test/foundry/NounsArt.t.sol index 5a65b2af93..74fdb2724a 100644 --- a/packages/nouns-contracts/test/foundry/NounsArt.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsArt.t.sol @@ -20,6 +20,8 @@ contract NounsArtTest is Test, DescriptorHelpers { event GlassesAdded(uint16 count); + event DescriptorUpdated(address oldDescriptor, address newDescriptor); + NounsArt art; address descriptor = address(1); @@ -28,7 +30,7 @@ contract NounsArtTest is Test, DescriptorHelpers { } /// - /// setDescriptor and confirmDescriptor + /// setDescriptor /// function testSetDescriptorRevertsIfSenderNotDescriptor() public { @@ -36,34 +38,15 @@ contract NounsArtTest is Test, DescriptorHelpers { art.setDescriptor(address(2)); } - function testSetDescriptorDoesntSetYet() public { - address newDescriptor = address(2); - - vm.prank(descriptor); - art.setDescriptor(newDescriptor); - - assertEq(art.descriptor(), descriptor); - } - - function testConfirmDescriptorRevertsIfSenderNotPendingDescriptor() public { + function testSetDescriptorWorks() public { address newDescriptor = address(2); - vm.prank(descriptor); - art.setDescriptor(newDescriptor); - - vm.expectRevert(INounsArt.SenderIsNotPendingDescriptor.selector); - art.confirmDescriptor(); - } - - function testConfirmDescriptorSetsDescriptor() public { - address newDescriptor = address(2); + vm.expectEmit(true, true, true, true); + emit DescriptorUpdated(descriptor, newDescriptor); vm.prank(descriptor); art.setDescriptor(newDescriptor); - vm.prank(newDescriptor); - art.confirmDescriptor(); - assertEq(art.descriptor(), newDescriptor); } From 28b5e03b328089af1237bf7bf93536b0dc089001 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Mon, 11 Jul 2022 10:41:14 +0300 Subject: [PATCH 080/116] cleanup --- packages/nouns-contracts/contracts/NounsArt.sol | 3 --- packages/nouns-contracts/contracts/interfaces/INounsArt.sol | 2 -- 2 files changed, 5 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsArt.sol b/packages/nouns-contracts/contracts/NounsArt.sol index 0f25cbf5c2..a0f9b30f4c 100644 --- a/packages/nouns-contracts/contracts/NounsArt.sol +++ b/packages/nouns-contracts/contracts/NounsArt.sol @@ -25,9 +25,6 @@ contract NounsArt is INounsArt { /// @notice Current Nouns Descriptor address address public override descriptor; - /// @notice Pending Nouns Descriptor address - address public override pendingDescriptor; - /// @notice Noun Backgrounds (Hex Colors) string[] public override backgrounds; diff --git a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol index eee9f3a967..7a3402af31 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol @@ -63,8 +63,6 @@ interface INounsArt { function descriptor() external view returns (address); - function pendingDescriptor() external view returns (address); - function setDescriptor(address descriptor) external; function addManyBackgrounds(string[] calldata _backgrounds) external; From ae513f8487fd9f4c6dd26eca5d4a0d27d94e29c9 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Mon, 11 Jul 2022 13:46:23 +0300 Subject: [PATCH 081/116] update deploy tasks to deploy descriptor v1 to rinkeby --- ...and-configure-short-times-descriptorv1.ts} | 53 ++++++++++++++----- ....ts => deploy-short-times-descriptorv1.ts} | 40 +++++++------- packages/nouns-contracts/tasks/index.ts | 5 +- .../tasks/populate-descriptor-v1.ts | 47 ++++++++++++++++ packages/nouns-contracts/tasks/types/index.ts | 8 ++- .../nouns-contracts/tasks/update-configs.ts | 17 ++++-- .../nouns-contracts/tasks/verify-etherscan.ts | 22 +++----- 7 files changed, 136 insertions(+), 56 deletions(-) rename packages/nouns-contracts/tasks/{deploy-and-configure-short-times.ts => deploy-and-configure-short-times-descriptorv1.ts} (68%) rename packages/nouns-contracts/tasks/{deploy-short-times.ts => deploy-short-times-descriptorv1.ts} (89%) create mode 100644 packages/nouns-contracts/tasks/populate-descriptor-v1.ts diff --git a/packages/nouns-contracts/tasks/deploy-and-configure-short-times.ts b/packages/nouns-contracts/tasks/deploy-and-configure-short-times-descriptorv1.ts similarity index 68% rename from packages/nouns-contracts/tasks/deploy-and-configure-short-times.ts rename to packages/nouns-contracts/tasks/deploy-and-configure-short-times-descriptorv1.ts index 7bc44e18ec..252e523f7c 100644 --- a/packages/nouns-contracts/tasks/deploy-and-configure-short-times.ts +++ b/packages/nouns-contracts/tasks/deploy-and-configure-short-times-descriptorv1.ts @@ -1,7 +1,7 @@ import { task, types } from 'hardhat/config'; import { printContractsTable } from './utils'; -task('deploy-and-configure-short-times', 'Deploy and configure all contracts') +task('deploy-and-configure-short-times-descriptorv1', 'Deploy and configure all contracts') .addFlag('startAuction', 'Start the first auction upon deployment completion') .addFlag('autoDeploy', 'Deploy all contracts without user interaction') .addFlag('updateConfigs', 'Write the deployed addresses to the SDK and subgraph configs') @@ -10,23 +10,50 @@ task('deploy-and-configure-short-times', 'Deploy and configure all contracts') .addOptionalParam( 'auctionTimeBuffer', 'The auction time buffer (seconds)', - 5 * 60 /* 5 minutes */, + 30 /* 30 seconds */, + types.int, + ) + .addOptionalParam( + 'auctionReservePrice', + 'The auction reserve price (wei)', + 1 /* 1 wei */, types.int, ) - .addOptionalParam('auctionReservePrice', 'The auction reserve price (wei)') .addOptionalParam( 'auctionMinIncrementBidPercentage', 'The auction min increment bid percentage (out of 100)', + 2 /* 2% */, + types.int, + ) + .addOptionalParam( + 'auctionDuration', + 'The auction duration (seconds)', + 60 * 2 /* 2 minutes */, + types.int, + ) + .addOptionalParam('timelockDelay', 'The timelock delay (seconds)', 3600 /* 1 hour */, types.int) + .addOptionalParam( + 'votingPeriod', + 'The voting period (blocks)', + 240 /* 1 hour (15s blocks) */, + types.int, ) - .addOptionalParam('auctionDuration', 'The auction duration (seconds)', 600, types.int) - .addOptionalParam('timelockDelay', 'The timelock delay (seconds)') - .addOptionalParam('votingPeriod', 'The voting period (blocks)', 5760, types.int) .addOptionalParam('votingDelay', 'The voting delay (blocks)', 1, types.int) - .addOptionalParam('proposalThresholdBps', 'The proposal threshold (basis points)') - .addOptionalParam('quorumVotesBps', 'Votes required for quorum (basis points)') + .addOptionalParam( + 'proposalThresholdBps', + 'The proposal threshold (basis points)', + 100 /* 1% */, + types.int, + ) + .addOptionalParam( + 'quorumVotesBps', + 'Votes required for quorum (basis points)', + 1_000 /* 10% */, + types.int, + ) .setAction(async (args, { run }) => { // Deploy the Nouns DAO contracts and return deployment information - const contracts = await run('deploy-short-times', args); + const contracts = await run('deploy-short-times-descriptorv1', args); // Verify the contracts on Etherscan await run('verify-etherscan', { @@ -34,15 +61,15 @@ task('deploy-and-configure-short-times', 'Deploy and configure all contracts') }); // Populate the on-chain art - await run('populate-descriptor', { - nftDescriptor: contracts.NFTDescriptorV2.address, - nounsDescriptor: contracts.NounsDescriptorV2.address, + await run('populate-descriptor-v1', { + nftDescriptor: contracts.NFTDescriptor.address, + nounsDescriptor: contracts.NounsDescriptor.address, }); // Transfer ownership of all contract except for the auction house. // We must maintain ownership of the auction house to kick off the first auction. const executorAddress = contracts.NounsDAOExecutor.address; - await contracts.NounsDescriptorV2.instance.transferOwnership(executorAddress); + await contracts.NounsDescriptor.instance.transferOwnership(executorAddress); await contracts.NounsToken.instance.transferOwnership(executorAddress); await contracts.NounsAuctionHouseProxyAdmin.instance.transferOwnership(executorAddress); console.log( diff --git a/packages/nouns-contracts/tasks/deploy-short-times.ts b/packages/nouns-contracts/tasks/deploy-short-times-descriptorv1.ts similarity index 89% rename from packages/nouns-contracts/tasks/deploy-short-times.ts rename to packages/nouns-contracts/tasks/deploy-short-times-descriptorv1.ts index 964b7a9eac..07b70b754b 100644 --- a/packages/nouns-contracts/tasks/deploy-short-times.ts +++ b/packages/nouns-contracts/tasks/deploy-short-times-descriptorv1.ts @@ -1,5 +1,11 @@ import { default as NounsAuctionHouseABI } from '../abi/contracts/NounsAuctionHouse.sol/NounsAuctionHouse.json'; -import { ChainId, ContractDeployment, ContractName, DeployedContract } from './types'; +import { + ChainId, + ContractDeployment, + ContractName, + ContractNameDescriptorV1, + DeployedContract, +} from './types'; import { Interface } from 'ethers/lib/utils'; import { task, types } from 'hardhat/config'; import promptjs from 'prompt'; @@ -19,11 +25,10 @@ const wethContracts: Record = { [ChainId.Kovan]: '0xd0a1e359811322d97991e03f863a0c30c2cf029c', }; -const NOUNS_ART_NONCE_OFFSET = 3; -const AUCTION_HOUSE_PROXY_NONCE_OFFSET = 8; -const GOVERNOR_N_DELEGATOR_NONCE_OFFSET = 11; +const AUCTION_HOUSE_PROXY_NONCE_OFFSET = 6; +const GOVERNOR_N_DELEGATOR_NONCE_OFFSET = 9; -task('deploy-short-times', 'Deploys NFTDescriptor, NounsDescriptor, NounsSeeder, and NounsToken') +task('deploy-short-times-descriptorv1', 'Deploy all Nouns contracts with NounsDescriptor v1') .addFlag('autoDeploy', 'Deploy all contracts without user interaction') .addOptionalParam('weth', 'The WETH contract address', undefined, types.string) .addOptionalParam('noundersdao', 'The nounders DAO contract address', undefined, types.string) @@ -95,10 +100,6 @@ task('deploy-short-times', 'Deploys NFTDescriptor, NounsDescriptor, NounsSeeder, } const nonce = await deployer.getTransactionCount(); - const expectedNounsArtAddress = ethers.utils.getContractAddress({ - from: deployer.address, - nonce: nonce + NOUNS_ART_NONCE_OFFSET, - }); const expectedAuctionHouseProxyAddress = ethers.utils.getContractAddress({ from: deployer.address, nonce: nonce + AUCTION_HOUSE_PROXY_NONCE_OFFSET, @@ -107,28 +108,23 @@ task('deploy-short-times', 'Deploys NFTDescriptor, NounsDescriptor, NounsSeeder, from: deployer.address, nonce: nonce + GOVERNOR_N_DELEGATOR_NONCE_OFFSET, }); - const deployment: Record = {} as Record< - ContractName, + const deployment: Record = {} as Record< + ContractNameDescriptorV1, DeployedContract >; - const contracts: Record = { - NFTDescriptorV2: {}, - SVGRenderer: {}, - NounsDescriptorV2: { - args: [expectedNounsArtAddress, () => deployment.SVGRenderer.address], + const contracts: Record = { + NFTDescriptor: {}, + NounsDescriptor: { libraries: () => ({ - NFTDescriptorV2: deployment.NFTDescriptorV2.address, + NFTDescriptor: deployment.NFTDescriptor.address, }), }, - NounsArt: { - args: [() => deployment.NounsDescriptorV2.address], - }, NounsSeeder: {}, NounsToken: { args: [ args.noundersdao, expectedAuctionHouseProxyAddress, - () => deployment.NounsDescriptorV2.address, + () => deployment.NounsDescriptor.address, () => deployment.NounsSeeder.address, proxyRegistryAddress, ], @@ -283,7 +279,7 @@ task('deploy-short-times', 'Deploys NFTDescriptor, NounsDescriptor, NounsSeeder, await deployedContract.deployed(); } - deployment[name as ContractName] = { + deployment[name as ContractNameDescriptorV1] = { name: nameForFactory, instance: deployedContract, address: deployedContract.address, diff --git a/packages/nouns-contracts/tasks/index.ts b/packages/nouns-contracts/tasks/index.ts index d67477730a..84520a77ea 100644 --- a/packages/nouns-contracts/tasks/index.ts +++ b/packages/nouns-contracts/tasks/index.ts @@ -12,7 +12,8 @@ export * from './update-configs'; export * from './descriptor-art-to-console'; export * from './descriptor-v1-export-abi'; export * from './deploy-descriptor-v2'; -export * from './deploy-short-times'; -export * from './deploy-and-configure-short-times'; +export * from './deploy-short-times-descriptorv1'; +export * from './deploy-and-configure-short-times-descriptorv1'; export * from './populate-descriptor-via-proposal'; export * from './deploy-test-minter'; +export * from './populate-descriptor-v1'; diff --git a/packages/nouns-contracts/tasks/populate-descriptor-v1.ts b/packages/nouns-contracts/tasks/populate-descriptor-v1.ts new file mode 100644 index 0000000000..cabf9d66bf --- /dev/null +++ b/packages/nouns-contracts/tasks/populate-descriptor-v1.ts @@ -0,0 +1,47 @@ +import { task, types } from 'hardhat/config'; +import ImageData from '../files/image-data.json'; +import { chunkArray } from '../utils'; + +task('populate-descriptor-v1', 'Populates the descriptor with color palettes and Noun parts') + .addOptionalParam( + 'nftDescriptor', + 'The `NFTDescriptor` contract address', + '0x5FbDB2315678afecb367f032d93F642f64180aa3', + types.string, + ) + .addOptionalParam( + 'nounsDescriptor', + 'The `NounsDescriptor` contract address', + '0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512', + types.string, + ) + .setAction(async ({ nftDescriptor, nounsDescriptor }, { ethers }) => { + const descriptorFactory = await ethers.getContractFactory('NounsDescriptor', { + libraries: { + NFTDescriptor: nftDescriptor, + }, + }); + const descriptorContract = descriptorFactory.attach(nounsDescriptor); + + const { bgcolors, palette, images } = ImageData; + const { bodies, accessories, heads, glasses } = images; + + // Chunk head and accessory population due to high gas usage + await descriptorContract.addManyBackgrounds(bgcolors); + await descriptorContract.addManyColorsToPalette(0, palette); + await descriptorContract.addManyBodies(bodies.map(({ data }) => data)); + + const accessoryChunk = chunkArray(accessories, 10); + for (const chunk of accessoryChunk) { + await descriptorContract.addManyAccessories(chunk.map(({ data }) => data)); + } + + const headChunk = chunkArray(heads, 10); + for (const chunk of headChunk) { + await descriptorContract.addManyHeads(chunk.map(({ data }) => data)); + } + + await descriptorContract.addManyGlasses(glasses.map(({ data }) => data)); + + console.log('Descriptor populated with palettes and parts.'); + }); diff --git a/packages/nouns-contracts/tasks/types/index.ts b/packages/nouns-contracts/tasks/types/index.ts index 479a8ca8ca..6e4bca0148 100644 --- a/packages/nouns-contracts/tasks/types/index.ts +++ b/packages/nouns-contracts/tasks/types/index.ts @@ -8,7 +8,13 @@ export enum ChainId { } // prettier-ignore -export type ContractName = 'NFTDescriptorV2' | 'NounsDescriptorV2' | 'SVGRenderer' | 'NounsArt' | 'NounsSeeder' | 'NounsToken' | 'NounsAuctionHouse' | 'NounsAuctionHouseProxyAdmin' | 'NounsAuctionHouseProxy' | 'NounsDAOExecutor' | 'NounsDAOLogicV1' | 'NounsDAOProxy'; +export type DescriptorV1ContractNames = 'NFTDescriptor' | 'NounsDescriptor'; +// prettier-ignore +export type DescriptorV2ContractNames = 'NFTDescriptorV2' | 'NounsDescriptorV2' | 'SVGRenderer' | 'NounsArt'; +// prettier-ignore +export type ContractName = DescriptorV2ContractNames | 'NounsSeeder' | 'NounsToken' | 'NounsAuctionHouse' | 'NounsAuctionHouseProxyAdmin' | 'NounsAuctionHouseProxy' | 'NounsDAOExecutor' | 'NounsDAOLogicV1' | 'NounsDAOProxy'; +// prettier-ignore +export type ContractNameDescriptorV1 = DescriptorV1ContractNames | 'NounsSeeder' | 'NounsToken' | 'NounsAuctionHouse' | 'NounsAuctionHouseProxyAdmin' | 'NounsAuctionHouseProxy' | 'NounsDAOExecutor' | 'NounsDAOLogicV1' | 'NounsDAOProxy'; export interface ContractDeployment { args?: (string | number | (() => string))[]; diff --git a/packages/nouns-contracts/tasks/update-configs.ts b/packages/nouns-contracts/tasks/update-configs.ts index 19b3335885..c82bb44a79 100644 --- a/packages/nouns-contracts/tasks/update-configs.ts +++ b/packages/nouns-contracts/tasks/update-configs.ts @@ -1,5 +1,5 @@ import { task, types } from 'hardhat/config'; -import { ContractName, DeployedContract } from './types'; +import { ContractName, ContractNameDescriptorV1, DeployedContract } from './types'; import { readFileSync, writeFileSync } from 'fs'; import { execSync } from 'child_process'; import { join } from 'path'; @@ -7,7 +7,12 @@ import { join } from 'path'; task('update-configs', 'Write the deployed addresses to the SDK and subgraph configs') .addParam('contracts', 'Contract objects from the deployment', undefined, types.json) .setAction( - async ({ contracts }: { contracts: Record }, { ethers }) => { + async ( + { + contracts, + }: { contracts: Record }, + { ethers }, + ) => { const { name: network, chainId } = await ethers.provider.getNetwork(); // Update SDK addresses @@ -17,8 +22,12 @@ task('update-configs', 'Write the deployed addresses to the SDK and subgraph con addresses[chainId] = { nounsToken: contracts.NounsToken.address, nounsSeeder: contracts.NounsSeeder.address, - nounsDescriptor: contracts.NounsDescriptorV2.address, - nftDescriptor: contracts.NFTDescriptorV2.address, + nounsDescriptor: contracts.NounsDescriptorV2 + ? contracts.NounsDescriptorV2.address + : contracts.NounsDescriptor.address, + nftDescriptor: contracts.NFTDescriptorV2 + ? contracts.NFTDescriptorV2.address + : contracts.NFTDescriptor.address, nounsAuctionHouse: contracts.NounsAuctionHouse.address, nounsAuctionHouseProxy: contracts.NounsAuctionHouseProxy.address, nounsAuctionHouseProxyAdmin: contracts.NounsAuctionHouseProxyAdmin.address, diff --git a/packages/nouns-contracts/tasks/verify-etherscan.ts b/packages/nouns-contracts/tasks/verify-etherscan.ts index 3dfe5bb94d..c389e80f49 100644 --- a/packages/nouns-contracts/tasks/verify-etherscan.ts +++ b/packages/nouns-contracts/tasks/verify-etherscan.ts @@ -1,13 +1,5 @@ -import { Contract } from 'ethers'; import { task, types } from 'hardhat/config'; -import { ContractName } from './types'; - -interface VerifyArgs { - address: string; - instance?: Contract; - constructorArguments?: (string | number)[]; - libraries?: Record; -} +import { ContractName, DeployedContract } from './types'; // prettier-ignore // These contracts require a fully qualified name to be passed because @@ -20,18 +12,20 @@ const nameToFullyQualifiedName: Record = { task('verify-etherscan', 'Verify the Solidity contracts on Etherscan') .addParam('contracts', 'Contract objects from the deployment', undefined, types.json) - .setAction(async ({ contracts }: { contracts: Record }, hre) => { - for (const [name, contract] of Object.entries(contracts)) { - console.log(`verifying ${name}...`); + .setAction(async ({ contracts }: { contracts: Record }, hre) => { + for (const [, contract] of Object.entries(contracts)) { + console.log(`verifying ${contract.name}...`); try { const code = await contract.instance?.provider.getCode(contract.address); if (code === '0x') { - console.log(`${name} contract deployment has not completed. waiting to verify...`); + console.log( + `${contract.name} contract deployment has not completed. waiting to verify...`, + ); await contract.instance?.deployed(); } await hre.run('verify:verify', { ...contract, - contract: nameToFullyQualifiedName[name], + contract: nameToFullyQualifiedName[contract.name], }); } catch ({ message }) { if ((message as string).includes('Reason: Already Verified')) { From cc47d00e13b68a811c6d65d5008c18333f2151b4 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Mon, 11 Jul 2022 14:20:04 +0300 Subject: [PATCH 082/116] add a task to upgrade to descriptor v2 via a proposal --- packages/nouns-contracts/tasks/index.ts | 1 + .../tasks/upgrade-descriptor-via-proposal.ts | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 packages/nouns-contracts/tasks/upgrade-descriptor-via-proposal.ts diff --git a/packages/nouns-contracts/tasks/index.ts b/packages/nouns-contracts/tasks/index.ts index 84520a77ea..ba16dc6aff 100644 --- a/packages/nouns-contracts/tasks/index.ts +++ b/packages/nouns-contracts/tasks/index.ts @@ -17,3 +17,4 @@ export * from './deploy-and-configure-short-times-descriptorv1'; export * from './populate-descriptor-via-proposal'; export * from './deploy-test-minter'; export * from './populate-descriptor-v1'; +export * from './upgrade-descriptor-via-proposal'; diff --git a/packages/nouns-contracts/tasks/upgrade-descriptor-via-proposal.ts b/packages/nouns-contracts/tasks/upgrade-descriptor-via-proposal.ts new file mode 100644 index 0000000000..1cd86cbc64 --- /dev/null +++ b/packages/nouns-contracts/tasks/upgrade-descriptor-via-proposal.ts @@ -0,0 +1,24 @@ +import { task } from 'hardhat/config'; + +task('upgrade-descriptor-via-proposal', 'Upgrade NounsToken to use Descriptor V2.') + .addParam('descriptor', 'The `NounsDescriptorV2` contract address') + .addParam('dao', 'The `NounsDAOProxy` contract address') + .addParam('token', 'The `NounsToken` contract address') + .setAction(async ({ descriptor, dao, token }, { ethers }) => { + const targets = [token as string]; + const values = [0]; + const signatures = ['setDescriptor(address)']; + const calldatas = [ethers.utils.defaultAbiCoder.encode(['address'], [descriptor])]; + + const gov = (await ethers.getContractFactory('NounsDAOLogicV1')).attach(dao); + const propTx = await gov.propose( + targets, + values, + signatures, + calldatas, + `Setting NounToken's descriptor to NounsDescriptorV2.`, + ); + await propTx.wait(); + + console.log('Proposal submitted!'); + }); From c9cda8be4c810cea5069ec61b0ea6def45bb90c4 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Mon, 11 Jul 2022 15:29:28 +0300 Subject: [PATCH 083/116] deploy-short-times: shorten proposal wait times even more --- .../tasks/deploy-and-configure-short-times-descriptorv1.ts | 4 ++-- .../nouns-contracts/tasks/deploy-short-times-descriptorv1.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/nouns-contracts/tasks/deploy-and-configure-short-times-descriptorv1.ts b/packages/nouns-contracts/tasks/deploy-and-configure-short-times-descriptorv1.ts index 252e523f7c..1ccabe7053 100644 --- a/packages/nouns-contracts/tasks/deploy-and-configure-short-times-descriptorv1.ts +++ b/packages/nouns-contracts/tasks/deploy-and-configure-short-times-descriptorv1.ts @@ -31,11 +31,11 @@ task('deploy-and-configure-short-times-descriptorv1', 'Deploy and configure all 60 * 2 /* 2 minutes */, types.int, ) - .addOptionalParam('timelockDelay', 'The timelock delay (seconds)', 3600 /* 1 hour */, types.int) + .addOptionalParam('timelockDelay', 'The timelock delay (seconds)', 60 /* 1 min */, types.int) .addOptionalParam( 'votingPeriod', 'The voting period (blocks)', - 240 /* 1 hour (15s blocks) */, + 80 /* 20 min (15s blocks) */, types.int, ) .addOptionalParam('votingDelay', 'The voting delay (blocks)', 1, types.int) diff --git a/packages/nouns-contracts/tasks/deploy-short-times-descriptorv1.ts b/packages/nouns-contracts/tasks/deploy-short-times-descriptorv1.ts index 07b70b754b..93459abdfb 100644 --- a/packages/nouns-contracts/tasks/deploy-short-times-descriptorv1.ts +++ b/packages/nouns-contracts/tasks/deploy-short-times-descriptorv1.ts @@ -56,11 +56,11 @@ task('deploy-short-times-descriptorv1', 'Deploy all Nouns contracts with NounsDe 60 * 2 /* 2 minutes */, types.int, ) - .addOptionalParam('timelockDelay', 'The timelock delay (seconds)', 3600 /* 1 hour */, types.int) + .addOptionalParam('timelockDelay', 'The timelock delay (seconds)', 60 /* 1 min */, types.int) .addOptionalParam( 'votingPeriod', 'The voting period (blocks)', - 240 /* 1 hour (15s blocks) */, + 80 /* 20 min (15s blocks) */, types.int, ) .addOptionalParam('votingDelay', 'The voting delay (blocks)', 1, types.int) From 615a1c2bb949162078d143be117bd292aebc746a Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Mon, 11 Jul 2022 18:13:40 +0200 Subject: [PATCH 084/116] run-local task transfers ownership of contracts --- packages/nouns-contracts/tasks/run-local.ts | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/nouns-contracts/tasks/run-local.ts b/packages/nouns-contracts/tasks/run-local.ts index 226dadf3f3..c87f0614fd 100644 --- a/packages/nouns-contracts/tasks/run-local.ts +++ b/packages/nouns-contracts/tasks/run-local.ts @@ -22,9 +22,21 @@ task( gasLimit: 1_000_000, }); - await run('create-proposal', { - nounsDaoProxy: contracts.NounsDAOProxy.instance.address, - }); + // Transfer ownership + const executorAddress = contracts.NounsDAOExecutor.instance.address; + await contracts.NounsDescriptorV2.instance.transferOwnership(executorAddress); + await contracts.NounsToken.instance.transferOwnership(executorAddress); + await contracts.NounsAuctionHouseProxyAdmin.instance.transferOwnership(executorAddress); + await contracts.NounsAuctionHouse.instance + .attach(contracts.NounsAuctionHouseProxy.instance.address) + .transferOwnership(executorAddress); + console.log( + 'Transferred ownership of the descriptor, token, and proxy admin contracts to the executor.', + ); + + // await run('create-proposal', { + // nounsDaoProxy: contracts.NounsDAOProxy.instance.address, + // }); const { chainId } = await ethers.provider.getNetwork(); From ec3bc1003127b911fb350bc2066a90b0474eff4b Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Mon, 11 Jul 2022 18:15:16 +0200 Subject: [PATCH 085/116] populate descriptor: set gaslimit manually to bypass some hardhat issue for some reason it's calculating the estimated gas wrong when running with run-local task --- packages/nouns-contracts/tasks/populate-descriptor.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/nouns-contracts/tasks/populate-descriptor.ts b/packages/nouns-contracts/tasks/populate-descriptor.ts index 784d62cae5..f856842537 100644 --- a/packages/nouns-contracts/tasks/populate-descriptor.ts +++ b/packages/nouns-contracts/tasks/populate-descriptor.ts @@ -15,7 +15,9 @@ task('populate-descriptor', 'Populates the descriptor with color palettes and No '0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512', types.string, ) - .setAction(async ({ nftDescriptor, nounsDescriptor }, { ethers }) => { + .setAction(async ({ nftDescriptor, nounsDescriptor }, { ethers, network }) => { + const options = { gasLimit: network.name === 'hardhat' ? 30000000 : undefined }; + const descriptorFactory = await ethers.getContractFactory('NounsDescriptorV2', { libraries: { NFTDescriptorV2: nftDescriptor, @@ -38,21 +40,25 @@ task('populate-descriptor', 'Populates the descriptor with color palettes and No bodiesPage.encodedCompressed, bodiesPage.originalLength, bodiesPage.itemCount, + options, ); await descriptorContract.addHeads( headsPage.encodedCompressed, headsPage.originalLength, headsPage.itemCount, + options, ); await descriptorContract.addGlasses( glassesPage.encodedCompressed, glassesPage.originalLength, glassesPage.itemCount, + options, ); await descriptorContract.addAccessories( accessoriesPage.encodedCompressed, accessoriesPage.originalLength, accessoriesPage.itemCount, + options, ); console.log('Descriptor populated with palettes and parts.'); From 23e5d1e6853322fb74be6791f372e7701904b110 Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Mon, 11 Jul 2022 18:46:29 +0200 Subject: [PATCH 086/116] add task for encoding an additional json art file this also includes some testing utilities for quickly creating a bunch of art --- .../1-bodies/body-green-reversed.png | Bin 0 -> 3200 bytes .../accessory-txt-dao-black-reversed.png | Bin 0 -> 3205 bytes .../3-heads/head-thumbsup-reversed.png | Bin 0 -> 3392 bytes .../glasses-hip-rose-reversed_reversed.png | Bin 0 -> 3249 bytes .../images_test/create_duplicates.py | 28 + packages/nouns-assets/package.json | 1 + packages/nouns-assets/scripts/encode-more.ts | 37 + packages/nouns-assets/scripts/encode.ts | 26 +- packages/nouns-assets/scripts/utils.ts | 27 + packages/nouns-assets/src/new-image-data.json | 1628 +++++++++++++++++ 10 files changed, 1722 insertions(+), 25 deletions(-) create mode 100644 packages/nouns-assets/images_test/1-bodies/body-green-reversed.png create mode 100644 packages/nouns-assets/images_test/2-accessories/accessory-txt-dao-black-reversed.png create mode 100644 packages/nouns-assets/images_test/3-heads/head-thumbsup-reversed.png create mode 100644 packages/nouns-assets/images_test/4-glasses/glasses-hip-rose-reversed_reversed.png create mode 100644 packages/nouns-assets/images_test/create_duplicates.py create mode 100644 packages/nouns-assets/scripts/encode-more.ts create mode 100644 packages/nouns-assets/scripts/utils.ts create mode 100644 packages/nouns-assets/src/new-image-data.json diff --git a/packages/nouns-assets/images_test/1-bodies/body-green-reversed.png b/packages/nouns-assets/images_test/1-bodies/body-green-reversed.png new file mode 100644 index 0000000000000000000000000000000000000000..d91aed34c143bd8118f14f8b6a95e4a73617aff9 GIT binary patch literal 3200 zcmeHJ&u`mQ9DnJ$vIPw!#$hTTyzH_eIsTE@j-S#WJUb~H6 zf$s;=diynOID;Z#VHQUNmocI02*Yqd1Hz34ecQ*Qr9xu_zX5d5+_%p4r1|jaSETxLYc01%ZnNVK^KXhoz$9Z3>dE>w+i?vdn`8@9)_G z8S%D%DI$q^8q_yD%MC2Y<`^&OIy=Eqp}-s^zbH=ANc^}vUO)6=8UpRp0ks2PkcyI! zg@dkaGkMDLxiPywZ*(~WLwIWGXA!1L#XZs)q>mW6Q zWfL`H=y>)xtSYch)3=_q3Tq?_>yEAd|B62UYAsjH_H-H71`*?WhIXC-$>_^-T#GyF9%Ku zm)UwAS2%^rrlx{iN~K5mGEplaoNVxFr6P3|L(*wCDV!%GTvUhC?J(@}neCH(a^S)1 zp0#P&q~CCi9roQHcNO!IyUI+ONiB_C{YMum_zCLP$)5OV`b5#E;3?{4KY&~H`l{#j ztUj%=Z8FzdsjHH%s=Qo;zM5&5$y0awjt8H4S}Ubtlj#(S?I@T!pa}_^F?c#LH@1(I zPwoA}RvgX3&a#$=G>CVpwfrC7ef=|RT;FOnmOJZbjg1SZzqlwa&Ye8ny?D2I@Mr(i zXa3rM(ifHu^r^4sr2H-D)mqm!ApHFzb3Pr(Y1mgI7^b3_r9Oc z_xrxT^7gIOGpCOfj}-v`N7^f`HS%QWb?A0-_s^aCg**!W+UZkZ`|?BA$jc4fZJU|~ z9wFmH;EuvQ;2;$tf1q#-+!l@j=oKDJ$1fF5#4-nni~z_TJWMXHAco_6$@uLzEwB({ zKO#^1TOk)=jh;(})5FZ_zzH0G;JAz^maEJO4e6FmXHEhj@}dBF8S*tosKc57MG1g~ z^9!ktt6PPsty>3DeazOu>6j{xm?S7FjL1V?f)xdP^XsP%kfp=!%5y#dcOIoz0lfGA z{Qwj%TAgmt)t-X7Gb$r$Xn8VnDHCW+AQ_HufSAc>X!~%oSPCT|8PjR5#DpTj%ZsJ1 zw#qae4>MAkFY_g}$S_R9GfcSFdLo9Cx5d&R2wcc<MRpo`s>faThM^Wi=kO4ZupRiE zP!_m69NBFOwEfr{#4p?gxdg<|18Lfy!$zZAq#rDAkR8Mx$yMlgHeJlEVc%KzbiBMl z%s-xIxtruxK3%#zcNc+WPJ=UJ3SEg{VN4@eHw+z`jyFPqYK>4IbFSTQaMQ_YP#VOk zP;(5++-#u$t294ZUS|1PC&_g33VFW4?ULNZ(eyA19IxXzL-nr;D&oo_^2l(;Ac+-~ zPEs&ggF=!>au<4SP=wS6iv3O_v&o5YRW7^y3F=uY}O1>kQFR8xQIOipRWVyw2P=Z z%_wXn(0Fz?tijQ4GqnCYanJ|I?qfsclAR?JySFw?jG53?cv_lb6$&Juqtd+9(Digl z#sV@}EJ!uBYVZQ92xgV72%;qQgsLt}a$@D*37wBN{tq1adcaKJa+}Ys2F}1eQxP%G z)_GoHtCbpNd)2za%CcC;Jwre;uK&A%i|TN;A%=ZEw}H~n4q15Gv-*~ehAl^5r{Dg# zs~G$4DsyS3wG^xRhbl7gJ=E>JJ#l~WiLB4SGt}vs0JfXWRnIZ4Ay(;OnQ1RKB|(u$ z4=)Q1E>|v>r|AqGk9_K}TFJtu(-{;!RnX{=n4qv36HR;OV)-cYne$)RilbR_x>SoK z4U&^8S^B#D4mrGb+O4Hd_we;EcZ%d6g5|To QLQlu-$2Ym>4VE_OC literal 0 HcmV?d00001 diff --git a/packages/nouns-assets/images_test/3-heads/head-thumbsup-reversed.png b/packages/nouns-assets/images_test/3-heads/head-thumbsup-reversed.png new file mode 100644 index 0000000000000000000000000000000000000000..c4d58637ad825403253aa8d05662330d51e2d4f0 GIT binary patch literal 3392 zcmeHJe{9rL9Piyu*oH(9K|mzshzX#*{8ZfuuuxQrtn2}FAB>sIKsXWMbx z42nu3m>Iy#e+bdVU<86>7$pS!0}TA3F@zWuf(aqI@gqVo3yMY|zP9(H8#hHvOia8> z`(EGsem>vtd*2`LZEIiAI<sT8sV_G^*JzK4+-TLk_Q-(2JYr;i|6-(%(edf%d=j33I72z(<8;A8kGr~e4- z54@%zfg*MiA_nj;wG(8}~oI8~Q#TWuo9 zlo|HpLw4<+jUe@3DCvxqNiF9@Jr@#eLqk2eyv>BfdpOw50ZTx8a;j!>Jq&bT; zs-r~`aiD@6&@2-tLnK}e2UlALYG!da;J)BJLLP#Mi9o5;pTlywsz}pn*$7uq+>xpZ z&2(=b;2pr!yA2VvY=q`7tY&$>6kFBl%F`3B!cydlbH)mg0z)uD9Cz70@QHN@qFqIJ(T*q}m7vAZ@vt~K<#4(PCR2Mor)%?30>^A&;DXnk?y&wOh{A7rJ|~TsKNuki#mCCO}sb%xYm2% z9_sR)fJ-(vw;Q^wsDQUG%V@Ht8G4stFe*gG@v3rFd75=qH{ekZ_^=mN8TO#;TZQc% z=o7&y#!%B;V?}w_^Pc;kQ;OYDc)R55VHlKds(k$rZJva8?}w6!#&o9cdiv$MPl;*j zDPN%V%$zkRPVD}C=9oe;iX^q{BWnc|LpCpH(q4> zX<7}gn^tq{$n~S&U!9XA#U{Ue^U+zW{Ot{E_RiT9P+Kn^y4_nlvfns9rES~jZ|dV6 zZ%F+^U)3$%ymRU1qrNACdyySazPY>hnmBw?eSheuI~Pt3%s#(mf8VjbkGG%scEPG+ zee%NL#gng0U;fR=JF7Q&-{M*z|hvW{Fzm6pPaGhyOoDu_~e=|u%G{NnBVt-IXvs^ lrAtfALH5kNU-s4Dr@mbO;L|r=zieOZlPxO}2b(<=Y~ literal 0 HcmV?d00001 diff --git a/packages/nouns-assets/images_test/4-glasses/glasses-hip-rose-reversed_reversed.png b/packages/nouns-assets/images_test/4-glasses/glasses-hip-rose-reversed_reversed.png new file mode 100644 index 0000000000000000000000000000000000000000..4b5c2328aaf7a1a02784328da3e21ef606c4443d GIT binary patch literal 3249 zcmeHJON`q@7@l+&*iBi17KBh+36tf}A{@VxIJS~V+hl1%o3h%CAgBjAu_uX_#Ln8@ zP10UgJy2Dm(t;3&3N6b84n;k1t5k_{D?%XkfP}~RH~kMi5WX~oL#4sBK3q5 z+vA!4`~H9Cf6Sa)Jbq**x-SXBwPl>GK0W;*T4s zTB?`J;Az~R0uMxH!2}V(KM>gm?sM7z)FS)+_Dba7KxPk?;Q)SuC-7}Xc&Gg+ZohF> z1Cs;nd-zSRBEB)J`<_>g8lo1PhHY3)qeJn0JV70NQPWkUYaIfBXL(L$MVU=fTv|@D zvLFF4xjE@;_w%)m&BA{@ArSahKHs*#g{Aq_C7-H z2)OX};{ZgjX_cy7EgzE=qaBCD%y_TeAxt3ClX0_+Y)JLmE!~oP*_b0C<2LDLVw59d zzmknr%ZpUrFcFoCvvD?-i&7MoG1a=fRCsm($6wi4)3!S@!*sjdcvpxUW`p4*Nn%)@ z;dvTM&{ki!VUO0WIhVxaDIiNRwT`VBIz@P4%~-Ruu^3V0U#^|1;_KfHSoGHJ=nn@b{wc&zCEnn4n>N5JgBMjU8>&|C7od%DBtB_Yq}gP}i*)=cvuuXhA-RJiZz5`^FqYW89yZm#)&l9GU|30nrOa(!{{H^Fbp%a-KQULcbiBb_%?Jg zT{cH*Jc*`THq;eVD&%l1#5GNog<8FqPNO6ZA+8SyCJ-$tJfaaR)YZC(c(JZ#7?(W& zAFl%{q=MuW5>3d54tjUOG7PCSE$v==p$rvGCtJlKZ*HT$+iB;}$4V3G4W#B659oD_ zhm5)orzIx~yqx5{Jh*GuacMyk5Tf~-nxYd(6zR06*64Iitg%u$As|8Vto%2wv*7yw zj>9{L9B^D{>A73SC6Xv9rc_8PlA_Rwl!$1UVr#Ubra6&CNjAZ8_ttT49*&knr^<(x zPqO9Uf#*%Fq3N(yFqAd2?+>bqddF2|EX^>N2CDv}iU52Ub!m4^yfgo})(7ALYX3YS zm-6{V)2M4Llq1Jvsu#Ru0{ONIGLb^4dh>(d+TgM|~T%imm; z?1{$ttuJSvn~k3NZS_y>boa?mj-ER^S=^W`ey8lY{QgJBE>pH^Lf?m;e9( literal 0 HcmV?d00001 diff --git a/packages/nouns-assets/images_test/create_duplicates.py b/packages/nouns-assets/images_test/create_duplicates.py new file mode 100644 index 0000000000..9c7f75b603 --- /dev/null +++ b/packages/nouns-assets/images_test/create_duplicates.py @@ -0,0 +1,28 @@ +""" +Copies all the images in the subfolders +This is just used for testing purposes +""" + +import os +import shutil + + +def get_subfolders(directory): + return [f.path for f in os.scandir(directory) if f.is_dir()] + + +def run(): + for folder in get_subfolders('.'): + print(f"Going into {folder}") + f = os.listdir(folder)[0] + print(f"Found {f}, duplicating it") + for i in range(100): + dst_file = f.replace('.png', '_%03d.png' % i) + shutil.copyfile(os.path.join(folder, f), + os.path.join(folder, dst_file)) + + print("Done") + + +if __name__ == "__main__": + run() diff --git a/packages/nouns-assets/package.json b/packages/nouns-assets/package.json index 5427785030..26eb64bb9a 100644 --- a/packages/nouns-assets/package.json +++ b/packages/nouns-assets/package.json @@ -9,6 +9,7 @@ "types": "dist/index.d.ts", "scripts": { "encode": "ts-node scripts/encode.ts", + "encode-more": "ts-node scripts/encode-more.ts", "clean": "rimraf dist tsconfig.build.tsbuildinfo", "build": "tsc -p tsconfig.build.json", "prepare": "yarn build", diff --git a/packages/nouns-assets/scripts/encode-more.ts b/packages/nouns-assets/scripts/encode-more.ts new file mode 100644 index 0000000000..52b445fb64 --- /dev/null +++ b/packages/nouns-assets/scripts/encode-more.ts @@ -0,0 +1,37 @@ +import { PNGCollectionEncoder } from '@nouns/sdk'; +import { promises as fs } from 'fs'; +import path from 'path'; +import { readPngImage } from './utils'; +import { palette } from '../src/image-data_v2.json'; + +/** + * @notice creates an additional art json file. it assumes it's not the first one. + * it also assumes the existing palette from the first one has all the needed colors. + * @sourceFolder a folder containing subfolders with the names: ['1-bodies', '2-accessories', '3-heads', '4-glasses'] + * @destinationFilepath wher to save the new json file + */ +const encode = async (sourceFolder: string, destinationFilepath: string) => { + const encoder = new PNGCollectionEncoder(palette); + + const partfolders = ['1-bodies', '2-accessories', '3-heads', '4-glasses']; + for (const folder of partfolders) { + const folderpath = path.join(sourceFolder, folder); + const files = await fs.readdir(folderpath); + for (const file of files) { + const image = await readPngImage(path.join(folderpath, file)); + encoder.encodeImage(file.replace(/\.png$/, ''), image, folder.replace(/^\d-/, '')); + } + } + await fs.writeFile( + destinationFilepath, + JSON.stringify( + { + images: encoder.data.images, + }, + null, + 2, + ), + ); +}; + +encode(process.argv[2], process.argv[3]); diff --git a/packages/nouns-assets/scripts/encode.ts b/packages/nouns-assets/scripts/encode.ts index 99f45844e5..6a26073f10 100644 --- a/packages/nouns-assets/scripts/encode.ts +++ b/packages/nouns-assets/scripts/encode.ts @@ -1,34 +1,10 @@ import { PNGCollectionEncoder, PngImage } from '@nouns/sdk'; import { promises as fs } from 'fs'; -import { PNG } from 'pngjs'; import path from 'path'; +import { readPngImage } from './utils'; const DESTINATION = path.join(__dirname, '../src/image-data_v2.json'); -/** - * Read a PNG image file and return a `PngImage` object. - * @param path The path to the PNG file - */ -const readPngImage = async (path: string): Promise => { - const buffer = await fs.readFile(path); - const png = PNG.sync.read(buffer); - - return { - width: png.width, - height: png.height, - rgbaAt: (x: number, y: number) => { - const idx = (png.width * y + x) << 2; - const [r, g, b, a] = [png.data[idx], png.data[idx + 1], png.data[idx + 2], png.data[idx + 3]]; - return { - r, - g, - b, - a, - }; - }, - }; -}; - const encode = async () => { const encoder = new PNGCollectionEncoder(); diff --git a/packages/nouns-assets/scripts/utils.ts b/packages/nouns-assets/scripts/utils.ts new file mode 100644 index 0000000000..29a936cb54 --- /dev/null +++ b/packages/nouns-assets/scripts/utils.ts @@ -0,0 +1,27 @@ +import { PngImage } from '@nouns/sdk'; +import { promises as fs } from 'fs'; +import { PNG } from 'pngjs'; + +/** + * Read a PNG image file and return a `PngImage` object. + * @param path The path to the PNG file + */ +export const readPngImage = async (path: string): Promise => { + const buffer = await fs.readFile(path); + const png = PNG.sync.read(buffer); + + return { + width: png.width, + height: png.height, + rgbaAt: (x: number, y: number) => { + const idx = (png.width * y + x) << 2; + const [r, g, b, a] = [png.data[idx], png.data[idx + 1], png.data[idx + 2], png.data[idx + 3]]; + return { + r, + g, + b, + a, + }; + }, + }; +}; diff --git a/packages/nouns-assets/src/new-image-data.json b/packages/nouns-assets/src/new-image-data.json new file mode 100644 index 0000000000..3f6aa5aad4 --- /dev/null +++ b/packages/nouns-assets/src/new-image-data.json @@ -0,0 +1,1628 @@ +{ + "images": { + "bodies": [ + { + "filename": "body-green-reversed", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_000", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_001", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_002", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_003", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_004", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_005", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_006", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_007", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_008", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_009", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_010", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_011", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_012", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_013", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_014", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_015", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_016", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_017", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_018", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_019", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_020", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_021", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_022", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_023", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_024", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_025", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_026", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_027", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_028", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_029", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_030", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_031", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_032", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_033", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_034", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_035", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_036", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_037", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_038", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_039", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_040", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_041", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_042", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_043", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_044", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_045", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_046", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_047", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_048", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_049", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_050", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_051", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_052", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_053", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_054", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_055", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_056", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_057", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_058", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_059", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_060", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_061", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_062", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_063", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_064", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_065", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_066", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_067", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_068", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_069", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_070", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_071", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_072", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_073", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_074", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_075", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_076", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_077", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_078", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_079", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_080", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_081", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_082", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_083", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_084", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_085", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_086", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_087", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_088", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_089", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_090", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_091", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_092", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_093", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_094", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_095", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_096", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_097", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_098", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_099", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + } + ], + "accessories": [ + { + "filename": "accessory-txt-dao-black-reversed", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_000", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_001", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_002", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_003", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_004", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_005", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_006", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_007", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_008", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_009", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_010", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_011", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_012", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_013", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_014", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_015", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_016", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_017", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_018", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_019", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_020", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_021", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_022", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_023", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_024", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_025", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_026", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_027", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_028", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_029", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_030", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_031", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_032", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_033", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_034", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_035", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_036", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_037", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_038", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_039", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_040", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_041", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_042", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_043", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_044", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_045", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_046", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_047", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_048", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_049", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_050", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_051", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_052", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_053", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_054", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_055", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_056", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_057", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_058", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_059", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_060", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_061", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_062", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_063", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_064", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_065", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_066", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_067", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_068", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_069", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_070", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_071", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_072", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_073", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_074", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_075", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_076", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_077", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_078", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_079", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_080", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_081", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_082", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_083", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_084", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_085", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_086", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_087", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_088", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_089", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_090", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_091", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_092", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_093", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_094", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_095", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_096", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_097", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_098", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_099", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + } + ], + "heads": [ + { + "filename": "head-thumbsup-reversed", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_000", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_001", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_002", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_003", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_004", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_005", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_006", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_007", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_008", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_009", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_010", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_011", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_012", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_013", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_014", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_015", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_016", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_017", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_018", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_019", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_020", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_021", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_022", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_023", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_024", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_025", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_026", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_027", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_028", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_029", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_030", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_031", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_032", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_033", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_034", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_035", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_036", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_037", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_038", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_039", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_040", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_041", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_042", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_043", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_044", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_045", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_046", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_047", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_048", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_049", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_050", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_051", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_052", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_053", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_054", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_055", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_056", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_057", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_058", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_059", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_060", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_061", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_062", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_063", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_064", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_065", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_066", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_067", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_068", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_069", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_070", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_071", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_072", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_073", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_074", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_075", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_076", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_077", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_078", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_079", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_080", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_081", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_082", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_083", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_084", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_085", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_086", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_087", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_088", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_089", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_090", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_091", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_092", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_093", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_094", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_095", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_096", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_097", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_098", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_099", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + } + ], + "glasses": [ + { + "filename": "glasses-hip-rose-reversed_reversed", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_000", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_001", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_002", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_003", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_004", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_005", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_006", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_007", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_008", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_009", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_010", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_011", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_012", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_013", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_014", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_015", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_016", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_017", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_018", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_019", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_020", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_021", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_022", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_023", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_024", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_025", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_026", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_027", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_028", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_029", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_030", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_031", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_032", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_033", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_034", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_035", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_036", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_037", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_038", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_039", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_040", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_041", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_042", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_043", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_044", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_045", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_046", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_047", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_048", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_049", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_050", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_051", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_052", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_053", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_054", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_055", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_056", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_057", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_058", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_059", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_060", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_061", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_062", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_063", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_064", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_065", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_066", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_067", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_068", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_069", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_070", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_071", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_072", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_073", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_074", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_075", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_076", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_077", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_078", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_079", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_080", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_081", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_082", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_083", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_084", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_085", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_086", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_087", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_088", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_089", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_090", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_091", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_092", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_093", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_094", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_095", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_096", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_097", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_098", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_099", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + } + ] + } +} \ No newline at end of file From bdb2696746949ee9ad19eb1ae19c2a5f1077f929 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Tue, 12 Jul 2022 11:04:25 +0300 Subject: [PATCH 087/116] extract Inflate to contract to support upgrades this is also a cleaner way to provide Inflate as a public good anyone can use --- .../nouns-contracts/contracts/Inflator.sol | 35 +++++++++++++++++++ .../nouns-contracts/contracts/NounsArt.sol | 22 ++++-------- .../contracts/interfaces/IInflator.sol | 24 +++++++++++++ .../contracts/interfaces/INounsArt.sol | 3 ++ .../tasks/deploy-descriptor-v2.ts | 11 +++++- .../nouns-contracts/tasks/deploy-local.ts | 12 ++++--- packages/nouns-contracts/tasks/deploy.ts | 9 ++--- packages/nouns-contracts/tasks/types/index.ts | 2 +- .../test/foundry/NounsArt.t.sol | 3 +- .../test/foundry/NounsDescriptorV2.t.sol | 3 +- .../test/foundry/helpers/DeployUtils.sol | 4 ++- .../NounsDAO/inflationHandling.test.ts | 1 - .../test/governance/NounsDAO/vetoing.test.ts | 1 - packages/nouns-contracts/test/utils.ts | 20 ++++++----- 14 files changed, 112 insertions(+), 38 deletions(-) create mode 100644 packages/nouns-contracts/contracts/Inflator.sol create mode 100644 packages/nouns-contracts/contracts/interfaces/IInflator.sol diff --git a/packages/nouns-contracts/contracts/Inflator.sol b/packages/nouns-contracts/contracts/Inflator.sol new file mode 100644 index 0000000000..dc36cdfab4 --- /dev/null +++ b/packages/nouns-contracts/contracts/Inflator.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-3.0 + +/// @title A contract used to convert multi-part RLE compressed images to SVG + +/********************************* + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░██░░░████░░██░░░████░░░ * + * ░░██████░░░████████░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + *********************************/ + +pragma solidity ^0.8.6; + +import { IInflator } from './interfaces/IInflator.sol'; +import { Inflate } from './libs/Inflate.sol'; + +contract Inflator is IInflator { + /** + * @notice Decompresses Deflated bytes using the Puff algorithm + * based on Based on https://github.com/adlerjohn/inflate-sol. + * @param source the bytes to decompress. + * @param destlen the length of the original decompressed bytes. + * @return Inflate.ErrorCode 0 if successful, otherwise an error code specifying the reason for failure. + * @return bytes the decompressed bytes. + */ + function puff(bytes memory source, uint256 destlen) public pure returns (Inflate.ErrorCode, bytes memory) { + return Inflate.puff(source, destlen); + } +} diff --git a/packages/nouns-contracts/contracts/NounsArt.sol b/packages/nouns-contracts/contracts/NounsArt.sol index a0f9b30f4c..5d05c23363 100644 --- a/packages/nouns-contracts/contracts/NounsArt.sol +++ b/packages/nouns-contracts/contracts/NounsArt.sol @@ -18,13 +18,16 @@ pragma solidity ^0.8.6; import { INounsArt } from './interfaces/INounsArt.sol'; -import { Inflate } from './libs/Inflate.sol'; import { SSTORE2 } from './libs/SSTORE2.sol'; +import { IInflator } from './interfaces/IInflator.sol'; contract NounsArt is INounsArt { /// @notice Current Nouns Descriptor address address public override descriptor; + /// @notice Current inflator address + IInflator public override inflator; + /// @notice Noun Backgrounds (Hex Colors) string[] public override backgrounds; @@ -53,8 +56,9 @@ contract NounsArt is INounsArt { _; } - constructor(address _descriptor) { + constructor(address _descriptor, IInflator _inflator) { descriptor = _descriptor; + inflator = _inflator; } /** @@ -359,18 +363,6 @@ contract NounsArt is INounsArt { return SSTORE2.read(palettesPointers[paletteIndex]); } - /** - * @notice Decompresses Deflated bytes using the Puff algorithm - * based on Based on https://github.com/adlerjohn/inflate-sol. - * @param source the bytes to decompress. - * @param destlen the length of the original decompressed bytes. - * @return Inflate.ErrorCode 0 if successful, otherwise an error code specifying the reason for failure. - * @return bytes the decompressed bytes. - */ - function puff(bytes memory source, uint256 destlen) public pure returns (Inflate.ErrorCode, bytes memory) { - return Inflate.puff(source, destlen); - } - function _addBackground(string calldata _background) internal { backgrounds.push(_background); } @@ -442,7 +434,7 @@ contract NounsArt is INounsArt { function decompressAndDecode(INounsArt.NounArtStoragePage storage page) internal view returns (bytes[] memory) { bytes memory compressedData = SSTORE2.read(page.pointer); - (, bytes memory decompressedData) = Inflate.puff(compressedData, page.decompressedLength); + (, bytes memory decompressedData) = inflator.puff(compressedData, page.decompressedLength); return abi.decode(decompressedData, (bytes[])); } } diff --git a/packages/nouns-contracts/contracts/interfaces/IInflator.sol b/packages/nouns-contracts/contracts/interfaces/IInflator.sol new file mode 100644 index 0000000000..07f8be43b0 --- /dev/null +++ b/packages/nouns-contracts/contracts/interfaces/IInflator.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-3.0 + +/// @title Interface for IInflator + +/********************************* + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░██░░░████░░██░░░████░░░ * + * ░░██████░░░████████░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░██░░██░░░████░░██░░░████░░░ * + * ░░░░░░█████████░░█████████░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * + *********************************/ + +pragma solidity ^0.8.6; + +import { Inflate } from '../libs/Inflate.sol'; + +interface IInflator { + function puff(bytes memory source, uint256 destlen) external pure returns (Inflate.ErrorCode, bytes memory); +} diff --git a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol index 7a3402af31..3baf2ec83a 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol @@ -18,6 +18,7 @@ pragma solidity ^0.8.6; import { Inflate } from '../libs/Inflate.sol'; +import { IInflator } from './IInflator.sol'; interface INounsArt { error SenderIsNotDescriptor(); @@ -63,6 +64,8 @@ interface INounsArt { function descriptor() external view returns (address); + function inflator() external view returns (IInflator); + function setDescriptor(address descriptor) external; function addManyBackgrounds(string[] calldata _backgrounds) external; diff --git a/packages/nouns-contracts/tasks/deploy-descriptor-v2.ts b/packages/nouns-contracts/tasks/deploy-descriptor-v2.ts index 544c20ae5f..740b3ee168 100644 --- a/packages/nouns-contracts/tasks/deploy-descriptor-v2.ts +++ b/packages/nouns-contracts/tasks/deploy-descriptor-v2.ts @@ -59,9 +59,18 @@ task('deploy-descriptor-v2', 'Deploy NounsDescriptorV2 & populate it with art'). }, }; + const inflator = await (await ethers.getContractFactory('Inflator', deployer)).deploy(); + contracts.Inflator = { + name: 'Inflator', + address: inflator.address, + instance: inflator, + constructorArguments: [], + libraries: {}, + }; + const art = await ( await ethers.getContractFactory('NounsArt', deployer) - ).deploy(nounsDescriptor.address); + ).deploy(nounsDescriptor.address, inflator.address); console.log(`actual art address: ${art.address}`); contracts.NounsArt = { name: 'NounsArt', diff --git a/packages/nouns-contracts/tasks/deploy-local.ts b/packages/nouns-contracts/tasks/deploy-local.ts index 7386031dd7..f5d84b11d5 100644 --- a/packages/nouns-contracts/tasks/deploy-local.ts +++ b/packages/nouns-contracts/tasks/deploy-local.ts @@ -38,9 +38,9 @@ task('deploy-local', 'Deploy contracts to hardhat') const proxyRegistryAddress = '0xa5409ec958c83c3f309868babaca7c86dcb077c1'; - const NOUNS_ART_NONCE_OFFSET = 4; - const AUCTION_HOUSE_PROXY_NONCE_OFFSET = 9; - const GOVERNOR_N_DELEGATOR_NONCE_OFFSET = 12; + const NOUNS_ART_NONCE_OFFSET = 5; + const AUCTION_HOUSE_PROXY_NONCE_OFFSET = 10; + const GOVERNOR_N_DELEGATOR_NONCE_OFFSET = 13; const [deployer] = await ethers.getSigners(); const nonce = await deployer.getTransactionCount(); @@ -66,8 +66,12 @@ task('deploy-local', 'Deploy contracts to hardhat') NFTDescriptorV2: contracts.NFTDescriptorV2.instance?.address as string, }), }, + Inflator: {}, NounsArt: { - args: [() => contracts.NounsDescriptorV2.instance?.address], + args: [ + () => contracts.NounsDescriptorV2.instance?.address, + () => contracts.Inflator.instance?.address, + ], }, NounsSeeder: {}, NounsToken: { diff --git a/packages/nouns-contracts/tasks/deploy.ts b/packages/nouns-contracts/tasks/deploy.ts index 04adfe83a0..90835cd3f9 100644 --- a/packages/nouns-contracts/tasks/deploy.ts +++ b/packages/nouns-contracts/tasks/deploy.ts @@ -19,9 +19,9 @@ const wethContracts: Record = { [ChainId.Kovan]: '0xd0a1e359811322d97991e03f863a0c30c2cf029c', }; -const NOUNS_ART_NONCE_OFFSET = 3; -const AUCTION_HOUSE_PROXY_NONCE_OFFSET = 8; -const GOVERNOR_N_DELEGATOR_NONCE_OFFSET = 11; +const NOUNS_ART_NONCE_OFFSET = 4; +const AUCTION_HOUSE_PROXY_NONCE_OFFSET = 9; +const GOVERNOR_N_DELEGATOR_NONCE_OFFSET = 12; task('deploy', 'Deploys NFTDescriptor, NounsDescriptor, NounsSeeder, and NounsToken') .addFlag('autoDeploy', 'Deploy all contracts without user interaction') @@ -130,8 +130,9 @@ task('deploy', 'Deploys NFTDescriptor, NounsDescriptor, NounsSeeder, and NounsTo NFTDescriptorV2: deployment.NFTDescriptorV2.address, }), }, + Inflator: {}, NounsArt: { - args: [() => deployment.NounsDescriptorV2.address], + args: [() => deployment.NounsDescriptorV2.address, () => deployment.Inflator.address], }, NounsSeeder: {}, NounsToken: { diff --git a/packages/nouns-contracts/tasks/types/index.ts b/packages/nouns-contracts/tasks/types/index.ts index 6e4bca0148..9070614f2f 100644 --- a/packages/nouns-contracts/tasks/types/index.ts +++ b/packages/nouns-contracts/tasks/types/index.ts @@ -10,7 +10,7 @@ export enum ChainId { // prettier-ignore export type DescriptorV1ContractNames = 'NFTDescriptor' | 'NounsDescriptor'; // prettier-ignore -export type DescriptorV2ContractNames = 'NFTDescriptorV2' | 'NounsDescriptorV2' | 'SVGRenderer' | 'NounsArt'; +export type DescriptorV2ContractNames = 'NFTDescriptorV2' | 'NounsDescriptorV2' | 'SVGRenderer' | 'NounsArt' | 'Inflator'; // prettier-ignore export type ContractName = DescriptorV2ContractNames | 'NounsSeeder' | 'NounsToken' | 'NounsAuctionHouse' | 'NounsAuctionHouseProxyAdmin' | 'NounsAuctionHouseProxy' | 'NounsDAOExecutor' | 'NounsDAOLogicV1' | 'NounsDAOProxy'; // prettier-ignore diff --git a/packages/nouns-contracts/test/foundry/NounsArt.t.sol b/packages/nouns-contracts/test/foundry/NounsArt.t.sol index 74fdb2724a..d9b9f8e9a6 100644 --- a/packages/nouns-contracts/test/foundry/NounsArt.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsArt.t.sol @@ -6,6 +6,7 @@ import { NounsArt } from '../../contracts/NounsArt.sol'; import { INounsArt } from '../../contracts/interfaces/INounsArt.sol'; import { SSTORE2 } from '../../contracts/libs/SSTORE2.sol'; import { DescriptorHelpers } from './helpers/DescriptorHelpers.sol'; +import { Inflator } from '../../contracts/Inflator.sol'; contract NounsArtTest is Test, DescriptorHelpers { event BackgroundsAdded(uint256 count); @@ -26,7 +27,7 @@ contract NounsArtTest is Test, DescriptorHelpers { address descriptor = address(1); function setUp() public { - art = new NounsArt(descriptor); + art = new NounsArt(descriptor, new Inflator()); } /// diff --git a/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol b/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol index e4710d29f4..a9b217917b 100644 --- a/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol @@ -9,6 +9,7 @@ import { INounsSeeder } from '../../contracts/interfaces/INounsSeeder.sol'; import { NounsArt } from '../../contracts/NounsArt.sol'; import { INounsArt } from '../../contracts/interfaces/INounsArt.sol'; import { Base64 } from 'base64-sol/base64.sol'; +import { Inflator } from '../../contracts/Inflator.sol'; contract NounsDescriptorV2Test is Test { NounsDescriptorV2 descriptor; @@ -18,7 +19,7 @@ contract NounsDescriptorV2Test is Test { function setUp() public { renderer = new SVGRenderer(); descriptor = new NounsDescriptorV2(INounsArt(address(0)), renderer); - art = new NounsArt(address(descriptor)); + art = new NounsArt(address(descriptor), new Inflator()); descriptor.setArt(art); } diff --git a/packages/nouns-contracts/test/foundry/helpers/DeployUtils.sol b/packages/nouns-contracts/test/foundry/helpers/DeployUtils.sol index 96bae9b7a9..783c0962e4 100644 --- a/packages/nouns-contracts/test/foundry/helpers/DeployUtils.sol +++ b/packages/nouns-contracts/test/foundry/helpers/DeployUtils.sol @@ -13,6 +13,7 @@ import { NounsDescriptor } from '../../../contracts/NounsDescriptor.sol'; import { NounsSeeder } from '../../../contracts/NounsSeeder.sol'; import { NounsToken } from '../../../contracts/NounsToken.sol'; import { NounsDAOProxy } from '../../../contracts/governance/NounsDAOProxy.sol'; +import { Inflator } from '../../../contracts/Inflator.sol'; abstract contract DeployUtils is Test, DescriptorHelpers { uint256 constant TIMELOCK_DELAY = 2 days; @@ -29,8 +30,9 @@ abstract contract DeployUtils is Test, DescriptorHelpers { function _deployDescriptorV2() internal returns (NounsDescriptorV2) { SVGRenderer renderer = new SVGRenderer(); + Inflator inflator = new Inflator(); NounsDescriptorV2 descriptorV2 = new NounsDescriptorV2(NounsArt(address(0)), renderer); - NounsArt art = new NounsArt(address(descriptorV2)); + NounsArt art = new NounsArt(address(descriptorV2), inflator); descriptorV2.setArt(art); return descriptorV2; } diff --git a/packages/nouns-contracts/test/governance/NounsDAO/inflationHandling.test.ts b/packages/nouns-contracts/test/governance/NounsDAO/inflationHandling.test.ts index 262a74d22d..92d00e843c 100644 --- a/packages/nouns-contracts/test/governance/NounsDAO/inflationHandling.test.ts +++ b/packages/nouns-contracts/test/governance/NounsDAO/inflationHandling.test.ts @@ -7,7 +7,6 @@ const { ethers } = hardhat; import { BigNumber as EthersBN } from 'ethers'; import { - deployNounsToken, getSigners, TestSigners, setTotalSupply, diff --git a/packages/nouns-contracts/test/governance/NounsDAO/vetoing.test.ts b/packages/nouns-contracts/test/governance/NounsDAO/vetoing.test.ts index 1e1a86bfdd..53aa85d647 100644 --- a/packages/nouns-contracts/test/governance/NounsDAO/vetoing.test.ts +++ b/packages/nouns-contracts/test/governance/NounsDAO/vetoing.test.ts @@ -7,7 +7,6 @@ const { ethers } = hardhat; import { BigNumber as EthersBN } from 'ethers'; import { - deployNounsToken, getSigners, TestSigners, setTotalSupply, diff --git a/packages/nouns-contracts/test/utils.ts b/packages/nouns-contracts/test/utils.ts index 528461e7a9..cc20a477b7 100644 --- a/packages/nouns-contracts/test/utils.ts +++ b/packages/nouns-contracts/test/utils.ts @@ -18,6 +18,7 @@ import { NounsDAOProxy__factory as NounsDaoProxyFactory, NounsDAOLogicV1, NounsDAOExecutor, + Inflator__factory, } from '../typechain'; import ImageData from '../files/image-data.json'; import ImageDataV2 from '../files/image-data_v2.json'; @@ -77,7 +78,9 @@ export const deployNounsDescriptorV2 = async ( renderer.address, ); - const art = await new NounsArtFactory(signer).deploy(descriptor.address); + const inflator = await new Inflator__factory(signer).deploy(); + + const art = await new NounsArtFactory(signer).deploy(descriptor.address, inflator.address); await descriptor.setArt(art.address); return descriptor; @@ -177,16 +180,17 @@ export const deployGovAndToken = async ( // nonce 2: Deploy nftDescriptorLibraryFactory // nonce 3: Deploy SVGRenderer // nonce 4: Deploy NounsDescriptor - // nonce 5: Deploy NounsArt - // nonce 6: NounsDescriptor.setArt - // nonce 7: Deploy NounsSeeder - // nonce 8: Deploy NounsToken - // nonce 9: Deploy NounsDAOProxy - // nonce 10+: populate Descriptor + // nonce 5: Deploy Inflator + // nonce 6: Deploy NounsArt + // nonce 7: NounsDescriptor.setArt + // nonce 8: Deploy NounsSeeder + // nonce 9: Deploy NounsToken + // nonce 10: Deploy NounsDAOProxy + // nonce 11+: populate Descriptor const govDelegatorAddress = ethers.utils.getContractAddress({ from: deployer.address, - nonce: (await deployer.getTransactionCount()) + 9, + nonce: (await deployer.getTransactionCount()) + 10, }); // Deploy NounsDAOExecutor with pre-computed Delegator address From 2f3f3d97aa11dfcd9efcfcaf392bb8a040cddc79 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Tue, 12 Jul 2022 11:06:05 +0300 Subject: [PATCH 088/116] cleanup --- packages/nouns-contracts/contracts/Inflator.sol | 2 +- packages/nouns-contracts/contracts/interfaces/IInflator.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nouns-contracts/contracts/Inflator.sol b/packages/nouns-contracts/contracts/Inflator.sol index dc36cdfab4..d6ebfe967e 100644 --- a/packages/nouns-contracts/contracts/Inflator.sol +++ b/packages/nouns-contracts/contracts/Inflator.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -/// @title A contract used to convert multi-part RLE compressed images to SVG +/// @title A contract used to decompress data compressed using the Deflate algorithm. /********************************* * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * diff --git a/packages/nouns-contracts/contracts/interfaces/IInflator.sol b/packages/nouns-contracts/contracts/interfaces/IInflator.sol index 07f8be43b0..2cdfd8b0f6 100644 --- a/packages/nouns-contracts/contracts/interfaces/IInflator.sol +++ b/packages/nouns-contracts/contracts/interfaces/IInflator.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -/// @title Interface for IInflator +/// @title Interface for Inflator /********************************* * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * From daa58afc1eb3c7503200644d892f4812bab5e0ae Mon Sep 17 00:00:00 2001 From: eladmallel Date: Tue, 12 Jul 2022 12:31:50 +0300 Subject: [PATCH 089/116] add inflator setter to art and descriptor v2 --- .../nouns-contracts/contracts/NounsArt.sol | 14 ++++++++-- .../contracts/NounsDescriptorV2.sol | 18 +++++++++--- .../contracts/interfaces/INounsArt.sol | 4 +++ .../test/foundry/NounsArt.t.sol | 28 ++++++++++++++++++- .../test/foundry/NounsDescriptorV2.t.sol | 12 ++++++++ 5 files changed, 69 insertions(+), 7 deletions(-) diff --git a/packages/nouns-contracts/contracts/NounsArt.sol b/packages/nouns-contracts/contracts/NounsArt.sol index 5d05c23363..99c4e32f6b 100644 --- a/packages/nouns-contracts/contracts/NounsArt.sol +++ b/packages/nouns-contracts/contracts/NounsArt.sol @@ -62,8 +62,7 @@ contract NounsArt is INounsArt { } /** - * @notice Set the pending descriptor, which can be confirmed - * by calling `confirmDescriptor`. + * @notice Set the descriptor. * @dev This function can only be called by the current descriptor. */ function setDescriptor(address _descriptor) external override onlyDescriptor { @@ -73,6 +72,17 @@ contract NounsArt is INounsArt { emit DescriptorUpdated(oldDescriptor, descriptor); } + /** + * @notice Set the inflator. + * @dev This function can only be called by the descriptor. + */ + function setInflator(IInflator _inflator) external override onlyDescriptor { + address oldInflator = address(inflator); + inflator = _inflator; + + emit InflatorUpdated(oldInflator, address(_inflator)); + } + /** * @notice Get the Trait struct for bodies. * @dev This explicit getter is needed because implicit getters for structs aren't fully supported yet: diff --git a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol index 0028cf34ec..026db3dc69 100644 --- a/packages/nouns-contracts/contracts/NounsDescriptorV2.sol +++ b/packages/nouns-contracts/contracts/NounsDescriptorV2.sol @@ -24,6 +24,7 @@ import { INounsSeeder } from './interfaces/INounsSeeder.sol'; import { NFTDescriptorV2 } from './libs/NFTDescriptorV2.sol'; import { ISVGRenderer } from './interfaces/ISVGRenderer.sol'; import { INounsArt } from './interfaces/INounsArt.sol'; +import { IInflator } from './interfaces/IInflator.sol'; contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { using Strings for uint256; @@ -81,12 +82,21 @@ contract NounsDescriptorV2 is INounsDescriptorV2, Ownable { } /** - * @notice Set the art contract's `pendingDescriptor`. - * @param pendingDescriptor the address to set. + * @notice Set the art contract's `descriptor`. + * @param descriptor the address to set. * @dev Only callable by the owner. */ - function setArtDescriptor(address pendingDescriptor) external onlyOwner { - art.setDescriptor(pendingDescriptor); + function setArtDescriptor(address descriptor) external onlyOwner { + art.setDescriptor(descriptor); + } + + /** + * @notice Set the art contract's `inflator`. + * @param inflator the address to set. + * @dev Only callable by the owner. + */ + function setArtInflator(IInflator inflator) external onlyOwner { + art.setInflator(inflator); } /** diff --git a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol index 3baf2ec83a..1005677264 100644 --- a/packages/nouns-contracts/contracts/interfaces/INounsArt.sol +++ b/packages/nouns-contracts/contracts/interfaces/INounsArt.sol @@ -39,6 +39,8 @@ interface INounsArt { event DescriptorUpdated(address oldDescriptor, address newDescriptor); + event InflatorUpdated(address oldInflator, address newInflator); + event BackgroundsAdded(uint256 count); event PaletteSet(uint8 paletteIndex); @@ -68,6 +70,8 @@ interface INounsArt { function setDescriptor(address descriptor) external; + function setInflator(IInflator inflator) external; + function addManyBackgrounds(string[] calldata _backgrounds) external; function addBackground(string calldata _background) external; diff --git a/packages/nouns-contracts/test/foundry/NounsArt.t.sol b/packages/nouns-contracts/test/foundry/NounsArt.t.sol index d9b9f8e9a6..cb04f415ec 100644 --- a/packages/nouns-contracts/test/foundry/NounsArt.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsArt.t.sol @@ -7,6 +7,7 @@ import { INounsArt } from '../../contracts/interfaces/INounsArt.sol'; import { SSTORE2 } from '../../contracts/libs/SSTORE2.sol'; import { DescriptorHelpers } from './helpers/DescriptorHelpers.sol'; import { Inflator } from '../../contracts/Inflator.sol'; +import { IInflator } from '../../contracts/interfaces/IInflator.sol'; contract NounsArtTest is Test, DescriptorHelpers { event BackgroundsAdded(uint256 count); @@ -23,11 +24,15 @@ contract NounsArtTest is Test, DescriptorHelpers { event DescriptorUpdated(address oldDescriptor, address newDescriptor); + event InflatorUpdated(address oldInflator, address newInflator); + NounsArt art; address descriptor = address(1); + IInflator inflator; function setUp() public { - art = new NounsArt(descriptor, new Inflator()); + inflator = new Inflator(); + art = new NounsArt(descriptor, inflator); } /// @@ -51,6 +56,27 @@ contract NounsArtTest is Test, DescriptorHelpers { assertEq(art.descriptor(), newDescriptor); } + /// + /// setInflator + /// + + function testSetInflatorRevertsIfSenderNotDescriptor() public { + vm.expectRevert(INounsArt.SenderIsNotDescriptor.selector); + art.setInflator(IInflator(address(2))); + } + + function testSetInflatorWorks() public { + IInflator newInflator = IInflator(address(2)); + + vm.expectEmit(true, true, true, true); + emit InflatorUpdated(address(inflator), address(newInflator)); + + vm.prank(descriptor); + art.setInflator(newInflator); + + assertEq(address(art.inflator()), address(newInflator)); + } + /// /// addBackground, addManyBackgrounds, backgroundsCount, backgrounds /// diff --git a/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol b/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol index a9b217917b..e1de02963f 100644 --- a/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol +++ b/packages/nouns-contracts/test/foundry/NounsDescriptorV2.t.sol @@ -10,6 +10,7 @@ import { NounsArt } from '../../contracts/NounsArt.sol'; import { INounsArt } from '../../contracts/interfaces/INounsArt.sol'; import { Base64 } from 'base64-sol/base64.sol'; import { Inflator } from '../../contracts/Inflator.sol'; +import { IInflator } from '../../contracts/interfaces/IInflator.sol'; contract NounsDescriptorV2Test is Test { NounsDescriptorV2 descriptor; @@ -68,6 +69,17 @@ contract NounsDescriptorV2Test is Test { descriptor.setArtDescriptor(address(42)); } + function testCannotSetArtInflatorIfNotOwner() public { + vm.prank(address(1)); + vm.expectRevert(bytes('Ownable: caller is not the owner')); + descriptor.setArtInflator(IInflator(address(2))); + } + + function testSetArtInflatorUsesArt() public { + vm.expectCall(address(art), abi.encodeCall(art.setInflator, IInflator(address(42)))); + descriptor.setArtInflator(IInflator(address(42))); + } + function testDataURIEnabledByDefault() public { assertEq(descriptor.isDataURIEnabled(), true); } From 29a0ce3e904cd2042a67364051d428efb36f7d8b Mon Sep 17 00:00:00 2001 From: eladmallel Date: Tue, 12 Jul 2022 16:09:23 +0300 Subject: [PATCH 090/116] fix descriptorv2 deployment task * transfer ownership to DAO executor * fix the expected art contract address calculation, it did not account for the added inflator contract --- .../tasks/deploy-descriptor-v2.ts | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/nouns-contracts/tasks/deploy-descriptor-v2.ts b/packages/nouns-contracts/tasks/deploy-descriptor-v2.ts index 740b3ee168..42715516a2 100644 --- a/packages/nouns-contracts/tasks/deploy-descriptor-v2.ts +++ b/packages/nouns-contracts/tasks/deploy-descriptor-v2.ts @@ -6,8 +6,12 @@ async function delay(seconds: number) { return new Promise(resolve => setTimeout(resolve, 1000 * seconds)); } -task('deploy-descriptor-v2', 'Deploy NounsDescriptorV2 & populate it with art').setAction( - async ({}, { ethers, run, network }) => { +task('deploy-descriptor-v2', 'Deploy NounsDescriptorV2 & populate it with art') + .addParam( + 'daoExecutor', + 'The address of the NounsDAOExecutor that should be the owner of the descriptor.', + ) + .setAction(async ({ daoExecutor }, { ethers, run, network }) => { const contracts: Record = {} as Record< ContractName, DeployedContract @@ -18,7 +22,7 @@ task('deploy-descriptor-v2', 'Deploy NounsDescriptorV2 & populate it with art'). const nonce = await deployer.getTransactionCount(); const expectedNounsArtAddress = ethers.utils.getContractAddress({ from: deployer.address, - nonce: nonce + 3, + nonce: nonce + 4, }); console.log('Deploying contracts...'); @@ -97,6 +101,10 @@ task('deploy-descriptor-v2', 'Deploy NounsDescriptorV2 & populate it with art'). }); console.log('Population complete.'); + console.log('Transfering ownership to DAO Executor...'); + await nounsDescriptor.transferOwnership(daoExecutor); + console.log('Transfer complete.'); + if (network.name !== 'localhost') { console.log('Waiting 1 minute before verifying contracts on Etherscan'); await delay(60); @@ -107,5 +115,4 @@ task('deploy-descriptor-v2', 'Deploy NounsDescriptorV2 & populate it with art'). }); console.log('Verify complete.'); } - }, -); + }); From c494674b3a08f97929caf53f1c37e6a4f278ff41 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Tue, 12 Jul 2022 16:49:58 +0300 Subject: [PATCH 091/116] point deploy preview to rinkeby --- netlify.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netlify.toml b/netlify.toml index 71254cd717..bdabc5132b 100644 --- a/netlify.toml +++ b/netlify.toml @@ -11,7 +11,7 @@ REACT_APP_ENABLE_HISTORY = "true" [context.deploy-preview.environment] - REACT_APP_CHAIN_ID = "1" + REACT_APP_CHAIN_ID = "4" REACT_APP_ENABLE_HISTORY = "true" [functions] From 41ccf22fa01194c8689ada1920fee59159db4596 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Tue, 12 Jul 2022 16:52:01 +0300 Subject: [PATCH 092/116] update rinkeby addresses to latest deployment --- .../nouns-sdk/src/contract/addresses.json | 22 +++++++++---------- packages/nouns-subgraph/config/rinkeby.json | 12 +++++----- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/nouns-sdk/src/contract/addresses.json b/packages/nouns-sdk/src/contract/addresses.json index b42f6b68a0..57ae94825e 100644 --- a/packages/nouns-sdk/src/contract/addresses.json +++ b/packages/nouns-sdk/src/contract/addresses.json @@ -12,16 +12,16 @@ "nounsDAOLogicV1": "0xa43aFE317985726E4e194eb061Af77fbCb43F944" }, "4": { - "nounsToken": "0x632f34c3aee991b10D4b421Bc05413a03d7a37eB", - "nounsSeeder": "0xA98A1b1Cc4f5746A753167BAf8e0C26AcBe42F2E", - "nounsDescriptor": "0x53cB482c73655D2287AE3282AD1395F82e6a402F", - "nftDescriptor": "0x1F28f148ef5f9BD182cCEfeAD4240A505C54dc9B", - "nounsAuctionHouse": "0xfAB74e535409A3ad1F7C2858dd2E5Da1eAAc6cE7", - "nounsAuctionHouseProxy": "0x7cb0384b923280269b3BD85f0a7fEaB776588382", - "nounsAuctionHouseProxyAdmin": "0x04d0e5a8ADB5076C098f49F39B01A774c313597d", - "nounsDaoExecutor": "0x6F3940820288855418B7ef8E33a2eC23d9DeD59B", - "nounsDAOProxy": "0xd1C753D9A23eb5c57e0d023e993B9bd4F5086b04", - "nounsDAOLogicV1": "0xdF05F2D3276F3F3fA00296702e4cf7190B78F6F9" + "nounsToken": "0x442961F79C3968f908ed295a5DEbfcD9aC1712B6", + "nounsSeeder": "0x2fb885C03285D409485b33a285D6f13108B8386E", + "nounsDescriptor": "0x9884B2DFEBEf89e9A1a420aF43f7A2cAD54e040D", + "nftDescriptor": "0xE3F474821e6e4F712ba16D64AEbcccFd63373f3D", + "nounsAuctionHouse": "0x3F2e938318f5a9438853D25083DbE7CFB9A0652d", + "nounsAuctionHouseProxy": "0x2e29f14602ca236D001e8C5855939464dCC7AcD9", + "nounsAuctionHouseProxyAdmin": "0xF82152a4322800E15F14eD85e490Fe12b815E6c3", + "nounsDaoExecutor": "0x440afFbe17339a4c955c5dCE232725dA3a3Ff040", + "nounsDAOProxy": "0xe3A8B54A2b0ec636d6310aCcA1b002B80934f741", + "nounsDAOLogicV1": "0xE45C75AcF9F09c93c67a0f9B8dCF99460ce15310" }, "31337": { "nounsToken": "0x0165878a594ca255338adfa4d48449f69242eb8f", @@ -35,4 +35,4 @@ "nounsDAOProxy": "0xa51c1fc2f0d1a1b8494ed1fe312d7c3a78ed91c0", "nounsDAOLogicV1": "0xb7f8bc63bbcad18155201308c8f3540b07f84f5e" } -} +} \ No newline at end of file diff --git a/packages/nouns-subgraph/config/rinkeby.json b/packages/nouns-subgraph/config/rinkeby.json index 000d1e7432..f29ece2902 100644 --- a/packages/nouns-subgraph/config/rinkeby.json +++ b/packages/nouns-subgraph/config/rinkeby.json @@ -1,15 +1,15 @@ { "network": "rinkeby", "nounsToken": { - "address": "0xc52bb4Fc4ed72f2a910BF0481D620B927Ded76f7", - "startBlock": 8947618 + "address": "0x442961F79C3968f908ed295a5DEbfcD9aC1712B6", + "startBlock": 11011622 }, "nounsAuctionHouse": { - "address": "0xBA088c634394775D89cAC7c67DFD52D73bfdFa05", - "startBlock": 8947622 + "address": "0x2e29f14602ca236D001e8C5855939464dCC7AcD9", + "startBlock": 11011622 }, "nounsDAO": { - "address": "0x2817A1A4Ae32AEc0D15b2E751AC207Da306Ea213", - "startBlock": 8973384 + "address": "0xe3A8B54A2b0ec636d6310aCcA1b002B80934f741", + "startBlock": 11011622 } } From 5e4ebd6eb7e130f5443da870ccc09de6b20b370b Mon Sep 17 00:00:00 2001 From: eladmallel Date: Tue, 12 Jul 2022 16:53:39 +0300 Subject: [PATCH 093/116] point webapp to latest subgraph --- packages/nouns-webapp/src/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nouns-webapp/src/config.ts b/packages/nouns-webapp/src/config.ts index f200c07cb7..dcec410033 100644 --- a/packages/nouns-webapp/src/config.ts +++ b/packages/nouns-webapp/src/config.ts @@ -59,7 +59,7 @@ const app: Record = { [ChainId.Rinkeby]: { jsonRpcUri: createNetworkHttpUrl('rinkeby'), wsRpcUri: createNetworkWsUrl('rinkeby'), - subgraphApiUri: 'https://api.thegraph.com/subgraphs/name/nounsdao/nouns-subgraph-rinkeby-v4', + subgraphApiUri: 'https://api.thegraph.com/subgraphs/name/verbsteam/nouns-rinkeby', enableHistory: process.env.REACT_APP_ENABLE_HISTORY === 'true', }, [ChainId.Mainnet]: { From eda03d1c1f525e1a7238ab87d0266e3375436968 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Tue, 12 Jul 2022 16:58:44 +0300 Subject: [PATCH 094/116] append new test art to the webapp's art file --- packages/nouns-assets/src/image-data.json | 1726 ++++++++++++++++++++- 1 file changed, 1671 insertions(+), 55 deletions(-) diff --git a/packages/nouns-assets/src/image-data.json b/packages/nouns-assets/src/image-data.json index a73610fe80..0b8a9e02f7 100644 --- a/packages/nouns-assets/src/image-data.json +++ b/packages/nouns-assets/src/image-data.json @@ -363,6 +363,410 @@ { "filename": "body-yellow", "data": "0x0015171f090e1e0e1e0e1e0e1e021e01000b1e021e01000b1e021e01000b1e021e01000b1e021e01000b1e021e01000b1e021e01000b1e" + }, + { + "filename": "body-green-reversed", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_000", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_001", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_002", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_003", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_004", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_005", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_006", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_007", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_008", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_009", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_010", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_011", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_012", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_013", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_014", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_015", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_016", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_017", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_018", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_019", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_020", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_021", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_022", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_023", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_024", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_025", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_026", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_027", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_028", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_029", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_030", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_031", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_032", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_033", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_034", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_035", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_036", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_037", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_038", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_039", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_040", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_041", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_042", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_043", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_044", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_045", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_046", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_047", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_048", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_049", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_050", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_051", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_052", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_053", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_054", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_055", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_056", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_057", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_058", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_059", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_060", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_061", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_062", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_063", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_064", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_065", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_066", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_067", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_068", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_069", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_070", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_071", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_072", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_073", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_074", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_075", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_076", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_077", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_078", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_079", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_080", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_081", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_082", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_083", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_084", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_085", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_086", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_087", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_088", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_089", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_090", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_091", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_092", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_093", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_094", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_095", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_096", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_097", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_098", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + }, + { + "filename": "body-green-reversed_099", + "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" } ], "accessories": [ @@ -913,108 +1317,512 @@ { "filename": "body-ice-cold", "data": "0x0015171f090e060e060e060e06020601000b06020601000b06020601000b06020601000b06020601000b06020601000b06020601000b06" - } - ], - "heads": [ + }, { - "filename": "head-aardvark", - "data": "0x00021e140605000137020001370f0004000237020002370e0003000337020003370d0002000437020004370c0003000337020003370d0004000237020002370e0005000137020001370f000d370b000d370b000d370b000d370b000d370b000d370b000d370600057d0d370600017d017e017d017e017d0b37097d017e017d017e017d0b370d7d0a370523097d0b370d7d" + "filename": "accessory-txt-dao-black-reversed", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-abstract", - "data": "0x00041a1405045c01000447010004470100017f01000114010001140100045c01230447012304470123017f01230114012301140123045c01230447012304470123017f01230114012301140123045c01230447012304470123017f01230114012301140123045c01230447012304470123017f012301140123011401230100142301230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f012304460100132301000123015401230154012301540123040701230455012304550123015401230154012301540123040701230455012304550123015401230154012301540123010703540123045501230455012301540123015401230154012304070123045501230455012301540123015401230154012304070123045501230455" + "filename": "accessory-txt-dao-black-reversed_000", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-ape", - "data": "0x0005191406030004800c0002000980080001000e80040002000f80020001001080020002000f80020002000f800200020001800e810200020001800e810200020001800e810200020001800e81020003800e8102000180018101800f8101000180018103800d82018005800d81018002001180" + "filename": "accessory-txt-dao-black-reversed_001", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-bag", - "data": "0x00031c140306000e3a050006000e3a05000400023a0e00023a03000400023a0e00023a03000400023a0e00023a030002000207023a0e07023a02070100020001070126023a040706260407023a01260107010001000126010702260607042606070226010701000100012608070626080701000100013a16070100013a0100013a15070100013a0100013a15070100013a0107013a1607013a0107013a1607010018070100070703760e0701001807020016070100" + "filename": "accessory-txt-dao-black-reversed_002", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-bagpipe", - "data": "0x00011d19050a0001830d000a00030f0b000a0001830200010f0100018308000a00020f0300010f017a07000a000108010f017a020f0108017a010f06000a00020f017a020f0183017a020f050001000183080001830100017a010f010001080100020f018304000200010807000108040001080200010f017a010f030003000108060001080300010803000183017a010f0300040001080500010803000108020001080100017a010f0200010f0200017a030f017a030f010803000108020001080200020f017a01000100010f017a030f017a030f017a03000108010001080400010f017a010f0100010f017a030f017a030f017a010f01000108020001080400010f02000100010f017a030f017a030f017a020f01080100010808000100010f017a030f017a030f017a030f017a020f07000100010f017a030f017a030f017a030f017a030f017a050001000108017a030f017a030f017a030f017a030f017a010f0400010001080200020f017a030f0211020f017a030f017a010f0400010001080400017a030f017a030f017a030f017a010f0400010001080400017a030f017a030f017a030f017a0500010001080500030f017a030f017a030f017a0500010001080700010f017a030f017a020f070001000108160001000183160003831500" + "filename": "accessory-txt-dao-black-reversed_003", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-banana", - "data": "0x00041d140304000523047903260a0005000323047905260900060001230479072608000700037909260700070002790226012b07260700070001790326012b0326022b0226070007000226012b0526022b02260700012606000826022b022606000126022605000826022b022605000226032604000c26040003260126012b022602000e26020004260226012b022601000e26010005260326012b1226012b032601001426012b0326010002000a26032b0926020003000626015706260157062603000400042603570526025704260400" + "filename": "accessory-txt-dao-black-reversed_004", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-bank", - "data": "0x00031c15040b00021f0b000900061f09000700031f0472031f07000500021f020c011f0472011f020c021f05000300021f020c031f0472031f020c021f03000100161f01000100167201000200031f0272041f0272041f0272031f02000200011f010c011f0272041f0272041f0272011f010c011f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200011f1272011f02000100161f0100021f1472021f" + "filename": "accessory-txt-dao-black-reversed_005", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-baseball-gameball", - "data": "0x00041a17060800040b08000600080b0600040001240b0b04000300020b01240a0b0124010b02000200030b01240a0b0124010b02000200030b01240a0b0124010b02000100040b01240a0b0124020b01000100030b01240c0b0124010b0100040b01240c0b0124020b030b01240e0b0124010b030b01240e0b0124010b030b01240e0b0124010b0100030b01240c0b0124010b01000100030b01240c0b0124010b01000200030b01240a0b0124010b02000200040b0224060b0224020b02000300050b0624030b030004000c0b04000600080b06000800040b0800" + "filename": "accessory-txt-dao-black-reversed_006", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-basketball", - "data": "0x00031a160607000542011a070005000442011a0242011a0242050003000242021a0542011a0442030002000542011a0442011a0442011a020002000142011a0442011a0342011a0342011a0142020001000842011a0242011a0242011a0342010001000142011a0742051a044201000c42011a07420c42011a07420c42011a0742141a0c42011a07420c42011a074201000b42011a0642010001000942051a04420100020004420166010e0166010e0166010e011a0242011a0242020002000642011a0342011a0342011a0142020003000442011a0442011a044203000500021a0542011a0242050007000542011a0700" + "filename": "accessory-txt-dao-black-reversed_007", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-bat", - "data": "0x00031e14020900018408000184090009000184080001840900080003840600038408000400018402000284018501840600018401850284020001840400040005840185028404000284018505840400030001840185038401850a84018503840185018403000300058401850a8401850584030002000184018514840185018402000200018401851484018501840200010001840185168401850184010001000184018516840185018401000100018401851684018501840100010001840185168401850184010001840185188401850184018401851884018501840784018504840223016201230162022301840185078402840300028401850384032301010123010101230284018502840300028401840500108405000184" + "filename": "accessory-txt-dao-black-reversed_008", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-bear", - "data": "0x0005181508058606000586018602370286060002860237018610861086108610861086108610861086108610860208028602080223018701230187022301080286020802860208072301080286020802860208028602080286020802860208028602080286020802860208028601000e080100" + "filename": "accessory-txt-dao-black-reversed_009", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-beer", - "data": "0x00021914060500028702000387070004000b87040003000f87010003000f870100020011870200018701420c87016d02870300024201680287016802470587016d018701000388024201680247016802470168014702870168016d0187010003880342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701420247016802470268016d0200028801000342024701420247016802470268016d020003880342024701420247016802470268016d0200010002880342024701420247014202470268016d020003000c420168016d02000300058807850288020003000e880200" + "filename": "accessory-txt-dao-black-reversed_010", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-beet", - "data": "0x00021a14060400031d0200028009000400011d0119021d0280010c018008000400021d0119011d0180010c028008000500021d0119010c028009000600011d0119010c01800a00070002850b000200108902000100091901890119018901190189011903890100148903191089011914891489128902191489148902190f89031901000a8902200689010002000419018901190789011901890119020003000e890300" + "filename": "accessory-txt-dao-black-reversed_011", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-bell", - "data": "0x00011c14040b0002260b000b0002260b0008000826080007000226010107260700060002260101092606000500022601010b26050005000e26050005000e2605000400102604000400102604000400102604000400102604000400102604000400108a04000400108a0400020014260200020001260101122602000c26033709261826010016260100" + "filename": "accessory-txt-dao-black-reversed_012", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-bigfoot-yeti", - "data": "0x00021d14020d00047f0a000d00067f08000c00037f0156017f0156017f08000c00027f0156015a0156015a017f08000c00027f028b0156018b017f08000900057f018b0156015a0156017f080008000b7f080007000b7f090006000d7f080005000e7f018c07000400047f01000a7f038c05000300047f02000a7f058c03000200047f02000b7f078c0100047f03000c7f0300058c037f04000c7f0400018c0100018c010007000b7f09000700087f028d027f08000800028c0a7f07000700068c087f0600" + "filename": "accessory-txt-dao-black-reversed_013", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-bigfoot", - "data": "0x00021d14020d0004340a000d00063408000c000334012b0134012b013408000c000234012b0136012b0136013408000c000234028e012b018e0134080009000534018e012b0136012b0134080008000b34080007000b34090006000d34080005000e34013607000400043401000a34033605000300043402000a34053603000200043402000b3407360100043403000c3403000536033404000c340400013601000136010007000b34090007000834021602340800080002360a3407000700063608340600" + "filename": "accessory-txt-dao-black-reversed_014", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-blackhole", - "data": "0x00011d17030e00018f0b000d00018f0c000400018f15000300018f0600015f0600015f0400018f03000300018f0500015f0600015f0600018f02000800015f0300045f0300015f06000800015f01190120015f0320031908000400015f0200015f01190220045f0220025f07000400015f0100015f01190120025f0490025f01200119015f06000400015f0100015f0120015f029004230290015f01200119015f0100015f03000200015f0200025f0120015f019006230190015f022001190300018f010005000119025f019008230190025f01190400018f018f0500025f019008230190015f0120015f01190300018f018f0400015f0120015f019008230190015f0120015f05000100018f0300015f0120015f019008230190015f0120015f05000500015f01190120015f019006230190015f02200119015f04000300015f0200035f029004230290025f02190100015f03000400025f02190120025f0490025f0220015f01190100015f03000700015f01190220045f0120015f01200119015f060006000219055f0320015f02190200015f04000200018f0700015f01000319015f0a000300018f0900015f0900018f02001600018f0300" + "filename": "accessory-txt-dao-black-reversed_015", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-blueberry", - "data": "0x00041a1706070006430700050005430691040003000143019101560591035403910300020002430691015403770154039102000200014306910254047701540291020001000243079101540477015403910100010001430156089104540491010002431291034311910343119102431291024312910243129101000143039106770891010001000143049102920991014301910100020002430e910200020004430c9102000400024309910143040004000543069101430400070006430700" + "filename": "accessory-txt-dao-black-reversed_016", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-bomb", - "data": "0x00041c16070f00010d05000600060d0200030d028302000400040d0172090d0100018301000300020d02720a0d030001830200030d0272090d040001830100100d030001830100100d03000193120d02000141120d0300120d0300120d0300120d0300120d03000100100d04000100100d04000200060d0572030d050003000c0d060004000a0d07000600060d0900" + "filename": "accessory-txt-dao-black-reversed_017", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-bonsai", - "data": "0x00021e15030c00070f08000a00030f031c040f07000800050f031c010f021c020f06000600040f011c020f031c010f021c020f06000500100f060006000e0f0200030f02000a00080f0300020f011c020f01000100070f0600027c0300080f020f021c060f0400037c060f021c020f020f021c010f011c050f0400017c070f021c020f0b0f0400037c080f01000b0f0300097c04000100080f087c0a000200030f047c0300047c0b000a00067c0b000900087c0a00040012940500040005940d0e050004001294050006000e940700" + "filename": "accessory-txt-dao-black-reversed_018", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-boombox", - "data": "0x00041b1f06040002580f00060002580d00080002580b00020008950258079502000200019509000258040001950200020001950b0002580200019502000296136f0296016f011c016f0195016f090e016f0195016f0124016f0296136f0296036f030e026f0195016f0195026f030e036f0296026f050e056f050e026f0296016f070e016f0195016f070e016f0296016f070e036f070e016f0296016f070e016f0195016f070e016f0296026f050e056f050e026f0296036f030e026f0195016f0195026f030e036f0296136f1200020e01001300010e01001300010e01001300010e01001300010e01001300010e01001300010e01001300010e01001300010e01001300010e01001300010e0100" + "filename": "accessory-txt-dao-black-reversed_019", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-boot", - "data": "0x00061c140701000697030002970900010006970208010001970198090001000797020801970198090001000897010801970198090001000b97090001000b97090001000b9709000d9708000e9707001497010015971597049703260e971597010013830100" + "filename": "accessory-txt-dao-black-reversed_020", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-box", - "data": "0x00061c1403040003970f9901080200030004970f99010802000200049701080f99020801000200049701080f99020801000100049702080f9902080100059702080f990308040003080f990308040003080f990300040003080f9903000400029901080f9903000400029901080f99030004000299010805990a0203000400030805990a0203000400030805990a020300040003080f990300" + "filename": "accessory-txt-dao-black-reversed_021", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-boxingglove", - "data": "0x000418140504000d55020002000a55043802550100010012551355135513550255018901550607095502550189015506070955025501890155060709550255018901550607095502550189015506070955030001550607095503000f550100040003550b26010004000355012605010123010103260100040003550b26010004000e550100" + "filename": "accessory-txt-dao-black-reversed_022", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" }, { - "filename": "head-brain", - "data": "0x00051a14060600086a06000300036a0320016a0420036a03000200016a0320036a0120046a0320016a02000100016a0120026a0120016a0120016a0120016a0120026a0120026a0120016a01000100016a0120016a0120026a0120026a0120026a0120056a0100066a0120036a0120026a0120026a0120016a0120016a016a0120046a0120066a0120046a0120016a016a0120026a0120026a0120036a0120066a0120016a046a0120026a0120046a0120016a0220026a0120016a016a0120026a0120036a0120096a0120016a016a0120036a0120056a0120066a0120016a066a0120056a0220046a0120016a0100126a01000100016a0120036a0220026a0120056a0220016a01000200016a0120016a0120026a0220046a0220026a020003000e6a0300" + "filename": "accessory-txt-dao-black-reversed_023", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_024", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_025", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_026", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_027", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_028", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_029", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_030", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_031", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_032", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_033", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_034", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_035", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_036", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_037", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_038", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_039", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_040", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_041", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_042", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_043", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_044", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_045", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_046", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_047", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_048", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_049", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_050", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_051", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_052", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_053", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_054", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_055", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_056", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_057", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_058", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_059", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_060", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_061", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_062", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_063", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_064", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_065", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_066", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_067", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_068", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_069", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_070", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_071", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_072", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_073", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_074", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_075", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_076", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_077", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_078", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_079", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_080", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_081", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_082", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_083", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_084", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_085", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_086", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_087", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_088", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_089", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_090", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_091", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_092", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_093", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_094", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_095", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_096", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_097", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_098", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + }, + { + "filename": "accessory-txt-dao-black-reversed_099", + "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + } + ], + "heads": [ + { + "filename": "head-aardvark", + "data": "0x00021e140605000137020001370f0004000237020002370e0003000337020003370d0002000437020004370c0003000337020003370d0004000237020002370e0005000137020001370f000d370b000d370b000d370b000d370b000d370b000d370b000d370600057d0d370600017d017e017d017e017d0b37097d017e017d017e017d0b370d7d0a370523097d0b370d7d" + }, + { + "filename": "head-abstract", + "data": "0x00041a1405045c01000447010004470100017f01000114010001140100045c01230447012304470123017f01230114012301140123045c01230447012304470123017f01230114012301140123045c01230447012304470123017f01230114012301140123045c01230447012304470123017f012301140123011401230100142301230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f012304460100132301000123015401230154012301540123040701230455012304550123015401230154012301540123040701230455012304550123015401230154012301540123010703540123045501230455012301540123015401230154012304070123045501230455012301540123015401230154012304070123045501230455" + }, + { + "filename": "head-ape", + "data": "0x0005191406030004800c0002000980080001000e80040002000f80020001001080020002000f80020002000f800200020001800e810200020001800e810200020001800e810200020001800e81020003800e8102000180018101800f8101000180018103800d82018005800d81018002001180" + }, + { + "filename": "head-bag", + "data": "0x00031c140306000e3a050006000e3a05000400023a0e00023a03000400023a0e00023a03000400023a0e00023a030002000207023a0e07023a02070100020001070126023a040706260407023a01260107010001000126010702260607042606070226010701000100012608070626080701000100013a16070100013a0100013a15070100013a0100013a15070100013a0107013a1607013a0107013a1607010018070100070703760e0701001807020016070100" + }, + { + "filename": "head-bagpipe", + "data": "0x00011d19050a0001830d000a00030f0b000a0001830200010f0100018308000a00020f0300010f017a07000a000108010f017a020f0108017a010f06000a00020f017a020f0183017a020f050001000183080001830100017a010f010001080100020f018304000200010807000108040001080200010f017a010f030003000108060001080300010803000183017a010f0300040001080500010803000108020001080100017a010f0200010f0200017a030f017a030f010803000108020001080200020f017a01000100010f017a030f017a030f017a03000108010001080400010f017a010f0100010f017a030f017a030f017a010f01000108020001080400010f02000100010f017a030f017a030f017a020f01080100010808000100010f017a030f017a030f017a030f017a020f07000100010f017a030f017a030f017a030f017a030f017a050001000108017a030f017a030f017a030f017a030f017a010f0400010001080200020f017a030f0211020f017a030f017a010f0400010001080400017a030f017a030f017a030f017a010f0400010001080400017a030f017a030f017a030f017a0500010001080500030f017a030f017a030f017a0500010001080700010f017a030f017a020f070001000108160001000183160003831500" + }, + { + "filename": "head-banana", + "data": "0x00041d140304000523047903260a0005000323047905260900060001230479072608000700037909260700070002790226012b07260700070001790326012b0326022b0226070007000226012b0526022b02260700012606000826022b022606000126022605000826022b022605000226032604000c26040003260126012b022602000e26020004260226012b022601000e26010005260326012b1226012b032601001426012b0326010002000a26032b0926020003000626015706260157062603000400042603570526025704260400" + }, + { + "filename": "head-bank", + "data": "0x00031c15040b00021f0b000900061f09000700031f0472031f07000500021f020c011f0472011f020c021f05000300021f020c031f0472031f020c021f03000100161f01000100167201000200031f0272041f0272041f0272031f02000200011f010c011f0272041f0272041f0272011f010c011f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200011f1272011f02000100161f0100021f1472021f" + }, + { + "filename": "head-baseball-gameball", + "data": "0x00041a17060800040b08000600080b0600040001240b0b04000300020b01240a0b0124010b02000200030b01240a0b0124010b02000200030b01240a0b0124010b02000100040b01240a0b0124020b01000100030b01240c0b0124010b0100040b01240c0b0124020b030b01240e0b0124010b030b01240e0b0124010b030b01240e0b0124010b0100030b01240c0b0124010b01000100030b01240c0b0124010b01000200030b01240a0b0124010b02000200040b0224060b0224020b02000300050b0624030b030004000c0b04000600080b06000800040b0800" + }, + { + "filename": "head-basketball", + "data": "0x00031a160607000542011a070005000442011a0242011a0242050003000242021a0542011a0442030002000542011a0442011a0442011a020002000142011a0442011a0342011a0342011a0142020001000842011a0242011a0242011a0342010001000142011a0742051a044201000c42011a07420c42011a07420c42011a0742141a0c42011a07420c42011a074201000b42011a0642010001000942051a04420100020004420166010e0166010e0166010e011a0242011a0242020002000642011a0342011a0342011a0142020003000442011a0442011a044203000500021a0542011a0242050007000542011a0700" + }, + { + "filename": "head-bat", + "data": "0x00031e14020900018408000184090009000184080001840900080003840600038408000400018402000284018501840600018401850284020001840400040005840185028404000284018505840400030001840185038401850a84018503840185018403000300058401850a8401850584030002000184018514840185018402000200018401851484018501840200010001840185168401850184010001000184018516840185018401000100018401851684018501840100010001840185168401850184010001840185188401850184018401851884018501840784018504840223016201230162022301840185078402840300028401850384032301010123010101230284018502840300028401840500108405000184" + }, + { + "filename": "head-bear", + "data": "0x0005181508058606000586018602370286060002860237018610861086108610861086108610861086108610860208028602080223018701230187022301080286020802860208072301080286020802860208028602080286020802860208028602080286020802860208028601000e080100" + }, + { + "filename": "head-beer", + "data": "0x00021914060500028702000387070004000b87040003000f87010003000f870100020011870200018701420c87016d02870300024201680287016802470587016d018701000388024201680247016802470168014702870168016d0187010003880342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701420247016802470268016d0200028801000342024701420247016802470268016d020003880342024701420247016802470268016d0200010002880342024701420247014202470268016d020003000c420168016d02000300058807850288020003000e880200" + }, + { + "filename": "head-beet", + "data": "0x00021a14060400031d0200028009000400011d0119021d0280010c018008000400021d0119011d0180010c028008000500021d0119010c028009000600011d0119010c01800a00070002850b000200108902000100091901890119018901190189011903890100148903191089011914891489128902191489148902190f89031901000a8902200689010002000419018901190789011901890119020003000e890300" + }, + { + "filename": "head-bell", + "data": "0x00011c14040b0002260b000b0002260b0008000826080007000226010107260700060002260101092606000500022601010b26050005000e26050005000e2605000400102604000400102604000400102604000400102604000400102604000400108a04000400108a0400020014260200020001260101122602000c26033709261826010016260100" + }, + { + "filename": "head-bigfoot-yeti", + "data": "0x00021d14020d00047f0a000d00067f08000c00037f0156017f0156017f08000c00027f0156015a0156015a017f08000c00027f028b0156018b017f08000900057f018b0156015a0156017f080008000b7f080007000b7f090006000d7f080005000e7f018c07000400047f01000a7f038c05000300047f02000a7f058c03000200047f02000b7f078c0100047f03000c7f0300058c037f04000c7f0400018c0100018c010007000b7f09000700087f028d027f08000800028c0a7f07000700068c087f0600" + }, + { + "filename": "head-bigfoot", + "data": "0x00021d14020d0004340a000d00063408000c000334012b0134012b013408000c000234012b0136012b0136013408000c000234028e012b018e0134080009000534018e012b0136012b0134080008000b34080007000b34090006000d34080005000e34013607000400043401000a34033605000300043402000a34053603000200043402000b3407360100043403000c3403000536033404000c340400013601000136010007000b34090007000834021602340800080002360a3407000700063608340600" + }, + { + "filename": "head-blackhole", + "data": "0x00011d17030e00018f0b000d00018f0c000400018f15000300018f0600015f0600015f0400018f03000300018f0500015f0600015f0600018f02000800015f0300045f0300015f06000800015f01190120015f0320031908000400015f0200015f01190220045f0220025f07000400015f0100015f01190120025f0490025f01200119015f06000400015f0100015f0120015f029004230290015f01200119015f0100015f03000200015f0200025f0120015f019006230190015f022001190300018f010005000119025f019008230190025f01190400018f018f0500025f019008230190015f0120015f01190300018f018f0400015f0120015f019008230190015f0120015f05000100018f0300015f0120015f019008230190015f0120015f05000500015f01190120015f019006230190015f02200119015f04000300015f0200035f029004230290025f02190100015f03000400025f02190120025f0490025f0220015f01190100015f03000700015f01190220045f0120015f01200119015f060006000219055f0320015f02190200015f04000200018f0700015f01000319015f0a000300018f0900015f0900018f02001600018f0300" + }, + { + "filename": "head-blueberry", + "data": "0x00041a1706070006430700050005430691040003000143019101560591035403910300020002430691015403770154039102000200014306910254047701540291020001000243079101540477015403910100010001430156089104540491010002431291034311910343119102431291024312910243129101000143039106770891010001000143049102920991014301910100020002430e910200020004430c9102000400024309910143040004000543069101430400070006430700" + }, + { + "filename": "head-bomb", + "data": "0x00041c16070f00010d05000600060d0200030d028302000400040d0172090d0100018301000300020d02720a0d030001830200030d0272090d040001830100100d030001830100100d03000193120d02000141120d0300120d0300120d0300120d0300120d03000100100d04000100100d04000200060d0572030d050003000c0d060004000a0d07000600060d0900" + }, + { + "filename": "head-bonsai", + "data": "0x00021e15030c00070f08000a00030f031c040f07000800050f031c010f021c020f06000600040f011c020f031c010f021c020f06000500100f060006000e0f0200030f02000a00080f0300020f011c020f01000100070f0600027c0300080f020f021c060f0400037c060f021c020f020f021c010f011c050f0400017c070f021c020f0b0f0400037c080f01000b0f0300097c04000100080f087c0a000200030f047c0300047c0b000a00067c0b000900087c0a00040012940500040005940d0e050004001294050006000e940700" + }, + { + "filename": "head-boombox", + "data": "0x00041b1f06040002580f00060002580d00080002580b00020008950258079502000200019509000258040001950200020001950b0002580200019502000296136f0296016f011c016f0195016f090e016f0195016f0124016f0296136f0296036f030e026f0195016f0195026f030e036f0296026f050e056f050e026f0296016f070e016f0195016f070e016f0296016f070e036f070e016f0296016f070e016f0195016f070e016f0296026f050e056f050e026f0296036f030e026f0195016f0195026f030e036f0296136f1200020e01001300010e01001300010e01001300010e01001300010e01001300010e01001300010e01001300010e01001300010e01001300010e01001300010e0100" + }, + { + "filename": "head-boot", + "data": "0x00061c140701000697030002970900010006970208010001970198090001000797020801970198090001000897010801970198090001000b97090001000b97090001000b9709000d9708000e9707001497010015971597049703260e971597010013830100" + }, + { + "filename": "head-box", + "data": "0x00061c1403040003970f9901080200030004970f99010802000200049701080f99020801000200049701080f99020801000100049702080f9902080100059702080f990308040003080f990308040003080f990300040003080f9903000400029901080f9903000400029901080f99030004000299010805990a0203000400030805990a0203000400030805990a020300040003080f990300" + }, + { + "filename": "head-boxingglove", + "data": "0x000418140504000d55020002000a55043802550100010012551355135513550255018901550607095502550189015506070955025501890155060709550255018901550607095502550189015506070955030001550607095503000f550100040003550b26010004000355012605010123010103260100040003550b26010004000e550100" + }, + { + "filename": "head-brain", + "data": "0x00051a14060600086a06000300036a0320016a0420036a03000200016a0320036a0120046a0320016a02000100016a0120026a0120016a0120016a0120016a0120026a0120026a0120016a01000100016a0120016a0120026a0120026a0120026a0120056a0100066a0120036a0120026a0120026a0120016a0120016a016a0120046a0120066a0120046a0120016a016a0120026a0120026a0120036a0120066a0120016a046a0120026a0120046a0120016a0220026a0120016a016a0120026a0120036a0120096a0120016a016a0120036a0120056a0120066a0120016a066a0120056a0220046a0120016a0100126a01000100016a0120036a0220026a0120056a0220016a01000200016a0120016a0120026a0220046a0220026a020003000e6a0300" }, { "filename": "head-bubble-speech", @@ -1851,8 +2659,412 @@ { "filename": "head-zebra", "data": "0x00061b14060a0001010123090001000223035e0101012301010123010102230100035e040001000201035e0101012301010123010101230200035e040001000223055e0123035e0123045e040001000201065e0323055e040001000223065e0323055e040001000201075e0123065e040001000223075e0123065e040001000201075e0123065e0400010002230e5e0400010002010c5e0623010002230d5e012301010123010101230301025e0101012301010123010101230101035e062303230d5e052303010d5e0523" - } - ], + }, + { + "filename": "head-thumbsup-reversed", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_000", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_001", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_002", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_003", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_004", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_005", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_006", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_007", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_008", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_009", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_010", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_011", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_012", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_013", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_014", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_015", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_016", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_017", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_018", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_019", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_020", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_021", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_022", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_023", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_024", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_025", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_026", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_027", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_028", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_029", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_030", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_031", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_032", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_033", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_034", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_035", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_036", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_037", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_038", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_039", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_040", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_041", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_042", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_043", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_044", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_045", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_046", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_047", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_048", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_049", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_050", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_051", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_052", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_053", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_054", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_055", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_056", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_057", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_058", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_059", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_060", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_061", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_062", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_063", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_064", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_065", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_066", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_067", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_068", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_069", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_070", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_071", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_072", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_073", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_074", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_075", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_076", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_077", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_078", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_079", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_080", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_081", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_082", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_083", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_084", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_085", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_086", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_087", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_088", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_089", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_090", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_091", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_092", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_093", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_094", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_095", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_096", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_097", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_098", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + }, + { + "filename": "head-thumbsup-reversed_099", + "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" + } + ], "glasses": [ { "filename": "glasses-hip-rose", @@ -1937,6 +3149,410 @@ { "filename": "glasses-square-yellow-saturated", "data": "0x000b17100703000628010006280300012802010223012801000128020102230128042802010223032802010223012801280200012802010223012801000128020102230128012802000128020102230128010001280201022301280300062801000628" + }, + { + "filename": "glasses-hip-rose-reversed_reversed", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_000", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_001", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_002", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_003", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_004", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_005", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_006", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_007", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_008", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_009", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_010", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_011", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_012", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_013", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_014", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_015", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_016", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_017", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_018", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_019", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_020", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_021", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_022", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_023", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_024", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_025", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_026", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_027", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_028", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_029", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_030", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_031", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_032", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_033", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_034", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_035", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_036", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_037", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_038", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_039", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_040", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_041", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_042", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_043", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_044", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_045", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_046", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_047", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_048", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_049", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_050", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_051", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_052", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_053", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_054", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_055", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_056", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_057", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_058", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_059", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_060", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_061", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_062", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_063", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_064", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_065", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_066", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_067", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_068", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_069", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_070", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_071", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_072", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_073", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_074", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_075", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_076", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_077", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_078", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_079", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_080", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_081", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_082", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_083", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_084", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_085", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_086", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_087", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_088", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_089", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_090", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_091", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_092", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_093", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_094", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_095", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_096", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_097", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_098", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_099", + "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" } ] } From b16a480ca2737493c0654e4eb681c43a4879e49d Mon Sep 17 00:00:00 2001 From: eladmallel Date: Tue, 12 Jul 2022 18:58:31 +0300 Subject: [PATCH 095/116] fix NounsArt verification in the v2 deploy task --- packages/nouns-contracts/tasks/deploy-descriptor-v2.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nouns-contracts/tasks/deploy-descriptor-v2.ts b/packages/nouns-contracts/tasks/deploy-descriptor-v2.ts index 42715516a2..6bc8bc3340 100644 --- a/packages/nouns-contracts/tasks/deploy-descriptor-v2.ts +++ b/packages/nouns-contracts/tasks/deploy-descriptor-v2.ts @@ -79,7 +79,7 @@ task('deploy-descriptor-v2', 'Deploy NounsDescriptorV2 & populate it with art') contracts.NounsArt = { name: 'NounsArt', address: art.address, - constructorArguments: [nounsDescriptor.address], + constructorArguments: [nounsDescriptor.address, inflator.address], instance: art, libraries: {}, }; From c6ba2fb927cdf637f4d49571b92625f87c59734e Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Wed, 13 Jul 2022 14:12:58 +0200 Subject: [PATCH 096/116] update image json with latest encoding version --- packages/nouns-assets/src/image-data_v2.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nouns-assets/src/image-data_v2.json b/packages/nouns-assets/src/image-data_v2.json index 375ef220d5..a63cb77239 100644 --- a/packages/nouns-assets/src/image-data_v2.json +++ b/packages/nouns-assets/src/image-data_v2.json @@ -650,7 +650,7 @@ }, { "filename": "accessory-none", - "data": "0x00000100000100" + "data": "0x0000000000" }, { "filename": "accessory-oldshirt", From 2fc18a10bc803b9224f53d902d414f339318653b Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Wed, 13 Jul 2022 14:32:55 +0200 Subject: [PATCH 097/116] also update image json in contracts package --- packages/nouns-contracts/files/image-data_v2.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nouns-contracts/files/image-data_v2.json b/packages/nouns-contracts/files/image-data_v2.json index 375ef220d5..a63cb77239 100644 --- a/packages/nouns-contracts/files/image-data_v2.json +++ b/packages/nouns-contracts/files/image-data_v2.json @@ -650,7 +650,7 @@ }, { "filename": "accessory-none", - "data": "0x00000100000100" + "data": "0x0000000000" }, { "filename": "accessory-oldshirt", From 59dd834e77843746b64bdf69fcf58c1c6348e400 Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Wed, 13 Jul 2022 14:42:57 +0200 Subject: [PATCH 098/116] update test with latest encoded images file --- .../test/foundry/DescriptorUpgrade.t.sol | 11 +++++------ .../foundry/files/descriptor_v2/accessoriesPage.abi | 2 +- .../test/foundry/helpers/DescriptorHelpers.sol | 2 ++ 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol b/packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol index a2dcdaea69..61e0349ed1 100644 --- a/packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol +++ b/packages/nouns-contracts/test/foundry/DescriptorUpgrade.t.sol @@ -29,20 +29,19 @@ contract DescriptorUpgradeTest is Test, DeployUtils { } function testUpgradeToV2MaintainsTokenURI() public { - for (uint256 i = 0; i < 10; i++) { + uint256 tokensToMint = 10; + for (uint256 i = 0; i < tokensToMint; i++) { vm.prank(minter); nounsToken.mint(); } - for (uint256 i = 0; i < 10; i++) { + for (uint256 i = 0; i < tokensToMint; i++) { nounsToken.setDescriptor(descriptor); - string memory tokenURIwithV1 = nounsToken.tokenURI(1); + string memory tokenURIwithV1 = nounsToken.tokenURI(i); nounsToken.setDescriptor(descriptorV2); - string memory tokenURIwithV2 = nounsToken.tokenURI(1); + string memory tokenURIwithV2 = nounsToken.tokenURI(i); - // both _populateDescriptor and _populateDescriptorV2 are hard-coded to populate - // with the first item of each type found in image-data.json. assertEq(tokenURIwithV2, tokenURIwithV1); } } diff --git a/packages/nouns-contracts/test/foundry/files/descriptor_v2/accessoriesPage.abi b/packages/nouns-contracts/test/foundry/files/descriptor_v2/accessoriesPage.abi index 253a20e194..689d471c54 100644 --- a/packages/nouns-contracts/test/foundry/files/descriptor_v2/accessoriesPage.abi +++ b/packages/nouns-contracts/test/foundry/files/descriptor_v2/accessoriesPage.abi @@ -1 +1 @@ -0x00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000004aa000000000000000000000000000000000000000000000000000000000000000890000000000000000000000000000000000000000000000000000000000000ed5bd5b5b731bb715060eb0a4e815494b9644c9a224da944545aae3b88e233bbec956e2c4719d3477374e5bc94dd2ba759b8b7b499b74469d3e743a7deebb66fa47f4de3fa19fd2ef1c60c925232d76576d31fa78cec1013e5c168b05b02ba5324327dbadfe9eed9e08e49fd80df80fb2fd939b01ff5ec01fe03f15e03f15e09fea04fcbbd9fee96cb79ade0ef8f7b3fd339b01ff5eb6bf95ed56aded6cff6ca0fcd940f97381f2e7f6b3fda73b01ff6ec07f90ed9fdf0cf8f7b2fded4eb67f21dbad1602fc8b9bd9fea500ffd26eb6bf13c8df39c8f69f09f09f0d147036c0dfddcbf62f6f07fcfbd9fe73d96e752ec07f6e2fdbbf12e05fd9cdf6f73a017f28ff41b67f7533e00ff0af06f89f0bf03fb797ed5fcb76abb500ffda6ec07f90ed5fdf0bf803f9bfd709f8b703fefd6cfff900fff900fff9bd6cfff301ff8580ff856cb77a6133e00ff05f0cf05f0cf05fdccff67fbf13f06f07fc01fe4b01fe4bbb017f80ffc5cd807f2fe03fc8f65f0ef05fde0df803fc2f7502fe00ff4b01fe8dcd807f3fdb7f25dbadae04f8afec65fbaf06f8af6e07fcfbd9fe973b01ff6eb6ff5a20ffb550fefd6cfff500fff5836cff8dcd807f37e00ff0df0cf0dfdccbf6dfca76ab5bdb01ff7eb67fb313f007f837f7b2fdb7b3ddea7680fff67eb6ff4e27e0df0df80fb2fd5b9b01ff5eb6ff956cb77a653be0dfcff6bfda09f8f7b2fd77b3ddeaee6ec07f90ed7f6d33dbff7aa0fcd7f702fe40f9f702e5df0bf0bf91edc604a05a538b75adf452a468a9026900f2883c083eede3585a2f43ecd840a9d9e9d37552a683f41d5211a04577a04e98232b5c40fd171a9aa2339aec19709239831248b32e1a7026f2a0c2fcebaa3529fd73965151044967a321a9cfa28cb3a654fd97a47fc0d5451f77c125127c5d0319e6ecaad6a9761dd763d92a5ad6ca2eebae3ec7d228b34c127f9c70434d4f2dd4f50a7a6f05b55b311eac735c45a411ddfa7897ceace4e9ed2d353db318eb5e4de91ef2f5aa00f87b91879138c3fe7a55513d422cd50dc7896d7ae5fa3d093d358bf16fa505d46f8191d6b0ed5a1695e6bf87fe5b1c77fda47d1f313b092b093b495cc5f5ebaa8355d6f5f92ae725e42d172ea2fcf98cf2adaa3c47288bfc6fd172647ce46a1fb70525483badf8f25cb90781fe43fd45d7d247bacf6f86e292b1593c6cf0fc52c7685e03a34043c73d0aa93d08b611dda5e1b479c3053573aaddd0ebb8db01bdae3dc84b233a41b700ad17adff2535c3d747ee54d3ef8d44729c5155b95bb987abd2bb45c2bfd4746ba946dfc39ce56153bae07c029bd281e765b67b9e0476c862c0be004d60872ce00549fd0209ec90c5807d119a47d13e4b87f3d2bef6f7db976842ab3a104fd08bd080f845ba0c0d882fd34bf87da938ff7ac2bf4c1be04a21dea02bd080f80a5dc56f68af7468f8abf0375fd6d7f4a138794d5b7d288c45e91ee3565f479f5ed7761406f1e3d7f50d786fe8eba330888f6f94a977129e73fd7373f1166a02c4b70825d65388afd3267e37cbf1fbeb7bbb7d87efe83a10af51131a1037690b1a106fd1247e278bf3f7847fed959335308d20aed1abd080f8d572b54feabf76b7718eee80e70e4de1778a5e032f10bf46af43f38843abd5434257cd9e5a6860ae58c0155e3002ba8719e91e74c1f1d6170fd46cab5de319c9f4913c2f4c7f1d91f868680d829ac047a9bcc5839fbf96a94d6fb85f9bd2f13bd0daf68d743a6aa32efd183b64e1176b319de24c5bcc0a3bc59bb64699a97d9cfe7d26edc33aa6aa059197a66abcaca6c036d63dfd34a84795bc1d797d9096aa035e0b5fc25baa7ef7b520f2d2dc375e5653601bf5eba741fdee93b723af0fd2d2fd01af852fe12d12fe96d4ef07c87b179c53063381b35043d1b10699448a07d02711873bd0e984f4ce429d45b78ee36ec287f83e1bdaf280bc8dd5caa4b31caf2e31f3b8f040eacf7b0994d5ad7839e12556995e0ee2b2d21ca37c427eaa7839e125b8bd1cc465a5295ebebfbfdfa42d7acbfdda948edf81b665df4aa7e3b95ff763ec9085df3761a738d316b3c24ef1a6ad5166da2adeaa41f8d4f56f13e30e88462479699ad188c4d86a5ad1ed88fc6e9e12dd3e5abf39f000d188242fcd5c342251bf392bba1d91dfcd739cfafdd38d0fbfff263fcee950d821dbf4f7ead48d52faf1f314b9cf7cfddf402e0f9bd287618f881fcd63f8e9e3f528a5e7cd53e47af4fbbf93c0a6f461d8211b25f6f528a51f3f4f9133a973bc3ec2fe90575c4472f2f4433c6dc8cd789a50ca0f8f73425107bf9c9f813b2e31d06fa8d6f422f2d302f67a0bd6afe35057c078908fd3f09b85c8db639061fe18d7af556bcc35561a778ad78ef7a7b353ed3a7ae96db4f16dddd56feb2b006cdc1d4eb20f7146d2b05d247c28e3abd12355e961ae808c815a0fadf6e07327237eadc6e4bc8904a637061bbbe29ef56949d2c64813f7f296bf93947f1be5df46397750fe1d947f871c98730df16bbefc35d84d8ec53cdcab36254ef621a8c716d203b0a41eb227c95d93c3c3ba6a61fca2b5efa0e5efa01448fb0edb5a6c9615f1959b652ff7cf6f68e40cc7faf3212b276d63729693ff5c68c0cfe7d7bc63e3e79481b47866697996b9679c96671a89ad0545762c2dbeff1a7a15d77f151cab9ad773abf9c7607ffff42e6af22e6af6ae7e0f50d17be011fb384f2f3e3f9a9d6ee3fad9f7c0054e02b400ad079c8eb2e1b7ef152fab8bf96381cfbf095788aa320f8d11cf4755d8633cdf1dabfee778fc35302e4e30c84b8c97f7b1ef7b1f63e17dbd32f67e797e5cbf99d3f52a9eaaa68b7b093072ca9e37ff92cbff017af203dd470530a287f2afcbf9e118d29280bcacaa313ff3d2027959a67d7f5733adc59afe10753914278f88673400f35fca537614a07ff9fd82a2870e0d207a8899fa219e090fc333c1929a999c6ff228a414f48fe4bdcf8fc2e3bd89f17dfaa47b4f14ad9c287c835cf0efcf28c63d8607b48ed13b31ee9318cf5b4867733c66b9b8782ff1f9b0cc1f8fc0f348af3b89fe79a459ae9b47b44e90f0495cd1e0fa1f73c3c7687f0af663b4e9e3f07b8f69d59a6c37c67f8cd43fc638fe09a3482dfeedd77fba39828f0fc1689ac3d2e5498376152f2b0af8cbdd01fdf6fff4ff89e87f90a75cfb2fa99999457ebf827d17cfd25599a10d55ba7c4f6b48433c633b9f655f21fe3979fe5a99f549dea9927054733e017ac8df6e68dcb90e913a5c2fd174091bf2fcab6c8323070c4022f3f25795d2f25732bc25e3b3b3537d38b1438f51fa8e79483bfa61b4831a419a1d7a68c56360d52416f3f88e650f62eb1253f556bc53b4fccb81f78b95fe1ad2ca3b547eff57a4b51398ffe74e827983776b46453f2b56bf9e1f5f7a4b4e80bcac8cd8e5cfc8cfab56ab5d8b9599ac2a3bcbe78b768a259f278aa69c86d5d8ddf152fcb3d37cffd127e8c54fd08b9f40ff943ea18fc0faa9fd88a13946714cf1b0a4e65af3352d5f34a4d194af1de2e05d28e32fb6a78caaa5109dc278fb0cf2b30c99a41b9245eb7f554d4f2f8d9b36c6960774cc1f150fe887fa4ccef9655ecd4ece37f4cfd1273f473f4312a4b3f3e4bf21f56ba02fa3aef6b31bf7affe85f1df905487c09ec4ca332a17503fcc7f8a30bf9b9fb2343cdffbaf78c281bf9fe1fda57e137905a82140ded66f467c360a943b2599c3fcd0facef729f9be3de1704dd6e75aeefd6415e924ef71306200def30ce20769f384753583fd5324a7967a4ecb29a69d635b8b4d7398c1e6ead02ba5dabf2ee73be06a9ef4bb5d70366b00ee67bf2eb1d0a9e4fae4913bbf78d2d86aac36dad2fa2efa4660872c06f74d62d9210b7882fbfd09b9b7a9d841c7ab79ca6fa1fc85dadaf29a7cdd54f78897f3d69ff3cfd7d63e6a28fa25f2fdb2215f6ec4a1ffbbe807f77e1ead570c57fba3645ece43f82f831f20f996e028790cfe5f811fa05f81e748790cfe39f0033caae3236519fe33b83f4fd74deac96ffc1b62edbf6729c33a0837f07c3d5da3cfa89ec0a67406cae85b76c8a27a98ff676e7dbf8a1aafa205aba83d60a1dbd59a8a002b3e2d3e96d64b92b8b4cdf9c67cdc893e28d77d7454b82ae77f5a666294f1a1bca94a49ac643e74b37522d9c7325f3825eb6723b3698dd7f34091fa5d54d3934b0dcc25f73183e480be5facfdffc0fcbc84fd395d430b9fe24a3c85846eaeb18e9ebfc6801f3afddaf988d3b1dec66f92cfd94f9d2d7a1287f4b8f2bf461aac1004d04d3b49e3f252bbdc39a0ef9fdfa07f7e433950b47f623533b1d8b4b7498d87be853f345c90f343b4f1733c833ec7b3ee73b419d2005a743de42b1a6e31ff38f6875f80e70bac6a20d3d05f9060381eeba02f5c9e1cf59f6ad7cd97b8e7bec495fb126c47484e63be2c5affcbeefcfd2bd40ad05f914a74faaaeae3c09bf2338af0cf4ecf8f537fddad059442d43f131d207fb88afdfb029f6f75c7c03226b98dac2e0f9363be8413b94f605dff20cf3394f10c357ea6451ab1abde2691896e9ee5afffbc9a9b9eaf731f58df1fc67f899def2d2cf2637d42bfc5ba6404f16ff3e45fe7f9b1ae3f30fe6c993cdc3933f938033f05cf9a0f0b175cffddc473e726da75530bf44dccc5b08de8ba2fe96651fe1eef9feb3ab542d623ab65873275e7c0dfafb6eb982b78873b05d629f23201c71376c0cec77145c205f9fedefc0eb973807e57b4fe7cbe23e7c358fdea27a8df13d6abde46cf0baa23fefc6de8f3cb15247f15abde7657d6f4edc49f9fff6ac2df42fe16f2b75807dfef93fe67cdf055e0b7967ec7917fb7b1c1e7dbccff74f0fca5a7556f8359501df1e7afff19dc5ff3e0afc8ffab68ffff2d3af57f2eb9a90e0de7dcfc8df51cc9fa4e2ba757543aae7cb8e4f8f99efa83fbd5c9bdf5073c4537b4fbce7dc3ad88f5067f135984ff1ec6ffc2389e87edc8cd3ab22e19cc4058a7a4de7ba53d324ff5edb2ff21c1cfa7d3e3ee94cc97be3580ac929253b4f6c09f3f6cc9fa1bcf9bc7d8633f46eff029e463ebed9ad816a83c3e3acd7102cf8f3cfecc0756defe714fb9191efc32ab73ef95dbfb73b82affbfa2bfa63feaaf2340ff497f6dbd649be351824d8092ed09d1f385bfb8efb7bef15f3242d2370da553b691591777d337c64b99a3fb299ad069907bcaa452934f9df03bee74eee3bd5d56eacfaefedf82cb83be451929db7c8b5a7c6bfa20d8d4f735c51ee435a9b434e26bf8b8017738d4e5fcaf52c7dabc5e29b836e7d095f6bdacb1e63802255e3a7e971f24f52310977ef791e26f80eb08c48dff027f055c4720cebef9fe030000000000000000000000 \ No newline at end of file +0x00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000004aa000000000000000000000000000000000000000000000000000000000000000890000000000000000000000000000000000000000000000000000000000000ed3bd5b5b731bb715060eb0a4e815494b9644c9a224da944545aae3b88e233bbec956e2c4719d3477374e5bc94dd2ba759b8b7b499b74469d3e743a7deebb66fa47f4de3fa19fd2ef1c60c925232d76576d31f3f19c83037cb82c160b60974a65864eb65bfd3ddb3d11c83fb11bf01f64fb273703febd803fc07f2ac07f2ac03fd509f877b3fdd3d96e35bd1df0ef67fb673603febd6c7f2bdbad5adbd9fed940f9b381f2e702e5cfed67fb4f7702fedd80ff20db3fbf19f0ef65fbdb9d6cff42b65b2d04f81737b3fd4b01fea5dd6c7f2790bf7390ed3f13e03f1b28e06c80bfbb97ed5fde0ef8f7b3fde7b2ddea5c80ffdc5eb67f25c0bfb29bedef7502fe50fe836cffea66c01fe05f0df03f17e07f6e2fdbbf96ed566b01feb5dd80ff20dbbfbe17f007f27faf13f06f07fcfbd9fef301fef301fef37bd9fee703fe0b01ff0bd96ef5c266c01fe0bf18e0bf18e0bfb89fedff7e27e0df0ef803fc9702fc977603fe00ff8b9b01ff5ec07f90edbf1ce0bfbc1bf007f85fea04fc01fe9702fc1b9b01ff7eb6ff4ab65b5d09f05fd9cbf65f0df05fdd0ef8f7b3fd2f7702fedd6cffb540fe6ba1fcfbd9feeb01feeb07d9fe1b9b01ff6ec01fe0bf19e0bfb997edbf95ed56b7b603fefd6cff6627e00ff06fee65fb6f67bbd5ed00ffedfd6cff9d4ec0bf1bf01f64fbb73603febd6cff2bd96ef5ca76c0bf9fed7fb513f0ef65fbef66bbd5dddd80ff20dbffda66b6fff540f9afef05fc81f2ef05cabf17e07f23db8d0940b5a616eb5ae9a548d15205d200e41179107cdac7b1b45e86d8b18152b3d3a7eba44c07e93ba422408bee409d304756b880fa2f3434456734d933e02473062590665d34e04ce44185f9d7556b52fae72ca3a20892ce4643529f4519674da9fa2f49ff80ab8b3eee824b24f8ba0632ccd955ad53ed3aaec7b255b4ac955dd65d7d8ea551669924fe38e1869a9e5aa8eb15f4de0a6ab7623c58e7b88a4823baf5f12e9d59c9d3db5b6a7a6631d6bd9ad23de4eb5501f0f7220f237186fdf5aaa27a8458aa1b8e13dbf4caf57b127a6a16e3df4a0ba8df0223ad61dbb52c2acd7f0ffdb738eefa49fb3e62761256127692b88aebd75507abacebf355ce4bc85b2e5c44f9f319e55b55798e5016f9dfa2e5c8f8c8d53e6e0b4a90765af1e5b9720f02fd87fa8baea58f749fdf0cc52563b378d8e0f9a58ed1bc064681868e7b14527b106c23ba4bc369f3860b6ae654bba1d771b7037a5d7b90974674826e015a2f5aff4b6a86af8fdca9a6df1b89e438a3aa72b7720f57a5778b847fa9e9d6528dbe8739cbc3a674c1f90436a503cfcb6cf73c09ec90c5807d019ac00e59c00b92fa0512d8218b01fb22348fa27d960ee7a57dedefb72fd1845675209ea017a101f18b74191a105fa697f0fb5271fef5847f9936c09542bc4157a001f115ba8adfd05ee9d0f057e16fbeacafe94371f29ab6fa50188bd23dc6adbe8e3ebdaeed280ce2c7afeb1bf0ded0d74761101fdf2853ef243ce7fae7e6e22dd404886f114aaca7105fa74dfc6e96e3f7d7f776fb0edfd175205ea32634206ed2163420dea249fc4e16e7ef09ffda2b276b601a415ca357a101f1abe56a9fd47fed6ee31cdd01cf1d9ac2ef14bd065e207e8d5e87e6118756ab8784ae9a3db5d0c05cb1802bbc6004740f33d23de882e3ad2f1ea8d956bbc63392e923795e98fe3a22f1d1d01a0435818f52798b073f7f2d539bde70bf36a5e377a0b5ed1be974d4465dfa3176c8c22fd6623ac599b69815768a376d8d3253fb38fdfb4cda87754c550b222f4dd578594d816dac7bfa69508f2a793bf2fa202d5507bc16be84b754fdee6b41e4a5b96fbcaca6c036ead74f83fadd276f475e1fa4a5fb035e0b5fc25b24fc2da9df0f90f72e38a70c660267a186a2630d3289140fa04f220e77a0d309e99d853a8b6e1dc7dd840ff17d36b4e501791bab954967395e5d62e671e181d49ff71228ab5bf172c24bac32bd1cc465a53946f984fc54f172c24b707b3988cb4a53bc7c7f7fbf495bf496fbb5291dbf036dcbbe954ec773bfeec7d8210bbf6fc24e71a62d66859de24d5ba3ccb455bc5583f0a9ebdf26c61d108d48f2d234a31189b1d5b4a2db11f9dd3c25ba7db47e73e001a211495e9ab96844a27e7356743b22bf9be738f5fba71b1f7eff4d7e9cd3a1b043b6e9efd5a91ba5f4e3e729729ff9fabf815c1e36a50fc31e113f9ac7f0d3c7eb514acf9ba7c8f5e8f77f27814de9c3b043364aeceb514a3f7e9e226752e7787d84fd21afb888e4e4e98778da909bf134a1941f1ee784a20e7e393f03775c62a0df50ade945e4a705ecf516ac5fc7a1ae80f1201fa7e1370b91b7c720c3fc31ae5fabd6986bac34ee14af1def4f67a7da75f4d2db68e3dbbaabdfd65700d8b83b9c641fe28ca461bb48f850c657a347aad2c35c011903b51e5aedc1e74e46fc5a8dc97913094c6f0c3676c53debd392a48d9126eee52d7f2729ff36cabf8d72eea0fc3b28ff0e3930e71ae2d77cf96bb09b1c8b79b8576d4a9cec43508f2da40760493d644f92bb26878775d5c2f8456bdf41cbdf412990f61db6b5d82c2be22b37cb5eee9fdfd0c8198ef5e743564edac6e42c27ffb9d0809fcfaf79c7c6cf290369f1ccd2f22c73cf382dcf34125b0b8aec585a7cff35f42aaeff2a385635afe756f38fc1fefee95dd4e45dd4ec5dfd1ea0a2f7c023f6719e5e7c7e343bddc6f5b3ef810b9c0468015a0f381d65c36fdf2b5e5617f3c7029f7f13ae1055651e1a239e8faab0c778be3b56fdcff1f86b605c9c609097182fef63dff73ec6c2fb7a65ecfdf2fcb87e33a7eb553c554d17f71260e4943d6ffe2597ff03f4e407ba8f0a60440fe55f97f3c331a42501795955637ee6a505f2b24cfbfeae665a8b35fd21ea72284e1e11cf6800e6bf94a7ec2840fff2fb05450f1d1a40f41033f5433c131e86678225353339dfe4514829e81fc97b9f1f85c77b13e3fbf449f79e285a3951f806b9e0df9f518c7b0c0f681da37762dc27319eb790cee678cc7271f15ee2f361993f1e81e7915e7712fdf348b35c378f689d20e193b8a2c1f53fe6868fd1fe14ecc768d3c7e1f71ed3aa35d96e8cff18a97f8c71fc1346915afcdbafff7473041f1f82d13487a5cb9306ed2a5e5614f097bb03faedffe9ff13d1ff204fb9f65f5233338bfc7e05fb2e9ea5ab32431baa74f99ed6908678c6763ecbbe42fc73f2fcb532eb93bc5325e1a8e67c02f490bfddd0b8731d2275b85ea2e91236e4f957d906470e188044e6e52fffe6d285b7647c7676aa0f2776e8314adf310f69473f8c76502348b3430fad780cac9ac4621edfb1ec416c5d62aade8a778a967f39f07eb1d25f435a7987caefff8a8cc409ccff7327c1bcc1bb35a3a29f15ab5fcf8f2fbd2527405e5646ecf267e4e755abd5aec5ca4c56959de5f3453bc592cf1345534ec36aecee7829fed969beffe813f4e227e8c54fa07f4a9fd04760fdd47ec4d01ca338a678585273adf99a962f1ad268cad70e71f02e94f117db5346d552884e61bc7d06f959864cd20dc9a2f5bfaaa6a797c64d1b63cb033ae68f8a07f4437d26e7fc32af6627e71bfae7e8939fa39f2109d2d979f2df90fa35d0975157fbd98dfb57ffc2f86f48aa43604f62e519950ba81fe63f4598dfcd4f591a9eeffd573ce1c0dfcff0fe52bf89bc02d410206feb37233e1b05ca9d92cc617e687de7fb947cdf9e70b826eb732df77eb28a7492f738183100ef7906f183b479c2ba9ac1fe2992534b3da7e514d3ceb1adc5a639cc607375e89552ed5f97f31d70354ffadd2e389b3500f7b35f9758e854727df2c89d5f3c696c35561b6d697d177d23b0431683fb26b1ec90053cc1fdfe84dcdb54eca0e3d53ce5b750fe426d6d794dbe6eaa7bc4cb79ebcff9e76b6b1f3514fd12f97ed9902f37e2d0ff2efac1bd9f47eb15c3d5fe289997f310fecbe00748be25384a1e83ff57e007e857e039521e837f0efc008feaf8485986ff0ceecfd375937af21bff8658fbef59cab00ec20d3c5f4fd7e833aa27b0299d8132fa961db2a81ee6ff995bdfafa2c6ab68c12a6a0f58e876b5a622c08a4f8b8fa5f592242e6d73be311f77a20fca751f1d15aecaf99f969918657c286faa52122b990fdd6c9d48f6b1cc174ec9fad9c86c5ae3f53c50a47e17d5f4e4520373c97dcc2039a0ef176bff3f303f2f617f4ed7d0c2a7b8124f21a19b6baca3e7af31e0874ebf763ee274acb7f19be473f653678b9ec4213daefcaf91062b040174d34ed2b8bcd42e770ee8fbe737e89fdf500e14ed9f58cd4c2c36ed6d52e3a16fe10f0d17e4fc106dfc1ccfa0cff1acfb1c6d863480165d0ff98a865bcc3f8efde117e0f902ab1ac834f41724188ec73ae80b972747fda7da75f325eeb92f71e5be04db1192d3982f8bd6ffb23b7fff0ab502f457a4129dbeaafa38f0a6fc8c22fcb3d3f3e3d45f776b01a510f5cf4407c81fae62ffbec0e75bdd31b08c496e23abcbc3e4982fe144ee1358d73fc8f30c653c438d9f699146ecaab74964a29b67f9eb3fafe6a6e7ebdc07d6f787f15f62e77b0b8bfc589fd06fb12e1941fcdb3cf9d7797eaceb0f8c3f5b260f77ce4c3ecec04fc1b3e6c3c205d77f37f1dcb98976ddd4027d1373316c23baee4bba5994bfc7fbe7ba4ead90f5c86ad9a14cdd39f0f7abed3ae60adee14e81758abc4cc0f1841db0f3715c917041bebf37bf43ee1ca0df15ad3f9fefc8f93056bffa09eaf784f5aab7d1f382ea883f7f1bfafc7205c95fc5aab7dd95357d3bf1e7e7bf9af0b790bf85fc2dd6c1f7fba4ff59337c15f8ada5df71e4df6d6cf0f936f33f1d3c7fe969d5db60165447fcf9eb7f06f7d73cf82bf27f15edffdfa253ff73c94d756838e7e66face748d6775a39bda2d271e5c325c7cff7d41fdcaf4eeead3fe029baa1dd77ee1b6e45ac37f89bc822fcf730fe17c6f13c6c476ed69175c96006c23a25f5de2bed9179aa6f973d67e4e7d3e971774ae64bdf1a405649c9295a7be0cf1fb664fd8de7cd63ecb11fa377f814f2b1f5764d6c0b541e1f9de63881e7471e7fe6032b6fffb8a7dc0c0f7e99d5b9f7caedfd395c95ffafe8afe98ffaeb08d07fd25f5b2fd9e678946013a0647b42f47ce12feefbad6ffc978c90f44d43e9946d64d6c5ddf48df152e6e87e8a26741ae49e32a9d4e45327fc8e3b9dfb786f9795fab3abffb7e0f2a06f5146ca36dfa216df9a3e0836f57d4db107794d2a2d8df81a3e6ec01d0e7539ffabd4b136af570aaecd3974a57d2f6bac398e4089978edfe50749fd08c4a5df7da4f81be03a0271e3bfc05f01d71188b36fbeff0000000000000000000000000000 \ No newline at end of file diff --git a/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol b/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol index 77e4261542..a4436eb28d 100644 --- a/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol +++ b/packages/nouns-contracts/test/foundry/helpers/DescriptorHelpers.sol @@ -8,6 +8,7 @@ import { Constants } from './Constants.sol'; abstract contract DescriptorHelpers is Test, Constants { function _populateDescriptor(NounsDescriptor descriptor) internal { + // created with `npx hardhat descriptor-v1-export-abi` string memory filename = './test/foundry/files/descriptor_v1/image-data.abi'; bytes memory content = readFile(filename); ( @@ -28,6 +29,7 @@ abstract contract DescriptorHelpers is Test, Constants { } function _populateDescriptorV2(NounsDescriptorV2 descriptor) internal { + // created with `npx hardhat descriptor-art-to-console` (bytes memory palette, string[] memory backgrounds) = abi.decode( readFile('./test/foundry/files/descriptor_v2/paletteAndBackgrounds.abi'), (bytes, string[]) From bb0131390daedc193619968aaf2fffc0306faf5b Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Wed, 13 Jul 2022 18:24:54 +0200 Subject: [PATCH 099/116] reorg image-data.json files image-data.json: used only by nouns-assets mostly for webapp currently has the data from image-data-v2.json image-data-v2/v1.json: used by contracts to populate descriptors --- packages/nouns-assets/scripts/encode-more.ts | 2 +- packages/nouns-assets/scripts/encode.ts | 2 +- packages/nouns-assets/src/image-data.json | 2546 +++-------------- .../{image-data.json => image-data-v1.json} | 0 .../files/image-data-v2.json} | 0 .../nouns-contracts/files/image-data_v2.json | 1945 ------------- .../tasks/descriptor-art-to-console.ts | 2 +- .../tasks/descriptor-v1-export-abi.ts | 2 +- .../tasks/populate-descriptor-v1.ts | 2 +- .../tasks/populate-descriptor.ts | 2 +- .../nouns-contracts/test/descriptor.test.ts | 2 +- .../nouns-contracts/test/descriptorV2.test.ts | 2 +- packages/nouns-contracts/test/utils.ts | 4 +- 13 files changed, 476 insertions(+), 4035 deletions(-) rename packages/nouns-contracts/files/{image-data.json => image-data-v1.json} (100%) rename packages/{nouns-assets/src/image-data_v2.json => nouns-contracts/files/image-data-v2.json} (100%) delete mode 100644 packages/nouns-contracts/files/image-data_v2.json diff --git a/packages/nouns-assets/scripts/encode-more.ts b/packages/nouns-assets/scripts/encode-more.ts index 52b445fb64..8556506b64 100644 --- a/packages/nouns-assets/scripts/encode-more.ts +++ b/packages/nouns-assets/scripts/encode-more.ts @@ -2,7 +2,7 @@ import { PNGCollectionEncoder } from '@nouns/sdk'; import { promises as fs } from 'fs'; import path from 'path'; import { readPngImage } from './utils'; -import { palette } from '../src/image-data_v2.json'; +import { palette } from '../src/image-data.json'; /** * @notice creates an additional art json file. it assumes it's not the first one. diff --git a/packages/nouns-assets/scripts/encode.ts b/packages/nouns-assets/scripts/encode.ts index 6a26073f10..0bfdf09d04 100644 --- a/packages/nouns-assets/scripts/encode.ts +++ b/packages/nouns-assets/scripts/encode.ts @@ -3,7 +3,7 @@ import { promises as fs } from 'fs'; import path from 'path'; import { readPngImage } from './utils'; -const DESTINATION = path.join(__dirname, '../src/image-data_v2.json'); +const DESTINATION = path.join(__dirname, '../src/image-data.json'); const encode = async () => { const encoder = new PNGCollectionEncoder(); diff --git a/packages/nouns-assets/src/image-data.json b/packages/nouns-assets/src/image-data.json index 0b8a9e02f7..a63cb77239 100644 --- a/packages/nouns-assets/src/image-data.json +++ b/packages/nouns-assets/src/image-data.json @@ -1,9 +1,12 @@ { - "bgcolors": ["d5d7e1", "e1d7d5"], + "bgcolors": [ + "d5d7e1", + "e1d7d5" + ], "palette": [ "", - "ffffff", "c5b9a1", + "ffffff", "cfc2ab", "63a0f9", "807f7e", @@ -159,7 +162,6 @@ "42ffb0", "d56333", "b8ced2", - "b91b43", "f39713", "e8e8e2", "ec5b43", @@ -246,545 +248,141 @@ "bodies": [ { "filename": "body-bege-bsod", - "data": "0x0015171f090e020e020e020e02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02" + "data": "0x0015171f093a0101000d0101000d0101000d0101000d0101000d0101000d0101000b01" }, { "filename": "body-bege-crt", - "data": "0x0015171f090e030e030e030e03020301000b03020301000b03020301000b03020301000b03020301000b03020301000b03020301000b03" + "data": "0x0015171f093a0301000d0301000d0301000d0301000d0301000d0301000d0301000b03" }, { "filename": "body-blue-sky", - "data": "0x0015171f090e040e040e040e04020401000b04020401000b04020401000b04020401000b04020401000b04020401000b04020401000b04" + "data": "0x0015171f093a0401000d0401000d0401000d0401000d0401000d0401000d0401000b04" }, { "filename": "body-bluegrey", - "data": "0x0015171f090e050e050e050e05020501000b05020501000b05020501000b05020501000b05020501000b05020501000b05020501000b05" + "data": "0x0015171f093a0501000d0501000d0501000d0501000d0501000d0501000d0501000b05" }, { "filename": "body-cold", - "data": "0x0015171f090e060e060e060e06020601000b06020601000b06020601000b06020601000b06020601000b06020601000b06020601000b06" + "data": "0x0015171f093a0601000d0601000d0601000d0601000d0601000d0601000d0601000b06" }, { "filename": "body-computerblue", - "data": "0x0015171f090e070e070e070e07020701000b07020701000b07020701000b07020701000b07020701000b07020701000b07020701000b07" + "data": "0x0015171f093a0701000d0701000d0701000d0701000d0701000d0701000d0701000b07" }, { "filename": "body-darkbrown", - "data": "0x0015171f090e080e080e080e08020801000b08020801000b08020801000b08020801000b08020801000b08020801000b08020801000b08" + "data": "0x0015171f093a0801000d0801000d0801000d0801000d0801000d0801000d0801000b08" }, { "filename": "body-darkpink", - "data": "0x0015171f090e090e090e090e09020901000b09020901000b09020901000b09020901000b09020901000b09020901000b09020901000b09" + "data": "0x0015171f093a0901000d0901000d0901000d0901000d0901000d0901000d0901000b09" }, { "filename": "body-foggrey", - "data": "0x0015171f090e030e030e030e03020301000b03020301000b03020301000b03020301000b03020301000b03020301000b03020301000b03" + "data": "0x0015171f093a0301000d0301000d0301000d0301000d0301000d0301000d0301000b03" }, { "filename": "body-gold", - "data": "0x0015171f090e0a0e0a0e0a0e0a020a01000b0a020a01000b0a020a01000b0a020a01000b0a020a01000b0a020a01000b0a020a01000b0a" + "data": "0x0015171f093a0a01000d0a01000d0a01000d0a01000d0a01000d0a01000d0a01000b0a" }, { "filename": "body-grayscale-1", - "data": "0x0015171f090e0b0e0b0e0b0e0b020b01000b0b020b01000b0b020b01000b0b020b01000b0b020b01000b0b020b01000b0b020b01000b0b" + "data": "0x0015171f093a0b01000d0b01000d0b01000d0b01000d0b01000d0b01000d0b01000b0b" }, { "filename": "body-grayscale-7", - "data": "0x0015171f090e0c0e0c0e0c0e0c020c01000b0c020c01000b0c020c01000b0c020c01000b0c020c01000b0c020c01000b0c020c01000b0c" + "data": "0x0015171f093a0c01000d0c01000d0c01000d0c01000d0c01000d0c01000d0c01000b0c" }, { "filename": "body-grayscale-8", - "data": "0x0015171f090e0d0e0d0e0d0e0d020d01000b0d020d01000b0d020d01000b0d020d01000b0d020d01000b0d020d01000b0d020d01000b0d" + "data": "0x0015171f093a0d01000d0d01000d0d01000d0d01000d0d01000d0d01000d0d01000b0d" }, { "filename": "body-grayscale-9", - "data": "0x0015171f090e0e0e0e0e0e0e0e020e01000b0e020e01000b0e020e01000b0e020e01000b0e020e01000b0e020e01000b0e020e01000b0e" + "data": "0x0015171f093a0e01000d0e01000d0e01000d0e01000d0e01000d0e01000d0e01000b0e" }, { "filename": "body-green", - "data": "0x0015171f090e0f0e0f0e0f0e0f020f01000b0f020f01000b0f020f01000b0f020f01000b0f020f01000b0f020f01000b0f020f01000b0f" + "data": "0x0015171f093a0f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f01000b0f" }, { "filename": "body-gunk", - "data": "0x0015171f090e100e100e100e10021001000b10021001000b10021001000b10021001000b10021001000b10021001000b10021001000b10" + "data": "0x0015171f093a1001000d1001000d1001000d1001000d1001000d1001000d1001000b10" }, { "filename": "body-hotbrown", - "data": "0x0015171f090e110e110e110e11021101000b11021101000b11021101000b11021101000b11021101000b11021101000b11021101000b11" + "data": "0x0015171f093a1101000d1101000d1101000d1101000d1101000d1101000d1101000b11" }, { "filename": "body-magenta", - "data": "0x0015171f090e120e120e120e12021201000b12021201000b12021201000b12021201000b12021201000b12021201000b12021201000b12" + "data": "0x0015171f093a1201000d1201000d1201000d1201000d1201000d1201000d1201000b12" }, { "filename": "body-orange-yellow", - "data": "0x0015171f090e130e130e130e13021301000b13021301000b13021301000b13021301000b13021301000b13021301000b13021301000b13" + "data": "0x0015171f093a1301000d1301000d1301000d1301000d1301000d1301000d1301000b13" }, { "filename": "body-orange", - "data": "0x0015171f090e140e140e140e14021401000b14021401000b14021401000b14021401000b14021401000b14021401000b14021401000b14" + "data": "0x0015171f093a1401000d1401000d1401000d1401000d1401000d1401000d1401000b14" }, { "filename": "body-peachy-B", - "data": "0x0015171f090e150e150e150e15021501000b15021501000b15021501000b15021501000b15021501000b15021501000b15021501000b15" + "data": "0x0015171f093a1501000d1501000d1501000d1501000d1501000d1501000d1501000b15" }, { "filename": "body-peachy-a", - "data": "0x0015171f090e160e160e160e16021601000b16021601000b16021601000b16021601000b16021601000b16021601000b16021601000b16" + "data": "0x0015171f093a1601000d1601000d1601000d1601000d1601000d1601000d1601000b16" }, { "filename": "body-purple", - "data": "0x0015171f090e170e170e170e17021701000b17021701000b17021701000b17021701000b17021701000b17021701000b17021701000b17" + "data": "0x0015171f093a1701000d1701000d1701000d1701000d1701000d1701000d1701000b17" }, { "filename": "body-red", - "data": "0x0015171f090e180e180e180e18021801000b18021801000b18021801000b18021801000b18021801000b18021801000b18021801000b18" + "data": "0x0015171f093a1801000d1801000d1801000d1801000d1801000d1801000d1801000b18" }, { "filename": "body-redpinkish", - "data": "0x0015171f090e190e190e190e19021901000b19021901000b19021901000b19021901000b19021901000b19021901000b19021901000b19" + "data": "0x0015171f093a1901000d1901000d1901000d1901000d1901000d1901000d1901000b19" }, { "filename": "body-rust", - "data": "0x0015171f090e1a0e1a0e1a0e1a021a01000b1a021a01000b1a021a01000b1a021a01000b1a021a01000b1a021a01000b1a021a01000b1a" + "data": "0x0015171f093a1a01000d1a01000d1a01000d1a01000d1a01000d1a01000d1a01000b1a" }, { "filename": "body-slimegreen", - "data": "0x0015171f090e1b0e1b0e1b0e1b021b01000b1b021b01000b1b021b01000b1b021b01000b1b021b01000b1b021b01000b1b021b01000b1b" + "data": "0x0015171f093a1b01000d1b01000d1b01000d1b01000d1b01000d1b01000d1b01000b1b" }, { "filename": "body-teal-light", - "data": "0x0015171f090e1c0e1c0e1c0e1c021c01000b1c021c01000b1c021c01000b1c021c01000b1c021c01000b1c021c01000b1c021c01000b1c" + "data": "0x0015171f093a1c01000d1c01000d1c01000d1c01000d1c01000d1c01000d1c01000b1c" }, { "filename": "body-teal", - "data": "0x0015171f090e1d0e1d0e1d0e1d021d01000b1d021d01000b1d021d01000b1d021d01000b1d021d01000b1d021d01000b1d021d01000b1d" + "data": "0x0015171f093a1d01000d1d01000d1d01000d1d01000d1d01000d1d01000d1d01000b1d" }, { "filename": "body-yellow", - "data": "0x0015171f090e1e0e1e0e1e0e1e021e01000b1e021e01000b1e021e01000b1e021e01000b1e021e01000b1e021e01000b1e021e01000b1e" - }, - { - "filename": "body-green-reversed", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_000", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_001", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_002", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_003", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_004", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_005", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_006", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_007", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_008", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_009", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_010", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_011", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_012", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_013", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_014", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_015", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_016", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_017", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_018", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_019", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_020", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_021", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_022", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_023", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_024", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_025", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_026", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_027", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_028", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_029", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_030", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_031", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_032", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_033", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_034", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_035", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_036", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_037", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_038", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_039", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_040", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_041", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_042", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_043", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_044", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_045", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_046", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_047", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_048", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_049", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_050", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_051", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_052", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_053", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_054", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_055", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_056", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_057", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_058", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_059", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_060", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_061", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_062", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_063", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_064", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_065", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_066", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_067", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_068", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_069", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_070", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_071", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_072", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_073", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_074", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_075", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_076", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_077", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_078", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_079", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_080", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_081", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_082", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_083", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_084", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_085", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_086", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_087", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_088", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_089", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_090", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_091", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_092", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_093", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_094", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_095", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_096", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_097", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_098", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_099", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" + "data": "0x0015171f093a1e01000d1e01000d1e01000d1e01000d1e01000d1e01000d1e01000b1e" } ], "accessories": [ { "filename": "accessory-1n", - "data": "0x0017141e0d0100011f0500021f05000100011f0300011f01000100011f0200011f02000300011f03000200011f0200021f0100011f0200011f0100011f0400011f0100011f" + "data": "0x0017141e0d0100011f0500021f0600011f0300011f0200011f0200011f0500011f0500011f0200021f0100011f0200011f0100011f0400011f0100011f" }, { "filename": "accessory-aardvark", - "data": "0x0018151a0d020003200100012001000100052002000120010001200100012001000220" + "data": "0x0018151a0d02000320010001200200052002000120010001200100012001000220" }, { "filename": "accessory-axe", - "data": "0x0017141d0e01010521010104210100010103210200010101210100012102000101020001210200030001210200030001210200" + "data": "0x0017141d0e010205210102042101000102032102000102012101000121020001020200012105000121050001210200" }, { "filename": "accessory-belly-chameleon", - "data": "0x0017121e0d010001220100012201000500022201000222050002220100022205000222010001220100010001220300" + "data": "0x0017121e0d0100012201000122060002220100022205000222010002220500022201000122020001220300" }, { "filename": "accessory-bird-flying", @@ -792,147 +390,147 @@ }, { "filename": "accessory-bird-side", - "data": "0x0017131c0d040001240100030002240100042401230125010004240100020003240100010001240400" + "data": "0x0017131c0d040001240400022401000424012301250100042403000324020001240400" }, { "filename": "accessory-bling-anchor", - "data": "0x0015141d0d01260500012601000126030001260100020001260100012602000300012603000300012603000200032602000300012603000100012601000126010001260100020003260200" + "data": "0x0015141d0d0126050001260100012603000126030001260100012605000126060001260500032605000126040001260100012601000126030003260200" }, { "filename": "accessory-bling-anvil", - "data": "0x0015161e0b0127090001270100012707000127010002000127050001270200030001270300012703000400032704000500010d05000200020d052702000300020d032703000400030d04000300020d03270300" + "data": "0x0015161e0b012709000127010001270700012703000127050001270500012703000127070003270900010d0700020d05270500020d03270700030d0700020d03270300" }, { "filename": "accessory-bling-arrow", - "data": "0x0018141e0d0400032605000226040001260100012603000126030001000226040003260400010001260500" + "data": "0x0018141e0d04000326050002260400012601000126030001260400022604000326050001260500" }, { "filename": "accessory-bling-cheese", - "data": "0x0015141e0c012606000126010001260400012601000200012602000126020003000226030002000126020001260200010006260100020001260128012601280126010003000426010004000126012801260100050002260100" + "data": "0x0015141e0c0126060001260100012604000126030001260200012605000226050001260200012603000626030001260128012601280126040004260500012601280126060002260100" }, { "filename": "accessory-bling-gold-ingot", - "data": "0x0015141b0c012606000126010001260400012601000200012602000126020003000226030001000629010001000426022901000100042602290100" + "data": "0x0015141b0c0126060001260100012604000126030001260200012605000226040006290200042602290200042602290100" }, { "filename": "accessory-bling-love", - "data": "0x0015141d0c01260600012601000126040001260100020001260200012602000300022603000200012602000126020001000126012804260100010006260100020004260200030002260300" + "data": "0x0015141d0c0126060001260100012604000126030001260200012605000226050001260200012603000126012804260200062603000426050002260300" }, { "filename": "accessory-bling-mask", - "data": "0x0015141e0c01260600012601000126040001260100020001260200012602000300022603000100062601000100012601000226010001260100010006260100020004260200010001260100022601000126010001000126040001260100" + "data": "0x0015141e0c012606000126010001260400012603000126020001260500022604000626020001260100022601000126020006260300042603000126010002260100012602000126040001260100" }, { "filename": "accessory-bling-rings", - "data": "0x0017141d0d0300032a01000200012a0300012a0100032a0200012a012a0100012a0100012a0100012a012a0200032a0100012a0300012a02000100032a0300" + "data": "0x0017141d0d0300032a0300012a0300012a0100032a0200022a0100012a0100012a0100022a0200032a0100012a0300012a0300032a0300" }, { "filename": "accessory-bling-scissors", - "data": "0x0016131c0e012b0300012b012b0300012b0100012b0100012b01000100012b0100012b01000200012b0200022b0100022b022b0100022b" + "data": "0x0016131c0e012b0300022b0300012b0100012b0100012b0200012b0100012b0300012b0200022b0100042b0100022b" }, { "filename": "accessory-bling-sparkles", - "data": "0x0016141d0c010001260600032601000126020001260100012602000126030003000326020001000726030003260200040001260300040001260300" + "data": "0x0016141d0c01000126060003260100012602000126010001260200012606000326030007260300032606000126070001260300" }, { "filename": "accessory-body-gradient-checkerdisco", - "data": "0x0015171f09022c0223022c0223022c0223022c022c0223022c0223022c0223022c0223022d0223022d0223022d02230223022d0223022d0223022d0223022e01000123022e0223022e0223022e022e01000123022e0223022e0223022e02230100012f0223022f0223022f022302230100012f0223022f0223022f0223023001000123023002230230022302300230010001230230022302300223023002230100013102230231022302310223" + "data": "0x0015171f09022c0223022c0223022c0223042c0223022c0223022c0223022c0223022d0223022d0223022d0423022d0223022d0223022d0223022e01000123022e0223022e0223042e01000123022e0223022e0223022e02230100012f0223022f0223022f04230100012f0223022f0223022f022302300100012302300223023002230430010001230230022302300223023002230100013102230231022302310223" }, { "filename": "accessory-body-gradient-dawn", - "data": "0x0015171f090e320e320e330e33021101000b11021101000b11023401000b34023401000b34023501000b35023501000b35023601000b36" + "data": "0x0015171f091c321c33021101000d1101000b11023401000d3401000b34023501000d3501000b35023601000b36" }, { "filename": "accessory-body-gradient-dusk", - "data": "0x0015171f090e320e320e240e24023701000b37023701000b37023701000b37023701000b37023801000b38023801000b38023901000b39" + "data": "0x0015171f091c321c24023701000d3701000d3701000d3701000b37023801000d3801000b38023901000b39" }, { "filename": "accessory-body-gradient-glacier", - "data": "0x0015171f090e3a013a013b013a013b013a013b013a013b013a013b013a013b013a013b0e3b013b0104013b0104013b0104013b0104013b0104013b0104013b0104020401000b04020401000b04020401000b040104013c0100013c0104013c0104013c0104013c0104013c0104013c023c01000b3c013c013d0100013d013c013d013c013d013c013d013c013d013c013d023d01000b3d" + "data": "0x0015171f090f3a013b013a013b013a013b013a013b013a013b013a013b013a103b0104013b0104013b0104013b0104013b0104013b0104013b030401000d0401000d0401000c04013c0100013c0104013c0104013c0104013c0104013c0104033c01000c3c013d0100013d013c013d013c013d013c013d013c013d013c033d01000b3d" }, { "filename": "accessory-body-gradient-ice", - "data": "0x0015171f090e3e0e3e0e3f0e3f023f01000b3f023f01000b3f023c01000b3c023c01000b3c023c01000b3c023c01000b3c024001000b40" + "data": "0x0015171f091c3e1e3f01000d3f01000b3f023c01000d3c01000d3c01000d3c01000b3c024001000b40" }, { "filename": "accessory-body-gradient-pride", - "data": "0x0015171f090e410e410e420e42022a01000b2a022a01000b2a020f01000b0f020f01000b0f024301000b43024301000b43021201000b12" + "data": "0x0015171f091c411c42022a01000d2a01000b2a020f01000d0f01000b0f024301000d4301000b43021201000b12" }, { "filename": "accessory-body-gradient-redpink", - "data": "0x0015171f090e440e440e440e09020901000b09020901000b09020901000b09020901000b09020901000b09024501000b45024501000b45" + "data": "0x0015171f092a44100901000d0901000d0901000d0901000d0901000b09024501000d4501000b45" }, { "filename": "accessory-body-gradient-sunset", - "data": "0x0015171f090e460e460e460e25024201000b42021401000b14024701000b47024701000b47024801000b48024801000b48024801000b48" + "data": "0x0015171f092a460e25024201000b42021401000b14024701000d4701000b47024801000d4801000d4801000b48" }, { "filename": "accessory-carrot", - "data": "0x0018131d0e0200011d0100011d0300011d010002000249010001000249020001000149030001490400" + "data": "0x0018131d0e0200011d0100011d0300011d030002490200024903000149030001490400" }, { "filename": "accessory-chain-logo", - "data": "0x0018171c09012601000326010003260100032601000100012603000126030001260300012602260200032601000326010002260100012603000126030001260300012601260200022601000326010003260100" + "data": "0x0018171c09012601000326010003260100032602000126030001260300012603000326020003260100032601000226010001260300012603000126030002260200022601000326010003260100" }, { "filename": "accessory-checker-RGB", - "data": "0x0015171f090224021c024a0224021c024a02240224021c024a0224021c024a0224024a0224021c024a0224021c024a024a0224021c024a0224021c024a021c0100014a0224021c024a0224021c021c0100014a0224021c024a0224021c02240100011c024a0224021c024a022402240100011c024a0224021c024a0224024a01000124021c024a0224021c024a024a01000124021c024a0224021c024a021c0100014a0224021c024a0224021c" + "data": "0x0015171f090224021c024a0224021c024a0424021c024a0224021c024a0224024a0224021c024a0224021c044a0224021c024a0224021c024a021c0100014a0224021c024a0224041c0100014a0224021c024a0224021c02240100011c024a0224021c024a04240100011c024a0224021c024a0224024a01000124021c024a0224021c044a01000124021c024a0224021c024a021c0100014a0224021c024a0224021c" }, { "filename": "accessory-checker-bigwalk-blue-prime", - "data": "0x0015171f09040003070100030701000207030701000307010003070300030701000307070003070700030701000600030701000307010003000207010003070100030701000107020002070100030705000107020002070700020701070700030701000207040003070100030701000207020702000307010003070300" + "data": "0x0015171f090400030701000307010005070100030701000307030003070100030707000307070003070700030701000307040002070100030701000307010001070200020701000307050001070200020707000307070003070100020704000307010003070100040702000307010003070300" }, { "filename": "accessory-checker-bigwalk-greylight", - "data": "0x0015171f090400034b0100034b0100024b034b0100034b0100034b0300034b0100034b0700034b0700034b01000600034b0100034b01000300024b0100034b0100034b0100014b0200024b0100034b0500014b0200024b0700024b014b0700034b0100024b0400034b0100034b0100024b024b0200034b0100034b0300" + "data": "0x0015171f090400034b0100034b0100054b0100034b0100034b0300034b0100034b0700034b0700034b0700034b0100034b0400024b0100034b0100034b0100014b0200024b0100034b0500014b0200024b0700034b0700034b0100024b0400034b0100034b0100044b0200034b0100034b0300" }, { "filename": "accessory-checker-bigwalk-rainbow", - "data": "0x0015171f090400034c010003460100021403120100034c01000346030003120100034c0400031203120400034d01000312030003140100034d010003120246010003140100034d040002460100031404000346010002460400034c010003460100030002120100034c010003460100014d020002120100034c04000112014d020002120400034d01000112" + "data": "0x0015171f090400034c010003460100021403120100034c01000346030003120100034c040006120400034d01000312030003140100034d010003120246010003140100034d040002460100031404000346010002460400034c01000346040002120100034c010003460100014d020002120100034c04000112014d020002120400034d01000112" }, { "filename": "accessory-checker-spaced-black", - "data": "0x0015171f0903000223040002230300030002230400022303000e0002230400022304000223022304000223040002230e0003000223040002230300030002230400022303000e000223040002230400022302230400022304000223" + "data": "0x0015171f09030002230400022306000223040002231100022304000223040004230400022304000223110002230400022306000223040002231100022304000223040004230400022304000223" }, { "filename": "accessory-checker-spaced-white", - "data": "0x0015171f0903000201040002010300030002010400020103000e0002010400020104000201020104000201040002010e0003000201040002010300030002010400020103000e000201040002010400020102010400020104000201" + "data": "0x0015171f09030002020400020206000202040002021100020204000202040004020400020204000202110002020400020206000202040002021100020204000202040004020400020204000202" }, { "filename": "accessory-checker-vibrant", - "data": "0x0015171f09024e0243024f024e0243024f024e024e0243024f024e0243024f024e024f024e0243024f024e0243024f024f024e0243024f024e0243024f02430100014f024e0243024f024e024302430100014f024e0243024f024e0243024e01000143024f024e0243024f024e024e01000143024f024e0243024f024e024f0100014e0243024f024e0243024f024f0100014e0243024f024e0243024f02430100014f024e0243024f024e0243" + "data": "0x0015171f09024e0243024f024e0243024f044e0243024f024e0243024f024e024f024e0243024f024e0243044f024e0243024f024e0243024f02430100014f024e0243024f024e04430100014f024e0243024f024e0243024e01000143024f024e0243024f044e01000143024f024e0243024f024e024f0100014e0243024f024e0243044f0100014e0243024f024e0243024f02430100014f024e0243024f024e0243" }, { "filename": "accessory-checkers-big-green", - "data": "0x0015171f09030f0300030f0300020f030f0300030f0300020f030f0300030f0300020f0300030f0300030f02000300030f0300030f02000300030f0300030f0200020f0400030f0300020f020f0400030f0300020f020f0400030f0300020f0300030f0300030f02000300030f0300030f0200" + "data": "0x0015171f09030f0300030f0300050f0300030f0300050f0300030f0300020f0300030f0300030f0500030f0300030f0500030f0300030f0200020f0400030f0300040f0400030f0300040f0400030f0300020f0300030f0300030f0500030f0300030f0200" }, { "filename": "accessory-checkers-big-red-cold", - "data": "0x0015171f090319030003190300021903190300031903000219031903000319030002190300031903000319020003000319030003190200030003190300031902000219040003190300021902190400031903000219021904000319030002190300031903000319020003000319030003190200" + "data": "0x0015171f09031903000319030005190300031903000519030003190300021903000319030003190500031903000319050003190300031902000219040003190300041904000319030004190400031903000219030003190300031905000319030003190200" }, { "filename": "accessory-checkers-black", - "data": "0x0015171f0902000223020002230200022302000200022302000223020002230200022302000223020002230200022302230200022302000223020002230300012302000223020002230200030001230200022302000223020002230200022302000223020002230223020002230200022302000223030001230200022302000223020003000123020002230200022302000223020002230200022302000223" + "data": "0x0015171f09020002230200022302000223040002230200022302000223020002230200022302000223020004230200022302000223020002230300012302000223020002230500012302000223020002230200022302000223020002230200042302000223020002230200022303000123020002230200022305000123020002230200022302000223020002230200022302000223" }, { "filename": "accessory-checkers-blue", - "data": "0x0015171f09024a0200024a0200024a0200024a024a0200024a0200024a0200024a0200024a0200024a0200024a02000200024a0200024a0200024a0200024a0200024a0200024a0200024a024a0200024a0200024a0200024a0300014a0200024a0200024a02000300014a0200024a0200024a0200024a0200024a0200024a0200024a024a0200024a0200024a0200024a0300014a0200024a0200024a0200" + "data": "0x0015171f09024a0200024a0200024a0200044a0200024a0200024a0200024a0200024a0200024a0200024a0400024a0200024a0200024a0200024a0200024a0200024a0200044a0200024a0200024a0200024a0300014a0200024a0200024a0500014a0200024a0200024a0200024a0200024a0200024a0200044a0200024a0200024a0200024a0300014a0200024a0200024a0200" }, { "filename": "accessory-checkers-magenta-80", - "data": "0x0015171f0902000220020002200200022002000200022002000220020002200200022002000220020002200200022002200200022002000220020002200300012002000220020002200200030001200200022002000220020002200200022002000220020002200220020002200200022002000220030001200200022002000220020003000120020002200200022002000220020002200200022002000220" + "data": "0x0015171f09020002200200022002000220040002200200022002000220020002200200022002000220020004200200022002000220020002200300012002000220020002200500012002000220020002200200022002000220020002200200042002000220020002200200022003000120020002200200022005000120020002200200022002000220020002200200022002000220" }, { "filename": "accessory-chicken", - "data": "0x0018131d0d0300024701000201020001010150010004010100020002010200020001010300020001500300" + "data": "0x0018131d0d0300024701000202020001020150010004020300020204000102050001500300" }, { "filename": "accessory-cloud", - "data": "0x0018131a0d020003010100010005010601" + "data": "0x0018131a0d0200030202000b02" }, { "filename": "accessory-clover", - "data": "0x0017151e0d0200021d04000200031d03000100011d0100011d0100021d0100031d0100031d0100021d0100011d0100011d02000200031d03000200021d0100011d02000600021d" + "data": "0x0017151e0d0200021d0600031d0400011d0100011d0100021d0100031d0100031d0100021d0100011d0100011d0400031d0500021d0100011d0800021d" }, { "filename": "accessory-collar-sunset", @@ -940,83 +538,83 @@ }, { "filename": "accessory-cow", - "data": "0x0018141c0d0500015101000100035101230151013801510100015101230251010001510100015102380151010002000151020001510100" + "data": "0x0018141c0d05000151020003510123015101380151010001510123025101000151010001510238015103000151020001510100" }, { "filename": "accessory-decay-gray-dark", - "data": "0x0015171f090e27020006270300032702000b270100010009270100022701000227010001270100032702000427022701000827030001270200012702000327050003000827030003000127040002270100022701000100012701000b2703000b27" + "data": "0x0015171f090e27020006270300032702000b2702000927010002270100022701000127010003270200062701000827030001270200012702000327080008270600012704000227010002270200012701000b2703000b27" }, { "filename": "accessory-decay-pride", - "data": "0x0015171f090e27024106270341032702420b27014201420927014202270142022701000127012a0327022a0427022701000827032a0127010f01000127020f0327050f020f01000827030f024301000127044302270143022701430143012701000b27021201000b27" + "data": "0x0015171f090e27024106270341032702420b2702420927014202270142022701000127012a0327022a062701000827032a0127010f01000127020f0327070f01000827030f02430100012704430227014302270243012701000b27021201000b27" }, { "filename": "accessory-dinosaur", - "data": "0x0017131d0d020003520100020001520100015201000200045202000352010001520100035201000652030001520200" + "data": "0x0017131d0d0200035203000152010001520300045202000352010001520100035201000652030001520200" }, { "filename": "accessory-dollar-bling", - "data": "0x0015141e0c01260600012601260600012601000126040001260100020004260200030002260300020004260200020002260400040002260200020004260200030002260300" + "data": "0x0015141e0c012606000226060001260100012604000126030004260500022605000426040002260800022604000426050002260300" }, { "filename": "accessory-dragon", - "data": "0x0017141e0d020f0100030f01000100030f0100020f020f0300010f01000300030f01000100020f0400010f0300020f01000100030f0200010f0200010f0400" + "data": "0x0017141e0d020f0100030f0200030f0100040f0300010f0400030f0200020f0400010f0300020f0200030f0200010f0200010f0400" }, { "filename": "accessory-ducky", - "data": "0x0018131a0e0128010002280100010003280114010003280100" + "data": "0x0018131a0e012801000228020003280114010003280100" }, { "filename": "accessory-eth", - "data": "0x0018131d0e020001530200020001530200010001530154015301000554010003530100020001530200" + "data": "0x0018131d0e020001530400015303000153015401530100055401000353030001530200" }, { "filename": "accessory-eye", - "data": "0x0018151c0d02000454020001000154010002540100015401000154020002540200015401000154040001540100020004540200" + "data": "0x0018151c0d020004540300015401000254010001540100015402000254020001540100015404000154030004540200" }, { "filename": "accessory-flash", - "data": "0x0017151d0d0100010106000200020104000300030102000801020003010300040002010200060001010100" + "data": "0x0017151d0d010001020800020207000302020008020200030207000202080001020100" }, { "filename": "accessory-fries", - "data": "0x0017131d0e0126010a0126010a01260126010a0126010a012605550155032601550155022602550155012603550555" + "data": "0x0017131d0e0126010a0126010a0226010a0126010a01260655032602550226035501260855" }, { "filename": "accessory-glasses-logo-sun", - "data": "0x0018161a0d0723020003230100052303230100032301000123" + "data": "0x0018161a0d072302000323010008230100032301000123" }, { "filename": "accessory-glasses-logo", - "data": "0x0018161a0d07560200015601000156010001560100035603560100035601000156" + "data": "0x0018161a0d0756020001560100015601000156010006560100035601000156" }, { "filename": "accessory-glasses", - "data": "0x0017141d0d07560156010002560100025602000256010002560700071d011d0100021d0100021d0200021d0100021d" + "data": "0x0017141d0d0856010002560100025602000256010002560700081d0100021d0100021d0200021d0100021d" }, { "filename": "accessory-grid-simple-bege", - "data": "0x0016171e09015701000157010001570100015701000157010001570100015701000e00010001570100015701000157010001570100015701000157010001570e000157030001570100015701000157010001570100015701000e00010001570100015701000157010001570100015701000157010001570e00015703000157010001570100015701000157010001570100" + "data": "0x0016171e090157010001570100015701000157010001570100015701000157100001570100015701000157010001570100015701000157010001570e0001570300015701000157010001570100015701000157100001570100015701000157010001570100015701000157010001570e00015703000157010001570100015701000157010001570100" }, { "filename": "accessory-heart", - "data": "0x0018141d0d0100025801000258010007580758010005580100020003580200030001580300" + "data": "0x0018141d0d010002580100025801000e580100055803000358050001580300" }, { "filename": "accessory-hoodiestrings-uneven", - "data": "0x0016121b0f0101010001010101010001010101010001010101010001590101020001590200" + "data": "0x0016121b0f0102010002020100020201000202010001590102020001590200" }, { "filename": "accessory-id", - "data": "0x0017151a10020001010200052605010501" + "data": "0x0017151a1002000102020005260a02" }, { "filename": "accessory-infinity", - "data": "0x0017141e0d0100020b0400010b0200010b0300010b06000100030b03000300030b01000600010b0300010b0200010b0400020b0100" + "data": "0x0017141e0d0100020b0400010b0200010b0300010b0700030b0600030b0700010b0300010b0200010b0400020b0100" }, { "filename": "accessory-insignia", - "data": "0x0016131d0e0200015b02000100015b012b015b01000200015b02000100035b0100015b032b015b025b022b015b015b032b015b0100035b0100" + "data": "0x0016131d0e0200015b0300015b012b015b0300015b0300035b0100015b032b035b022b025b032b015b0100035b0100" }, { "filename": "accessory-leaf", @@ -1024,23 +622,23 @@ }, { "filename": "accessory-lightbulb", - "data": "0x0017121c0e045d045d045d0100025d01000100025e01000100025e0100" + "data": "0x0017121c0e0c5d0100025d0200025e0200025e0100" }, { "filename": "accessory-lines-45-greens", - "data": "0x0015171f090200010f0200010f0200010f0200010f0200015c0200015c0200015c0200015c0200015c01000100010f0200010f0200010f0200010f0200010f0200015c0200015c0200015c0200015c0200010f0200010f0200010f0200010f0200010f01000100015c0200015c0200015c0200015c0200015c0500010f0200010f0200010f0200015c0200015c0200015c0200015c0200015c01000100010f0200010f0200010f0200010f0200010f0500015c0200015c0200015c0200010f0200010f0200010f0200010f0200010f0100" + "data": "0x0015171f090200010f0200010f0200010f0200010f0200015c0200015c0200015c0200015c0200015c0200010f0200010f0200010f0200010f0200010f0200015c0200015c0200015c0200015c0200010f0200010f0200010f0200010f0200010f0200015c0200015c0200015c0200015c0200015c0500010f0200010f0200010f0200015c0200015c0200015c0200015c0200015c0200010f0200010f0200010f0200010f0200010f0500015c0200015c0200015c0200010f0200010f0200010f0200010f0200010f0100" }, { "filename": "accessory-lines-45-rose", - "data": "0x0015171f090200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f01000100015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f01000100015f0200015f0200015f0200015f0200015f0500015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f01000100015f0200015f0200015f0200015f0200015f0500015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0100" + "data": "0x0015171f090200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0500015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0500015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0100" }, { "filename": "accessory-lp", - "data": "0x0016161e0d03000323030001000723010001000723010003230301032303230101010001010323032303010323010007230100010007230100030003230300" + "data": "0x0016161e0d03000323040007230200072301000323030206230102010001020623030203230100072302000723040003230300" }, { "filename": "accessory-marsface", - "data": "0x0018131d0e040001230223010002230300022302000323030002230523" + "data": "0x0018131d0e0400032301000223030002230200032303000723" }, { "filename": "accessory-matrix-white", @@ -1048,7 +646,7 @@ }, { "filename": "accessory-moon-block", - "data": "0x0017131d0e056001600100016001000160010001600100016001000160010001600100016001000160010001600100036001000160016001000360" + "data": "0x0017131d0e0660010001600100016001000160010001600100016001000160010001600100016001000160010003600100026001000360" }, { "filename": "accessory-none", @@ -1056,19 +654,19 @@ }, { "filename": "accessory-oldshirt", - "data": "0x0015171f090e610e610461075803610e6102620100026103580261015803610261010001610158036102580461026201000361015807610261010001610258016104580361026201000b6102610100016107580361026201000b61" + "data": "0x0015171f09206107581161026201000261035802610158056101000161015803610258046102620100036101580961010001610258016104580361026201000d610100016107580361026201000b61" }, { "filename": "accessory-pizza-bling", - "data": "0x0015141d0c0126060001260100012604000126010002000126020001260200030002260300030002260300020004260200020004260200010006260100010006260100" + "data": "0x0015141d0c012606000126010001260400012603000126020001260500022606000226050004260400042603000626020006260100" }, { "filename": "accessory-pocket-pencil", - "data": "0x00171519100100013703000100010103000563" + "data": "0x0017151910010001370400010203000563" }, { "filename": "accessory-rain", - "data": "0x0018131d0e040001430100014302000143010001430300030001430100014302000143010001430400" + "data": "0x0018131d0e04000143010001430200014301000143060001430100014302000143010001430400" }, { "filename": "accessory-rainbow-steps", @@ -1076,63 +674,63 @@ }, { "filename": "accessory-rgb", - "data": "0x0018151e0d030002640300020004640200020004640200010002650264025a01000465045a0465045a010002650200025a0100" + "data": "0x0018151e0d030002640500046404000464030002650264025a01000465045a0465045a010002650200025a0100" }, { "filename": "accessory-robot", - "data": "0x0019171b0901230200012302000123020001230200012301000e00022301000b23" + "data": "0x0019171b090123020001230200012302000123020001230f00022301000b23" }, { "filename": "accessory-safety-vest", - "data": "0x0015171f0b0413030005130413030005130413030005130413030005130100036603000566010003660300056601000366030005660100036603000566010003130300051301000313030005130100031303000513" + "data": "0x0015171f0b0413030009130300091303000913030005130100036603000566010003660300056601000366030005660100036603000566010003130300051301000313030005130100031303000513" }, { "filename": "accessory-scarf-clown", - "data": "0x0015151f0c031c0300031c031c0300031c031c0300031c032303000323032303000323032303000323031c0300031c031c0300031c031c0300031c032303000323032303000323" + "data": "0x0015151f0c031c0300061c0300061c0300031c0323030006230300062303000323031c0300061c0300061c0300031c03230300062303000323" }, { "filename": "accessory-secret-x", - "data": "0x0018121b0e016702000167010002670100010002670100016702000167" + "data": "0x0018121b0e01670200016701000267020002670100016702000167" }, { "filename": "accessory-shirt-black", - "data": "0x0015151f0c0923052301000323022301000223020002230123020001230168030001230300022304000300022304000300022304000300022304000300012301680400030002230400030002230400" + "data": "0x0015151f0c0e23010005230100022302000323020001230168030001230300022307000223070002230700022307000123016807000223070002230400" }, { "filename": "accessory-shrimp", - "data": "0x0018121c0e0100025f0100035f0100025f02000100015f0220020001200100" + "data": "0x0018121c0e0100025f0100035f0100025f0300015f0220020001200100" }, { "filename": "accessory-slimesplat", - "data": "0x0017121d0d0200014e0100014e014e0100024e01000100034e01000100024e0100014e014e0100014e02000300014e01000100014e0300" + "data": "0x0017121d0d0200014e0100024e0100024e0200034e0200024e0100024e0100014e0500014e0200014e0300" }, { "filename": "accessory-small-bling", - "data": "0x001514170d01260500012601000126030001260100020003260200" + "data": "0x001514170d0126050001260100012603000126030003260200" }, { "filename": "accessory-snowflake", - "data": "0x0017141d0d01000101030001010100020101000101010002010200030102000100050101000200030102000201010001010100020101000101030001010100" + "data": "0x0017141d0d010001020300010201000202010001020100020202000302030005020300030202000202010001020100020201000102030001020100" }, { "filename": "accessory-stains-blood", - "data": "0x0016151d0d05000219010002000119010004190400041905000219010001190100021904000200021904000800010001190600" + "data": "0x0016151d0d05000219030001190100041904000419050002190100011901000219060002190d0001190600" }, { "filename": "accessory-stains-zombie", - "data": "0x0017151e0d0100010f060008000200020f0400010f0100020f04000500020f01000400040f0200010f0100040f0500020f0100" + "data": "0x0017151e0d0100010f1000020f0400010f0100020f0900020f0500040f0200010f0100040f0500020f0100" }, { "filename": "accessory-stripes-and-checks", - "data": "0x0015171f090e690e430e280e1c02010100012302010223020102230201020101000123020102230201022302010223010001010223020102230201022302230100010102230201022302010223026901000b69024301000b43022801000b28" + "data": "0x0015171f090e690e430e280e1c020201000123020202230202022304020100012302020223020202230202022301000102022302020223020204230100010202230202022302020223026901000b69024301000b43022801000b28" }, { "filename": "accessory-stripes-big-red", - "data": "0x0015171d090e240e240e240e000e000e00022401000b24022401000b24022401000b24" + "data": "0x0015171d092a242a00022401000d2401000d2401000b24" }, { "filename": "accessory-stripes-blit", - "data": "0x0015171b090e5a0e5a0e5a0e00026a01000b6a0e00022a01000b2a" + "data": "0x0015171b092a5a0e00026a01000b6a0e00022a01000b2a" }, { "filename": "accessory-stripes-blue-med", @@ -1152,15 +750,15 @@ }, { "filename": "accessory-sunset", - "data": "0x0017141a0d0300012603000100012603000126010002000326020001260100032601000126" + "data": "0x0017141a0d03000126040001260300012603000326020001260100032601000126" }, { "filename": "accessory-taxi-checkers", - "data": "0x0017171a090266020d0266020d0266020d02660266020d0266020d0266020d0266020d01000166020d0266020d0266020d020d01000166020d0266020d0266020d" + "data": "0x0017171a090266020d0266020d0266020d0466020d0266020d0266020d0266020d01000166020d0266020d0266040d01000166020d0266020d0266020d" }, { "filename": "accessory-tee-yo", - "data": "0x0015171f0902280200012804000128030001280228030004280400012803280900022803280900022802280200012801000128030001280100022802280300012801000228010001280100022802280300012801000228030002280228080001280100022802280a00022802280a00022802280a000228" + "data": "0x0015171f09022802000128040001280300032803000428040004280900052809000428020001280100012803000128010004280300012801000228010001280100042803000128010002280300042808000128010004280a0004280a0004280a000228" }, { "filename": "accessory-text-yolo", @@ -1168,75 +766,75 @@ }, { "filename": "accessory-think", - "data": "0x0018131c0e0301020003010200050002000101020004000101" + "data": "0x0018131c0e0302020003020900010206000102" }, { "filename": "accessory-tie-black-on-white", - "data": "0x0015121f0e0423014b0223014b014b0223014b014b0223014b014b0223014b014b0223014b014b0223014b014b0223014b014b0223014b014b0223014b014b0223014b" + "data": "0x0015121f0e0423014b0223024b0223024b0223024b0223024b0223024b0223024b0223024b0223024b0223024b0223014b" }, { "filename": "accessory-tie-dye", - "data": "0x0016151f0b0200023b0100016c0200016c0100013b0100033b0200016c02000100013b0300013b0200026c0300026d0100013b0100026c0200016d0100011c016d013b0100016c01000100016d0100011c016c013b0100016c0100011c0100016d0100011c0100026c03000100016d0200011c0300011c01000200016d0200031c0100011c0100016d0200016d0100021c0200" + "data": "0x0016151f0b0200023b0100016c0200016c0100013b0100033b0200016c0300013b0300013b0200026c0300026d0100013b0100026c0200016d0100011c016d013b0100016c0200016d0100011c016c013b0100016c0100011c0100016d0100011c0100026c0400016d0200011c0300011c0300016d0200031c0100011c0100016d0200016d0100021c0200" }, { "filename": "accessory-tie-purple-on-white", - "data": "0x0015121f0e046e014b026e014b014b026e014b014b026e014b014b026e014b014b026e014b014b026e014b014b026e014b014b026e014b014b026e014b014b026e014b" + "data": "0x0015121f0e046e014b026e024b026e024b026e024b026e024b026e024b026e024b026e024b026e024b026e024b026e014b" }, { "filename": "accessory-tie-red", - "data": "0x0016111e0f024102410200024102410241024102410241" + "data": "0x0016111e0f044102000c41" }, { "filename": "accessory-txt-a2+b2", - "data": "0x0017151d0d0200016f0500026f0600026f0100016f04000200036f03000300016f0100016f0100016f0500026f01000500026f0100" + "data": "0x0017151d0d0200016f0500026f0600026f0100016f0600036f0600016f0100016f0100016f0500026f0600026f0100" }, { "filename": "accessory-txt-cc", - "data": "0x0017151d0c010007700100017007000170017001000270010002700100017001700100017002000170020001700170010002700100027001000170017007000170010007700100" + "data": "0x0017151d0c01000770010001700700027001000270010002700100027001000170020001700200027001000270010002700100027007000170010007700100" }, { "filename": "accessory-txt-cc2", - "data": "0x0017141c0d0371010003710171030001710200017103000171020001710300017102000171030001710200037101000371" + "data": "0x0017141c0d037101000471030001710200017103000171020001710300017102000171030001710200037101000371" }, { "filename": "accessory-txt-copy", - "data": "0x0017131d0d02720100027201000172020002720100027201000272010006000272010001720100017202720100027201000172020001720200" + "data": "0x0017131d0d027201000272010001720200027201000272010002720700027201000172010003720100027201000172020001720200" }, { "filename": "accessory-txt-dao-black", - "data": "0x0018151b0c02230200012302000123010001230100022301000223010001230123010005230100012302230100012301000123010001230100" + "data": "0x0018151b0c022302000123020001230100012301000223010002230100022301000523010003230100012301000123010001230100" }, { "filename": "accessory-txt-doom", - "data": "0x0016161d0b0200012308000323080001230100032306000100022301000323040003000223010003230200050002230100032308000123010001230a000123" + "data": "0x0016161d0b0200012308000323080001230100032307000223010003230700022301000323070002230100032308000123010001230a000123" }, { "filename": "accessory-txt-dope-text", - "data": "0x0017131d0d01000173020001730100027301000173010001730273020001730100060002730100017302000273010002730100017302000373" + "data": "0x0017131d0d010001730200017301000273010001730100037302000173070002730100017302000273010002730100017302000373" }, { "filename": "accessory-txt-foo-black", - "data": "0x0019151b0d0523010002230223010002230100022301230200022301000223" + "data": "0x0019151b0d05230100042301000223010003230200022301000223" }, { "filename": "accessory-txt-ico", - "data": "0x0019171d09027401000b74027401000b74027401000b74027401000b74027401000b74" + "data": "0x0019171d09027401000d7401000d7401000d7401000d7401000b74" }, { "filename": "accessory-txt-io", - "data": "0x0018131c0d01560300015601000156020001560200015601000156010002560100015602000256015603000256" + "data": "0x0018131c0d0156030001560100015602000156020001560100015601000256010001560200035603000256" }, { "filename": "accessory-txt-lmao", - "data": "0x0017131d0d013e0300023e013e0200023e0100023e0100013e020006000100013e0200023e013e0100013e0100023e013e0100013e0100023e" + "data": "0x0017131d0d013e0300033e0200023e0100023e0100013e0900013e0200033e0100013e0100033e0100013e0100023e" }, { "filename": "accessory-txt-lol", - "data": "0x001715190d01010200020101000101010001010200020101000101010002010100020101000201" + "data": "0x001715190d01020200020201000102010001020200020201000102010002020100020201000202" }, { "filename": "accessory-txt-mint", - "data": "0x0016141c0d0600011407000214010001140200011401140100011401000114010001140700021402000314011401000114020001140100" + "data": "0x0016141c0d06000114070002140100011402000214010001140100011401000114070002140200041401000114020001140100" }, { "filename": "accessory-txt-nil-grey-dark", @@ -1244,1165 +842,761 @@ }, { "filename": "accessory-txt-noun-f0f", - "data": "0x0017131e0d010002690100016901000100016901000269010006000269010001690100016902690100036906000100026901000169010001000169010002690100" + "data": "0x0017131e0d0100026901000169020001690100026907000269010001690100036901000369070002690100016902000169010002690100" }, { "filename": "accessory-txt-noun-green", - "data": "0x0017131e0d0100023e0100013e01000100013e0100023e01000600023e0100013e0100013e023e0100033e06000100023e0100013e01000100013e0100023e0100" + "data": "0x0017131e0d0100023e0100013e0200013e0100023e0700023e0100013e0100033e0100033e0700023e0100013e0200013e0100023e0100" }, { "filename": "accessory-txt-noun-multicolor", - "data": "0x0017131e0d010002170100011701000100011701000217010006000276010001140100011402760100031406000100020f0100010f01000100010f0100020f0100" + "data": "0x0017131e0d010002170100011702000117010002170700027601000114010001140276010003140700020f0100010f0200010f0100020f0100" }, { "filename": "accessory-txt-noun", - "data": "0x0016131d0d0100026c0100016c01000100016c0100026c01000600026c0100016c0100016c026c0100036c06000100026c0100016c01000100016c0100026c0100" + "data": "0x0016131d0d0100026c0100016c0200016c0100026c0700026c0100016c0100036c0100036c0700026c0100016c0200016c0100026c0100" }, { "filename": "accessory-txt-pi", - "data": "0x0018131b0d0100051f011f0100011f0100011f01000200011f0100011f01000200011f0200011f" + "data": "0x0018131b0d0100061f0100011f0100011f0300011f0100011f0300011f0200011f" }, { "filename": "accessory-txt-pop", - "data": "0x0017131d0d022804000228040001280100022802000200022802000400022804000228040001280100" + "data": "0x0017131d0d0228040002280400012801000228040002280600022804000228040001280100" }, { "filename": "accessory-txt-rofl", - "data": "0x0017131d0d02010200027702010200027701010100010101000277060003370100012601000237020001260100013703000226" + "data": "0x0017131d0d02020200027702020200027701020100010201000277060003370100012601000237020001260100013703000226" }, { "filename": "accessory-txt-we", - "data": "0x0018151d0c0700011c0100040001560100011c0100011c02000156010001560100031c015601000156010001560100011c0200015601000156010001560200011c010001000156010001560500" + "data": "0x0018151d0c0700011c050001560100011c0100011c02000156010001560100031c015601000156010001560100011c0200015601000156010001560200011c02000156010001560500" }, { "filename": "accessory-txt-yay", - "data": "0x0018151a0c0143010001430100011c0100014301000143010001430100031c010001430100010001430100011c0100011c010001430100" + "data": "0x0018151a0c0143010001430100011c0100014301000143010001430100031c01000143020001430100011c0100011c010001430100" }, { "filename": "accessory-wall", - "data": "0x0015171f090a00016203000a0001620300026201000b62040001620900040001620900026201000462010006620a00016203000a0001620300026201000b62040001620900040001620900" + "data": "0x0015171f090a0001620d0001620300026201000b62040001620d0001620900026201000462010006620a0001620d0001620300026201000b62040001620d0001620900" }, { "filename": "accessory-wave", - "data": "0x0017151b0d0100035604000256020001560300020001560200015602000200015603000256010001560600" + "data": "0x0017151b0d01000356040002560200015605000156020001560400015603000256010001560600" }, { "filename": "accessory-wet-money", - "data": "0x0018141e0d017802790178037902790178017a0178027902790178017a0178027903790178027901780100010401000104010001040100010001040500050001040100" + "data": "0x0018141e0d01780279017805790178017a017804790178017a01780579017802790178010001040100010401000104020001040a0001040100" }, { "filename": "accessory-woolweave-bicolor", - "data": "0x0015171f09037b010003140100037b0100027b0e00017b010003140100037b010003140100010001140300017b030001140300017b01140200027b010003140100037b01000e00027b020003140100037b01000214030001140300017b030001140200017b01140200037b010003140100027b0e00017b0200027b010003140100037b0100" + "data": "0x0015171f09037b010003140100037b0100027b0e00017b010003140100037b01000314020001140300017b030001140300017b01140200027b010003140100037b0f00027b020003140100037b01000214030001140300017b030001140200017b01140200037b010003140100027b0e00017b0200027b010003140100037b0100" }, { "filename": "accessory-woolweave-dirt", - "data": "0x0015171f09037c0100037c0100037c0100027c0e00017c0100037c0100037c0100037c01000100017c0300017c0300017c0300017c017c0200027c0100037c0100037c01000e00027c0200037c0100037c0100027c0300017c0300017c0300017c0200027c0200037c0100037c0100027c0e00017c0200027c0100037c0100037c0100" + "data": "0x0015171f09037c0100037c0100037c0100027c0e00017c0100037c0100037c0100037c0200017c0300017c0300017c0300027c0200027c0100037c0100037c0f00027c0200037c0100037c0100027c0300017c0300017c0300017c0200027c0200037c0100037c0100027c0e00017c0200027c0100037c0100037c0100" }, { "filename": "accessory-yingyang", - "data": "0x0018121b0e040d020d024b020d024b044b" + "data": "0x0018121b0e060d024b020d064b" }, { "filename": "body-bege", - "data": "0x0015171f090e020e020e020e02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02020201000b02" + "data": "0x0015171f093a0101000d0101000d0101000d0101000d0101000d0101000d0101000b01" }, { "filename": "body-gray-scale-1", - "data": "0x0015171f090e0b0e0b0e0b0e0b020b01000b0b020b01000b0b020b01000b0b020b01000b0b020b01000b0b020b01000b0b020b01000b0b" + "data": "0x0015171f093a0b01000d0b01000d0b01000d0b01000d0b01000d0b01000d0b01000b0b" }, { "filename": "body-gray-scale-9", - "data": "0x0015171f090e0e0e0e0e0e0e0e020e01000b0e020e01000b0e020e01000b0e020e01000b0e020e01000b0e020e01000b0e020e01000b0e" + "data": "0x0015171f093a0e01000d0e01000d0e01000d0e01000d0e01000d0e01000d0e01000b0e" }, { "filename": "body-ice-cold", - "data": "0x0015171f090e060e060e060e06020601000b06020601000b06020601000b06020601000b06020601000b06020601000b06020601000b06" - }, + "data": "0x0015171f093a0601000d0601000d0601000d0601000d0601000d0601000d0601000b06" + } + ], + "heads": [ { - "filename": "accessory-txt-dao-black-reversed", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-aardvark", + "data": "0x00021e14060500013702000137130002370200023711000337020003370f000437020004370f00033702000337110002370200023713000137020001370f000d370b000d370b000d370b000d370b000d370b000d370b000d370600057d0d370600017d017e017d017e017d0b37097d017e017d017e017d0b370d7d0a370523097d0b370d7d" }, { - "filename": "accessory-txt-dao-black-reversed_000", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-abstract", + "data": "0x00041a1405045c01000447010004470100017f01000114010001140100045c01230447012304470123017f01230114012301140123045c01230447012304470123017f01230114012301140123045c01230447012304470123017f01230114012301140123045c01230447012304470123017f01230114012301140123010015230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f012304460100132301000123015401230154012301540123040701230455012304550123015401230154012301540123040701230455012304550123015401230154012301540123010703540123045501230455012301540123015401230154012304070123045501230455012301540123015401230154012304070123045501230455" }, { - "filename": "accessory-txt-dao-black-reversed_001", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-ape", + "data": "0x0005191406030004800e00098009000e8006000f800300108004000f8004000f80040001800e81040001800e81040001800e81040001800e81020003800e8102000180018101800f8101000180018103800d8206800d81018002001180" }, { - "filename": "accessory-txt-dao-black-reversed_002", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-bag", + "data": "0x00031c140306000e3a0b000e3a0900023a0e00023a0700023a0e00023a0700023a0e00023a05000207023a0e07023a0207030001070126023a040706260407023a01260107020001260107022606070426060702260107020001260807062608070200013a16070100013a0100013a15070100013a0100013a15070100013a0107013a1607013a0107013a1607010018070100070703760e0701001807020016070100" }, { - "filename": "accessory-txt-dao-black-reversed_003", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-bagpipe", + "data": "0x00011d19050a0001831700030f150001830200010f010001831200020f0300010f017a11000108010f017a020f0108017a010f1000020f017a020f0183017a020f06000183080001830100017a010f010001080100020f01830600010807000108040001080200010f017a010f06000108060001080300010803000183017a010f070001080500010803000108020001080100017a010f0200010f0200017a030f017a030f010803000108020001080200020f017a0200010f017a030f017a030f017a03000108010001080400010f017a010f0100010f017a030f017a030f017a010f01000108020001080400010f0300010f017a030f017a030f017a020f0108010001080900010f017a030f017a030f017a030f017a020f0800010f017a030f017a030f017a030f017a030f017a06000108017a030f017a030f017a030f017a030f017a010f050001080200020f017a030f0211020f017a030f017a010f050001080400017a030f017a030f017a030f017a010f050001080400017a030f017a030f017a030f017a060001080500030f017a030f017a030f017a060001080700010f017a030f017a020f0800010817000183160003831500" }, { - "filename": "accessory-txt-dao-black-reversed_004", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-banana", + "data": "0x00041d140304000523047903260f000323047905260f000123047907260f00037909260e0002790226012b07260e0001790326012b0326022b02260e000226012b0526022b02260700012606000826022b02260600032605000826022b02260500052604000c2604000426012b022602000e2602000626012b022601000e2601000826012b1226012b032601001426012b032603000a26032b09260500062601570626015706260700042603570526025704260400" }, { - "filename": "accessory-txt-dao-black-reversed_005", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-bank", + "data": "0x00031c15040b00021f1400061f1000031f0472031f0c00021f020c011f0472011f020c021f0800021f020c031f0472031f020c021f0400161f020016720300031f0272041f0272041f0272031f0400011f010c011f0272041f0272041f0272011f010c011f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400011f1272011f0300161f0100021f1472021f" }, { - "filename": "accessory-txt-dao-black-reversed_006", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-baseball-gameball", + "data": "0x00041a17060800040b0e00080b0a0001240b0b0700020b01240a0b0124010b0400030b01240a0b0124010b0400030b01240a0b0124010b0300040b01240a0b0124020b0200030b01240c0b0124010b0100040b01240c0b0124050b01240e0b0124040b01240e0b0124040b01240e0b0124010b0100030b01240c0b0124010b0200030b01240c0b0124010b0300030b01240a0b0124010b0400040b0224060b0224020b0500050b0624030b07000c0b0a00080b0e00040b0800" }, { - "filename": "accessory-txt-dao-black-reversed_007", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-basketball", + "data": "0x00031a160607000542011a0c000442011a0242011a024208000242021a0542011a044205000542011a0442011a0442011a04000142011a0442011a0342011a0342011a014203000842011a0242011a0242011a034202000142011a0742051a044201000c42011a1342011a1342011a0742141a0c42011a1342011a074201000b42011a064202000942051a0442030004420166010e0166010e0166010e011a0242011a024204000642011a0342011a0342011a014205000442011a0442011a04420800021a0542011a02420c000542011a0700" }, { - "filename": "accessory-txt-dao-black-reversed_008", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-bat", + "data": "0x00031e14020900018408000184120001840800018411000384060003840c000184020002840185018406000184018502840200018408000584018502840400028401850584070001840185038401850a8401850384018501840600058401850a840185058405000184018514840185018404000184018514840185018403000184018516840185018402000184018516840185018402000184018516840185018402000184018516840185018401000184018518840185028401851884018508840185048402230162012301620223018401850984030002840185038403230102012301020123028401850284030003840500108405000184" }, { - "filename": "accessory-txt-dao-black-reversed_009", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-bear", + "data": "0x000518150805860600068602370286060002860237a1860208028602080223018701230187022301080286020802860208072301080286020802860208028602080286020802860208028602080286020802860208028601000e080100" }, { - "filename": "accessory-txt-dao-black-reversed_010", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-beer", + "data": "0x000219140605000287020003870b000b8707000f8704000f87030011870200018701420c87016d02870300024201680287016802470587016d018701000388024201680247016802470168014702870168016d0187010003880342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701420247016802470268016d0200028801000342024701420247016802470268016d020003880342024701420247016802470268016d030002880342024701420247014202470268016d05000c420168016d050005880785028805000e880200" }, { - "filename": "accessory-txt-dao-black-reversed_011", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-beet", + "data": "0x00021a14060400031d020002800d00011d0119021d0280010c01800c00021d0119011d0180010c02800d00021d0119010c02800f00011d0119010c0180110002850d001089030009190189011901890119018901190389010014890319108901193a890219288902190f89031901000a89022006890300041901890119078901190189011905000e890300" }, { - "filename": "accessory-txt-dao-black-reversed_012", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-bell", + "data": "0x00011c14040b00022616000226130008260f000226010207260d000226010209260b00022601020b260a000e260a000e2609001026080010260800102608001026080010260800108a0800108a06001426040001260102122602000c2603372126010016260100" }, { - "filename": "accessory-txt-dao-black-reversed_013", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-bigfoot-yeti", + "data": "0x00021d14020d00047f1700067f1400037f0156017f0156017f1400027f0156015a0156015a017f1400027f028b0156018b017f1100057f018b0156015a0156017f10000b7f0f000b7f0f000d7f0d000e7f018c0b00047f01000a7f038c0800047f02000a7f058c0500047f02000b7f078c0100047f03000c7f0300058c037f04000c7f0400018c0100018c08000b7f1000087f028d027f1000028c0a7f0e00068c087f0600" }, { - "filename": "accessory-txt-dao-black-reversed_014", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-bigfoot", + "data": "0x00021d14020d0004341700063414000334012b0134012b013414000234012b0136012b0136013414000234028e012b018e013411000534018e012b0136012b013410000b340f000b340f000d340d000e3401360b00043401000a3403360800043402000a3405360500043402000b3407360100043403000c3403000536033404000c34040001360100013608000b341000083402160234100002360a340e00063608340600" }, { - "filename": "accessory-txt-dao-black-reversed_015", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-blackhole", + "data": "0x00011d17030e00018f1800018f1000018f1800018f0600015f0600015f0400018f0600018f0500015f0600015f0600018f0a00015f0300045f0300015f0e00015f01190120015f032003190c00015f0200015f01190220045f0220025f0b00015f0100015f01190120025f0490025f01200119015f0a00015f0100015f0120015f029004230290015f01200119015f0100015f0500015f0200025f0120015f019006230190015f022001190300018f06000119025f019008230190025f01190400028f0500025f019008230190015f0120015f01190300028f0400015f0120015f019008230190015f0120015f0600018f0300015f0120015f019008230190015f0120015f0a00015f01190120015f019006230190015f02200119015f0700015f0200035f029004230290025f02190100015f0700025f02190120025f0490025f0220015f01190100015f0a00015f01190220045f0120015f01200119015f0c000219055f0320015f02190200015f0600018f0700015f01000319015f0d00018f0900015f0900018f1800018f0300" }, { - "filename": "accessory-txt-dao-black-reversed_016", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-blueberry", + "data": "0x00041a1706070006430c000543069107000143019101560591035403910500024306910154037701540391040001430691025404770154029103000243079101540477015403910200014301560891045404910100024312910343119103431191024312910243129102431291010001430391067708910200014304910292099101430191030002430e91040004430c91060002430991014308000543069101430b0006430700" }, { - "filename": "accessory-txt-dao-black-reversed_017", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-bomb", + "data": "0x00041c16070f00010d0b00060d0200030d02830600040d0172090d010001830400020d02720a0d030001830200030d0272090d040001830100100d030001830100100d03000193120d02000141120d0300120d0300120d0300120d0300120d0400100d0500100d0600060d0572030d08000c0d0a000a0d0d00060d0900" }, { - "filename": "accessory-txt-dao-black-reversed_018", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-bonsai", + "data": "0x00021e15030c00070f1200030f031c040f0f00050f031c010f021c020f0c00040f011c020f031c010f021c020f0b00100f0c000e0f0200030f0c00080f0300020f011c020f0200070f0600027c03000a0f021c060f0400037c060f021c040f021c010f011c050f0400017c070f021c0d0f0400037c080f01000b0f0300097c0500080f087c0c00030f047c0300047c1500067c1400087c0e001294090005940d0e090012940b000e940700" }, { - "filename": "accessory-txt-dao-black-reversed_019", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-boombox", + "data": "0x00041b1f060400025815000258150002580d00089502580795040001950900025804000195040001950b0002580200019502000296136f0296016f011c016f0195016f090e016f0195016f0124016f0296136f0296036f030e026f0195016f0195026f030e036f0296026f050e056f050e026f0296016f070e016f0195016f070e016f0296016f070e036f070e016f0296016f070e016f0195016f070e016f0296026f050e056f050e026f0296036f030e026f0195016f0195026f030e036f0296136f1200020e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e0100" }, { - "filename": "accessory-txt-dao-black-reversed_020", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-boot", + "data": "0x00061c140701000697030002970a00069702080100019701980a0007970208019701980a0008970108019701980a000b970a000b970a000b9709000d9708000e970700149701002e9703262397010013830100" }, { - "filename": "accessory-txt-dao-black-reversed_021", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-box", + "data": "0x00061c1403040003970f990108050004970f9901080400049701080f9902080300049701080f9902080200049702080f9902080100059702080f990308040003080f990308040003080f99070003080f990700029901080f990700029901080f9907000299010805990a010700030805990a010700030805990a01070003080f990300" }, { - "filename": "accessory-txt-dao-black-reversed_022", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-boxingglove", + "data": "0x000418140504000d5504000a550438025502004d550189015506070b550189015506070b550189015506070b550189015506070b550189015506070955030001550607095503000f55050003550b260500035501260502012301020326050003550b2605000e550100" }, { - "filename": "accessory-txt-dao-black-reversed_023", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-brain", + "data": "0x00051a14060600086a0900036a0320016a0420036a0500016a0320036a0120046a0320016a0300016a0120026a0120016a0120016a0120016a0120026a0120026a0120016a0200016a0120016a0120026a0120026a0120026a0120056a0100066a0120036a0120026a0120026a0120016a0120026a0120046a0120066a0120046a0120026a0120026a0120026a0120036a0120066a0120056a0120026a0120046a0120016a0220026a0120026a0120026a0120036a0120096a0120026a0120036a0120056a0120066a0120076a0120056a0220046a0120016a0100126a0200016a0120036a0220026a0120056a0220016a0300016a0120016a0120026a0220046a0220026a05000e6a0300" }, { - "filename": "accessory-txt-dao-black-reversed_024", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-bubble-speech", + "data": "0x00041b160504000e0206001202030014020200140201009a0201001402020014020300120206000f02120003021300020213000202140001020700" }, { - "filename": "accessory-txt-dao-black-reversed_025", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-bubblegum", + "data": "0x00021b1705080006690e000369029a05690a000269029a04690202046907000269019a05690402046905000269019a06690402056904000a69020202690202026903000f6902020369020002690102116901008469010014690200146903000a69019a076904000b69019a066905000169019a0769019a0469019a016907000169039a0669039a01690a000a9a0e00069a0800" }, { - "filename": "accessory-txt-dao-black-reversed_026", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-burger-dollarmenu", + "data": "0x00071a14060600080a0a00060a0125050a0700040a0125050a0125030a0500020a01250d0a04000e0a0125010a0300120a0200120a020012260100082601970626029701260197012601970226019704260e9701260c9701260497010012970300100a0400100a0200" }, { - "filename": "accessory-txt-dao-black-reversed_027", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-cake", + "data": "0x00021a14060500013704000137030001370900013701290137020001370129013701000137012901370800013701290126020001370129012601000137012901260900012604000126030001260900033c0200033c0100033c08000156023c02000156023c01000156023c0600102003000520060207200200042008020620020004200802052001020200010203200902032002020200020202200e020200020202200e020200020201200f0202001202020012020200012001020220020205200202022002020120010001200102012002020220050202200202022001021520" }, { - "filename": "accessory-txt-dao-black-reversed_028", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-calculator", + "data": "0x00051a16060200120302001203020001030488010303880103070701030200060303880103070701030200010304880d03020006030388010303880103038801030200010304880d03020006030388010303880103038801030200010304180d0302000103041801030388010303880103038801030200120302000103105c010302080103015c019b035c019b035c019b015c019b015c029b015c010302080103015c039b015c029b025c019b015c019b015c029b015c010302080103015c019b015c019b015c039b015c019b015c019b015c029b015c010302080103105c010302000103109c010302001203" }, { - "filename": "accessory-txt-dao-black-reversed_029", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-calendar", + "data": "0x00041a14050100029d0200029d0200029d0200029d0200029d02000202019d0302019d0302019d0302019d0302019d180201230102012301020123010201230102012301020123010201230102059e1002029e0102029e02020d9f0102019e0102019e0102019e0302019f0102019f0102019f0102019f0102019f0102019f0202059e02020d9f0102059e0302019f0102019f0102019f0102019f0102019f0102019f0202059e02020d9f0102059e0302019f0102019f0102019f0102019f0102019f0102019f0202059e02020d9f0102059e0302019f0102019f0102019f0102019f0102019f0102019f0202059e02020d9f0102059e0302019f0102019f0102019f0623019f0102059e02020d9f0102059e1602" }, { - "filename": "accessory-txt-dao-black-reversed_030", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-camcorder", + "data": "0x00091c14050400047e0500047e060001230100117c03000223017e017c01240f7c02000323017e117c027e03230100117c027e02230200117c027e02230200117c027e022302001123027e022302001123027e022302000e23027e0123027e0223020001230b7c0223027e0123020002230200112303000123" }, { - "filename": "accessory-txt-dao-black-reversed_031", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-cannedham", + "data": "0x00041a14060f00017a10000383017a1200027a0f00047a0c00067a030002390200097a0500053901001483508c14a12d07010e0151010e0151010e0151010e01511b071483" }, { - "filename": "accessory-txt-dao-black-reversed_032", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-car", + "data": "0x00091c1406050008550d000155080401550b00035508040155090005550804015507000755060401a20104015505000e5502a20455020014550157010014550157045501230227095502270123045502a20155012702a20127015502230455012702a20127025504a20100012702a2012707a2012702a20127010002a205000227090002270500" }, { - "filename": "accessory-txt-dao-black-reversed_033", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-cash-register", + "data": "0x00021a1408010004580e000158026201580e00045802000a27010001610158016202580261012708430127026104580261012701430654014301270261016f0262016f02610127084301270261046f0261012701430354044301270261042702610127084301278e61022a026102870161028701610287016102870161042a026102870161028701610287016102870161042a1361" }, { - "filename": "accessory-txt-dao-black-reversed_034", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-cassettetape", + "data": "0x00071b14050100140e0100020e1202040e0102010e1002030e0102010e0102010e1002020e05a3010203a3020203a3010205a3020e04a3030203a3010202a3030204a3020e04a3030203a3010202a3030204a3020e05a3010203a3020203a3010205a3020e14a3020e1426020e1426010e060c0a1f0b0c021f0100061f0100021f090c0e1f040c" }, { - "filename": "accessory-txt-dao-black-reversed_035", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-cat", + "data": "0x00031a14060100020e0d00020e0300040e0900040e0300010e0106040e0500040e0106010e0300010e0306020e0500020e0306010e0300010e0406070e0406010e0300010e0306090e0306010e0300010e01060d0e0106010e0300110e0400100e0400100e0400100e0400100e0400100e0400100e0200053c0506026c0406043c02000806019607060200053c030604960406043c020010060200" }, { - "filename": "accessory-txt-dao-black-reversed_036", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-cd", + "data": "0x00031b1805080006a30e0002a3066702a30a0002a30a6702a3070001a30e6701a3050001a301220f6701a3040001a302220e6701a3030001a305220b67024301a3020001a30622016704080367044301a3010001a304200322010804a30108074302a30620010806a30108064302a30620010802a3020002a30108064302a30620010802a3020002a30108069a02a30626010806a30108069a02a30726010804a30108026e059a01a3010001a30426036704080167046e029a01a3020001a302260b67056e01a3030001a30d67036e01a3040001a30f67016e01a3050001a30e6701a3070002a30a6702a30a0002a3066702a30e0006a30800" }, { - "filename": "accessory-txt-dao-black-reversed_037", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-chain", + "data": "0x00051e1602030004840100068401000684010003840600049301840693018406930184039306000484010a0684010a0684010a038407000184010a0184010a018402000184010a0184010a018402000184010a0184010a01840700038401930684019306840193068404000393018401020593018401020593018401020593040003840100068401000684010006847500068401000684010006840100048402000184010205930184010205930184010205930184010203930100018401930684010a0684010a06840193048401000184010a0184010a018402000184010a0184010a018402000184010a0184010a018402000184010a0184010a01840100048401930684019306840193068401930184010004930184069301840693018406930184020004840100068401000684010006840300" }, { - "filename": "accessory-txt-dao-black-reversed_038", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-chainsaw", + "data": "0x00051d16040300036315000163030001631400016303000163120008630200010d0200010d0200010d0200010d05000863010d0100020d0100020d0100020d0100020d04000863020d0263010d0263010d0263010d0263020d0300010d06630e0d0163020d08630e0d0163010d0200010d06630f0d020008630e0d0163020d0100010d06630e0d0163010d010008630f0d020008630e0d0163020d03630102010d0102010d01630e0d0163010d02000263010d0102010d010201630f0d04000863010d0263010d0263010d0263010d0263010d05000563020d0100020d0100020d0100020d0100020d070004630100010d0200010d0200010d0200010d0200010d0300" }, { - "filename": "accessory-txt-dao-black-reversed_039", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-chameleon", + "data": "0x00021c16040b00021d1600021d1500041d1300061d0e000184031d0184041d0184031d01840800030f0184031d0484031d0184030f0500010f0222020f0184011d0184041d0184011d0184050f0300010f0423010f0184021d0484021d0184060f0200010f012202230122020f0184061d0184050f02220200020f0222030f0184061d0184040f03230200070f0184061d0184040f012202230200070f0184061d0184050f02220300040f0284081d0284040f050003840c1d03840500141d0300161d0200041d048406230484041d0100021d03840e220384031d01840522010f0122060f0122010f05220184011d01001622030003220e0003220200" }, { - "filename": "accessory-txt-dao-black-reversed_040", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-chart-bars", + "data": "0x00041a1406100004730800041c040004730800041c040004730800041c0469047304000428041c0469047304000428041c0469047304000428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428011c06230169047304190428041c0469047304190428041c04690473" }, { - "filename": "accessory-txt-dao-black-reversed_041", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-cheese", + "data": "0x00031a140605000226012b022602290d00052602290d00052603290b000226012902260229012b01290b0001260129022b01260129012b03290a0001260129022b012601290126032909000526032902260229080005260729080005260829060005260929060005260a29050005260a29040005260c29030005260c2903000126012903260d29010001260129012b02260429012b012903230529010001260129012b02260229022607290126032905260f29" }, { - "filename": "accessory-txt-dao-black-reversed_042", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" + "filename": "head-chefhat", + "data": "0x00051c14040500060210000b020c00090203a308020300060204a30c020200030203a310020100250201a3060201a3030201000b0201a3050202a303020300030201a3060201a3030202a304020500030201a3050201a3020201a3050208000e7c0a000ea30a000ea30a0001020c5501020a000e020a000e020500" }, { - "filename": "accessory-txt-dao-black-reversed_043", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_044", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_045", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_046", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_047", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_048", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_049", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_050", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_051", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_052", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_053", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_054", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_055", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_056", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_057", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_058", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_059", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_060", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_061", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_062", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_063", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_064", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_065", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_066", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_067", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_068", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_069", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_070", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_071", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_072", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_073", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_074", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_075", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_076", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_077", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_078", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_079", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_080", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_081", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_082", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_083", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_084", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_085", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_086", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_087", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_088", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_089", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_090", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_091", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_092", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_093", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_094", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_095", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_096", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_097", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_098", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_099", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - } - ], - "heads": [ - { - "filename": "head-aardvark", - "data": "0x00021e140605000137020001370f0004000237020002370e0003000337020003370d0002000437020004370c0003000337020003370d0004000237020002370e0005000137020001370f000d370b000d370b000d370b000d370b000d370b000d370b000d370600057d0d370600017d017e017d017e017d0b37097d017e017d017e017d0b370d7d0a370523097d0b370d7d" - }, - { - "filename": "head-abstract", - "data": "0x00041a1405045c01000447010004470100017f01000114010001140100045c01230447012304470123017f01230114012301140123045c01230447012304470123017f01230114012301140123045c01230447012304470123017f01230114012301140123045c01230447012304470123017f012301140123011401230100142301230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f012304460100132301000123015401230154012301540123040701230455012304550123015401230154012301540123040701230455012304550123015401230154012301540123010703540123045501230455012301540123015401230154012304070123045501230455012301540123015401230154012304070123045501230455" - }, - { - "filename": "head-ape", - "data": "0x0005191406030004800c0002000980080001000e80040002000f80020001001080020002000f80020002000f800200020001800e810200020001800e810200020001800e810200020001800e81020003800e8102000180018101800f8101000180018103800d82018005800d81018002001180" - }, - { - "filename": "head-bag", - "data": "0x00031c140306000e3a050006000e3a05000400023a0e00023a03000400023a0e00023a03000400023a0e00023a030002000207023a0e07023a02070100020001070126023a040706260407023a01260107010001000126010702260607042606070226010701000100012608070626080701000100013a16070100013a0100013a15070100013a0100013a15070100013a0107013a1607013a0107013a1607010018070100070703760e0701001807020016070100" - }, - { - "filename": "head-bagpipe", - "data": "0x00011d19050a0001830d000a00030f0b000a0001830200010f0100018308000a00020f0300010f017a07000a000108010f017a020f0108017a010f06000a00020f017a020f0183017a020f050001000183080001830100017a010f010001080100020f018304000200010807000108040001080200010f017a010f030003000108060001080300010803000183017a010f0300040001080500010803000108020001080100017a010f0200010f0200017a030f017a030f010803000108020001080200020f017a01000100010f017a030f017a030f017a03000108010001080400010f017a010f0100010f017a030f017a030f017a010f01000108020001080400010f02000100010f017a030f017a030f017a020f01080100010808000100010f017a030f017a030f017a030f017a020f07000100010f017a030f017a030f017a030f017a030f017a050001000108017a030f017a030f017a030f017a030f017a010f0400010001080200020f017a030f0211020f017a030f017a010f0400010001080400017a030f017a030f017a030f017a010f0400010001080400017a030f017a030f017a030f017a0500010001080500030f017a030f017a030f017a0500010001080700010f017a030f017a020f070001000108160001000183160003831500" - }, - { - "filename": "head-banana", - "data": "0x00041d140304000523047903260a0005000323047905260900060001230479072608000700037909260700070002790226012b07260700070001790326012b0326022b0226070007000226012b0526022b02260700012606000826022b022606000126022605000826022b022605000226032604000c26040003260126012b022602000e26020004260226012b022601000e26010005260326012b1226012b032601001426012b0326010002000a26032b0926020003000626015706260157062603000400042603570526025704260400" - }, - { - "filename": "head-bank", - "data": "0x00031c15040b00021f0b000900061f09000700031f0472031f07000500021f020c011f0472011f020c021f05000300021f020c031f0472031f020c021f03000100161f01000100167201000200031f0272041f0272041f0272031f02000200011f010c011f0272041f0272041f0272011f010c011f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200031f0272041f0272041f0272031f02000200011f1272011f02000100161f0100021f1472021f" - }, - { - "filename": "head-baseball-gameball", - "data": "0x00041a17060800040b08000600080b0600040001240b0b04000300020b01240a0b0124010b02000200030b01240a0b0124010b02000200030b01240a0b0124010b02000100040b01240a0b0124020b01000100030b01240c0b0124010b0100040b01240c0b0124020b030b01240e0b0124010b030b01240e0b0124010b030b01240e0b0124010b0100030b01240c0b0124010b01000100030b01240c0b0124010b01000200030b01240a0b0124010b02000200040b0224060b0224020b02000300050b0624030b030004000c0b04000600080b06000800040b0800" - }, - { - "filename": "head-basketball", - "data": "0x00031a160607000542011a070005000442011a0242011a0242050003000242021a0542011a0442030002000542011a0442011a0442011a020002000142011a0442011a0342011a0342011a0142020001000842011a0242011a0242011a0342010001000142011a0742051a044201000c42011a07420c42011a07420c42011a0742141a0c42011a07420c42011a074201000b42011a0642010001000942051a04420100020004420166010e0166010e0166010e011a0242011a0242020002000642011a0342011a0342011a0142020003000442011a0442011a044203000500021a0542011a0242050007000542011a0700" - }, - { - "filename": "head-bat", - "data": "0x00031e14020900018408000184090009000184080001840900080003840600038408000400018402000284018501840600018401850284020001840400040005840185028404000284018505840400030001840185038401850a84018503840185018403000300058401850a8401850584030002000184018514840185018402000200018401851484018501840200010001840185168401850184010001000184018516840185018401000100018401851684018501840100010001840185168401850184010001840185188401850184018401851884018501840784018504840223016201230162022301840185078402840300028401850384032301010123010101230284018502840300028401840500108405000184" - }, - { - "filename": "head-bear", - "data": "0x0005181508058606000586018602370286060002860237018610861086108610861086108610861086108610860208028602080223018701230187022301080286020802860208072301080286020802860208028602080286020802860208028602080286020802860208028601000e080100" - }, - { - "filename": "head-beer", - "data": "0x00021914060500028702000387070004000b87040003000f87010003000f870100020011870200018701420c87016d02870300024201680287016802470587016d018701000388024201680247016802470168014702870168016d0187010003880342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701420247016802470268016d0200028801000342024701420247016802470268016d020003880342024701420247016802470268016d0200010002880342024701420247014202470268016d020003000c420168016d02000300058807850288020003000e880200" - }, - { - "filename": "head-beet", - "data": "0x00021a14060400031d0200028009000400011d0119021d0280010c018008000400021d0119011d0180010c028008000500021d0119010c028009000600011d0119010c01800a00070002850b000200108902000100091901890119018901190189011903890100148903191089011914891489128902191489148902190f89031901000a8902200689010002000419018901190789011901890119020003000e890300" - }, - { - "filename": "head-bell", - "data": "0x00011c14040b0002260b000b0002260b0008000826080007000226010107260700060002260101092606000500022601010b26050005000e26050005000e2605000400102604000400102604000400102604000400102604000400102604000400108a04000400108a0400020014260200020001260101122602000c26033709261826010016260100" - }, - { - "filename": "head-bigfoot-yeti", - "data": "0x00021d14020d00047f0a000d00067f08000c00037f0156017f0156017f08000c00027f0156015a0156015a017f08000c00027f028b0156018b017f08000900057f018b0156015a0156017f080008000b7f080007000b7f090006000d7f080005000e7f018c07000400047f01000a7f038c05000300047f02000a7f058c03000200047f02000b7f078c0100047f03000c7f0300058c037f04000c7f0400018c0100018c010007000b7f09000700087f028d027f08000800028c0a7f07000700068c087f0600" - }, - { - "filename": "head-bigfoot", - "data": "0x00021d14020d0004340a000d00063408000c000334012b0134012b013408000c000234012b0136012b0136013408000c000234028e012b018e0134080009000534018e012b0136012b0134080008000b34080007000b34090006000d34080005000e34013607000400043401000a34033605000300043402000a34053603000200043402000b3407360100043403000c3403000536033404000c340400013601000136010007000b34090007000834021602340800080002360a3407000700063608340600" - }, - { - "filename": "head-blackhole", - "data": "0x00011d17030e00018f0b000d00018f0c000400018f15000300018f0600015f0600015f0400018f03000300018f0500015f0600015f0600018f02000800015f0300045f0300015f06000800015f01190120015f0320031908000400015f0200015f01190220045f0220025f07000400015f0100015f01190120025f0490025f01200119015f06000400015f0100015f0120015f029004230290015f01200119015f0100015f03000200015f0200025f0120015f019006230190015f022001190300018f010005000119025f019008230190025f01190400018f018f0500025f019008230190015f0120015f01190300018f018f0400015f0120015f019008230190015f0120015f05000100018f0300015f0120015f019008230190015f0120015f05000500015f01190120015f019006230190015f02200119015f04000300015f0200035f029004230290025f02190100015f03000400025f02190120025f0490025f0220015f01190100015f03000700015f01190220045f0120015f01200119015f060006000219055f0320015f02190200015f04000200018f0700015f01000319015f0a000300018f0900015f0900018f02001600018f0300" - }, - { - "filename": "head-blueberry", - "data": "0x00041a1706070006430700050005430691040003000143019101560591035403910300020002430691015403770154039102000200014306910254047701540291020001000243079101540477015403910100010001430156089104540491010002431291034311910343119102431291024312910243129101000143039106770891010001000143049102920991014301910100020002430e910200020004430c9102000400024309910143040004000543069101430400070006430700" - }, - { - "filename": "head-bomb", - "data": "0x00041c16070f00010d05000600060d0200030d028302000400040d0172090d0100018301000300020d02720a0d030001830200030d0272090d040001830100100d030001830100100d03000193120d02000141120d0300120d0300120d0300120d0300120d03000100100d04000100100d04000200060d0572030d050003000c0d060004000a0d07000600060d0900" - }, - { - "filename": "head-bonsai", - "data": "0x00021e15030c00070f08000a00030f031c040f07000800050f031c010f021c020f06000600040f011c020f031c010f021c020f06000500100f060006000e0f0200030f02000a00080f0300020f011c020f01000100070f0600027c0300080f020f021c060f0400037c060f021c020f020f021c010f011c050f0400017c070f021c020f0b0f0400037c080f01000b0f0300097c04000100080f087c0a000200030f047c0300047c0b000a00067c0b000900087c0a00040012940500040005940d0e050004001294050006000e940700" - }, - { - "filename": "head-boombox", - "data": "0x00041b1f06040002580f00060002580d00080002580b00020008950258079502000200019509000258040001950200020001950b0002580200019502000296136f0296016f011c016f0195016f090e016f0195016f0124016f0296136f0296036f030e026f0195016f0195026f030e036f0296026f050e056f050e026f0296016f070e016f0195016f070e016f0296016f070e036f070e016f0296016f070e016f0195016f070e016f0296026f050e056f050e026f0296036f030e026f0195016f0195026f030e036f0296136f1200020e01001300010e01001300010e01001300010e01001300010e01001300010e01001300010e01001300010e01001300010e01001300010e01001300010e0100" - }, - { - "filename": "head-boot", - "data": "0x00061c140701000697030002970900010006970208010001970198090001000797020801970198090001000897010801970198090001000b97090001000b97090001000b9709000d9708000e9707001497010015971597049703260e971597010013830100" - }, - { - "filename": "head-box", - "data": "0x00061c1403040003970f9901080200030004970f99010802000200049701080f99020801000200049701080f99020801000100049702080f9902080100059702080f990308040003080f990308040003080f990300040003080f9903000400029901080f9903000400029901080f99030004000299010805990a0203000400030805990a0203000400030805990a020300040003080f990300" - }, - { - "filename": "head-boxingglove", - "data": "0x000418140504000d55020002000a55043802550100010012551355135513550255018901550607095502550189015506070955025501890155060709550255018901550607095502550189015506070955030001550607095503000f550100040003550b26010004000355012605010123010103260100040003550b26010004000e550100" - }, - { - "filename": "head-brain", - "data": "0x00051a14060600086a06000300036a0320016a0420036a03000200016a0320036a0120046a0320016a02000100016a0120026a0120016a0120016a0120016a0120026a0120026a0120016a01000100016a0120016a0120026a0120026a0120026a0120056a0100066a0120036a0120026a0120026a0120016a0120016a016a0120046a0120066a0120046a0120016a016a0120026a0120026a0120036a0120066a0120016a046a0120026a0120046a0120016a0220026a0120016a016a0120026a0120036a0120096a0120016a016a0120036a0120056a0120066a0120016a066a0120056a0220046a0120016a0100126a01000100016a0120036a0220026a0120056a0220016a01000200016a0120016a0120026a0220046a0220026a020003000e6a0300" - }, - { - "filename": "head-bubble-speech", - "data": "0x00041b160504000e010400020012010200010014010100010014010100160116011601160116011601160101001401010001001401010002001201020004000f0103000f00030104000f00020105000e00020106000e0001010700" - }, - { - "filename": "head-bubblegum", - "data": "0x00021b170508000669080006000369029a0569060004000269029a046902010469040003000269019a056904010469030002000269019a066904010569020002000a690201026902010269020001000f690201036901000100026901011169010016691669166916691669166901001469010001001469010002000a69019a0769020002000b69019a0669020003000169019a0769019a0469019a0169030004000169039a0669039a0169040006000a9a06000800069a0800" - }, - { - "filename": "head-burger-dollarmenu", - "data": "0x00071a14060600080a06000400060a0125050a04000300040a0125050a0125030a03000200020a01250d0a020002000e0a0125010a02000100120a01000100120a0100010012260100082601970626029701260197012601970226019704260c97029701260c97012604970100129701000200100a02000200100a0200" - }, - { - "filename": "head-cake", - "data": "0x00021a140605000137040001370300013705000400013701290137020001370129013701000137012901370400040001370129012602000137012901260100013701290126040005000126040001260300012605000400033c0200033c0100033c040004000156023c02000156023c01000156023c0400020010200200010005200601072001000100042008010620010001000420080105200101010001000101032009010320020101000100020102200e0101000100020102200e0101000100020101200f01010001001201010001001201010001000120010102200201052002010220020101200100012001010120020102200501022002010220010101201420" - }, - { - "filename": "head-calculator", - "data": "0x00051a16060200120302001203020001030488010303880103070701030200060303880103070701030200010304880d03020006030388010303880103038801030200010304880d03020006030388010303880103038801030200010304180d0302000103041801030388010303880103038801030200120302000103105c010302080103015c019b035c019b035c019b015c019b015c029b015c010302080103015c039b015c029b025c019b015c019b015c029b015c010302080103015c019b015c019b015c039b015c019b015c019b015c029b015c010302080103105c010302000103109c010302001203" - }, - { - "filename": "head-calendar", - "data": "0x00041a14050100029d0200029d0200029d0200029d0200029d02000201019d0301019d0301019d0301019d0301019d02011501010101230101012301010123010101230101012301010123010101230101059f01010f01029f0101029f010101010da00101019f0101019f0101019f0101020101a0010101a0010101a0010101a0010101a0010101a00201059f010101010da00101059f0101020101a0010101a0010101a0010101a0010101a0010101a00201059f010101010da00101059f0101020101a0010101a0010101a0010101a0010101a0010101a00201059f010101010da00101059f0101020101a0010101a0010101a0010101a0010101a0010101a00201059f010101010da00101059f0101020101a0010101a0010101a0062301a00101059f010101010da00101059f01011501" - }, - { - "filename": "head-camcorder", - "data": "0x00091c14050400047e0500047e060001230100117c030001230123017e017c01240f7c020002230123017e117c027e022301230100117c027e02230200117c027e02230200117c027e022302001123027e022302001123027e022302000e23027e0123027e0223020001230b7c0223027e0123020002230200112303000123" - }, - { - "filename": "head-cannedham", - "data": "0x00041a14060f00017a04000c000383017a04000e00027a04000b00047a05000700067a030002390200097a0500053901001483148c148c148c148c14a2140714070507010e0151010e0151010e0151010e0151070714071483" - }, - { - "filename": "head-car", - "data": "0x00091c140605000855090004000155080401550800030003550804015507000200055508040155060001000755060401a30104015505000e5502a304550200145501570100145501570155035501230227095502270123045502a30155012702a30127015502230455012702a30127025502a302a30100012702a3012707a3012702a30127010002a3010004000227090002270500" - }, - { - "filename": "head-cash-register", - "data": "0x00021a1408010004580d0001000158026201580d000100045802000a2701000161015801620258026101270843012701610161045802610127014306540143012701610161016f0262016f026101270843012701610161046f0261012701430354044301270161016104270261012708430127016112611261126112611261126112610f61022a0161016102870161028701610287016102870161042a0161016102870161028701610287016102870161042a01611261" - }, - { - "filename": "head-cassettetape", - "data": "0x00071b14050100140e0100020e1201020e020e0101010e1001020e010e0101010e0101010e1001010e010e05a4010103a4020103a4010105a4010e010e04a4030103a4010102a4030104a4010e010e04a4030103a4010102a4030104a4010e010e05a4010103a4020103a4010105a4010e010e14a4010e010e1426010e010e1426010e060c0a1f060c050c021f0100061f0100021f050c040c0e1f040c" - }, - { - "filename": "head-cat", - "data": "0x00031a14060100020e0d00020e02000100040e0900040e02000100010e0106040e0500040e0106010e02000100010e0306020e0500020e0306010e02000100010e0406070e0406010e02000100010e0306090e0306010e02000100010e01060d0e0106010e02000100110e02000200100e02000200100e02000200100e02000200100e02000200100e02000200100e0200053c0506026c0406043c02000806019607060200053c030604960406043c020010060200" - }, - { - "filename": "head-cd", - "data": "0x00031b1805080006a40800060002a4066702a40600040002a40a6702a40400030001a40e6701a40300020001a401220f6701a40200020001a402220e6701a40200010001a405220b67024301a40100010001a40622016704080367044301a4010001a404200322010804a40108074301a401a40620010806a40108064301a401a40620010802a4020002a40108064301a401a40620010802a4020002a40108069a01a401a40626010806a40108069a01a401a40726010804a40108026e059a01a4010001a40426036704080167046e029a01a40100010001a402260b67056e01a40100020001a40d67036e01a40200020001a40f67016e01a40200030001a40e6701a40300040002a40a6702a40400060002a4066702a40600080006a40800" - }, - { - "filename": "head-chain", - "data": "0x00051e160203000484010006840100068401000384030003000493018406930184069301840393030003000484010a0684010a0684010a0384030004000184010a0184010a018402000184010a0184010a018402000184010a0184010a018405000200038401930684019306840193068402000200039301840101059301840101059301840101059302000200038401000684010006840100068402001c001c001c001c000300068401000684010006840100048402000184010105930184010105930184010105930184010103930100018401930684010a0684010a06840193048401000184010a0184010a018402000184010a0184010a018402000184010a0184010a018402000184010a0184010a01840100048401930684019306840193068401930184010004930184069301840693018406930184020004840100068401000684010006840300" - }, - { - "filename": "head-chainsaw", - "data": "0x00051d1604030003631300020001630300016312000200016303000163120008630200010d0200010d0200010d0200010d05000863010d0100020d0100020d0100020d0100020d04000863020d0263010d0263010d0263010d0263020d02000100010d06630e0d0163020d08630e0d0163010d01000100010d06630f0d020008630e0d0163020d0100010d06630e0d0163010d010008630f0d020008630e0d0163020d03630101010d0101010d01630e0d0163010d010001000263010d0101010d010101630f0d020002000863010d0263010d0263010d0263010d0263010d020003000563020d0100020d0100020d0100020d0100020d0300040004630100010d0200010d0200010d0200010d0200010d0300" - }, - { - "filename": "head-chameleon", - "data": "0x00021c16040b00021d0b000b00021d0b000a00041d0a000900061d090005000184031d0184041d0184031d018405000300030f0184031d0484031d0184030f03000200010f0222020f0184011d0184041d0184011d0184050f02000100010f0423010f0184021d0484021d0184060f01000100010f012202230122020f0184061d0184050f022201000100020f0222030f0184061d0184040f032301000100070f0184061d0184040f0122022301000100070f0184061d0184050f022201000200040f0284081d0284040f0200030003840c1d038403000200141d02000100161d01000100041d048406230484041d0100021d03840e220384021d011d01840522010f0122060f0122010f05220184011d010016220100020003220e0003220200" - }, - { - "filename": "head-chart-bars", - "data": "0x00041a1406100004730800041c040004730800041c040004730800041c0469047304000428041c0469047304000428041c0469047304000428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428011c06230169047304190428041c0469047304190428041c04690473" - }, - { - "filename": "head-cheese", - "data": "0x00031a140605000226012b0226022908000500052602290800050005260329070004000226012902260229012b01290700040001260129022b01260129012b03290600040001260129022b01260129012603290600030005260329022602290500030005260729050003000526082904000200052609290400020005260a290300020005260a290300010005260c290200010005260c29020001000126012903260d29010001260129012b02260429012b012903230529010001260129012b02260229022607290126032905260f29" - }, - { - "filename": "head-chefhat", - "data": "0x00051c1404050006010d0003000b010a000200090103a4080102000100060104a40c0101000100030103a41001010018010d0101a4060101a4030101000b0101a4050102a4030101000200030101a4060101a4030102a4040102000300030101a4050101a4020101a40501030005000e7c050005000ea4050005000ea40500050001010c550101050005000e01050005000e010500" - }, - { - "filename": "head-cherry", - "data": "0x00011b15050900030f0a000400010f0200070f080005000b0f06000500010f0100070f08000600010f0200030f0a000600010f0300010f0b000700010f0300010f0a000700010f0400010f090004000318010f01180400010f044104000200091809410200010009180b41010001000918094101010141010009180d4109180d4109180d4109180d4109180d410100091806410318024101000100091805410118020103410100020009180941020004000518040005410400" + "filename": "head-cherry", + "data": "0x00011b15050900030f0e00010f0200070f0d000b0f0b00010f0100070f0e00010f0200030f1000010f0300010f1200010f0300010f1100010f0400010f0d000318010f01180400010f0441060009180941030009180b4102000918094101020141010009180d4109180d4109180d4109180d4109180d410100091806410318024102000918054101180202034103000918094106000518040005410400" }, { "filename": "head-chicken", - "data": "0x00031814080500015501000355060004000755050003000855050002000287075503870200010006870455048701000100098701550487010010871087108710871087108710871087088704130487088706130287088704550487088704550487" + "data": "0x000318140805000155010003550a000755080008550700028707550387030006870455048702000987015504870100888704130c8706130a8704550c8704550487" }, { "filename": "head-chilli", - "data": "0x00041c16050600081c090004000a1c09000200081c0d0001000a1c0c000100071c0224011c0c00041c07240c00011c0a240c0001000a240c0001000a240c0001000b240b0001000b240b0002000b240900012402000c240700022403000d2404000324040005240523092405001124010006000f24020007000c2404000a0007240600" + "data": "0x00041c16050600081c0d000a1c0b00081c0e000a1c0d00071c0224011c0c00041c07240c00011c0a240d000a240d000a240d000b240c000b240d000b240900012402000c240700022403000d240400032404000524052309240500112407000f2409000c240e0007240600" }, { "filename": "head-chipboard", - "data": "0x00061c140513a5040001a501a603a502a701a508a801a501a601a5040005a502a706a501a906a5030001a503aa01a502a701a50aab02a5030001a501aa01ab01aa02a501a906a501a907a501ac01a601a503aa01a501a904a501a903a501a905a501a902a605a501a903a501a905a501a903a501a901a501ac01a605a501a903a501a905a501a902a501a902a502a602a510a903a501ac01a601a501a903a501a90fa5020001a501a902a510a901a501ac01a601a501a901a501a910a501a902a603a501a901a502ab01a502ab01a502ab01a502ab01a502ab02a501ac01a601a501a601a501a901a502ab01a502ab01a502ab01a502ab01a502ab02a502a615a501ac01a6" + "data": "0x00061c140513a4040001a401a503a402a601a408a701a401a501a4040005a402a606a401a806a4030001a403a901a402a601a40aaa02a4030001a401a901aa01a902a401a806a401a807a401ab01a501a403a901a401a804a401a803a401a805a401a802a505a401a803a401a805a401a803a401a801a401ab01a505a401a803a401a805a401a802a401a802a402a502a410a803a401ab01a501a401a803a401a80fa4020001a401a802a410a801a401ab01a501a401a801a401a810a401a802a503a401a801a402aa01a402aa01a402aa01a402aa01a402aa02a401ab01a501a401a501a401a801a402aa01a402aa01a402aa01a402aa01a402aa02a402a515a401ab01a5" }, { "filename": "head-chips", - "data": "0x00021c19040d0001230a000c000107022309000b000307022308000a000207010102070223070009000287050702230600080004870507022305000700028701010387050703420300060002870101058705070242030005000a87050701420123020004000c8705070223010003000e8705070223020001070f8705070123010003070f870407010005070f870207020006070f870300010006070d870200014201000200060703870214068702000242010003000607098702000342010004000607078707001800180015000342150002420100150001420200" + "data": "0x00021c19040d0001231600010702231400030702231200020701020207022310000287050702230e000487050702230c000287010203870507034209000287010205870507024208000a8705070142012306000c870507022304000e8705070223020001070f8705070123010003070f870407010005070f870207020006070f87040006070d87020001420300060703870214068702000242040006070987020003420500060707874c00034215000242160001420200" }, { "filename": "head-chocolate", - "data": "0x000319140701000185010e039701850397080001000185010e028501970385019708000100020e0985060001000185010e03970185039701850197060001000185010e028501970385019703850197018503000100020e0c85030001000185010e03970185039701850397018502970100038c0f06128c128c128c128c128c010002890e190100010010190100010010190100010003190c8901190100010010190100" + "data": "0x000319140701000185010e03970185039709000185010e02850197038501970900020e098507000185010e0397018503970185019707000185010e02850197038501970385019701850400020e0c8504000185010e03970185039701850397018502970100038c0f065a8c010002890e190200101902001019020003190c890119020010190100" }, { "filename": "head-cloud", - "data": "0x00041c14040b000501080009000901060008000b01050007000d01040006000f0103000400110103000200140102000100150102000100150102001601020017010100180118010100170101001701020015010100040012010200" + "data": "0x00041c14040b000502110009020e000b020c000d020a000f0207001102050014020300150203001502020016020200170201003002010017020100170202001502050012020200" }, { "filename": "head-clover", - "data": "0x00041d16070400031d0500031c07000300051d0300051c06000300051d0300051c06000100031c051d0100061c021d0400041c061d041c051d0300051c051d031c061d0300061c010f021d031c010f061d03000100061c010f011d021c010f061d04000300051c010f011c010f051d06000400021d031c010f031c021d07000300051d010f011c010f051c06000100061d010f021c011d010f061c0400061d010f031c021d010f061c0300061d031c051d051c0300051d041c011d055c041c0100020f0100021d061c010f051d031c040f0300051c030f051d050f01000300051c0300051d06000400031c0500031d0700" + "data": "0x00041d16070400031d0500031c0a00051d0300051c0900051d0300051c0700031c051d0100061c021d0400041c061d041c051d0300051c051d031c061d0300061c010f021d031c010f061d0400061c010f011d021c010f061d0700051c010f011c010f051d0a00021d031c010f031c021d0a00051d010f011c010f051c0700061d010f021c011d010f061c0400061d010f031c021d010f061c0300061d031c051d051c0300051d041c011d055c041c0100020f0100021d061c010f051d031c040f0300051c030f051d050f0400051c0300051d0a00031c0500031d0700" }, { "filename": "head-clutch", - "data": "0x00071b14030b0004120900020009760412097602000876015b0412015b087602000876065b087602000812015b04ad015b0812010001120876015b0412015b087601000112097604120976015b0100097604120976015b0100097604120976020009760412097602000976041209760200097601010123010101230101087602000976041209760200097604120976" + "data": "0x00071b14030b0004120b0009760412097602000876015b0412015b087602000876065b087602000812015b04ac015b0812010001120876015b0412015b087601000112097604120976015b0100097604120976015b0100097604120976020009760412097602000976041209760200097601020123010201230102087602000976041209760200097604120976" }, { "filename": "head-coffeebean", - "data": "0x0005191608040004ae010004ae0400020005ae01340135013405ae0200010002ae013403ae01340123013406ae010002ae013404ae01340123013407ae01ae013405ae01340123013407ae01ae013405ae01340123013407ae01ae013405ae01340123013407ae07ae01340123013407ae07ae01340123013407ae07ae01340123013407ae07ae01340123013407ae07ae01340123013407ae07ae01340123013407ae04ae032301340123013407ae07ae01340123013407ae010006ae01340123013406ae0100020005ae01340135013405ae0200040004ae010004ae0400" + "data": "0x0005191608040004ad010004ad060005ad01340135013405ad030002ad013403ad01340123013406ad010002ad013404ad01340123013408ad013405ad01340123013408ad013405ad01340123013408ad013405ad0134012301340ead0134012301340ead0134012301340ead0134012301340ead0134012301340ead0134012301340ead0134012301340bad03230134012301340ead01340123013407ad010006ad01340123013406ad030005ad01340135013405ad060004ad010004ad0400" }, { "filename": "head-cone", - "data": "0x0003191407080002240800080002240800070004240700070004240700070004240700060006240600060006af0600060006af0600050008af050005000824050005000824050004000a24040004000aaf040004000aaf040003000caf030003000c24030004240c4802241224" + "data": "0x000319140708000224100002240f0004240e0004240e0004240d0006240c0006ae0c0006ae0b0008ae0a0008240a00082409000a2408000aae08000aae07000cae06000c24030004240c481424" }, { "filename": "head-console-handheld", - "data": "0x00031914071203010310100103010301100f79010301030110077901b0077901030103011005790510017901b0011001b00179010301030110067903b00279011001b0011001790103010301100179021001790110017901b0017901b0027901b0011001b001790103010301100f790103010301100f790103010301100f790103010301100f790103010301100f790103010301100f7901031203020301b10f03010303b1020301b1010301b1010303b2010303240103020301b1020301b1010301b1020303b20103032401031203" + "data": "0x000319140713031010020301100f7902030110077901af07790203011005790510017901af011001af017902030110067903af0279011001af01100179020301100179021001790110017901af017901af027901af011001af0179020301100f79020301100f79020301100f79020301100f79020301100f79020301100f79150301b0100303b0020301b0010301b0010303b101030324030301b0020301b0010301b0020303b1010303241303" }, { "filename": "head-cookie", - "data": "0x00031a160607000698070005000a98050003000e9803000200079801850898020002000d98018502980200010012980100010012980100149814981498149814980f980285039801000e98028502980100010003980285029801850a980100020002980285029805850598020002000698018509980200030004980185049801850498030005000a980500070006980700" + "data": "0x00031a1606070006980c000a9808000e98050007980185089804000d98018502980300129802001298010073980285039801000e9802850298020003980285029801850a98030002980285029805850598040006980185099805000498018504980185049808000a980c0006980700" }, { "filename": "head-cordlessphone", - "data": "0x000a1d1402020009030db10303020005030389010301b1028801b1028801b1028802b1018901b103030200020301b102030389010301b1028801b1028801b1028802b1018901b1030302000503038901030db1010301230103020005030389010301b1028801b1028801b1028804b10103012301030200010301b1010301b101030389010301b1028801b1028801b1028804b1010301230103020005030389010301b1028801b1028801b1028804b101030123010302230503038901030db10103012301030223020301b102030389010301b1028801b1028801b1028802b1018801b1010301230103020005030389010301b1028801b1028801b1028802b1018801b10303020009030db10303" + "data": "0x000a1d1402020009030db00303020005030389010301b0028801b0028801b0028802b0018901b003030200020301b002030389010301b0028801b0028801b0028802b0018901b0030302000503038901030db0010301230103020005030389010301b0028801b0028801b0028804b00103012301030200010301b0010301b001030389010301b0028801b0028801b0028804b0010301230103020005030389010301b0028801b0028801b0028804b001030123010302230503038901030db00103012301030223020301b002030389010301b0028801b0028801b0028802b0018801b0010301230103020005030389010301b0028801b0028801b0028802b0018801b00303020009030db00303" }, { "filename": "head-cottonball", - "data": "0x00021c16040a0001010d0009000301014b02010200010106000400010102000201014b0701070005000501014b0401014b030102000101020004000101014b0401014b0501014b0401030004000201014b0a01014b0201040003000301014b0601014b0301014b0301030003000101014b0201014b0601014b0401014b0101030001000201014b0301014b0601014b0701020002000501014b0d01014b020002000401014b0f01020002001101014b02010100010101001201014b03010100010101000301014b0d01014b0201020003000101014b0d01014b0201030003000401014b0201014b0201014b0301014b0301030004000301014b0301024b070101000101020003000301014b0301014b0201014b0401014b010104000500014b0d01050007000801014b0101070009000101014b0301014b0900" + "data": "0x00021c16040a00010216000302014b0202020001020a00010202000202014b07020c000502014b0402014b03020200010206000102014b0402014b0502014b040207000202014b0a02014b020207000302014b0602014b0302014b030206000102014b0202014b0602014b0402014b010204000202014b0302014b0602014b070204000502014b0d02014b04000402014b0f0204001102014b02020100010201001202014b03020100010201000302014b0d02014b020205000102014b0d02014b020206000402014b0202014b0202014b0302014b030207000302014b0302024b07020100010205000302014b0302014b0202014b0402014b01020900014b0d020c000802014b010210000102014b0302014b0900" }, { "filename": "head-cow", - "data": "0x00061914060300017f0323057f052302000300017f0323057f052302000100037f0323057f0523017f01000c7f0523027f137f047f02230d7f030003230b7f020003000323047f0323047f02000300077f0323047f02000300077f0323047f02000300027f0e5f03000123017f045f0208035f0208035f030002230e5f03000223035f0908025f030002230e5f" + "data": "0x00061914060300017f0323057f05230500017f0323057f05230300037f0323057f0523017f01000c7f0523197f02230d7f030003230b7f05000323047f0323047f0500077f0323047f0500077f0323047f0500027f0e5f03000123017f045f0208035f0208035f030002230e5f03000223035f0908025f030002230e5f" }, { "filename": "head-crab", - "data": "0x00021b1405040004130600041304000200071304000713020001000913020009130100031302b30c0002b303130a1302000a130913040009130213010005130600051301000213021307000123020001230700021302130100101301000213021301001013010002131613161316130300101303000300101303000300101303000300061304b306130300030010130300030010130300" + "data": "0x00021b14050400041306000413060007130400071303000913020009130100031302b20c0002b20d130200131304000b13010005130600051301000413070001230200012307000413010010130100041301001013010044130300101306001013060010130600061304b2061306001013060010130300" }, { "filename": "head-crane", - "data": "0x00061f1405060005b40f0004000ab40c0003000cb40b00020003b4050106230a00010002b406010823090001b40801092308000901072304b606000a01052308b60300060109230bb6050107230e00040108230e00010002010a230d00020002010323040105230a00030002010d230800040002010c230800" + "data": "0x00061f1405060005b313000ab30f000cb30d0003b3050206230b0002b306020823090001b30802092308000902072304b506000a02052308b50300060209230bb5050207230e00040208230f0002020a230f0002020323040205230d0002020d230c0002020c230800" }, { "filename": "head-croc-hat", - "data": "0x00061e150801000e23070001000e2307001023060001000e1d070001000e1d070001000e1d070001000e1d070001000e1d070001000e1d070001000e1d07000100151d0100151d0100031d0323021d0423021d0423031d0100051d0123021d0123021d0123021d0123021d0123031d0100051d0423021d0423021d0323011d0100151d" + "data": "0x00061e150801000e2308000e230700102307000e1d08000e1d08000e1d08000e1d08000e1d08000e1d08000e1d0800151d0100151d0100031d0323021d0423021d0423031d0100051d0123021d0123021d0123021d0123021d0123031d0100051d0423021d0423021d0323011d0100151d" }, { "filename": "head-crown", - "data": "0x00041a14060100015b0700025b0700015b01000100015b0700025b0700015b01000100025b0500045b0500025b0100028b012b015b0300015b041d015b0300015b012b0241018b0154012b025b0100025b011d029b010f025b0100025b012b011801410254012b055b021d020f055b012b02180100125b01000100125b01000100125b01000100125b01000100125b01000100125b01000100125b01000100125b010002000135052b0435052b013502000100125b01000100125b0100" + "data": "0x00041a14060100015b0700025b0700015b0200015b0700025b0700015b0200025b0500045b0500025b0100028b012b015b0300015b041d015b0300015b012b0241018b0154012b025b0100025b011d029b010f025b0100025b012b011801410254012b055b021d020f055b012b02180100125b0200125b0200125b0200125b0200125b0200125b0200125b0200125b03000135052b0435052b01350300125b0200125b0100" }, { "filename": "head-crt-bsod", - "data": "0x00051a15040400120204001202020004020166025a01660a5a02020602025a01660b5a020206020166025a01660a5a020206020e5a020206020e5a020206020e5a020206020e5a020202b104020e5a020206020e5a020202b104020e5a020206020e5a020202b104020e5a02020d02012301020123060202000a0201230102012301020123050204001202" + "data": "0x00051a15040400120104001201020004010166025a01660a5a0801025a01660b5a08010166025a01660a5a08010e5a08010e5a08010e5a08010e5a020102b004010e5a08010e5a020102b004010e5a08010e5a020102b004010e5a0f01012301010123060102000a0101230101012301010123050104001201" }, { "filename": "head-crystalball", - "data": "0x00021a14060700062d07000500022d06b7022d05000400012d0ab7012d04000300012d07b7012d04b7012d03000200012d03b7012d0ab7012d02000100012d03b7012d01b7012d05b7012d04b7012d01000100012d04b7012d05b7032d03b7012d0100012d0cb7012d05b7012d012d07b7012d0ab7012d012d12b7012d012d12b7012d012d12b7012d012d12b7012d0100012d10b7012d01000100012d10b7012d01000200012d0eb7012d0200020010b80200020005b8072304b80200020010b80200" + "data": "0x00021a14060700062d0c00022d06b6022d0900012d0ab6012d0700012d07b6012d04b6012d0500012d03b6012d0ab6012d0300012d03b6012d01b6012d05b6012d04b6012d0200012d04b6012d05b6032d03b6012d0100012d0cb6012d05b6022d07b6012d0ab6022d12b6022d12b6022d12b6022d12b6012d0100012d10b6012d0200012d10b6012d0300012d0eb6012d040010b7040005b7072304b7040010b70200" }, { "filename": "head-diamond-blue", - "data": "0x00051a18060500024a0104044a0104024a05000400034a0104044a0104034a04000300034a0104064a0104034a03000200044a0104064a0104044a02000100044a0101084a0104044a01000204010101040301010401010b04054a0101084a0104054a054a0104084a0104054a054a0104084a0104054a054a0104084a0104054a14040100054a0104064a0104054a01000200044a0104064a0104044a02000300044a0104044a0104044a03000400034a0104044a0104034a04000500024a0104044a0104024a05000600024a0104024a0104024a06000700014a0104024a0104014a070008000104024a010408000900024a0900" + "data": "0x00051a18060500024a0104044a0104024a0900034a0104044a0104034a0700034a0104064a0104034a0500044a0104064a0104044a0300044a0102084a0104044a01000204010201040302010401020b04054a0102084a01040a4a0104084a01040a4a0104084a01040a4a0104084a0104054a14040100054a0104064a0104054a0300044a0104064a0104044a0500044a0104044a0104044a0700034a0104044a0104034a0900024a0104044a0104024a0b00024a0104024a0104024a0d00014a0104024a0104014a0f000104024a01041100024a0900" }, { "filename": "head-diamond-red", - "data": "0x00051a1806050002b9014204b9014202b90500040003b9014204b9014203b90400030003b9014206b9014203b90300020004b9014206b9014204b90200010004b9010108b9014204b901000242010101420301014201010b4205b9010108b9014205b905b9014208b9014205b905b9014208b9014205b905b9014208b9014205b91442010005b9014206b9014205b90100020004b9014206b9014204b90200030004b9014204b9014204b90300040003b9014204b9014203b90400050002b9014204b9014202b90500060002b9014202b9014202b90600070001b9014202b9014201b907000800014202b901420800090002b90900" + "data": "0x00051a1806050002b8014204b8014202b8090003b8014204b8014203b8070003b8014206b8014203b8050004b8014206b8014204b8030004b8010208b8014204b801000242010201420302014201020b4205b8010208b801420ab8014208b801420ab8014208b801420ab8014208b8014205b81442010005b8014206b8014205b8030004b8014206b8014204b8050004b8014204b8014204b8070003b8014204b8014203b8090002b8014204b8014202b80b0002b8014202b8014202b80d0001b8014202b8014201b80f00014202b80142110002b80900" }, { "filename": "head-dictionary", - "data": "0x00051b150501000801040008010100014a01010372010103720101020001010372010103720101014a014a1401014a014a010103720101037204010372010103720101014a014a1401014a014a010103720101037204010372010103720101014a014a1401014a014a010103720d0102720101014a014a1401014a014a010103720d0102720101014a014a1401014a014a010103720d0102720101014a014a070106410701014a014a1401014a014a1401014a0a4a02010a4a0900044a0900" + "data": "0x00051b150501000802040008020100014a01020372010203720102020001020372010203720102024a1402024a010203720102037204020372010203720102024a1402024a010203720102037204020372010203720102024a1402024a010203720d0202720102024a1402024a010203720d0202720102024a1402024a010203720d0202720102024a070206410702024a1402024a14020b4a02020a4a0900044a0900" }, { "filename": "head-dino", - "data": "0x00071d15080300061d0c000300061d0c00151d151d151d151d151d151d151d151d151d0100051d0301011d0301011d0301011d03010100051d0301011d0301011d0301011d03010100141d0100141d" + "data": "0x00071d15080300061d0f00061d0c00bd1d0100051d0302011d0302011d0302011d03020100051d0302011d0302011d0302011d03020100141d0100141d" }, { "filename": "head-dna", - "data": "0x00091d160304431200045501000126010004430c00045501000151010001000126010001550100044308000355014301000126010001510100010001260100015501000143010001510243060002550143010001430100012601000151010001000126010001550100014301000151010002430400025501000143010001430100012601000151010001000126010001550100014301000151010003430200025501430100014301000143010001260100015101000100012601000155010001430100015101000143010002430255010001430100014301000143010001260100015101000100014301000151010001260100015501000143020002550200014301000143010001550100014301000155010001000143010001510100012601000155010001430100025502430100014301000143010001550100014301000155010001000143010001510100012601000155010001430255020003430100014301000155010001430100015501000100014301000151010001260100015501000255040002430100014301000155010001430100015501000100014301000151010001260100035506000343010001550100014301000155010001000143010005550a000543010001550100055510000543" + "data": "0x00091d160304431200045501000126010004430c000455010001510200012601000155010004430800035501430100012601000151020001260100015501000143010001510243060002550143010001430100012601000151020001260100015501000143010001510100024304000255010001430100014301000126010001510200012601000155010001430100015101000343020002550143010001430100014301000126010001510200012601000155010001430100015101000143010002430255010001430100014301000143010001260100015102000143010001510100012601000155010001430200025502000143010001430100015501000143010001550200014301000151010001260100015501000143010002550243010001430100014301000155010001430100015502000143010001510100012601000155010001430255020003430100014301000155010001430100015502000143010001510100012601000155010002550400024301000143010001550100014301000155020001430100015101000126010003550600034301000155010001430100015502000143010005550a000543010001550100055510000543" }, { "filename": "head-dog", - "data": "0x00061a140603000e970300010004850d970185010005850d97028504850e97028504850e97028504850e97028504850e97028504850e9702850485049706380497028504850497063804970285048503970838039702850485019708380223020d013802850200039708380423013802000200039704380223010103230101012301380200020003970d380200" + "data": "0x00061a140603000e97040004850d970185010005850d9706850e9706850e9706850e9706850e9706850e970685049706380497068504970638049706850397083803970685019708380223020d0138028502000397083804230138040003970438022301020323010201230138040003970d380200" }, { "filename": "head-doughnut", - "data": "0x00031a160607000156056c07000500026c0156046c01ba026c050003000a6c01ba036c03000200086c016d056c021902000200026c02ba016c0119036c016d066c02000100076c0119016c0138056c0156026c01000100076c0538026c0156036c0100046c016d026c013804000138066c011c016c021c016c016d016c013806000138026d036c011c066c013806000138066c066c013806000138066c026c0156036c013806000138036c02ba016c026c0156036c023804000138026c0156046c0100076c0538036c0156026c01000100046c01ba066c0219056c01000200026c01ba046c0156086c02000200076c0156040e016d036c02000300026c0119096c016d016c030005000119096c05000700016c021c036c0700" + "data": "0x00031a160607000156056c0c00026c0156046c01b9026c08000a6c01b9036c0500086c016d056c02190400026c02b9016c0119036c016d066c0300076c0119016c0138056c0156026c0200076c0538026c0156036c0100046c016d026c013804000138066c011c016c021c016c016d016c013806000138026d036c011c066c0138060001380c6c013806000138086c0156036c013806000138036c02b9036c0156036c023804000138026c0156046c0100076c0538036c0156026c0200046c01b9066c0219056c0300026c01b9046c0156086c0400076c0156040e016d036c0500026c0119096c016d016c08000119096c0c00016c021c036c0700" }, { "filename": "head-drill", - "data": "0x00071c140502000e1401a4060001000f1401a4017e050001000f1401a4017e017c017e017c017e017c101401a4027e017c017e017c017e101401a4017e050001000f1401a4060001000f1401a4060002000e1401a406000500057e01a40c000500057e02a40b000500057e03a40a000500077e0b0004000114012301260123012601230814050004000e140500" + "data": "0x00071c140502000e1401a307000f1401a3017e06000f1401a3017e017c017e017c017e017c101401a3027e017c017e017c017e101401a3017e06000f1401a307000f1401a308000e1401a30b00057e01a31100057e02a31000057e03a30f00077e0f00011401230126012301260123081409000e140500" }, { "filename": "head-duck", - "data": "0x00041d1407070006010900050005010c001001060011010500110105001101050011010500110105001101050011010500110105001101050011010500050110460100050104460142014601420a4605011146010005011046" + "data": "0x00041d1407070006020e0005020c001002060011020500110205001102050011020500110205001102050011020500110205001102050011020500050210460100050204460142014601420a4605021146010005021046" }, { "filename": "head-ducky", - "data": "0x00031c14040c00082604000a000526045102260300090005260251022302510126030009000526025102230251012601140200090006260451022603140100022607000a26031401000100052605000a260300162602001726010018261826182601001726010017260200162602000b26018a0926010003000726038a09260200050010260300" + "data": "0x00031c14040c0008260e000526045102260c00052602510223025101260c000526025102230251012601140b0006260451022603140100022607000a2603140200052605000a2603001626020017260100482601001726010017260200162602000b26018a092604000726038a0926070010260300" }, { "filename": "head-earth", - "data": "0x00031a160607000643070005000a43050003000343011c0543011c0243021c030002000243031c0543061c020002000243021c0543071c02000100011c0243031c0343091c01000100021c0243011c0443091c0100031c0843091c031c0d43041c041c0743091c051c0543091c0143061c0443081c0243061c0443071c03430100031c0643071c024301000100021c0843041c044301000200011c0943041c024302000200011c0443081c0343020003000e43030005000a430500070006430700" + "data": "0x00031a1606070006430c000a4308000343011c0543011c0243021c05000243031c0543061c04000243021c0543071c0300011c0243031c0343091c0200021c0243011c0443091c0100031c08430c1c0d43081c07430e1c0543091c0143061c0443081c0243061c0443071c03430100031c0643071c02430200021c0843041c04430300011c0943041c02430400011c0443081c034305000e4308000a430c0006430700" }, { "filename": "head-egg", - "data": "0x00011915070700040107000500020102af040105000400010101af010102af020102af0101040003000c0103000200010101af020101af020101af060102000200010101af060102af020101af010102000100010101af020101af040102af030101af010101000100010101af0c0101af010101000100010101af0b0101af02010100100101af0101050101af0a0101af0101020101af0a0101af020101af0101020101af0a0101af020101af0101120112010e0102af02010100100101000100030101af080101af0301010002000501021e0701020003000c0103000500050101af02010500" + "data": "0x0001191507070004020c00020202ae04020900010201ae010202ae020202ae010207000c020500010201ae020201ae020201ae06020400010201ae060202ae020201ae01020300010201ae020201ae040202ae030201ae01020200010201ae0c0201ae01020200010201ae0b0201ae02020100100201ae060201ae0a0201ae030201ae0a0201ae020201ae030201ae0a0201ae020201ae330202ae0202010010020200030201ae080201ae030203000502021e070205000c020800050201ae02020500" }, { "filename": "head-faberge", - "data": "0x000119140608000326080005000126020701260107012602070126050005000207012603070126020705000400010f0407010f0407010f040003000d07030003000107012604070126040701260107030002000107012601890126020701260189012602070126018901260107020002000207012604070126040701260207020001001107010001001126010013260100118a010001001107010001001107010002000f07020002000f07020002000f07020003000d070300030006260323032604000500098a0500" + "data": "0x0001191406080003260d0001260207012601070126020701260a00020701260307012602070900010f0407010f0407010f07000d070600010701260407012604070126010705000107012601890126020701260189012602070126018901260107040002070126040701260407012602070300110702001126010013260100118a020011070200110703000f0704000f0704000f0705000d0706000626032303260900098a0500" }, { "filename": "head-factory-dark", - "data": "0x00031a14080300057c0a000100010e0300087c05000100020e0b00047c010002240f000100020e0400010e0300010e0300010e02000100020e0300020e0200020e0200020e0200040e0100030e0100030e0100030e0200100e0200100e0200100e0200100e0200100e0200100e0200100e0200100e0200020e0172010e026d010e026d010e0172050e0200100e0200100e0200" + "data": "0x00031a14080300057c0b00010e0300087c0600020e0b00047c010002241000020e0400010e0300010e0300010e0300020e0300020e0200020e0200020e0200040e0100030e0100030e0100030e0200100e0200100e0200100e0200100e0200100e0200100e0200100e0200100e0200020e0172010e026d010e026d010e0172050e0200100e0200100e0200" }, { "filename": "head-fan", - "data": "0x00031a160607000651070005000351010001510200035105000300035102000151020001510200035103000200035102000151027e0151027e01510200025102000200025102000151027e0151027e0151027e015101000151020001000251020001510100017e0151027e0151027e0151017e010002510100010001510200015102000151027e0151027e0151017e01000151010001510100025101000151020001510100017e0262017e0151017e0100015102000251015101000151027e0151020004620200015102000151010001510251027e0151027e06620151027e01510200015101510100017e0151027e01510662027e0151017e01000251015101000151027e0151027e0462027e0151027e01510100015102510100017e0151027e0151017e0262027e0151027e0151017e02510100015101000151027e0151027e01510100017e0151027e0151027e01510100010002510100017e0151027e01510100017e0151027e0151027e025101000200015101000151027e015102000151027e0151017e010002510200020002510200015102000151027e01510200035102000300035102000151020001510200035103000500035102000151010003510500070006510700" + "data": "0x00031a1606070006510c0003510100015102000351080003510200015102000151020003510500035102000151027e0151027e0151020002510400025102000151027e0151027e0151027e01510100015103000251020001510100017e0151027e0151027e0151017e01000251020001510200015102000151027e0151027e0151017e01000151010001510100025101000151020001510100017e0262017e0151017e010001510200035101000151027e015102000462020001510200015101000351027e0151027e06620151027e0151020002510100017e0151027e01510662027e0151017e0100035101000151027e0151027e0462027e0151027e0151010003510100017e0151027e0151017e0262027e0151027e0151017e02510100015101000151027e0151027e01510100017e0151027e0151027e0151020002510100017e0151027e01510100017e0151027e0151027e02510300015101000151027e015102000151027e0151017e01000251040002510200015102000151027e015102000351050003510200015102000151020003510800035102000151010003510c0006510700" }, { "filename": "head-fence", - "data": "0x00041d1403020001bb060001bb060001bb060001340200010003bb0400013402bb040003bb040001bb013401bb010005bb020001bb013403bb020005bb020002bb013402bb05bb020001bb013403bb020003bb013401bb020002bb013402bb03bb013401bb020001bb013403bb020003bb013401bb020005bb03bb013401bb023401bb013403bb023403bb013401bb023402bb013402bb03bb013401bb023401bb013403bb023405bb023405bb03bb013401bb023401bb013403bb023405bb023405bb03bb013401bb020005bb020005bb020005bb013404bb020005bb020001bb013403bb020003bb013401bb013404bb020005bb020001bb013403bb020003bb013401bb013402bb013401bb023405bb023401bb013403bb023403bb013401bb013404bb023405bb023401bb013403bb023401bb013401bb013401bb013404bb023405bb023401bb013403bb023403bb013401bb013404bb020005bb02000585020003bb013401bb05bb020003bb013401bb02000585020003bb013401bb05bb020003bb013401bb020001bb013403bb020005bb" + "data": "0x00041d1403020001ba060001ba060001ba06000134030003ba0400013402ba040003ba040001ba013401ba010005ba020001ba013403ba020005ba020002ba013407ba020001ba013403ba020003ba013401ba020002ba013405ba013401ba020001ba013403ba020003ba013401ba020008ba013401ba023401ba013403ba023403ba013401ba023402ba013405ba013401ba023401ba013403ba023405ba023408ba013401ba023401ba013403ba023405ba023408ba013401ba020005ba020005ba020005ba013404ba020005ba020001ba013403ba020003ba013401ba013404ba020005ba020001ba013403ba020003ba013401ba013402ba013401ba023405ba023401ba013403ba023403ba013401ba013404ba023405ba023401ba013403ba023401ba013401ba013401ba013404ba023405ba023401ba013403ba023403ba013401ba013404ba020005ba02000585020003ba013406ba020003ba013401ba02000585020003ba013406ba020003ba013401ba020001ba013403ba020005ba" }, { "filename": "head-film-35mm", - "data": "0x00031814050800062305000800062305000300102303420726078702260100014201000726078702260342072607870226034207260787022603420726078702260342072607870226034207260787022603420726078702260342072607870226034207260787022603420726078702260342072607870226010001420100022603ae022607870226034207260787022603001023" + "data": "0x0003181405080006230d0006230800102303420726078702260100014201000726078702260342072607870226034207260787022603420726078702260342072607870226034207260787022603420726078702260342072607870226034207260787022603420726078702260342072607870226010001420100022603ad022607870226034207260787022603001023" }, { "filename": "head-film-strip", - "data": "0x00051b140516bc010002bc010002bc010002bc010002bc010002bc010002bc010002bc010016bc02bd01bc10bd01bc02bd02bd01bc10bd01bc02bd02bd01bc10bd01bc02bd02bd01bc10bd01bc02bd01bd017b01bc10bd01bc02bd02bd01bc10bd01bc02bd02bd01bc10bd01bc02bd02bd01bc10bd01bc02bd02bd01bc10bd01bc02bd02bd01bc10bd01bc02bd16bc010002bc010002bc010002bc010002bc010002bc010002bc010002bc010016bc" + "data": "0x00051b140516bb010002bb010002bb010002bb010002bb010002bb010002bb010002bb010016bb02bc01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb03bc017b01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb02bc16bb010002bb010002bb010002bb010002bb010002bb010002bb010002bb010016bb" }, { "filename": "head-fir", - "data": "0x00011f18010e00020f0e000d00040f0d000c00060f0c000b00030f015c040f0b000a00030f015c060f0a000900030f015c040f015c030f090008000a0f015c030f080007000c0f015c030f07000600120f06000500140f05000400160f04000300180f030002001a0f020001001c0f01001e0f0600120f06000500140f05000400160f04000300060f065c0c0f030002001a0f02001e000700010f0e00010f07000600020f0e00020f06000500030f0e00030f0500" + "data": "0x00011f18010e00020f1b00040f1900060f1700030f015c040f1500030f015c060f1300030f015c040f015c030f11000a0f015c030f0f000c0f015c030f0d00120f0b00140f0900160f0700180f05001a0f03001c0f01001e0f0600120f0b00140f0900160f0700060f065c0c0f05001a0f2700010f0e00010f0d00020f0e00020f0b00030f0e00030f0500" }, { "filename": "head-firehydrant", - "data": "0x00021c14040b0002be0b00090006be0900080002bf01be02bf01be02bf0800070003bf01be02bf01be03bf0700060003bf01be04bf01be03bf0600060003bf01be04bf01be03bf0600050003bf01be06bf01be03bf0500050003bf01be06bf01be03bf0500030012be0300030012be030005000ebf050005000ebf0500010002bf012310be012302bf0100010002bf012310be012302bf010001be02bf012310be012302bf01be01be02bf012310be012302bf01be010002bf012303be0b2302be012302bf0100010002bf012310be012302bf010005000ebf0500" + "data": "0x00021c14040b0002bd140006bd110002be01bd02be01bd02be0f0003be01bd02be01bd03be0d0003be01bd04be01bd03be0c0003be01bd04be01bd03be0b0003be01bd06be01bd03be0a0003be01bd06be01bd03be080012bd060012bd08000ebe0a000ebe060002be012310bd012302be020002be012310bd012302be010001bd02be012310bd012302be02bd02be012310bd012302be01bd010002be012303bd0b2302bd012302be020002be012310bd012302be06000ebe0500" }, { "filename": "head-flamingo", - "data": "0x00031b14050c00042003ba03000a00062001ba012301ba012002000900072003ba022001000800042005000320025f070004200800035f070004200800025f010e070005200800020e080006200600020e090008200300010e01000a00092003000b00092002000d00082001000f00062001000100156a166a0b20060905201620010014200100" + "data": "0x00031b14050c00042003b90d00062001b9012301b901200b00072003b902200900042005000320025f070004200800035f070004200800025f010e070005200800020e080006200600020e090008200300010e0b0009200e0009200f0008201000062002002b6a0b2006091b20010014200100" }, { "filename": "head-flower", - "data": "0x00031b18050a00024f0a000900044f0900040002ba0200019a044f019a020002ba0400030005ba019a044f019a05ba0300020007ba019a024f019a07ba0200020007ba041307ba0200030004ba0213046d021304ba0300030003ba0113086d011303ba03000200029a02ba0113086d011302ba029a02000100034f019a01130a6d0113019a034f0100054f01130a6d0113054f054f01130a6d0113054f0100034f019a01130a6d0113019a034f01000200029a02ba0113086d011302ba029a0200030003ba0113086d011303ba0300030004ba0213016d0385021304ba0300020007ba041307ba0200020007ba019a024f019a07ba0200030005ba019a044f019a05ba0300040002ba0200019a044f019a020002ba04000900044f09000a00024f0a00" + "data": "0x00031b18050a00024f1300044f0d0002b90200019a044f019a020002b9070005b9019a044f019a05b9050007b9019a024f019a07b9040007b9041307b9050004b90213046d021304b9060003b90113086d011303b90500029a02b90113086d011302b9029a0300034f019a01130a6d0113019a034f0100054f01130a6d01130a4f01130a6d0113054f0100034f019a01130a6d0113019a034f0300029a02b90113086d011302b9029a050003b90113086d011303b9060004b90213016d0385021304b9050007b9041307b9040007b9019a024f019a07b9050005b9019a044f019a05b9070002b90200019a044f019a020002b90d00044f1300024f0a00" }, { "filename": "head-fox", - "data": "0x00031c1904050003011000040005010f000300014205010800022301000223020002000242050108000242010002420200010004420301090006420100074204000223064201110142011102420542070006010642044209000b01054209000a010100054209000901020004420a00080104000f4205010400104204010400114203010400124202010400054207010742010104000542062302010642010004000542090104420200040001420e0002420300010004420e00014204000100014211000242030001000123120002420223010001231600" + "data": "0x00031c190405000302140005021200014205020800022301000223040002420502080002420100024203000442030209000642010007420400022306420111014201110742070006020a4209000b02054209000a020100054209000902020004420a00080204000f42050204001042040204001142030204001242020204000542070207420102040005420623020206420500054209020442060001420e000242040004420e000142050001421100024204000123120002420223010001231600" }, { "filename": "head-frog", - "data": "0x00061914070300051c0300041c03000200071c0100061c02000100041c020f0a1c01000100041c020f0a1c010001000d1c020f011c010001000d1c020f011c01000100101c01000100101c01000100020f0e1c0100011c020f0f1c121c121c126702670e5c0267010010670100" + "data": "0x00061914070300051c0300041c0500071c0100061c0300041c020f0a1c0200041c020f0a1c02000d1c020f011c02000d1c020f011c0200101c0200101c0200020f0e1c0100011c020f331c14670e5c0267010010670100" }, { "filename": "head-garlic", - "data": "0x00051914070700010b0100010b0100010b06000800030b07000800030b070007000157030b0157060003000157030b0157030b0157030b03000200010b0157030b0157030b0157030b015702000100020b0157030b0157030b0157030b0157010b0100030b0157030b0157030b0157030b0157020b030b0157030b0157030b0157030b0157020b030b0157030b0157030b0157030b0157020b030b0157030b0157030b0157030b0157020b030b0157030b0157030b0157030b0157020b030b0157010b01c0010b0157030b0157030b0157020b030b0157020b04c0010b0157030b0157020b0100020b0157030b0157030b0157030b0157010b01000200010b0157030b0157030b0157030b01570200" + "data": "0x00051914070700010b0100010b0100010b0e00030b0f00030b0e000157030b015709000157030b0157030b0157030b0500010b0157030b0157030b0157030b01570300020b0157030b0157030b0157030b0157010b0100030b0157030b0157030b0157030b0157050b0157030b0157030b0157030b0157050b0157030b0157030b0157030b0157050b0157030b0157030b0157030b0157050b0157030b0157030b0157030b0157050b0157010b01bf010b0157030b0157030b0157050b0157020b04bf010b0157030b0157020b0100020b0157030b0157030b0157030b0157010b0300010b0157030b0157030b0157030b01570200" }, { "filename": "head-gavel", - "data": "0x000419140108000f34010008000f34010009000d23020009000d26020009000126015d0b26020009000126015d0b260200013401000234010004340d26020002000134020004340d26020001000234010005340d26020009000d26020009000d26020009000d26020008000f34010008000f2301000700118e0700118e07001123" + "data": "0x000419140108000f3409000f340a000d230b000d260b000126015d0b260b000126015d0b260200013401000234010004340d2604000134020004340d2603000234010005340d260b000d260b000d260b000d260a000f3409000f230800118e0700118e07001123" }, { "filename": "head-ghost-B", - "data": "0x00051b16030c00028c0a000b00048c09000200028c0700058c0600028c0200048c0400028c0104018c0104018c0400048c0200068c0200068c0200068c0300148c01000300148c01000300148c01000300148c01000400128c02000400128c02000400118c03000400118c030005000f8c040003000f8c0600118c07000400028c12000200048c1200" + "data": "0x00051b16030c00028c1500048c0b00028c0700058c0600028c0200048c0400028c0104018c0104018c0400048c0200068c0200068c0200068c0300148c0400148c0400148c0400148c0500128c0600128c0600118c0700118c08000f8c07000f8c0600118c0b00028c1400048c1200" }, { "filename": "head-glasses-big", - "data": "0x00091c120204000a8002000a80040001800501048002000180050104800400018005010480020001800501048005800501078005010480058005010780050104800180030001800501048002000180050104800180030001800501048002000180050104800180030001800501048002000180050104800400018005010480020001800501048004000a8002000a80" + "data": "0x00091c120204000a8002000a800400018005020480020001800502048004000180050204800200018005020980050207800502098005020780050205800300018005020480020001800502058003000180050204800200018005020580030001800502048002000180050204800400018005020480020001800502048004000a8002000a80" }, { "filename": "head-gnome", - "data": "0x00011a140609000241090009000241090008000441080007000641070007000641070006000841060006000841060005000a41050003000ec1030001c2010001c10ec201c1010001c202c201c10ec201c102c202c201c10ec201c102c202c201c10ec201c102c20200104c02000200104c02000200104c02000200104c0200020003c20123010101230101012301010123010101230101012302c20200020003c20b4102c202000300088a018e078a0100" + "data": "0x00011a14060900024112000241110004410f0006410e0006410d0008410c0008410b000a4108000ec0030001c1010001c00ec101c0010003c101c00ec101c004c101c00ec101c004c101c00ec101c002c10200104c0400104c0400104c0400104c040003c10123010201230102012301020123010201230102012302c1040003c10b4102c10500088a018e078a0100" }, { "filename": "head-goat", - "data": "0x00051d1805030001b10c00040d0400020002b10e0004b10200010002b10e0002b1017e022301b10100010002b10e0002b1017e04b101000fb1017e02b1017e02b1029802000eb1017e02b1017e01b1017e02b103000eb1027e02b1010002b1030010b1030001b10100030010b10500030010b10500030011b10400030011b10400020005b1017e0cb10400020005b1017e01230101012301010123010107b10300020004b1017e0ab1010003b10300020003b101000ab1040001b10300010002b1110001b1030003b1100002b1030001b1120001b1040001b1120001b10400" + "data": "0x00051d1805030001b00c00040d060002b00e0004b0030002b00e0002b0017e022301b0020002b00e0002b0017e04b001000fb0017e02b0017e02b0029802000eb0017e02b0017e01b0017e02b003000eb0027e02b0010002b0030010b0030001b0040010b0080010b0080011b0070011b0060005b0017e0cb0060005b0017e01230102012301020123010207b0050004b0017e0ab0010003b0050003b001000ab0040001b0040002b0110001b0030003b0100002b0030001b0120001b0040001b0120001b00400" }, { "filename": "head-goldcoin", - "data": "0x00031a160607000626070005000326042b0326050003000326022b0426022b0326030002000226022b0826022b0226020002000126012b0c26012b0126020001000226012b0c26012b0226010001000126012b092603290226012b012601000226012b032603290826012b02260126012b1026012b01260126012b1026012b01260126012b1026012b01260126012b1026012b01260226012b112601000126012b1026010001000226012b0f26010002000126012b02260129012604290426012b0126020002000226022b0826022b0226020003000326022b0426022b0326030005000326042b03260500070006260700" + "data": "0x00031a1606070006260c000326042b032608000326022b0426022b032605000226022b0826022b022604000126012b0c26012b012603000226012b0c26012b022602000126012b092603290226012b012601000226012b032603290826012b0326012b1026012b0226012b1026012b0226012b1026012b0226012b1026012b0326012b112601000126012b102602000226012b0f2603000126012b02260129012604290426012b012604000226022b0826022b022605000326022b0426022b032608000326042b03260c0006260700" }, { "filename": "head-goldfish", - "data": "0x00051b1405020012210200030010950300010014210100162113210151022101211207015101070121012114070121012112070151010701210121140701210121140701210121140701210221080703250707022101000121070701140125012302250607012101000100022107070325060702210100020003210c070321020004000e210400" + "data": "0x00051b1405020012210500109504001421010029210151032112070151010702211407022112070151010702211407022114070221140703210807032507070221010001210707011401250123022506070121020002210707032506070221030003210c07032106000e210400" }, { "filename": "head-grouper", - "data": "0x00061d16020900010801000108010001080100010801000108090007000c08080006000f08060001000208020004080e7a040004080200137a020001000408157a01000508157a010001000408117a0108047a02000308107a02c5047a010004080e7a02c5047a0282020003080d7a01c5047a02820200010004080c7a01c5047a018204000508057a0208047a010801c5037a018205c501000408047a0108057a020801c5027a018201c5047a010004080200077a040801c5077a0200010002080600027a0508027a01c5047a04000c0003080c00" + "data": "0x00061d1602090001080100010801000108010001080100010810000c080e000f0807000208020004080e7a040004080200137a03000408157a01000508157a02000408117a0108047a02000308107a02c4047a010004080e7a02c4047a0282020003080d7a01c4047a0282030004080c7a01c4047a018204000508057a0208047a010801c4037a018205c401000408047a0108057a020801c4027a018201c4047a010004080200077a040801c4077a030002080600027a0508027a01c4047a100003080c00" }, { "filename": "head-hair", - "data": "0x00031e15020800068e0100058e08000700018e0626018e0526018e07000600018e0126068e0126058e0126018e06000300018e0100018e0126018e0626018e0526018e0126018e0100018e03000400018e0126018e0126068e0126058e0126018e0126018e04000400018e0126018e0126018e0500018e0400018e0126018e0126018e04000400018e0126018e0126018e0a00018e0126018e0126018e04000400018e0126018e0126018e0a00018e0126018e0126018e04000200018e0100018e0126018e0126018e0a00018e0126018e0126018e0100018e02000300018e0126018e0126018e0c00018e0126018e0126018e03000300018e0126018e0126018e0c00018e0126018e0126018e03000300018e0126018e0126018e0c00018e0126018e0126018e03000300018e0126018e0126018e0c00018e0126018e0126018e03000100018e0100018e0126018e0126018e0c00018e0126018e0126018e0100018e01000200018e0126018e0126018e0e00018e0126018e0126018e02000200018e0126018e0126018e0e00018e0126018e0126018e02000200018e0126018e0126018e0e00018e0126018e0126018e02000200018e0126018e0126018e0e00018e0126018e0126018e0200028e0100018e0100018e1000018e0100018e0100028e" + "data": "0x00031e15020800068e0100058e0f00018e0626018e0526018e0d00018e0126068e0126058e0126018e0900018e0100018e0126018e0626018e0526018e0126018e0100018e0700018e0126018e0126068e0126058e0126018e0126018e0800018e0126018e0126018e0500018e0400018e0126018e0126018e0800018e0126018e0126018e0a00018e0126018e0126018e0800018e0126018e0126018e0a00018e0126018e0126018e0600018e0100018e0126018e0126018e0a00018e0126018e0126018e0100018e0500018e0126018e0126018e0c00018e0126018e0126018e0600018e0126018e0126018e0c00018e0126018e0126018e0600018e0126018e0126018e0c00018e0126018e0126018e0600018e0126018e0126018e0c00018e0126018e0126018e0400018e0100018e0126018e0126018e0c00018e0126018e0126018e0100018e0300018e0126018e0126018e0e00018e0126018e0126018e0400018e0126018e0126018e0e00018e0126018e0126018e0400018e0126018e0126018e0e00018e0126018e0126018e0400018e0126018e0126018e0e00018e0126018e0126018e0200028e0100018e0100018e1000018e0100018e0100028e" }, { "filename": "head-hardhat", - "data": "0x00041d1405050005c605c70900040006c701c605c70800030006c602c701c605c70700020007c701c602c701c605c70600020008c701c601c701c605c70600010009c701c602c705c601c70500010009c701c608c70500010009c701c608c70500010009c701c608c70500010009c701c608c70500010009c701c608c70500010009c701c608c70500010009c701c608c70500010003c70fc6050004c701c60d2301c605c704c701c60dc701c605c718c7" + "data": "0x00041d1405050005c505c60d0006c601c505c60b0006c502c601c505c6090007c601c502c601c505c6080008c601c501c601c505c6070009c601c502c605c501c6060009c601c508c6060009c601c508c6060009c601c508c6060009c601c508c6060009c601c508c6060009c601c508c6060009c601c508c6060003c60fc5050004c601c50d2301c509c601c50dc601c51dc6" }, { "filename": "head-heart", - "data": "0x00041c1704050005240400052405000300092401000824030002000624020106240201042402000100092401010524020101240101032401000100132401010224010014240101032418241824182401001624010001001624010002001424020002001424020003001224030004000724020101230624040005000e24050006000c24060007000a2407000900062409000b0002240b00" + "data": "0x00041c1704050005240400052408000924010008240500062402020624020204240300092401020524020201240102032402001324010202240100142401024b2401001624020016240300142404001424050012240700072402020123062409000e240b000c240d000a2410000624140002240b00" }, { "filename": "head-helicopter", - "data": "0x00031d14020d0002230c000400016104620261062302610462016103000d0002230c000d0002230c000a000720075603000100022006000220019a0120019a0120019a0120085602000100032004000320019a0120019a0120019a012009560100010002620e200556030102560162022301620d200556030102560162022301620d200556030102560100026202000c200a5606000b2008560101015607000a2008560101015608000920065602010156010009000820085602000a000e2003000c000123020001230b0007000e230600" + "data": "0x00031d14020d0002231000016104620261062302610462016110000223190002231600072007560400022006000220019a0120019a0120019a012008560300032004000320019a0120019a0120019a01200956020002620e200556030202560162022301620d200556030202560162022301620d200556030202560100026202000c200a5606000b2008560102015607000a20085601020156080009200656020201560a00082008560c000e200f0001230200012312000e230600" }, { "filename": "head-highheel", - "data": "0x00061b1405020003181100010005181000010006180f0008180e0008180e0008180e0008180e0009180d000b180b0001000c18090002000418020008180600030002180400091804000300021805000a1802000300021806000318042304180300025b07000a5b" + "data": "0x00061b14050200031812000518110006180f0008180e0008180e0008180e0008180e0009180d000b180c000c180b0004180200081809000218040009180700021805000a180500021806000318042304180300025b07000a5b" }, { "filename": "head-hockeypuck", - "data": "0x00051b150507000805070004000305081f03050400020002050e1f0205020001000105121f010501000105141f01050105141f01050105141f0105010d0105121f0105011f020d02050e1f0205010c011f040d0305081f0305020c021f070d0805060c011f040d030c020d010c010d090c021f070d0e0c011f0100030d030c020d0b0c011f01000200050d030c0105010d0205010d050c02000400030c020d090c04000700080c0700" + "data": "0x00051b1505070008050b000305081f0305060002050e1f020503000105121f010501000105141f0205141f0205141f0105010d0105121f0105011f020d02050e1f0205010c011f040d0305081f0305020c021f070d0805060c011f040d030c020d010c010d090c021f070d0e0c011f0100030d030c020d0b0c011f0300050d030c0105010d0205010d050c0600030c020d090c0b00080c0700" }, { "filename": "head-horse-deepfried", - "data": "0x00061b15050900018e0100028e0900040003ad0100068e010003ad04000200028e03ad068e020003ad04000200028e07ad018e06ad04000100038e06ad036d05ad04000200028e07ad016d06ad04000200028e07ad016d06ad04000100038e07ad016d06ad04000200028e07ad016d06ad04000200028e07ad016d06ad04000100038e128a0200028e0e8a0123018a0123018a0100038e028a016d0123016d0123016d0123016d098a048e128a0100038e128a0100018e0100018e0e8a0400" + "data": "0x00061b15050900018e0100028e0d0003ac0100068e010003ac0600028e03ac068e020003ac0600028e07ac018e06ac0500038e06ac036d05ac0600028e07ac016d06ac0600028e07ac016d06ac0500038e07ac016d06ac0600028e07ac016d06ac0600028e07ac016d06ac0500038e128a0200028e0e8a0123018a0123018a0100038e028a016d0123016d0123016d0123016d098a048e128a0100038e128a0100018e0100018e0e8a0400" }, { "filename": "head-hotdog", - "data": "0x000317140905000489050002000183013906890139018302000100028301390689013902830100028301390289016d0219038901390283028301390389026d0119028901390283028301390589016d0119018901390283028301390389026d0119028901390283028301390289016d0219038901390283028301390389026d0119028901390283028301390589016d0119018901390283028301390389026d0119028901390283028301390289016d0219038901390283028301390389026d0119028901390283028301390589016d0119018901390283028301390389026d0119028901390283028301390289016d0219038901390283028301390389026d0119028901390283028301390589016d0119018901390283" + "data": "0x0003171409050004890700018301390689013901830300028301390689013902830100028301390289016d021903890139048301390389026d011902890139048301390589016d011901890139048301390389026d011902890139048301390289016d021903890139048301390389026d011902890139048301390589016d011901890139048301390389026d011902890139048301390289016d021903890139048301390389026d011902890139048301390589016d011901890139048301390389026d011902890139048301390289016d021903890139048301390389026d011902890139048301390589016d0119018901390283" }, { "filename": "head-house", - "data": "0x00031c1505080001830e000100027c04000183015101830d000100021103000183035101830c00010002110200018302510183025101830b0001000211010001830251018301c8018302510183071103000100021101830351038303510183071102000100011101830b51018307110100010001830d510183071101830f51078317510351051103510b8301510351051103510183031103c80311018301510351051103510183021105c80211018301510351051103510183011107c801110183015103510311012601110351018306c8017c02c801830151035105110351018305c8027c02c80183015103510111032301110351018304c8037c02c8018301510351051103510b8301510251077c0e51" + "data": "0x00031c1505080001830f00027c04000183015101830e00021103000183035101830d0002110200018302510183025101830c000211010001830251018301c70183025101830711040002110183035103830351018307110300011101830b5101830711020001830d510183071101830f5107831a51051103510b830451051103510183031103c7031101830451051103510183021105c7021101830451051103510183011107c70111018304510311012601110351018306c7017c02c70183045105110351018305c7027c02c7018304510111032301110351018304c7037c02c701830451051103510b830351077c0e51" }, { "filename": "head-icepop-b", - "data": "0x00071c19020500061c0893051902000400021c059b08010316031901000400011c019b051c08930319020102190400011c019b051c08930319020102190400071c089305190116011904c9071c089305190116011904c9071c0893071904c9071c089305190116011904c9071c0893071904c9071c089307190400071c089307190400011c029b041c089307190400011c029b041c01930201019301010393061901000500061c0893051902000800021c0c00021902000800011c0d00011903001600011903001a00160001190300" + "data": "0x00071c19020500061c089305190600021c059b0802031603190500011c019b051c08930319020202190400011c019b051c08930319020202190400071c089305190116011904c8071c089305190116011904c8071c0893071904c8071c089305190116011904c8071c0893071904c8071c089307190400071c089307190400011c029b041c089307190400011c029b041c0193020201930102039306190600061c089305190a00021c0c0002190a00011c0d00011919000119330001190300" }, { "filename": "head-igloo", - "data": "0x00051e1405080006010b0005000401013c0201023c0301080004000101033c0301013c0301023c0101070003000101013c0601013c0501013c0101060002000101033c0101043c0101013c0101053c0101050002000601013c0601013c0401050001000101013c1001013c0101040001000501053c0101063c030104000100140104001201013c0101013c020102000101023c0901063c0101013c040101000301013c0401013c0501013c0201013c0101013c0201013c010101000301013c0401013c0501013c0301013c0201023a013c01010101023c0101053c0101033c0201043c0201023a013c01010101013c0301013c0501013c0401013c0101013c0201033c010101000401013c0501013c0401013c0101013c05010100" + "data": "0x00051e14050800060210000402013c0202023c03020c000102033c0302013c0302023c01020a000102013c0602013c0502013c010208000102033c0102043c0102013c0102053c010207000602013c0602013c040206000102013c1002013c010205000502053c0102063c03020500140204001202013c0102013c020202000102023c0902063c0102013c040201000302013c0402013c0502013c0202013c0102013c0202013c010201000302013c0402013c0502013c0302013c0202023a013c0202023c0102053c0102033c0202043c0202023a013c0202013c0302013c0502013c0402013c0102013c0202033c010201000402013c0502013c0402013c0102013c05020100" }, { "filename": "head-island", - "data": "0x00021b14060400040f0d000300060f0100061c05000700020f091c03000500080f031c01ca031c01000400040f01ca030f031c01ca0200031c0400020f020002ca0100010f021c02ca0300021c0400010f040002ca0100021c01ca0400021c090002ca0200011c01ca0500011c0400060f01ca020002ca06000300080f01ca010002ca06000300080f01ca010002ca06000300080f01ca010002ca06000300080f01ca010002ca060003000e26040002001026030001000d2601460426020002260146012602290226022902260146032601460326010006260229062601460526010014260100" + "data": "0x00021b14060400040f1000060f0100061c0c00020f091c0800080f031c01c9031c0500040f01c9030f031c01c90200031c0400020f020002c90100010f021c02c90300021c0400010f040002c90100021c01c90400021c090002c90200011c01c90500011c0400060f01c9020002c90900080f01c9010002c90900080f01c9010002c90900080f01c9010002c90900080f01c9010002c909000e260600102604000d2601460426020002260146012602290226022902260146032601460326010006260229062601460526010014260100" }, { "filename": "head-jellyfish", - "data": "0x00031c1b050700055f016a035f07000400016a0e5f04000200065f016a0c5f02000200135f02000100085f0576055f016a025f01000100015f016a045f0976065f0100055f0d76055f015f016a025f0f76025f016a015f045f0f76045f035f1176035f035f1176035f0100015f1376015f01000100015f1376015f01000100015f1376015f01000100015f036e0176036e0176036e0176036e0176036e015f01000100156e01000100016a086e0690066e01000100016a0200016a0e6e016a0100016a01000100016a0200016a0e00016a0100016a01000100016a0200016a0e00016a0100016a0100016a0200016a0f00016a0200016a016a0200016a1000016a0100016a016a1300016a0100016a016a1500016a016a1500016a" + "data": "0x00031c1b050700055f016a035f0b00016a0e5f0600065f016a0c5f0400135f0300085f0576055f016a025f0200015f016a045f0976065f0100055f0d76065f016a025f0f76025f016a055f0f76075f1176065f1176035f0100015f1376015f0200015f1376015f0200015f1376015f0200015f036e0176036e0176036e0176036e0176036e015f0200156e0200016a086e0690066e0200016a0200016a0e6e016a0100016a0200016a0200016a0e00016a0100016a0200016a0200016a0e00016a0100016a0100016a0200016a0f00016a0200026a0200016a1000016a0100026a1300016a0100026a1500026a1500016a" }, { "filename": "head-jupiter", - "data": "0x00011d1a0309000882090007000c82070007000982037d07000400107d023704000300057d0f37030003000b3709380300010005370a3809370100010006380a37087d0100010009370f7d01000637147d0437167d1a7d1a7d1a7d187d0237167d0437147d0637010001370b7d0c37010001000e37042503370382010003000b370225022302250382030003000482083704250482030003001482030004001282040007000c820700090008820900090008820900" + "data": "0x00011d1a030900088210000c820e000982037d0b00107d02370700057d0f3706000b370938040005370a380937020006380a37087d020009370f7d01000637147d04377c7d0237167d0437147d0637010001370b7d0c3702000e3704250337038204000b3702250223022503820600048208370425048206001482070012820b000c8210000882120008820900" }, { "filename": "head-kangaroo", - "data": "0x00051a1406037e0a00037e0400017e0238017e0800017e0238017e0400017e0338017e0600017e0338017e04000100017e0338017e0400017e0338017e05000200017e0238027e0200027e0238017e060003000a7e07000300087e09000300087e09000300087e09000300087e09000300067e088103230300067e088103230300067e0b810300067e022309810300067e0b810300067e0b81" + "data": "0x00051a1406037e0a00037e0400017e0238017e0800017e0238017e0400017e0338017e0600017e0338017e0500017e0338017e0400017e0338017e0700017e0238027e0200027e0238017e09000a7e0a00087e0c00087e0c00087e0c00087e0c00067e088103230300067e088103230300067e0b810300067e022309810300067e0b810300067e0b81" }, { "filename": "head-ketchup", - "data": "0x000218140807000224070007000224070006000424060006000424060005000689050005000623050001000224028902240289022402890224010001000e23010010241024102410241024102410241024022403890224038906240424048908241024" + "data": "0x0002181408070002240e0002240d0004240c0004240b0006890a0006230600022402890224028902240289022402000e23010082240389022403890a2404891824" }, { "filename": "head-laptop", - "data": "0x00061b1605161f011f010b013c120b011f011f1456011f011f1456011f011f1456011f011f1456011f011f1456011f011f1456011f011f1456011f011f1456011f011f1456011f011f1456011f031f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e021f021f130e011f021f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e031f011f130e021f161f" + "data": "0x00061b1605171f010b013c120b021f1456021f1456021f1456021f1456021f1456021f1456021f1456021f1456021f1456021f1456041f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e041f130e031f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e041f130e181f" }, { "filename": "head-lightning-bolt", - "data": "0x00021e19050800031e0e000700081e0a0007000c1e060006000c1e070006000b1e080005000b1e090005000a1e0a0004000a1e0b000400091e0c000300091e0d000300081e0e000200171e0200161e01000100151e03000100131e0500121e070005000b1e090004000a1e0b000400081e0d000300071e0f000300051e11000200041e13000200021e15000100011e1700" + "data": "0x00021e19050800031e1500081e11000c1e0c000c1e0d000b1e0d000b1e0e000a1e0e000a1e0f00091e0f00091e1000081e1000171e0200161e0200151e0400131e0500121e0c000b1e0d000a1e0f00081e1000071e1200051e1300041e1500021e1600011e1700" }, { "filename": "head-lint", - "data": "0x00021b16050a00018c0b000900018c0c00030001910600018c040001400600020001910300018c0200038c0140010002400600030002910200028c0191028c034004000291010005000340028c0191018c014001910240018c0200019102000100018c0200014001910340018c0191018c024001910240028c0300038c034001910340038c024001910140018c04000100018c0100018c024001910340018c0191028c014001910140028c03000300018c0191024001910240028c0191028c02400191028c010001910100028c0191018c024001910240028c0191028c0240038c010001910200018c0140028c014001910240058c0240028c0191018c01910100058c0740038c01400191038c010001910100038c01910840028c01400191028c020001910200018c01910a40018c0191028c03000200038c0140018c01910640018c0191038c01910200030001910140028c0191014004230140048c0100029101000200048c01910740028c0191028c03000200018c010002910740028c0191018c01910400050001910100014001000340018c0191018c0100018c0500090001400191010001910900" + "data": "0x00021b16050a00018c1400018c0f0001910600018c04000140080001910300018c0200038c014001000240090002910200028c0191028c03400400029106000340028c0191018c014001910240018c020001910300018c0200014001910340018c0191018c024001910240028c0300038c034001910340038c024001910140018c0500018c0100018c024001910340018c0191028c014001910140028c0600018c0191024001910240028c0191028c02400191028c010001910100028c0191018c024001910240028c0191028c0240038c010001910200018c0140028c014001910240058c0240028c0191018c01910100058c0740038c01400191038c010001910100038c01910840028c01400191028c020001910200018c01910a40018c0191028c0500038c0140018c01910640018c0191038c0191050001910140028c0191014004230140048c010002910300048c01910740028c0191028c0500018c010002910740028c0191018c0191090001910100014001000340018c0191018c0100018c0e0001400191010001910900" }, { "filename": "head-lips", - "data": "0x00051d1503070004240400042407000500072402000724050004000d2402010324040003000e2403010324030002001324010102240200010018240100010006240c01062401000524100105240424120104240324140103241a240100182401000100182401000200162402000300082404010824030005001024050008000a240800" + "data": "0x00051d150307000424040004240c0007240200072409000d240202032407000e2403020324050013240102022403001824020006240c02062401000524100209241202072414021d240100182402001824030016240500082404020824080010240d000a240800" }, { "filename": "head-lipstick2", - "data": "0x000118140806000324070004000724050003000137092403000200012401370a240200020002240137062401370224020002000324043702010324020002000724023703240200020007240237032402000b2a0101042a0b2a0101042a0b2a0101042a0b0d0105040d0b0d0105040d0b0d0105040d0b0d0105040d0b0d0105040d0b0d0105040d060d0223030d0105040d0b0d0105040d0b0501010405" + "data": "0x0001181408060003240b0007240800013709240500012401370a24040002240137062401370224040003240437020203240400072402370324040007240237032402000b2a01020f2a01020f2a0102042a0b0d01050f0d01050f0d01050f0d01050f0d01050f0d01050a0d0223030d01050f0d0105040d0b0501020405" }, { "filename": "head-lock", - "data": "0x00031814080400081f040003000a1f03000200031f0600031f02000200021f0800021f02000200011f010d0800011f010d02000200020d0800020d0200107a108a108a108a108a108a108a108a018a026d0a8a026d018a018a026d048a0223048a026d018a078a0223078a108a" + "data": "0x00031814080400081f07000a1f0500031f0600031f0400021f0800021f0400011f010d0800011f010d0400020d0800020d0200107a718a026d0a8a026d028a026d048a0223048a026d088a0223178a" }, { "filename": "head-macaroni", - "data": "0x00081d1403010008290800082901000229060a022906000229060a022901260829012606000126082901260a2606000a26012601280826060008260128012601260128092604000826022801261726012802260100182601000100152601280226010002001626020003000626020a0126020a0126020a0626030004001226040006000e260600" + "data": "0x00081d1403010008290800082901000229060a022906000229060a02290126082901260600012608290b2606000b26012808260600082601280226012809260400082602281826012802260100182602001526012802260300162605000626020a0126020a0126020a0626070012260a000e260600" }, { "filename": "head-mailbox", - "data": "0x00071c1405070005890b00070005890b000a0002890b000a050289030508000a050289030508000a050289030508000a050289030508000a0502890305060102000a05028903050401013a010102000a0502890305060102000a0502890305060102000a050289030501010423010102000f05060102001705" + "data": "0x00071c14050700058912000589150002890b000a050289030508000a050289030508000a050289030508000a050289030508000a0502890305060202000a05028903050402013a010202000a0502890305060202000a0502890305060202000a050289030501020423010202000f05060202001705" }, { "filename": "head-maze", - "data": "0x00061b14050acb01000bcb01cb0b0001cb040001cb030001cb01cb01000bcb010001cb010004cb010001cb01cb010001cb030001cb070001cb040001cb010001cb01cb030001cb030007cb010004cb010001cb06cb010002cb030001cb080001cb01cb010001cb050001cb010001cb010001cb010006cb010001cb01cb010005cb010001cb010003cb080001cb01cb050001cb050001cb010008cb01cb010003cb010003cb010001cb080001cb010001cb01cb030001cb010001cb010001cb010008cb010001cb010001cb03cb010001cb100001cb01cb010001cb010004cb010007cb010005cb01cb030001cb080001cb070001cb14cb010001cb" + "data": "0x00061b14050aca01000cca0b0001ca040001ca030002ca01000bca010001ca010004ca010002ca010001ca030001ca070001ca040001ca010002ca030001ca030007ca010004ca010007ca010002ca030001ca080002ca010001ca050001ca010001ca010001ca010006ca010002ca010005ca010001ca010003ca080002ca050001ca050001ca010009ca010003ca010003ca010001ca080001ca010002ca030001ca010001ca010001ca010008ca010001ca010004ca010001ca100002ca010001ca010004ca010007ca010006ca030001ca080001ca070015ca010001ca" }, { "filename": "head-microwave", - "data": "0x00071a1f05010002950f06012102060100029501060e9201210143010e0100029501060e920121010e01430100029501060e92012102c80100029501060e92012102060100029501060e92012102c80100029501060e92012102060100029501060e92012102c80100029501060e92012102060100029501060e92012102c80100010e019501060e9201210206020e019501060e92012102c8020e01950f06012102c8010e02950f0601210206010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400" + "data": "0x00071a1f05010002950f06012102060100029501060e9201210143010e0100029501060e920121010e01430100029501060e92012102c70100029501060e92012102060100029501060e92012102c70100029501060e92012102060100029501060e92012102c70100029501060e92012102060100029501060e92012102c70100010e019501060e9201210206020e019501060e92012102c7020e01950f06012102c7010e02950f0601210206010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400" }, { "filename": "head-milk", - "data": "0x00031b14080100014a0d7f04000100014a067f0524027f0400034a057f09240289034a097f05240289034a0d430300034a0143017f0143027f0143047f0143017f01430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d43030003c80d7f0300034a0d430300034a0d430300" + "data": "0x00031b14080100014a0d7f0500014a067f0524027f0400034a057f09240289034a097f05240289034a0d430300034a0143017f0143027f0143047f0143017f01430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d43030003c70d7f0300034a0d430300034a0d430300" }, { "filename": "head-mirror", - "data": "0x00041a14061497019702060101010603010a0601010197019701060101010603010b060101019701970101010603010c06010101970197010603010d0601010197019703010106063c0106063c01010197019702010206013c0406013c0106013c0406013c0101019701970101043c0406033c0406013c0101019701970106013c0206013c0406013c0106013c0406013c0101019701970106013c0206013c0406013c0106013c0406013c0101019701970406063c0106063c0101019701971106010101970197110601010197019711060101019701971106010101970197120101971497" + "data": "0x00041a1406159702060102010603020a060102029701060102010603020b06010202970102010603020c0601020297010603020d060102029703020106063c0106063c0102029702020206013c0406013c0106013c0406013c010202970102043c0406033c0406013c010202970106013c0206013c0406013c0106013c0406013c010202970106013c0206013c0406013c0106013c0406013c010202970406063c0106063c0102029711060102029711060102029711060102029711060102029712021597" }, { "filename": "head-mixer", - "data": "0x00021a1406030002230300022403000224050002000172030001230172030001240172030001240300140c010c030f020c030f020c030f020c0123010c0123010c010c010f015c010f020c010f015c010f020c010f015c010f020c0124010c0123010c100c014e010c01b0010c020c0123040c0123030c0301020c014e010c014e010c020c0123040c0123030c0372020c014e010c014e010c020c0123040c0123040c0123070c020c0123040c0123040c0123070c020c0123040c0123040c0123050c011f010c020c0123040c0123040c0123070c020c0123040c0123040c0123050c011f010c020c0123040c0123040c0123070c020c0123040c0123040c0123050c011f010c010c0301030c0123040c0123070c010c0372020c0301030c0123040c021f010c020c0123030c0372030c0123040c021f010c140c" + "data": "0x00021a140603000223030002240300022407000172030001230172030001240172030001240300150c030f020c030f020c030f020c0123010c0123020c010f015c010f020c010f015c010f020c010f015c010f020c0124010c0123110c014e010c01af030c0123040c0123030c0302020c014e010c014e030c0123040c0123030c0372020c014e010c014e030c0123040c0123040c0123090c0123040c0123040c0123090c0123040c0123040c0123050c011f030c0123040c0123040c0123090c0123040c0123040c0123050c011f030c0123040c0123040c0123090c0123040c0123040c0123050c011f020c0302030c0123040c0123080c0372020c0302030c0123040c021f030c0123030c0372030c0123040c021f150c" }, { "filename": "head-moon", - "data": "0x00031a160607000687070005000387035e0487050003000487035e0787030002000487025e0687015e0387020002000e87015e0187020001001287010001000587015e0887015e038701000287015e11870187025e11870187015e128714871487148701001287010001000f87015e028701000200058702230687025e0187020002000b87035e0287020003000687015e0387015e0387030005000a870500070006870700" + "data": "0x00031a1606070006870c000387035e048708000487035e078705000487025e0687015e038704000e87015e01870300128702000587015e0887015e038701000287015e1287025e1287015e4e870100128702000f87015e02870300058702230687025e018704000b87035e028705000687015e0387015e038708000a870c0006870700" }, { "filename": "head-moose", - "data": "0x00051c15040383010002830c000283010003830383010002830c850283010003830383010002830c850283010003830383010002830c8502830100038307830b85068307830b85068307830b85068304000e85060004000f85050004000f85050004000f850500040005850d980200040005850d98020004000585069802840298028401980200040005850d9802000400058501980b840198020009000d980200" + "data": "0x00051c15040383010002830c00028301000683010002830c85028301000683010002830c85028301000683010002830c85028301000a830b850d830b850d830b85068304000e850a000f8509000f8509000f85090005850d98060005850d980600058506980284029802840198060005850d980600058501980b8401980b000d980200" }, { "filename": "head-mosquito", - "data": "0x00011f14030c0002350e000a000235030002350b0009000135030002350d0008000135030001350f00080001350200013510000800013502000135100008000135020001351000040009110f0003000211014909110d000200021101490b110c000100021101490d110b00010011110a001311090002110149101109001411080001001b1102001511050003000a11078508000400021107850711080005000f110800" + "data": "0x00011f14030c0002351800023503000235140001350300023515000135030001351700013502000135180001350200013518000135020001351400091112000211014909110f00021101490b110d00021101490d110c0011110a00131109000211014910110900141109001b110200151108000a1107850c000211078507110d000f110800" }, { "filename": "head-mountain-snowcap", - "data": "0x00031c15040a0004010a0009000101028d0301090008000101018d0601080008000101018d0601080007000a01070007000101018d0601018d0101070006000c01060006000c01060005000e01050005000e0105000400021d0201021d0401021d0301011d04000400021d0101041d0201041d0101021d04000300021d0201051d0101041d0201021d03000300021d02010a1d0201021d03000200031d0201051d0101041d0201031d02000100021d01010f1d0101031d01000b1d0301071d0101021d0100161d01000300061d0600061d0300" + "data": "0x00031c15040a00040213000102028d030211000102018d060210000102018d06020f000a020e000102018d0602018d01020d000c020c000c020b000e020a000e020900021d0202021d0402021d0302011d0800021d0102041d0202041d0102021d0700021d0202051d0102041d0202021d0600021d02020a1d0202021d0500031d0202051d0102041d0202031d0300021d01020f1d0102031d01000b1d0302071d0102021d0100161d0400061d0600061d0300" }, { "filename": "head-mouse", - "data": "0x00031e1407070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e050002000e05070002000e05070002000e05070002000e05070002000e050400030e02000e050400030e02000e050400030e02001205030002000e05011f0105011f0105030002000805024b0105024b05050300020012050300" + "data": "0x00031e1407070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e07000e0509000e0509000e0509000e0509000e050400030e02000e050400030e02000e050400030e0200120505000e05011f0105011f010505000805024b0105024b0505050012050300" }, { "filename": "head-mug", - "data": "0x00031b14020900067f0200017f07000700037f0400017f0300027f0100017f03000600017f0200037f0300037f07000700027f0100017f0e0019000300160103000101016f014b1101014b010101000101014b0101016f014b1101014b0101020101000101016f024b1001014b0101010102000101016f024b1001014b0101010102000101016f024b1001014b0101020101000101016f024b1001014b010101000101014b0101016f024b120102000101014b0101016f014b1101010004000101016f014b1101010005000101016f014b040104370401014b0201020006000101016f014b040102370401014b0201030007000101016f024b0601024b02010400" + "data": "0x00031b14020900067f0200017f0e00037f0400017f0300027f0100017f0900017f0200037f0300037f0e00027f0100017f2a00160203000102016f014b1102014b010201000102014b0102016f014b1102014b030201000102016f024b1002014b020202000102016f024b1002014b020202000102016f024b1002014b030201000102016f024b1002014b010201000102014b0102016f024b120202000102014b0102016f014b110205000102016f014b110206000102016f014b040204370402014b020208000102016f014b040202370402014b02020a000102016f024b0602024b02020400" }, { "filename": "head-mushroom", - "data": "0x00021c150408000855080005000855025104550500030003550151045502510455025102550300020008550451055501510255020001000a5502510a5501000100035502510c5503510255010003550451065502510255055102550155015102550251035501510355025102550551025501550151105503510355185501001655010003001255030005000eaf050005000eaf050005000eaf050005000eaf050005000eaf0500050002af045508af0500050002af01550223015508af0500070004550d00" + "data": "0x00021c1504080008550d000855025104550800035501510455025104550251025505000855045105550151025503000a5502510a550200035502510c55035102550100035504510655025102550551035501510255025103550151035502510255055103550151105503511b55010016550400125508000eae0a000eae0a000eae0a000eae0a000eae0a0002ae045508ae0a0002ae01550223015508ae0c0004550d00" }, { "filename": "head-mustard", - "data": "0x00021814080700022607000700022607000600042606000600042606000500068a050005000623050001000226028a0226028a0226028a0226010001000e230100104610461046104610461046104610460246038a0246038a06460446048a08461046" + "data": "0x0002181408070002260e0002260d0004260c0004260b00068a0a00062306000226028a0226028a0226028a022602000e2301008246038a0246038a0a46048a1846" }, { "filename": "head-nigiri", - "data": "0x00051c1404040002ce01cd03ce01cd03ce01cd03ce01cd01ce0400020001cd03ce01cd03ce01cd03ce01cd03ce01cd03ce020002ce01cd04ce01cd03ce01cd03ce01cd03ce01cd04ce03ce01cd03ce01cd03ce01cd03ce01cd03ce01cd04ce03ce01cd03ce01cd03ce01cd03ce01cd03ce01cd04ce03ce120103ce01001601010001001601010002001401020001001601010001001601010002001401020001001601010001000a0103cf09010100020014010200030012010300" + "data": "0x00051c1404040002cd01cc03cd01cc03cd01cc03cd01cc01cd060001cc03cd01cc03cd01cc03cd01cc03cd01cc03cd020002cd01cc04cd01cc03cd01cc03cd01cc03cd01cc07cd01cc03cd01cc03cd01cc03cd01cc03cd01cc07cd01cc03cd01cc03cd01cc03cd01cc03cd01cc07cd120203cd0100160202001602030014020300160202001602030014020300160202000a0203ce090203001402050012020300" }, { "filename": "head-noodles", - "data": "0x00021e1402100001360b00100001360500013605000f000136040002360600050001d0010001d0010001d005000136020002360800040001d0015c01d0015c01d0015c01d002000298038803160700030001d0015c01d0025c03160398068802160600020001d0015c01d0025c02160419038803c20288011602980400020001d0015c01d0015c02160619018801c2034601c201880116039803001c0b01001a0b010001001a8901000200188902000200180b02000300168903000300160b03000400140b04000500070b0789040b05000600100b060008000c0b0800" + "data": "0x00021e1402100001361b0001360500013614000136040002360b0001cf010001cf010001cf05000136020002360c0001cf015c01cf015c01cf015c01cf02000298038803160a0001cf015c01cf025c0316039806880216080001cf015c01cf025c02160419038803c1028801160298060001cf015c01cf015c02160619018801c1034601c101880116039803001c0b01001a0b02001a89030018890400180b050016890600160b0700140b0900070b0789040b0b00100b0e000c0b0800" }, { "filename": "head-onion", - "data": "0x00041a14060a00019c09000800019c0100019c0100019c07000900039c080008000137039c013707000200029c0137039c0137039c0137039c0137019c02000100039c0137039c0137039c0137039c0137029c0100049c0137039c0137039c0137039c0137039c049c0137039c0137039c0137039c0137039c049c0137039c0137039c0137039c0137039c049c0137039c0137039c0137039c0137039c049c0137039c0137039c0137039c0137039c049c0137039c0137039c0137039c0137039c049c0137039c0137039c0137039c0137039c049c01c8019c0123019c0137039c0137029c01c80137039c0100039c0137029c0423019c0137039c0137029c01000200029c0137039c0137039c0137039c0137019c02000300019c0137039c0137039c0137039c01370300" + "data": "0x00041a14060a00019c1100019c0100019c0100019c1000039c10000137039c01370900029c0137039c0137039c0137039c0137019c0300039c0137039c0137039c0137039c0137029c0100049c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c01c7019c0123019c0137039c0137029c01c70137039c0100039c0137029c0423019c0137039c0137029c0300029c0137039c0137039c0137039c0137019c0500019c0137039c0137039c0137039c01370300" }, { "filename": "head-orangutan", - "data": "0x0002181406070001240a0004000b24030003000b24040003000c24030001000e2403000624070e0424010002000424070e04240100020002240c0e01240100020002240c0e01240100020002240c0e01240100020002240c0e01240100020002240c0e012401000200100e0200040e0a08020e0200030e0c08010e0200030e010801240208010e0108010e030801240108010e0200030e01240a080124010e0200030e01240a230124010e0200030e0c24010e" + "data": "0x0002181406070001240e000b2406000b2407000c2404000e2403000624070e042403000424070e0424030002240c0e0124030002240c0e0124030002240c0e0124030002240c0e0124030002240c0e01240300100e0200040e0a08020e0200030e0c08010e0200030e010801240208010e0108010e030801240108010e0200030e01240a080124010e0200030e01240a230124010e0200030e0c24010e" }, { "filename": "head-orca", - "data": "0x00021b14010d00010d0c000d00020d0b000d00030d0a000d00040d09000d00050d08000d00060d07000b000b0d040009000e0d03000800100d02000100030d0300110d02000200030d0100130d01000200170d01000300160d01000200180d0200030d0100140d0100030d0200130d0100030d0400080d090b02000800060d090b03000900040d090b0400" + "data": "0x00021b14010d00010d1900020d1800030d1700040d1600050d1500060d12000b0d0d000e0d0b00100d0300030d0300110d0400030d0100130d0300170d0400160d0300180d0200030d0100140d0100030d0200130d0100030d0400080d090b0a00060d090b0c00040d090b0400" }, { "filename": "head-otter", - "data": "0x000918140704000b86020002000e86010002000f8602000f8602000f86010010861186118602000286047f0623037f020001d10486017f0623017f0286020002d1037f04d1012303d1027f020008d1012301d1012304d1" + "data": "0x000918140704000b8604000e8603000f8602000f8602000f860100328602000286047f0623037f020001d00486017f0623017f0286020002d0037f04d0012303d0027f020008d0012301d0012304d0" }, { "filename": "head-outlet", - "data": "0x000418160810511051045108a40451035102a4012304a4012302a40351035102a4012304a4012302a40351035101a4037c02a4037c01a40351035104a4022304a40351035104a4022304a40351045108a404511051045108a40451035102a4012304a4012302a40351035102a4012304a4012302a40351035101a4037c02a4037c01a40351035104a4022304a40351035104a4022304a40351045108a4045110511051" + "data": "0x0004181608245108a3075102a3012304a3012302a3065102a3012304a3012302a3065101a3037c02a3037c01a3065104a3022304a3065104a3022304a3075108a3185108a3075102a3012304a3012302a3065102a3012304a3012302a3065101a3037c02a3037c01a3065104a3022304a3065104a3022304a3075108a32451" }, { "filename": "head-owl", - "data": "0x000218140507000ad20200060001d20ad301d20100050001d201d304d402d304d401d301d2050001d201d30ad401d301d2050001d201d301d402d501d302d401d302d501d401d301d2050001d201d303d401d302d401d303d401d301d2050001d201d304d402d304d401d301d2050002d201d308d402d301d20400042b01d308d401d301d20300062b08d401d301d20300062b01d207d401d301d20200072b01d207d401d301d20200072b01d207d401d301d20200072b01d207d401d301d20200062b02d207d401d201000200052b03d206d401d202000200032b04d206d401d20300010001d2012b07d206d403000bd207d40100" + "data": "0x000218140507000ad1080001d10ad201d1060001d101d204d302d204d301d201d1050001d101d20ad301d201d1050001d101d201d302d401d202d301d202d401d301d201d1050001d101d203d301d202d301d203d301d201d1050001d101d204d302d204d301d201d1050002d101d208d302d201d10400042b01d208d301d201d10300062b08d301d201d10300062b01d107d301d201d10200072b01d107d301d201d10200072b01d107d301d201d10200072b01d107d301d201d10200062b02d107d301d10300052b03d106d301d10400032b04d106d301d1040001d1012b07d106d303000bd107d30100" }, { "filename": "head-oyster", - "data": "0x00021d14040a0005810a000700048103820481070007000181098201810700050003810982038105000500018105820398058201810500020004810282099802820481020002000181058209980582018102000200018102820f980282018102000381018211980182038101810382119803820181018102821398028201810181048206980351079803820181010002810382049805510498038202810100030002810182039807510398018202810300050001810198025507510255019801810500040001810f550181040003000481035505810355048103000300018102d6058103d6058102d601810300040011d60400" + "data": "0x00021d14040a00058111000481038204810e000181098201810c000381098203810a00018105820398058201810700048102820998028204810400018105820998058201810400018102820f980282018102000381018211980182048103821198038202810282139802820281048206980351079803820181010002810382049805510498038202810400028101820398075103980182028108000181019802550751025501980181090001810f5501810700048103550581035504810600018102d5058103d5058102d50181070011d50400" }, { "filename": "head-paintbrush", - "data": "0x00091c18020700036d0572097502240600046d027201b10272097502240600046d0572087503240100096d0572087503240a6d0572087503240a6d0572087503240a6d0572077504240a6d0572077504240100096d0572077504240600046d0572077504240600036d0224017201b10272067505240700036d057206750524160001240100022418000224180001240100180001240100" + "data": "0x00091c18020700036d0572097502240600046d027201b00272097502240600046d0572087503240100096d0572087503240a6d0572087503240a6d0572087503240a6d0572077504240a6d0572077504240100096d0572077504240600046d0572077504240600036d0224017201b00272067505240700036d05720675052416000124010002241800022418000124190001240100" }, { "filename": "head-panda", - "data": "0x00051914060100042309000423010006230700062306230901042305230b01032304230d010223010002230e010123010002001001010002001001010002001001010002001001010002001001010002001001010002000a0104230201010002000a0104230201010002000701062303010100020010010100" + "data": "0x000519140601000423090004230100062307000c23090209230b0207230d020223010002230e02012303001002030010020300100203001002030010020300100203000a020423020203000a02042302020300070206230302030010020100" }, { "filename": "head-paperclip", - "data": "0x00091d14031ad701d7180001d701d7180001d701d7180001d701d7030010d7050001d701d7030001d7140001d701d7030001d7140001d701d7030001d7140001d701d7030001d7140001d701d7030016d701d7190014d70600" + "data": "0x00091d14031bd6180002d6180002d6180002d6030010d6050002d6030001d6140002d6030001d6140002d6030001d6140002d6030001d6140002d6030017d6190014d60600" }, { "filename": "head-peanut", - "data": "0x00041b1605040005d80d00020002d8036004d80b00010002d8016003c9036002d80a00010002d8016001c902d8016002c9016001d80a0002d8026003d8016002d8016002d8090001d8016002c9036001d8046002d8080001d8016002d8016003d8016001d802c9016005d8040001d801600bd8016006d8020002d8016012d80100010001d8016010d8016001d80100010002d8016012d8020002d801600dd8026002d803000fd802c9016001d8040005d8036005d8016002d8016001d8050002d8016002d802c9056001d8026002d8060002d8026002d8016004c9016002c901d80100080002d8036004d8016003d801000a0003d8046003d802000d0005d80400" + "data": "0x00041b1605040005d70f0002d7036004d70c0002d7016003c8036002d70b0002d7016001c802d7016002c8016001d70a0002d7026003d7016002d7016002d7090001d7016002c8036001d7046002d7080001d7016002d7016003d7016001d702c8016005d7040001d701600bd7016006d7020002d7016012d7020001d7016010d7016001d7020002d7016012d7020002d701600dd7026002d703000fd702c8016001d7040005d7036005d7016002d7016001d7050002d7016002d702c8056001d7026002d7060002d7026002d7016004c8016002c801d7090002d7036004d7016003d70b0003d7046003d70f0005d70400" }, { "filename": "head-pencil-tip", - "data": "0x00031714090600022306000600022306000500042305000500042305000400062304000400022301570323040003000223035703230300030007570123030002000a57020002000a57020001000c57010001000c5701000e570e57025704260557032601570626035704260326083703260e26" + "data": "0x0003171409060002230c0002230b0004230a000423090006230800022301570323070002230357032306000757012305000a5704000a5703000c5702000c5701001e57042605570326015706260357072608371126" }, { "filename": "head-peyote", - "data": "0x00021e14030a0001d9020001da020001d90a000a0001d901db010001da010001db01d90a00080001d9020001db01dc01da01dc01db020001d90800090002db05dc02db0900050001d9010002aa01dd02aa03dd02aa01dd02aa010001d90500040002d902aa01dd04aa01dd04aa01dd02aa02d90400050002aa01dd02aa02d901aa01dd01aa02d902aa01dd02aa0500040002aa01dd02aa02d902aa01dd02aa02d902aa01dd02aa0400030002aa01dd0faa01dd02aa0300020017aa020001d9010017aa010001d9010001d917aa01d9010002d917aa02d9010001d917aa01d9010001d9010017aa010001d9020002aa01da11aa01da02aa0200030001aa13da01aa0300030015aa0300050011aa0500" + "data": "0x00021e14030a0001d8020001d9020001d8140001d801da010001d9010001da01d8120001d8020001da01db01d901db01da020001d8110002da05db02da0e0001d8010002a901dc02a903dc02a901dc02a9010001d8090002d802a901dc04a901dc04a901dc02a902d8090002a901dc02a902d801a901dc01a902d802a901dc02a9090002a901dc02a902d802a901dc02a902d802a901dc02a9070002a901dc0fa901dc02a9050017a9020001d8010017a9010001d8010001d817a901d8010002d817a902d8010001d817a901d8010001d8010017a9010001d8020002a901d911a901d902a9050001a913d901a9060015a9080011a90500" }, { "filename": "head-piano", - "data": "0x00041b15080400050e0a000200020e010501590105040e08000100020e0105080e070001000b0e07000d0e06000d0e06000e0e05000e0e05000f0e0400110e0200130e130e130e130e010e0159070e0159050e0159030e010e0159010e0159010e0159010e0159010e0159010e0159010e0159010e0159010e0159010e010e1159010e130e" + "data": "0x00041b15080400050e0c00020e010501590105040e0900020e0105080e08000b0e07000d0e06000d0e06000e0e05000e0e05000f0e0400110e02004d0e0159070e0159050e0159040e0159010e0159010e0159010e0159010e0159010e0159010e0159010e0159010e0159020e1159140e" }, { "filename": "head-pickle", - "data": "0x00031b15050400040f0e000200080f0c000100030f01c0060f0b000100030f015c030f01c0020f0b00020f01c0060f015c020f0a00020f015c030f01c0070f0800060f015c040f01c0015c050f0400010f01c0120f0200010f015c130f0100150f0100160f0100150f0100130f01c0010f0100020f01c0100f015c010f0200010f015c120f02000b0f012302c0015c040f01000300030f01c0015c010f01c0040f025c050f01000500050f015c090f020007000b0f0400" + "data": "0x00031b15050400040f1000080f0d00030f01bf060f0c00030f015c030f01bf020f0b00020f01bf060f015c020f0a00020f015c030f01bf070f0800060f015c040f01bf015c050f0400010f01bf120f0200010f015c130f0100150f0100160f0100150f0100130f01bf010f0100020f01bf100f015c010f0200010f015c120f02000b0f012302bf015c040f0400030f01bf015c010f01bf040f025c050f0600050f015c090f09000b0f0400" }, { "filename": "head-pie", - "data": "0x00011c14040b0002cc0b00050002cc030002cc050002cc0500060002cc030002cc030002cc0600050002cc030002cc050002cc0500060002cc080002cc0600050002cc04000209040002cc0500060002cc0200020901190109020002cc0600090001de040901de0900050002de010903de020903de010902de0500030012de0300020001de010910de010901de0200010016de0100010001de04bb01de04bb01de04bb01de04bb01de01bb010018bb18bb03bb029503bb0196019503bb0195019603bb029504bb01bb01950196029501960295019202950196029501960295019602950196029501bb01000195019602950196029509920196029501960295010002000196029501960295019202950196029501960295019602950196019502000200019602950196029501960295019602950196029501960295019601950200" + "data": "0x00011c14040b0002cb100002cb030002cb050002cb0b0002cb030002cb030002cb0b0002cb030002cb050002cb0b0002cb080002cb0b0002cb04000209040002cb0b0002cb0200020901190109020002cb0f0001dd040901dd0e0002dd010903dd020903dd010902dd080012dd050001dd010910dd010901dd030016dd020001dd04ba01dd04ba01dd04ba01dd04ba01dd01ba010033ba029503ba0196019503ba0195019603ba029505ba01950196029501960295019202950196029501960295019602950196029501ba010001950196029501960295099201960295019602950300019602950196029501920295019602950196029501960295019601950400019602950196029501960295019602950196029501960295019601950200" }, { "filename": "head-piggybank", - "data": "0x00041d14020c0003420c000b000142039301420500027604000800036c012503930125026c02000176016c0176040006000276026c017605120176026c0176026c0176040005000176106c01760400020001760100036c01010f6c01760300010001760259146c01760200010001760159136c0112016c03760100017601590176166c0176015901000276166c017603000176146c037603000276156c0176030001590176146c0176010004000376106c02760200050013760300060006760112020101120676050008000c760700" + "data": "0x00041d14020c0003421700014203930142050002760c00036c012503930125026c02000176016c01760a000276026c017605120176026c0176026c017609000176106c0176060001760100036c01020f6c0176040001760259146c0176030001760159136c0112016c03760100017601590176166c0176015901000276166c017603000176146c037603000276156c0176030001590176146c017605000376106c0276070013760900067601120202011206760d000c760700" }, { "filename": "head-pill", - "data": "0x00061d140305000924071d050003000c24081d03000200062401010724081d02000100032402010a24091d01000100032402010b24081d01001124091d1124091d1124091d1124091d1124091d01001024061d010f011d010001000f24071d010f011d010002000a2403230124061d010f011d020003000c24081d030005000924071d0500" + "data": "0x00061d140305000924071d08000c24081d0500062401020724081d0300032402020a24091d0200032402020b24081d01001124091d1124091d1124091d1124091d1124091d01001024061d010f011d02000f24071d010f011d03000a2403230124061d010f011d05000c24081d08000924071d0500" }, { "filename": "head-pillow", - "data": "0x000319160702df0e0002e00ddf05e0010002df0ee00100010003df0de00100010003df08e003df02e00100010003df0de00100010003df02e002df09e00100010003df0de00100010003df0de00100010003df0de00100010003df0de00100010003df0de00100010003df0de00100010003df0de00100010003df0de00100010003df05e004df04e00100010003df0de00100010002df0ee001000ddf05e002df0e0002e0" + "data": "0x000319160702de0e0002df0dde05df010002de0edf020003de0ddf020003de08df03de02df020003de0ddf020003de02df02de09df020003de0ddf020003de0ddf020003de0ddf020003de0ddf020003de0ddf020003de0ddf020003de0ddf020003de0ddf020003de05df04de04df020003de0ddf020002de0edf01000dde05df02de0e0002df" }, { "filename": "head-pineapple", - "data": "0x00031914070600010f010002e10100010f0600040001e10100020f02e1020f010001e10400040003e1010f02e1010f03e10400060006e1060004000228022602280226022804000200022802260228022602280226022802000200022802260228022602280226022802000100012802260228022602280226022802260128010001000128022602280226022802260228022601280100010001260228022602280226022802260228012601000100012602280226022802260228022602280126010001001126010010260100010010260100122601000226034201260442012603420226010001000226034201260442012603420226010002000e260200" + "data": "0x00031914070600010f010002e00100010f0a0001e00100020f02e0020f010001e0080003e0010f02e0010f03e00a0006e00a00022802260228022602280600022802260228022602280226022804000228022602280226022802260228030001280226022802260228022602280226012802000128022602280226022802260228022601280200012602280226022802260228022602280126020001260228022602280226022802260228012602001126010010260200102601001226010002260342012604420126034202260200022603420126044201260342022603000e260200" }, { "filename": "head-pipe", - "data": "0x00061c150509160e0009980e0009980e000100030804980f000100030804980f000100030804980f000100030804980f000100030804980c0003160100030804980c160398010003081398010003081398010004081298010006080123010101230101012308080398020015080300140814000308" + "data": "0x00061c150509160e0009980e0009980f00030804981000030804981000030804981000030804981000030804980c0003160100030804980c160398010003081398010003081398010004081298010006080123010201230102012308080398020015080300140814000308" }, { "filename": "head-pirateship", - "data": "0x00011f14030c0002230e000d0001980e0005000198030008230b00040002230400082302000223060005000198050001230151012302510123015101230200019806000300025501980500032302510323010003550500030003550500042301510323020003550400030004550300022301510423015101230100035505000200065501000923030001980600050001980700019807000198060005000198070001980700019806000d2601980700019806000c97012601980700019806000197022309970126089701980100052601970223099701260198010001970100019701000197010001980126049701000c970a2603970300020004970123109705000300029703230197012301970123019701230197012301970123049706000400029701230e97070005000f970800" + "data": "0x00011f14030c0002231b00019813000198030008230f00022304000823020002230b00019805000123015101230251012301510123020001980900025501980500032302510323010003550800035505000423015103230200035507000455030002230151042301510123010003550700065501000923030001980b00019807000198070001980b000198070001980700019806000d2601980700019806000c97012601980700019806000197022309970126089701980100052601970223099701260198010001970100019701000197010001980126049701000c970a2603970500049701231097080002970323019701230197012301970123019701230197012304970a00029701230e970c000f970800" }, { "filename": "head-pizza", - "data": "0x000319140708000237080008000237080007000137022801370700070001370228013707000600013704280137060006000137012802370128013706000500013702280237022801370500050001370628013705000400013708280137040004000137082801370400030001370a2801370300030001370a2801370300020001370c2801370200020001370c280137020001000137032803370828013701000100013701280137012803370528023701280137010001370828032305280137013710280137" + "data": "0x000319140708000237100002370f000137022801370e000137022801370d000137042801370c00013701280237012801370b00013702280237022801370a0001370628013709000137082801370800013708280137070001370a280137060001370a280137050001370c280137040001370c280137030001370328033708280137020001370128013701280337052802370128013701000137082803230528023710280137" }, { "filename": "head-plane", - "data": "0x00041e14030d0002010c000c0005010a0009000901090007000b01090005000c010a001b001b0006000bc80a0006000bc80a0006000bc80a0006000cc8090006000cc8090002c8040012c80200010102c8040005c8060107c8020001010ac8090105c8010001c801010924020106230201052402000101010007c80b0105c802000101" + "data": "0x00041e14030d000202180005021300090210000b020e000c0246000bc710000bc710000bc710000cc70f000cc7090002c7040012c70200010202c7040005c7060207c7020001020ac7090205c7010001c701020924020206230202052402000102010007c70b0205c702000102" }, { "filename": "head-pop", - "data": "0x000318140802000ca302000100061405280314010005140128031404280314022802140128011401280314042802140214012802140128041405280114021401280814042801140228051401280314042801140a14052801140a1404280214091405280214091404280314081404280414071404280514051405280614031404280914021403280314012801230201012301280214010002280c14010002000ca30200" + "data": "0x000318140802000ca20300061405280314010005140128031404280314022802140128011401280314042804140128021401280414052803140128081404280114022805140128031404280b1405280b1404280b1405280b1404280b1404280b1404280a140528091404280b1403280314012801230202012301280214010002280c1403000ca20200" }, { "filename": "head-porkbao", - "data": "0x00051914070500025701000257010002570500050002570183025701830257050004000257018302570183025701830157040004000157018302570183025701830257040002000e57020002000e57020001001057010001001057010001001057010012571257125712570957037d06571257010010570100" + "data": "0x00051914070500025701000257010002570a0002570183025701830257090002570183025701830257018301570800015701830257018302570183025706000e5704000e5703001057020010570200105701005157037d1857010010570100" }, { "filename": "head-potato", - "data": "0x00061d15040f0001c909000d00077a05000b00037a01c9077a030008000b7a02c9027a020005000f7a01c9027a02000200167a01000100177a0100187a0100187a0100187a01c9187a0100107a02c9057a02000100097a01230101012301010123017a02c9057a02000200057a02c90d7a03000300047a02c90b7a050006000a7a0900" + "data": "0x00061d15040f0001c81600077a1000037a01c8077a0b000b7a02c8027a07000f7a01c8027a0400167a0200177a0100187a0100187a0100187a01c8187a0100107a02c8057a0300097a01230102012301020123017a02c8057a0400057a02c80d7a0600047a02c80b7a0b000a7a0900" }, { "filename": "head-pufferfish", - "data": "0x00041c160509000168020001680a000600016801000668010001680700034903000568014904680700054902680349076806000449036803490368024903680500034904680349036802490468040003491068040002001268030002001268030002001268030005490d6805490149046801930b680193046801490549029309680293054901490a68044907680149054902930468014902350149026801930549030006930268044901680393040004000e93050005000c930600070008930800" + "data": "0x00041c160509000168020001681000016801000668010001680700034903000568014904680700054902680349076806000449036803490368024903680500034904680349036802490468040003491068060012680500126805001268030005490d680649046801930b6801930468064902930968029306490a680449076806490293046801490235014902680193054903000693026804490168039308000e930a000c930d0008930800" }, { "filename": "head-pumpkin", - "data": "0x00051b1406080003b001c501b00800080003b001c501b00800080003b001c501b008000300072401b0072403000300072401480724030002240148072401480724014802240224014807240148072401480224022401480724014807240148022402240148072401480724014802240224014807240148072401480224022401480724014807240148022402240148072401480724014802240224014807240148072401480224022401480585016d0385016d05850148022402240148072401480724014802240224014807240148072401480224" + "data": "0x00051b1406080003af01c401af100003af01c401af100003af01c401af0b00072401af072406000724014807240300022401480724014807240148042401480724014807240148042401480724014807240148042401480724014807240148042401480724014807240148042401480724014807240148042401480724014807240148042401480724014807240148042401480585016d0385016d058501480424014807240148072401480424014807240148072401480224" }, { "filename": "head-pyramid", - "data": "0x00031e14030800018601b111000800028601b110000700038602b10f000700038603b10e000600058603b10d000600058604b10c00050002860284028601b1028602b10b000500078605b10a000400088606b109000400088607b1080003000a8607b1070003000a8608b1060002000b8609b1050002000c8606b1028601b1040001000d860ab1030001000186038401860184078607b1038601b102000986032303860bb101000f860cb1" + "data": "0x00031e14030800018601b01900028601b01700038602b01600038603b01400058603b01300058604b0110002860284028601b0028602b01000078605b00e00088606b00d00088607b00b000a8607b00a000a8608b008000b8609b007000c8606b0028601b005000d860ab004000186038401860184078607b0038601b002000986032303860bb001000f860cb0" }, { "filename": "head-queencrown", - "data": "0x00021b14050a00025b0a000900015b01180141015b09000900015b01410118015b09000500035b0200025b0200035b05000400015b0300015b0100025b0100015b0300015b04000100035b0500045b0500035b0100015b0200015b03000241015b018b0154015b02410300015b0200015b015b0200015b01000441015b0254015b04410100015b0200015b015b01000141015b0541015b0154018b015b0541015b01410100015b0100015b0141015b0541045b0541015b0141015b01000100015b0141015b0641025b0641015b0141015b01000100015b0241015b0441045b0441015b0241015b01000200015b0241015b0341015b028a015b0341015b0241015b02000200015b0241015b0341015b028a015b0341015b0241015b02000100025b0141035b0241015b028a015b0241035b0141025b01000200125b02000300103503000200055b0841055b02000200125b0200" + "data": "0x00021b14050a00025b1300015b01180141015b1200015b01410118015b0e00035b0200025b0200035b0900015b0300015b0100025b0100015b0300015b0500035b0500045b0500035b0100015b0200015b03000241015b018b0154015b02410300015b0200025b0200015b01000441015b0254015b04410100015b0200025b01000141015b0541015b0154018b015b0541015b01410100015b0100015b0141015b0541045b0541015b0141015b0200015b0141015b0641025b0641015b0141015b0200015b0241015b0441045b0441015b0241015b0300015b0241015b0341015b028a015b0341015b0241015b0400015b0241015b0341015b028a015b0341015b0241015b0300025b0141035b0241015b028a015b0241035b0141025b0300125b050010350500055b0841055b0400125b0200" }, { "filename": "head-rabbit", - "data": "0x00041715090372080003720372080003720372080003720372080003720372080003720e720e720e720e720e720e720e720e050e0502050b230105030502010405020103050e050e05" + "data": "0x0004171509037208000672080006720800067208000672080065721e050b2304050202040502021f05" }, { "filename": "head-rainbow", @@ -2410,39 +1604,39 @@ }, { "filename": "head-rangefinder", - "data": "0x00061b1405020002050100020501000d72010501050b7203050172020e0101010e017201050105027201050372020c037203050172040e0172010501050172020511720105010e010c0205110c010e010e140c010e010e140c010e010e140c010e010e140c010e010e140c010e010e140c010e010e120c0205010e010e080c0505050c0205010e010e140c010e010514720105" + "data": "0x00061b1405020002050100020501000d7202050b7203050172020e0102010e01720205027201050372020c037203050172040e017202050172020511720105010e010c0205110c020e140c020e140c020e140c020e140c020e140c020e140c020e120c0205020e080c0505050c0205020e140c010e010514720105" }, { "filename": "head-raven", - "data": "0x00041e14080100080e0d000400070e0b0001000c0e090002000c0e080001000e0e070001000e0e070001000f0e0600100e0600100e0600100e0600100e0600090e070d0600080e0c0d0200070e0f0d070e0f0d070e0d0d0200080e090d0500" + "data": "0x00041e14080100080e1100070e0c000c0e0b000c0e09000e0e08000e0e08000f0e0600100e0600100e0600100e0600100e0600090e070d0600080e0c0d0200070e0f0d070e0f0d070e0d0d0200080e090d0500" }, { "filename": "head-retainer", - "data": "0x00091d150504000320110004000120011906200c0004000320011906200a0003000520011902200119042008000300092001190620050003000220011903200119062001190320040002000220021903200119032002190120031901200400020002200f19022003000100022011190120030001000120031904a4011904a4011904a40119022002a402200219012001a40120011901a4011901a4021901a4011901a40119012001a40320010001a4052001a4022003a4022003a4022006a4030003a41200" + "data": "0x00091d150504000320150001200119062010000320011906200d00052001190220011904200b00092001190620080002200119032001190620011903200600022002190320011903200219012003190120060002200f190220040002201119012004000120031904a3011904a3011904a30119022002a302200219012001a30120011901a3011901a3021901a3011901a30119012001a30320010001a3052001a3022003a3022003a3022006a3030003a31200" }, { "filename": "head-rgb", - "data": "0x00011c160409000664090007000a64070006000c64060005000e64050005000e640500040010640400040001640628026406690164040003000165072802010769015a030002000265062804010669025a020001000365052806010569035a010001000365052806010569035a01000565032808010369055a0565032808010369055a0665022808010269065a0765012808010169075a086501e2060101e2085a086508e2085a0100086506e2085a01000100086506e2085a01000200086504e2085a02000300086502e2085a0300050006650200065a0500" + "data": "0x00011c16040900066410000a640d000c640b000e640a000e640900106408000164062802640669016407000165072802020769015a05000265062804020669025a03000365052806020569035a02000365052806020569035a01000565032808020369055a0565032808020369055a0665022808020269065a0765012808020169075a086501e1060201e1085a086508e1085a0100086506e1085a0200086506e1085a0300086504e1085a0500086502e1085a080006650200065a0500" }, { "filename": "head-ring", - "data": "0x00021a15060600084f06000600024f0101024f016c024f06000700034f016c024f07000500032a044f032a05000300022a021e022a024f022a021e022a03000200012a021e0a2a021e012a02000100052a011e0700052a01000100032a011e0b00032a0100032a021e0c00032a012a0101012a011e0d00032a032a011e0d00032a032a011e0d00032a032a011e0d00012a0101012a032a011e0d00012a0101012a032a011e0d00032a0100032a021e0a00032a01000100052a081e052a01000200102a020003000e2a030005000a2a0500" + "data": "0x00021a15060600084f0c00024f0102024f016c024f0d00034f016c024f0c00032a044f032a0800022a021e022a024f022a021e022a0500012a021e0a2a021e012a0300052a011e0700052a0200032a011e0b00032a0100032a021e0c00042a0102012a011e0d00062a011e0d00062a011e0d00062a011e0d00012a0102042a011e0d00012a0102042a011e0d00032a0100032a021e0a00032a0200052a081e052a0300102a05000e2a08000a2a0500" }, { "filename": "head-road", - "data": "0x00061c1403020017e3020017e3020017d4020017e3020017e3010017e30100010017e30100010017e30100010017e30100010017e3010018e3010017e4020017e3020001e303e403e303e403e303e403e303e401e3020017e30200" + "data": "0x00061c1403020017e2020017e2020017d3020017e2020017e2010017e2020017e2020017e2020017e2020017e2010018e2010017e3020017e2020001e203e303e203e303e203e303e203e301e2020017e20200" }, { "filename": "head-robot", - "data": "0x00031c140405000e1f050005000e1f050003001205030003000105011f0205011f0205011f0205011f0205011f0205011f0105030003001205030003001205030003000105101f01050300010001050100120503000100010501001205010001050100031f1205010001050100010e021f1205031f031f1205021f010e010e021f1205031f031f1205021f010e03000105010e0259010e0259010e0259010e0259010e0259010e0105031f03000105010e020b010e020b010e020b010e020b010e020b010e0105030003000105100e01050300030012050300" + "data": "0x00031c140405000e1f0a000e1f0800120506000105011f0205011f0205011f0205011f0205011f0205011f0105060012050600120506000105101f010504000105010012050400010501001205010001050100031f1205010001050100010e021f1205061f1205021f020e021f1205061f1205021f010e03000105010e0259010e0259010e0259010e0259010e0259010e0105031f03000105010e020b010e020b010e020b010e020b010e020b010e010506000105100e0105060012050300" }, { "filename": "head-rock", - "data": "0x00031b14050b00030c08000a00010c031f020c06000900010c011f010c041f020c04000800020c021f010c051f020c02000300050c051f010c061f010c01000200010c121f010c0100010c051f040c0a1f010c0100010c091f010c091f010c0100010c021f010c101f010c0100010c071f020c011f070c021f010c0100010c051f020c0c1f010c010c141f010c010c041f010c0e1f020c010c041f010c081f020c011f030c02000100010c041f010c041f030c021f010c021f010c02000200010c051f030c041f010c021f010c03000300050c041f030c031f010c03000400010c0c1f010c0400" + "data": "0x00031b14050b00030c1200010c031f020c0f00010c011f010c041f020c0c00020c021f010c051f020c0500050c051f010c061f010c0300010c121f010c0100010c051f040c0a1f010c0100010c091f010c091f010c0100010c021f010c101f010c0100010c071f020c011f070c021f010c0100010c051f020c0c1f020c141f020c041f010c0e1f030c041f010c081f020c011f030c0300010c041f010c041f030c021f010c021f010c0400010c051f030c041f010c021f010c0600050c041f030c031f010c0700010c0c1f010c0400" }, { "filename": "head-rosebud", - "data": "0x00021c14040c0001940b000a000119010002940a000900021904940900070004190694070006000419089406000500051909940500040006190a940400040005190b940400030006190394011d08940300030006190394011d08940300011d020006190294021d08940200011d0100011d010007190194021d08940100011d01000100041d05190194021d0694041d01000200051d03190194021d0494051d02000300051d0219041d0294051d03000400041d0119011d0123021d0123011d0194041d04000500031d0119021d0223021d0194031d050006000c1d060006000c1d0600" + "data": "0x00021c14040c00019415000119010002941300021904941000041906940d00041908940b0005190994090006190a94080005190b94070006190394011d0894060006190394011d08940300011d020006190294021d08940200011d0100011d010007190194021d08940100011d0200041d05190194021d0694041d0300051d03190194021d0494051d0500051d0219041d0294051d0700041d0119011d0123021d0123011d0194041d0900031d0119021d0223021d0194031d0b000c1d0c000c1d0600" }, { "filename": "head-ruler-triangular", @@ -2450,1110 +1644,302 @@ }, { "filename": "head-saguaro", - "data": "0x00031c14040c00047908000c00057907000300047905000579070003000479020002790100057907000300047902000279010005790700027901000479020002790100057907000279010004790200017902b0057902000279010002790100017901b004790500057902000279010002790300047905000579010003790100027904000379050004790200037901b001790100027902000479020001790100047902000379030002790200047902000179010004790200027904000279020004790200017901b00479020002790400037901000479030001b004790100037904000100027901b0047904b004790100037904000200017901b0077902b00379010002790500040002790323037901b0037901b0027905000500077901b0037901b002790500" + "data": "0x00031c14040c000479140005790a000479050005790a00047902000279010005790a00047902000279010005790700027901000479020002790100057907000279010004790200017902af057902000279010002790100017901af04790500057902000279010002790300047905000579010003790100027904000379050004790200037901af01790100027902000479020001790100047902000379030002790200047902000179010004790200027904000279020004790200017901af0479020002790400037901000479030001af0479010003790500027901af047904af0479010003790600017901af077902af037901000279090002790323037901af037901af02790a00077901af037901af02790500" }, { "filename": "head-sailboat", - "data": "0x00011c14040d0001010a000c0002010100010108000b0003010100010108000a0004010100020107000900020102df01010100020107000800030102df010101000301060007000701010003010600060008010100040105000500090101000401050004000a0101000501040003000b0101000501040002000c0101000601030001000d010100060103000e010100070102001800188301000183149801830100020001830198108301980183020003000183109801830300040010830400" + "data": "0x00011c14040d0001021600020201000102130003020100010212000402010002021000020202de0102010002020f00030202de0102010003020d000702010003020c000802010004020a0009020100040209000a020100050207000b020100050206000c020100060204000d020100060203000e02010007021a00188301000183149801830300018301981083019801830500018310980183070010830400" }, { "filename": "head-sandwich", - "data": "0x00041d14030d0001880c000c0003e10b000c0002e1011a0b000c0003e10b000500088301880783050003000783017d028301880483017d0483030002000283017d088301880183017d0883020001000883017d0a83017d04830100010018830100010018e501000100185501000100016d0655016d0855016d07550100011c186d011c031c066d081c056d041c0100041c0298051c0398051c0298011c0100011c010003000698082306980300040012980400" + "data": "0x00041d14030d000188180003e0170002e0011a170003e0100008830188078308000783017d028301880483017d048305000283017d088301880183017d088303000883017d0a83017d048302001883020018e4020018550200016d0655016d0855016d07550100011c186d041c066d081c056d041c0100041c0298051c0398051c0298011c0100011c0400069808230698070012980400" }, { "filename": "head-saturn", - "data": "0x00051c16030b0004e60a00090008e6080007000ce60200023a0200010005510ee60100023a0200015105000ee605000151040002140de6011404000151040003140ce601140400010001510200025503140be6021403000200015101000255041409e603140300030001510355061405e6041403000400015102550f1403000500015104550b140151020001e60500015502510555061402550100015102000600025502510a55030001510100030002e60100045503510755040001510200013a02e60200065503510355050001510200023a050007550351050001510b000455040005510100" + "data": "0x00051c16030b0004e5130008e50f000ce50200023a030005510ee50100023a0200015105000ee505000151040002140de5011404000151040003140ce50114050001510200025503140be502140500015101000255041409e50314060001510355061405e504140700015102550f140800015104550b140151020001e5050001550251055506140255010001510800025502510a5503000151040002e50100045503510755040001510200013a02e50200065503510355050001510200023a050007550351050001510b000455040005510100" }, { "filename": "head-saw", - "data": "0x00091e15020c9710a301000b9710a3020003970100069710a3020002970300059710a3020002970300059710a3020002970300059710a3020002970300059710a302000297030005970ea3010001a302000297030005970ca3010001a302000200039701000297012602970ba3010001a304000100099703a3025105a3010001a30600099702a3025105a3010001a30800080008a30c00" + "data": "0x00091e15020c9710a201000b9710a2020003970100069710a2020002970300059710a2020002970300059710a2020002970300059710a2020002970300059710a202000297030005970ea2010001a202000297030005970ca2010001a20400039701000297012602970ba2010001a20500099703a2025105a2010001a20600099702a2025105a2010001a2100008a20c00" }, { "filename": "head-scorpion", - "data": "0x00031e1403060008e70d00060008e70d00060008e70d00030004e7050003e70c00030004e7020003e803e70c00030004e7020001e8010002e802e70c00010003e7070003e80d00010003e71700010003e7170003e7180003e7180003e7180003e703000de8080003e7020010e80300039f05e710e803e7019f0200010004e702e802e902e802e902e802e901e807e70200010004e704e802e902e802e904e806e7020006000ee8010003e7039f" + "data": "0x00031e1403060008e6130008e6130008e6100004e6050003e60f0004e6020003e703e60f0004e6020001e7010002e702e60d0003e6070003e70e0003e6180003e6170003e6180003e6180003e6180003e603000de7080003e6020010e70300039e05e610e703e6019e030004e602e702e802e702e802e702e801e707e6030004e604e702e802e702e804e706e608000ee7010003e6039e" }, { "filename": "head-shark", - "data": "0x00031c14030a0004ec0b000b0005ec09000c0005ec08000c0005ec080001ec0b0006ec0700010001ec08000b430400010002ec05000e430300010003ec020011430200020003ec010012430100020004ec1343030003ec1343030003ec104301ec01430100030003ec104301ec01430100020003ec010011430200020002ec020011430200020001ec0300034301ec014301ec0243023c0101013c0101013c0101013c0300010001ec0400024301ec014301ec0243023c0101013c0101013c0101023c030006000643093c0400" + "data": "0x00031c14030a0004eb160005eb150005eb140005eb080001eb0b0006eb080001eb08000b43050002eb05000e43040003eb02001143040003eb01001243030004eb1343030003eb1343030003eb104301eb0143040003eb104301eb0143030003eb01001143040002eb02001143040001eb0300034301eb014301eb0243023c0102013c0102013c0102013c040001eb0400024301eb014301eb0243023c0102013c0102013c0102023c09000643093c0400" }, { "filename": "head-shower", - "data": "0x00011c19040b00020d0b000b00020d0b000800080d080006000c0d060005000e0d05000400101f04000400081f010b011f030b031f04000400101f040005000e43050005000e430500040010430400040010430400040010430400030012430300030012430300030012430300020014430200020014430200020014430200010016430100010001430100014310000143010001430100010004430e0004430100014301000143010001430e00014301000143010001431800010001430100014310000143010001430100" + "data": "0x00011c19040b00020d1600020d1300080d0e000c0d0b000e0d0900101f0800081f010b011f030b031f0800101f09000e430a000e430900104308001043080010430700124306001243060012430500144304001443040014430300164302000143010001431000014301000143020004430e0004430100014301000143010001430e0001430100014301000143190001430100014310000143010001430100" }, { "filename": "head-skateboard", - "data": "0x00091e1402030016c00300010003c0016a0369016a0ac0016a0369016a03c00100010001c0011b01c0016a0369016a0ac0016a0369016a01c0011b01c0010002c0011b01c0016a0369016a0ac0016a0369016a01c0011b02c002c0011b03c0017c0ec0017c03c0011b02c002c0011b03c0017c0ec0017c03c0011b02c002c0011b03c0017c0ec0017c03c0011b02c002c0011b03c0017c0ec0017c03c0011b02c002c0011b01c0016a0369016a0ac0016a0369016a01c0011b02c0010001c0011b01c0016a0369016a05c0030e02c0016a0369016a01c0011b01c00100010003c0016a0369016a0ac0016a0369016a03c00100030016c00300" + "data": "0x00091e1402030016bf040003bf016a0369016a0abf016a0369016a03bf020001bf011b01bf016a0369016a0abf016a0369016a01bf011b01bf010002bf011b01bf016a0369016a0abf016a0369016a01bf011b04bf011b03bf017c0ebf017c03bf011b04bf011b03bf017c0ebf017c03bf011b04bf011b03bf017c0ebf017c03bf011b04bf011b03bf017c0ebf017c03bf011b04bf011b01bf016a0369016a0abf016a0369016a01bf011b02bf010001bf011b01bf016a0369016a05bf030e02bf016a0369016a01bf011b01bf020003bf016a0369016a0abf016a0369016a03bf040016bf0300" }, { "filename": "head-skeleton-hat", - "data": "0x000519150704000a43040001001043010001001043010012431243010010af0100010010af0100010010af0100010010af0100010010af0100010010af0100010010af0100010007af01b101af01b106af010003000caf0300030002af01b101af016d01af01b101af01b101af01b101af0300030003af01b101af01b101af01b101af01b101af01b1030004000baf0300" + "data": "0x000519150704000a43050010430200104301002443010010ae020010ae020010ae020010ae020010ae020010ae020010ae020007ae01b001ae01b006ae04000cae060002ae01b001ae016d01ae01b001ae01b001ae01b001ae060003ae01b001ae01b001ae01b001ae01b001ae01b007000bae0300" }, { "filename": "head-skilift", - "data": "0x00011e1403010001230100142301000123010001230800012301000123100001230200152301000123010006000123140006000123140006000223130006000423110007000b230900030014880400020001880a770188097701880300020001880a77018807770166017701880300020001880a77018807770166017701880300020001880a77018807770166017701880300020001880a7701880977018803000200163303000200168803000200163303000200063306230a330300020016330300040012330500" + "data": "0x00011e1403010001230100142301000123010001230800012301000123100001230200152301000123070001231a0001231a0002231900042318000b230c001488060001880a77018809770188050001880a7701880777016601770188050001880a7701880777016601770188050001880a7701880777016601770188050001880a770188097701880500163305001688050016330500063306230a3305001633070012330500" }, { "filename": "head-smile", - "data": "0x00051d14030600042406000424060004000824020008240400012402001424020001240724020108240201072401240101162401010124012404011024040101240224160102240324140103240100032412010324010001000424100104240100020004240e0104240200020006240a010624020003001424030004000a2402010624040005001024050007000c240700" + "data": "0x00051d140306000424060004240a00082402000824040001240200142402000824020208240202082401021624010202240402102404020324160205241402032401000324120203240200042410020424030004240e020424040006240a0206240500142407000a2402020624090010240c000c240700" }, { "filename": "head-snowglobe", - "data": "0x00051914080600048c07000300038c0151038c0151038c03000100018c0151058c0151068c015101000100048c0151018c0351028c0151038c0100038c0151018c0197025101970251038c0151028c0151048c025103970251058c048c025105970251038c0151038c0251039701260197012601970251038c048c0997048c048c04970126019701260297048c048c09970151038c038c015109970251028c11510100045104110751010001000f08010001000f080100" + "data": "0x00051914080600048c0a00038c0151038c0151038c0400018c0151058c0151068c01510200048c0151018c0351028c0151038c0100038c0151018c0197025101970251038c0151028c0151048c025103970251098c025105970251038c0151038c0251039701260197012601970251078c0997088c04970126019701260297088c09970151068c015109970251028c1151010004510411075102000f0802000f080100" }, { "filename": "head-snowmobile", - "data": "0x00071e15050c0001040c000c0001040c0008000305010002040b000b00010502040b000b00010502040b000b000123010402260a000a0003230426080003230600032302260155052605000c23012603550104052603000b23022602550804020002230901022602550804020005010123110102000601032301010b05030001040a010a050300010401000100012301050123010501230105012301000e040200" + "data": "0x00071e15050c0001041800010414000305010002041600010502041600010502041600012301040226140003230426080003230600032302260155052605000c23012603550104052603000b23022602550804020002230902022602550804020005020123110202000602032301020b05030001040a020a05030001040200012301050123010501230105012301000e040200" }, { "filename": "head-spaghetti", - "data": "0x00041a1c060c000384050005000384030001840385018404000400038401850484028501d00284030003000184028501d001840485028404850200030004850184048501840585020003000f8502000300015503850255028501d002550385015502000200105502000200105502000100037d0c55027d02000100127d0100147d147d017d0201017d0101017d0701017d0301017d0101017d017d0401017d0701017d0301017d0101017d017d0c01017d0501017d017d010010010100017d017d0100017d0e00017d0100017d017d0100017d0e00017d0100017d017d0100017d0e00017d0100017d017d0100017d0e00017d0100017d017d0100017d0e00017d0100017d0200017d0e00017d02000200017d0e00017d02000200017d0e00017d0200" + "data": "0x00041a1c060c0003840a00038403000184038501840800038401850484028501cf028406000184028501cf018404850284048505000485018404850184058505000f850500015503850255028501cf02550385015504001055040010550300037d0c55027d0300127d0100297d0202017d0102017d0702017d0302017d0102027d0402017d0702017d0302017d0102027d0c02017d0502027d010010020100027d0100017d0e00017d0100027d0100017d0e00017d0100027d0100017d0e00017d0100027d0100017d0e00017d0100027d0100017d0e00017d0100017d0200017d0e00017d0400017d0e00017d0400017d0e00017d0200" }, { "filename": "head-sponge", - "data": "0x0004191408010003290200022902000429030001290222032901220929010001290222092903220229010007290222022903220229010003290222022902220229032202290100032902220a2901001029010010290100112911291129112910290100012902220d29010001290222032905230429020001000d2901220129010001000e290200" + "data": "0x0004191408010003290200022902000429030001290222032901220929010001290222092903220229010007290222022903220229010003290222022902220229032202290100032902220a290100102901001029010054290100012902220d2901000129022203290523042903000d290122012902000e290200" }, { "filename": "head-squid", - "data": "0x00011c1a020d00026a0b000c00046a0a000b00036a01ed026a09000a00056a01ed026a08000900076a01ed026a070008000c6a060007000e6a05000600014f0e6a014f04000500024f0e6a024f03000400024f106a024f02000300034f106a034f01000200044f106a014f01ed024f0200044f106a024f01ed014f0200044f106a044f0200044f106a044f0300034f106a034f01000100014f0200034f0e6a034f0200014f016a014f03000245014f0123010101230101012301010123010101230101014f02450400014f016a014f020003450c4f03450300014f016a014f0100144502000100014f014501000145010002450100024506000245010002450100024501000200034501000145020001450800014502000145020001450100030001451300014f014501001700014f014501001700014f014501001700014f0200" + "data": "0x00011c1a020d00026a1700046a1500036a01ec026a1300056a01ec026a1100076a01ec026a0f000c6a0d000e6a0b00014f0e6a014f0900024f0e6a024f0700024f106a024f0500034f106a034f0300044f106a014f01ec024f0200044f106a024f01ec014f0200044f106a044f0200044f106a044f0300034f106a034f0200014f0200034f0e6a034f0200014f016a014f03000245014f0123010201230102012301020123010201230102014f02450400014f016a014f020003450c4f03450300014f016a014f010014450300014f0145010001450100024501000245060002450100024501000245030003450100014502000145080001450200014502000145040001451300014f01451800014f01451800014f01451800014f0200" }, { "filename": "head-stapler", - "data": "0x00081c140407000d2404000400122402000200162401001724010017240100172401001724051812720100061811720100041801240218110005181224010018181818" + "data": "0x00081c140407000d2408001224040016240100172401001724010017240100172405181272010006181172010004180124021811000518122401003018" }, { "filename": "head-star-sparkles", - "data": "0x00021b17050a0002ad0a0006000129020001ad022901ad0900090001ad022901ad0900080001ad042901ad0300012901000129020003000129040001ad042901ad04000129030002000329020001ad062901ad0200012901000129020003000129030001ad062901ad0700050002ad082902ad0500030002ad0c2902ad0300010002ad102902ad010001ad142901ad01ad142901ad010002ad102902ad0100030002ad0c2902ad0300050001ad0a2901ad0500050001ad0a2901ad050001000129020001ad072903ad022901ad0400040001ad0c2901ad0400030001ad062902ad062901ad0300030001ad042902ad020002ad042901ad0300030001ad022902ad060002ad022901ad0300040002ad0a0002ad0400" + "data": "0x00021b17050a0002ac10000129020001ac022901ac120001ac022901ac110001ac042901ac030001290100012905000129040001ac042901ac0400012905000329020001ac062901ac020001290100012905000129030001ac062901ac0c0002ac082902ac080002ac0c2902ac040002ac102902ac010001ac142902ac142901ac010002ac102902ac040002ac0c2902ac080001ac0a2901ac0a0001ac0a2901ac06000129020001ac072903ac022901ac080001ac0c2901ac070001ac062902ac062901ac060001ac042902ac020002ac042901ac060001ac022902ac060002ac022901ac070002ac0a0002ac0400" }, { "filename": "head-steak", - "data": "0x00071b160504000e51040002000251061803380518025102000100015109180138081801510100010001510918013808180151010001510a1801380918015101510a1801380918015101510a1801380918015101510a1801380918015101510a1801380918015101510138091801380918015102510238051803380118035105180151010003510838011801510138015104180251020008510238011803510418015101000400075102380518035101000a000a5102000b0007510400" + "data": "0x00071b160504000e51060002510618033805180251030001510918013808180151020001510918013808180151010001510a180138091802510a180138091802510a180138091802510a180138091802510a180138091802510138091801380918035102380518033801180351051801510100035108380118015101380151041802510200085102380118035104180151050007510238051803510b000a510d0007510400" }, { "filename": "head-sunset", - "data": "0x00031d1403090008490900070004490142024901420449070005000549014201490242014901420549050004000149014201490c420149014201490400030001490142014904420126014202260142012604420149014201490300020001490142014903420a2603420149014201490200020002490342032601280126022801260128032603420249020001000249034203260828032603420249010001000249024203260a2803260242024901000349024202260c280226024203490249024202260e28022602420249014901420149024202260d28012602420149014201490249024202260e280226024202490249024202260e28022602420249014901420149024202260c280226024201490142014902490242022606280201012605280226024202490349024202260c2802260242034901000349024202260a280226024203490100" + "data": "0x00031d1403090008491000044901420249014204490c00054901420149024201490142054909000149014201490c4201490142014907000149014201490442012601420226014201260442014901420149050001490142014903420a2603420149014201490400024903420326012801260228012601280326034202490300024903420326082803260342024902000249024203260a2803260242024901000349024202260c28022602420549024202260e2802260242034901420149024202260d2801260242014901420349024202260e28022602420449024202260e2802260242034901420149024202260c2802260242014901420349024202260628020201260528022602420549024202260c2802260242034901000349024202260a280226024203490100" }, { "filename": "head-taco-classic", - "data": "0x00051d14030a00038e0167028e0a000800038e0167018e0167048e08000600038e0167018e015701670157018e0167028e0167018e06000500018e0267018e0367011102570367038e05000500028e026708500157038e05000300018e0167018e015702110150018a0350018a025002110267028e03000300028e01670650018a0750038e03000300018e01110d50018a02500167018e03000200018e015701110150018a0e5001110157018e020001000167018e1450018e0200020001670450018a0c50018a02500267010002000111145001110200016701000350018a0d50018a0150018a025002000100016716500167010002000550018a0550018a0750018a0250010001670300145001670200" + "data": "0x00051d14030a00038e0167028e1200038e0167018e0167048e0e00038e0167018e015701670157018e0167028e0167018e0b00018e0267018e0367011102570367038e0a00028e026708500157038e0800018e0167018e015702110150018a0350018a025002110267028e0600028e01670650018a0750038e0600018e01110d50018a02500167018e0500018e015701110150018a0e5001110157018e03000167018e1450018e040001670450018a0c50018a0250026703000111145001110200016701000350018a0d50018a0150018a0250030001671650016703000550018a0550018a0750018a0250010001670300145001670200" }, { "filename": "head-taxi", - "data": "0x00041c170405000ee60500050001e603c8040105c801e60500040001e603c8040107c801e60400040001e602c8040108c801e60400030001e602c8040104c8034303c801e60300030001e601c8040104c8014303c8014302c801e60300010016e60100010016e60100010016e60100010016e60100010016e60100010016e60100010016e60100010002e6011f10e6011f02e60100011f0137141f0137011f091f061d091f010008e6061d08e601000200020e0500061d0500020e02000200020d1000020d02000200020d1000020d0200" + "data": "0x00041c170405000ee50a0001e503c7040205c701e5090001e503c7040207c701e5080001e502c7040208c701e5070001e502c7040204c7034303c701e5060001e501c7040204c7014303c7014302c701e5040016e5020016e5020016e5020016e5020016e5020016e5020016e5020002e5011f10e5011f02e50100011f0137141f01370a1f061d091f010008e5061d08e50300020e0500061d0500020e0400020d1000020d0400020d1000020d0200" }, { "filename": "head-thumbsup", - "data": "0x00011a14050a00012b02e608000a0001e6012b02e607000a0001e6012b02e607000a00012b03e60700090005e60700080006e60700070006e60800060006e6012b07e60100030008e6012b07e6012b01e60be6012b07e6012b01e60de6012b06e6012b0de6072b01000ae6012b0ae60ae6012b08e6012b01e60ae6012b09e6012b0ce6082b010001e6022b05e6012b02e6012b08e6010008e6042b06e6012b01e60100030004e6012b03e6012b07e6012b0100040008e6072b0200" + "data": "0x00011a14050a00012b02e5120001e5012b02e5110001e5012b02e51100012b03e5100005e50f0006e50e0006e50e0006e5012b07e5040008e5012b07e5012b0ce5012b07e5012b0ee5012b06e5012b0de5072b01000ae5012b14e5012b08e5012b0be5012b09e5012b0ce5082b010001e5022b05e5012b02e5012b08e5010008e5042b06e5012b01e5040004e5012b03e5012b07e5012b050008e5072b0200" }, { "filename": "head-toaster", - "data": "0x00031a1f0504000e840300030002840cd8028402000300018403d8089903d801840200040001840cd8018403000400018402d8089902d8018403000300010b0e72010b02000300010b0e72010b02000300010b0e72010b020d0300010b0e72010b020d0300010b0e72010b02000300010b0e72010b02000300010b0e72010b02000300010b0e72010b02000300010b0e72010b02000300010b0e72010b02000200120d0100021f120d0100011f0100120d0100011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400" + "data": "0x00031a1f0504000e84060002840cd702840500018403d7089903d70184060001840cd701840700018402d7089902d701840600010b0e72010b0500010b0e72010b0500010b0e72010b020d0300010b0e72010b020d0300010b0e72010b0500010b0e72010b0500010b0e72010b0500010b0e72010b0500010b0e72010b0500010b0e72010b0400120d0100021f120d0100011f0100120d0100011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400" }, { "filename": "head-toiletpaper-full", - "data": "0x00071a1605010002ee11010100010002ee1101010004ee110104ee110104ee110101ee017c010d01ee110101ee017c010d01ee110101ee017c010d01ee110101ee017c010d01ee110104ee110104ee110104ee1101010002ee027c01ee010101ee010101ee010101ee010101ee010101ee010101ee01010200010002ee017c1001010004000c010500050008010800" + "data": "0x00071a1605010002ed1102020002ed1102010004ed110204ed110204ed110201ed017c010d01ed110201ed017c010d01ed110201ed017c010d01ed110201ed017c010d01ed110204ed110204ed110204ed1102010002ed027c01ed010201ed010201ed010201ed010201ed010201ed010201ed0102030002ed017c100205000c020a0008020800" }, { "filename": "head-tooth", - "data": "0x00041917060a0005570400030004570100025705010257020002000157040101570301015705010157010001000157060103570701015701000157100101570157110101570157110101570157110101570157110101570157110101570157110101570100015710010157020001570e0101570100020001570e0101570100030001570201097c020101570100030001570d0101570100040001570401035704010157020004000157030101570300015703010157020005000157020101570400015702010157020006000257060002570300" + "data": "0x00041917060a0005570700045701000257050202570400015704020157030201570502015702000157060203570702015701000157100202571102025711020257110202571102025711020257110201570100015710020157020001570e020157030001570e020157040001570202097c02020157040001570d020157050001570402035704020157060001570302015703000157030201570700015702020157040001570202015708000257060002570300" }, { "filename": "head-toothbrush-fresh", - "data": "0x00021914011000016707000f000167011c016706000f000167021c046702000f000167061c016701000c000667021c0101011c0167010009000367081c0101011c01670100080001670d1c01670100080001670d1c0167010008000101011c0101011c0101011c0101011c0101011c0101011c0101011c0101010008000f01010008000f01010008000f01010008000f01010008000f0101000143010002430100134302000143020013430100024301000543012301460123014601230a430700114307001143" + "data": "0x00021914011000016716000167011c016715000167021c046711000167061c01670d000667021c0102011c01670a000367081c0102011c0167090001670d1c0167090001670d1c016709000102011c0102011c0102011c0102011c0102011c0102011c0102011c010209000f0209000f0209000f0209000f0209000f0201000143010002430100134302000143020013430100024301000543012301460123014601230a430700114307001143" }, { "filename": "head-tornado", - "data": "0x00031c150406000c81060003000281017c0281047e057c0381040002000281027c0b81017c03810300020003810f7c038101000200168103000b7c0181017c078101000500118102000700047c0181017c0181017c0581040006000c81060005000d81060004000b81090002000b810b00010009810e0002000a810800018103000500088106000181040001000181010001810100017c049c0281017c0681010001810300018101000481067c0881040003001281030003000481080004810500" + "data": "0x00031c150406000c8109000281017c0281047e057c038106000281027c0b81017c0381050003810f7c03810300168103000b7c0181017c0781060011810900047c0181017c0181017c05810a000c810b000d810a000b810b000b810c00098110000a8108000181080008810600018105000181010001810100017c049c0281017c0681010001810300018101000481067c08810700128106000481080004810500" }, { "filename": "head-trashcan", - "data": "0x00031b14050900050508000700020504000105080007000105020009050300020011050300020008050723010d04000300010d08230a0d020006050323030d0505010d020002000205031f0205031f0205031f02050100010d010001000305031f0205031f0205031f03050200010501000205031f0205031f0205031f020501000105010002000205031f0205031f0205031f0205030002000205031f0205031f0205031f0205030002000205031f0205031f0205031f0205030002000205031f0205031f0205031f0205030002000205031f0205031f0205031f0205030002000205011f0523021f0205031f0205030002000205031f0205031f0205031f02050300020011050300" + "data": "0x00031b1405090005050f000205040001050f0001050200090505001105050008050723010d0700010d08230a0d020006050323030d0505010d04000205031f0205031f0205031f02050100010d02000305031f0205031f0205031f03050200010501000205031f0205031f0205031f02050100010503000205031f0205031f0205031f020505000205031f0205031f0205031f020505000205031f0205031f0205031f020505000205031f0205031f0205031f020505000205031f0205031f0205031f020505000205011f0523021f0205031f020505000205031f0205031f0205031f0205050011050300" }, { "filename": "head-turing", - "data": "0x00041d19031500018904000300126101890161030002000289016101cc01820161018201cc01610282016101cc0182016101cc0182016101820189016103000100018901940261028201610282016101cc018201610282016102820161018201cc028902000100018901941461018902000100018901000261018201cc016102820161018201cc0161018201cc016102820161028201610189020001000189010002890282016101cc01820161028201610282016101cc0182016101cc018201610189020002890194016101891261018901940100038901610189018201cc01610282016101cc01820161018201cc016102820161018201cc0161018901000189018901000189016101890282016101cc018201610282016102820161018201cc01610282016101890100018901890100018901610189126101890100018901890100018901610189018201cc016102820161028201610282016101cc018201610282016101890100018901890100038902820161018201cc0161018201cc0161018201cc01610282016101cc018201610189010001890189010001891461018901000189018901000189026102010161020101610201016102010161020101610201016102000189018901000189026102010161020101610201016102010161020101610201016101890100018901890100018914610189010001890189010001890194110001940100028901000189020002891100018903000100018901000289150001000189010001941600020002891600" + "data": "0x00041d190315000189070012610189016105000289016101cb01820161018201cb01610282016101cb0182016101cb018201610182018901610400018901940261028201610282016101cb018201610282016102820161018201cb0289030001890194146101890300018901000261018201cb016102820161018201cb0161018201cb01610282016102820161018903000189010002890282016101cb01820161028201610282016101cb0182016101cb018201610189020002890194016101891261018901940100038901610189018201cb01610282016101cb01820161018201cb016102820161018201cb016101890100028901000189016101890282016101cb018201610282016102820161018201cb016102820161018901000289010001890161018912610189010002890100018901610189018201cb016102820161028201610282016101cb01820161028201610189010002890100038902820161018201cb0161018201cb0161018201cb01610282016101cb0182016101890100028901000189146101890100028901000189026102020161020201610202016102020161020201610202016102000289010001890261020201610202016102020161020201610202016102020161018901000289010001891461018901000289010001890194110001940100028901000189020002891100018904000189010002891600018901000194180002891600" }, { "filename": "head-ufo", - "data": "0x00021e15020e00014f0d000d00034f0c000e00014f0d000b00064f0b0009000a4f090007000e43070006000a430106014302060243060006000c430206024306000500124305000500124305000500124305000400144304000400144304000400144304000400144f04000200184f02000100054f026d014f026d014f026d014f026d014f026d014f026d044f0100064f026d014f026d014f026d014f026d014f026d014f026d054f0400144f040009000a4f0900" + "data": "0x00021e15020e00014f1a00034f1a00014f1800064f14000a4f10000e430d000a4301060143020602430c000c43020602430b0012430a0012430a0012430900144308001443080014430800144f0600184f0300054f026d014f026d014f026d014f026d014f026d014f026d044f0100064f026d014f026d014f026d014f026d014f026d014f026d054f0400144f0d000a4f0900" }, { "filename": "head-undead", - "data": "0x00021b16050600027903260b00060004790200027903260500020001260300027903000579060002000126017902000279020003790900020001260179020002790200037909000200027902000279020002790200018003000126030002000279020003790100027905000179022602000200027903000579050004790100018002000279020005790600037901000280010002790200057907000279010003000a7904000479010004001079020004000f7902000180018005000a79040002800700087907000300018003000879070006000180017901230125012301250123027901800300018002000500038006790380050004000e80040005000180010003800200028001000180060008000180090001800300" + "data": "0x00021b16050600027903261100047902000279032607000126030002790300057908000126017902000279020003790b000126017902000279020003790b00027902000279020002790200018003000126050002790200037901000279050001790226040002790300057905000479010001800200027902000579060003790100028001000279020005790700027904000a79040004790500107906000f790200028005000a7904000280070008790a000180030008790d0001800179012301250123012501230279018003000180070003800679038009000e80090001800100038002000280010001800e000180090001800300" }, { "filename": "head-unicorn", - "data": "0x00041b16040b00021c0a000800011c0300021c0600012602000900021c0100021c040002260300050003660100051c0200032604000200031c0366071c032601660400011c0100031c0766011c0426026604000100031c012007660426036604000200011c02200766032604660400020003200766022605660400010004200766012606660400020003200e660400020003200e66040002000320125f01000220023a0e5f0120015f0120015f0100043a035f012001660123016601230166012301660120065f0200033a125f0200033a125f0300023a12000400013a1200" + "data": "0x00041b16040b00021c1200011c0300021c060001260b00021c0100021c04000226080003660100051c020003260600031c0366071c032601660400011c0100031c0766011c042602660500031c01200766042603660600011c02200766032604660600032007660226056605000420076601260666060003200e66060003200e6606000320125f01000220023a0e5f0120015f0120015f0100043a035f012001660123016601230166012301660120065f0200033a125f0200033a125f0300023a1600013a1200" }, { "filename": "head-vent", - "data": "0x00081c140418011801030101230101012301010123010101230201012301010123010101230101012305010301011f0101011f0101011f0101011f0201011f0101011f0101011f0101011f05010301011f0101011f0101011f0101011f0201011f0101011f0101011f0101011f0101012303010301011f0101011f0101011f0101011f0201011f0101011f0101011f0101011f0101012303010101011f0101011f0101011f0101011f0101011f0201011f0101011f0101011f0101011f010101230101011f01010301011f0101011f0101011f0101011f0201011f0101011f0101011f0101011f0101012303010301011f0101011f0101011f0101011f0201011f0101011f0101011f0101011f0101020202010301011f0101011f0101011f0101011f0201011f0101011f0101011f0101011f05010301010201010102010101020101010202010102010101020101010201010102050118011801" + "data": "0x00081c140433020123010201230102012301020123020201230102012301020123010201230802011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f0802011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f010201230602011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f010201230402011f0102011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f010201230102011f0402011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f010201230602011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f010202010502011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f08020101010201010102010101020101020201010102010101020101010201013502" }, { "filename": "head-void", - "data": "0x00051b14050123020001230200012302000123020001230200012302000123020001231600160001231400012316001600012314000123160016000123140001231600160001231400012316001600012302000123020001230200012302000123020001230200012302000123" + "data": "0x00051b14050123020001230200012302000123020001230200012302000123020001232c000123140001232c000123140001232c000123140001232c000123140001232c00012302000123020001230200012302000123020001230200012302000123" }, { "filename": "head-volcano", - "data": "0x00031c15040800081f08000800011f0641011f08000700021f0642021f07000700011f014106280141011f07000600021f0341031f0241021f06000600021f0141041f0141021f0141011f06000500021f01410b1f05000500041f010c051f010c031f05000400051f010c051f010c041f04000400051f010c051f010c041f04000300051f010c071f010c041f03000300051f010c071f010c041f03000200061f010c071f010c051f02000200051f010c091f010c041f02000100021f020c0f1f010c021f01000100021f020c051f010c0c1f01000a1f010c0341010c041f020c031f061f010c021f010c091f020c031f0200141f0200" + "data": "0x00031c15040800081f1000011f0641011f0f00021f0642021f0e00011f014106280141011f0d00021f0341031f0241021f0c00021f0141041f0141021f0141011f0b00021f01410b1f0a00041f010c051f010c031f0900051f010c051f010c041f0800051f010c051f010c041f0700051f010c071f010c041f0600051f010c071f010c041f0500061f010c071f010c051f0400051f010c091f010c041f0300021f020c0f1f010c021f0200021f020c051f010c0c1f01000a1f010c0341010c041f020c091f010c021f010c091f020c031f0200141f0200" }, { "filename": "head-volleyball", - "data": "0x00031b1505090004d40900060001d401ef02d4020102d401ef01d40600040003d401ef02d4020102d401ef03d40400030001d401ef03d401ef04d401ef03d401ef01d40300020003d401ef02d401ef04d401ef02d401ef03d40200020004d40aef02d4010101d40200010004d401ef0ad401ef04d40100010003d401ef0cd401ef01d4010101d40100010003d401ef0cd401ef01d4010101d4010004d401ef0cd401ef01d4010102d404d401ef0cd401ef02d4010101d404d401ef0cd401ef02d4010101d404d401ef0cd401ef04d4010003d401ef0cd401ef04d4010003d401ef0cd401ef03d40100010001d4010102d401ef0ad401ef04d40100020001d4010102d40aef04d40200020003d401ef02d401ef04d401ef02d401ef03d40200030001d401ef03d401ef04d401ef03d401ef01d40300" + "data": "0x00031b1505090004d30f0001d301ee02d3020202d301ee01d30a0003d301ee02d3020202d301ee03d3070001d301ee03d301ee04d301ee03d301ee01d3050003d301ee02d301ee04d301ee02d301ee03d3040004d30aee02d3010201d3030004d301ee0ad301ee04d3020003d301ee0cd301ee01d3010201d3020003d301ee0cd301ee01d3010201d3010004d301ee0cd301ee01d3010206d301ee0cd301ee02d3010205d301ee0cd301ee02d3010205d301ee0cd301ee04d3010003d301ee0cd301ee04d3010003d301ee0cd301ee03d3020001d3010202d301ee0ad301ee04d3030001d3010202d30aee04d3040003d301ee02d301ee04d301ee02d301ee03d3050001d301ee03d301ee04d301ee03d301ee01d30300" }, { "filename": "head-wall", - "data": "0x00031a15060237041a01830237011a0137091a061a01830d1a061a01830d1a061a01830d1a0100128301000237011a0137091a01830237041a0d1a0183061a0d1a0183061a0d1a0183061a0100128301000237041a018301370c1a061a01830d1a061a01830d1a061a01830d1a0100128301000237011a0137091a01830237041a071a0337031a0183061a0d1a0183061a0d1a0183061a" + "data": "0x00031a15060237041a01830237011a01370f1a0183131a0183131a01830d1a0100128301000237011a0137091a01830237111a0183131a0183131a0183061a0100128301000237041a01830137121a0183131a0183131a01830d1a0100128301000237011a0137091a018302370b1a0337031a0183131a0183131a0183061a" }, { "filename": "head-wallet", - "data": "0x00081d1403020008a40e8c0200029701a408510ec801970197012301a408510ec801970d9701080c9701970ba40197010801970a430197019701a4057c05a4019701080c97019701a4017c03a4017c05a40197010801970a260197019701a4017c03a4017c05a4019701080c97019701a4027c01a4027c05a40197010801970a980197019701a4017c03a4017c05a40197010801970a980197019701a4057c01a4034701a4019701080c9701970ba4019701080c970d9701080c97" + "data": "0x00081d1403020008a30e8c0200029701a308510ec70297012301a308510ec70e9701080d970ba30197010801970a43029701a3057c05a3019701080d9701a3017c03a3017c05a30197010801970a26029701a3017c03a3017c05a3019701080d9701a3027c01a3027c05a30197010801970a98029701a3017c03a3017c05a30197010801970a98029701a3057c01a3034701a3019701080d970ba301970108199701080c97" }, { "filename": "head-wallsafe", - "data": "0x00091d140419080108117e0108052401080108017e0f08017e0108052401080108017e0f08017e07080108017e0f08017e01080124010801240108012401080108017e0f08017e07080108017e0f08017e01080124010801240108012401080108017e010801a40d08017e07080108017e01a4010801a40c08017e01080124010801240108012401080108017e010801a40208010101230101012301010123010101230308017e07080108117e010801a401080124010801a401081908" + "data": "0x00091d14041a08117e010805240208017e0f08017e010805240208017e0f08017e0808017e0f08017e0108012401080124010801240208017e0f08017e0808017e0f08017e0108012401080124010801240208017e010801a30d08017e0808017e01a3010801a30c08017e0108012401080124010801240208017e010801a30208010201230102012301020123010201230308017e0808117e010801a301080124010801a31a08" }, { "filename": "head-washingmachine", - "data": "0x0003191f0402000fee0400020002ee017201ee017201ee017401ee017201ee015101ee0155017402ee0300020002ee017401ee017401ee017201ee017403ee0143017402ee03000200037210510200037206510472065102000372045102720475027204510200037203510172087501720351020003720351017208750172035102000372025101720a750172025102000372025101720a750172025102000372025101720a750172025102000372025101720a75017202510200037203510172087501720351020003720351017208750172035102000372045102720475027204510223037201510243035104720651012301000372105101230100037210510123140001231400012314000123140001231400012314000123140001231400012314000123140001231400" + "data": "0x0003191f0402000fed060002ed017201ed017201ed017401ed017201ed015101ed0155017402ed050002ed017401ed017401ed017201ed017403ed0143017402ed0500037210510200037206510472065102000372045102720475027204510200037203510172087501720351020003720351017208750172035102000372025101720a750172025102000372025101720a750172025102000372025101720a750172025102000372025101720a75017202510200037203510172087501720351020003720351017208750172035102000372045102720475027204510223037201510243035104720651012301000372105101230100037210510123140001231400012314000123140001231400012314000123140001231400012314000123140001231400" }, { "filename": "head-watch", - "data": "0x00041a150802000c0a040001000826011e0126021e0226030001260e51012602000126065102780651012602000126035101780651017803510126020001260e51012602000126015101780a51017801510126020001260e5101260100010a01260e510126010a012601260e510126020a01260e510126010a012601260e5101260100010a0126045101780451017804510126020001260e510126020001260651027806510126020001260e510126020001000e26030002000c0a0400" + "data": "0x00041a150802000c0a05000826011e0126021e0226030001260e51012602000126065102780651012602000126035101780651017803510126020001260e51012602000126015101780a51017801510126020001260e5101260100010a01260e510126010a02260e510126020a01260e510126010a02260e5101260100010a0126045101780451017804510126020001260e510126020001260651027806510126020001260e51012603000e2605000c0a0400" }, { "filename": "head-watermelon", - "data": "0x00031b15050400051d0d000300051d02240c000200051d0124011802240b000200041d0224012303240a000100041d082409000100031d06240123011802240800041d02240123011807240700031d0d240600031d0e240500031d0f240400031d10240300031d112402000100021d122401000100031d1124011d0200021d1024011d01000300021d042401230118012301180624011d02000400031d0a24021d03000500041d0624021d05000800071d0700" + "data": "0x00031b15050400051d1000051d02240e00051d0124011802240d00041d0224012303240b00041d08240a00031d06240123011802240800041d02240123011807240700031d0d240600031d0e240500031d0f240400031d10240300031d11240300021d12240200031d1124011d0200021d1024011d0400021d042401230118012301180624011d0600031d0a24021d0800041d0624021d0d00071d0700" }, { "filename": "head-wave", - "data": "0x00021c1401120004df05000e000adf03000c0002df014a0adf02000b0005df024a0243014a02df014a02df01000a0002df024a01df024a0143054a02df014a01df090002df024a01df024a01df034a01df0143024a03df090001df034a01df024a01df024a01df064a01df080002df024a01df024a01df034a01df024a0300014a01df080001df034a01df024a01df054a040001df0100070001df0d4a0600070001df0d4a0600060002df0d4a0600060001df0e4a0600050001df0f4a0600050001df0f4a0600040001df074a0143024a0143034a0143014a0600040001df044a01df024a0143034a0143034a0143014a050001df020001df044a01df044a0143034a0243054a0300010002df164a0100014a" + "data": "0x00021c1401120004de13000ade0f0002de014a0ade0d0005de024a0243014a02de014a02de0b0002de024a01de024a0143054a02de014a01de090002de024a01de024a01de034a01de0143024a03de090001de034a01de024a01de024a01de064a01de080002de024a01de024a01de034a01de024a0300014a01de080001de034a01de024a01de054a040001de080001de0d4a0d0001de0d4a0c0002de0d4a0c0001de0e4a0b0001de0f4a0b0001de0f4a0a0001de074a0143024a0143034a0143014a0a0001de044a01de024a0143034a0143034a0143014a050001de020001de044a01de044a0143034a0243054a040002de164a0100014a" }, { "filename": "head-weed", - "data": "0x00011d15020d00010f0d000c00020f0d000c00020f0100010f0b000b00040f0c000400010f0600040f0700010f04000400020f0600030f0100010f0400020f04000400030f0100010f0200050f0400030f04000500040f0200060f0100040f05000500050f0200040f0100050f05000600050f0100040f0100040f0600010f06000d0f0600010f0100020f0100010f03000b0f0500020f01000100040f0200130f01000200170f02000400130f040005000f0f07000900030f015c030f015c010f09000800050f035c030f080006000f0f06000500110f05000400020f0f00020f0400" + "data": "0x00011d15020d00010f1900020f1900020f0100010f1600040f1000010f0600040f0700010f0800020f0600030f0100010f0400020f0800030f0100010f0200050f0400030f0900040f0200060f0100040f0a00050f0200040f0100050f0b00050f0100040f0100040f0600010f06000d0f0600010f0100020f0100010f03000b0f0500020f0200040f0200130f0300170f0600130f09000f0f1000030f015c030f015c010f1100050f035c030f0e000f0f0b00110f0900020f0f00020f0400" }, { "filename": "head-weight", - "data": "0x00021a1405060001270896019505000600012701960727019505000600012701960600012701950500020003270d9601950200020003270396010e0196010e0196020e049601950200020003270396020e0296010e059601950200020003270396010e0196010e0196010e0196010e039601950200020003270396010e0196010e0296020e039601950200010003270f9601950100010003270f9601950100010003270f9601950100010003270f9601950100010003270f9601950100010003270f960195010003271196019503271196019503270496092704960195032711960195032711960195" + "data": "0x00021a140506000127089601950b0001270196072701950b0001270196060001270195070003270d960195040003270396010e0196010e0196020e04960195040003270396020e0296010e05960195040003270396010e0196010e0196010e0196010e03960195040003270396010e0196010e0296020e03960195030003270f960195020003270f960195020003270f960195020003270f960195020003270f960195020003270f960195010003271196019503271196019503270496092704960195032711960195032711960195" }, { "filename": "head-werewolf", - "data": "0x00061c1404030005970700059704000300059707000597040003000597070005970400030011260400030011070400030011260400030002970e8101970400030002970e8101970400020003970e8101970400010004970e810197040005971181029703000297018101d6018101d60f8102000397018101d6018101d60181042301010123010103230381010001000497018101d6018101d602230101062301010223018102000597018101d6018101d60c820300" + "data": "0x00061c1404030005970700059707000597070005970700059707000597070011260700110707001126070002970e810197070002970e810197060003970e810197050004970e810197040005971181029703000297018101d5018101d50f8102000397018101d5018101d5018104230102012301020323038102000497018101d5018101d502230102062301020223018102000597018101d5018101d50c820300" }, { "filename": "head-whale-alive", - "data": "0x00021e15021100044a07001000064a06000f00084a05000e000a4a04000d00064a010e054a0300014a0400014a0600064a010e014a010e054a0200024a0200024a05000f4a01560100064a05000f4a015601000100044a07000d4a03560200034a07000c4a04560200054a05000b4a055602000156134a065603000156114a0756030003560e4a07560100040005560a4a0856010004000656084a0856020005000556014a030e034a0856030006000356074a0856040007000156064a085606000a0009560900" + "data": "0x00021e15021100044a1700064a1500084a13000a4a1100064a010e054a0300014a0400014a0600064a010e014a010e054a0200024a0200024a05000f4a01560100064a05000f4a01560200044a07000d4a03560200034a07000c4a04560200054a05000b4a055602000156134a065603000156114a0756030003560e4a0756050005560a4a085605000656084a085607000556014a030e034a085609000356074a08560b000156064a0856100009560900" }, { "filename": "head-whale", - "data": "0x00041a1606080009d6030007000cd60100060005d6080d0100050005d6010d097c040005d6010d037c0281017c0281017c0181030005d6010d017c0281017c0281017c0281017c0181020005d6010d0481017c0281017c0281017c0181010005d6010d0581017c0281017c0281017c018106d6010d0581017c0281017c0281017c018106d6010d0581017c0281017c0281017c018106d6010d0581017c0281017c0281017c018106d6010d0481017c0381017c0281017c018106d6010d0381017c0381017c0381017c018103d6010d02d6010d0281017c0381017c0381017c028102d6030d01d602980181017c0281017c0381017c038103d6010d02d60398017c0281017c0281017c0381010006d60398017c0281017c0281017c02810200060003980b00060003980b00" + "data": "0x00041a1606080009d50a000cd5070005d5080d060005d5010d097c040005d5010d037c0281017c0281017c0181030005d5010d017c0281017c0281017c0281017c0181020005d5010d0481017c0281017c0281017c0181010005d5010d0581017c0281017c0281017c018106d5010d0581017c0281017c0281017c018106d5010d0581017c0281017c0281017c018106d5010d0581017c0281017c0281017c018106d5010d0481017c0381017c0281017c018106d5010d0381017c0381017c0381017c018103d5010d02d5010d0281017c0381017c0381017c028102d5030d01d502980181017c0281017c0381017c038103d5010d02d50398017c0281017c0281017c0381010006d50398017c0281017c0281017c028108000398110003980b00" }, { "filename": "head-wine", - "data": "0x00051b1405166f166f136f0101026f136f0101026f136f0101026f016f129401190194016f016f1494016f016f1494016f016f1494016f016f1494016f016f1494016f026f1294026f0100016f1294016f01000100026f069404190694026f01000200036f0c94036f020004000e6f0400" + "data": "0x00051b14053f6f0102156f0102156f0102036f129401190194026f1494026f1494026f1494026f1494026f1494036f1294026f0100016f1294016f0200026f069404190694026f0300036f0c94036f06000e6f0400" }, { "filename": "head-wizardhat", - "data": "0x00041b1404030008ec0c00020006ec014604ec0a00020001ec020002ec034604ec090002000146030002ec014606ec08000546020004ec014604ec070001000346040002ec014601ec014601ec014602ec06000100014601000146050002ec014606ec050009000aec0400080008ec014602ec0400080001ec014605ec034602ec0300080008ec014603ec0300080004ec014607ec030007000dec030006000eec0300050007ec050e02ec040003001254020001001654" + "data": "0x00041b1404030008eb0e0006eb014604eb0c0001eb020002eb034604eb0b000146030002eb014606eb08000546020004eb014604eb08000346040002eb014601eb014601eb014602eb0700014601000146050002eb014606eb0e000aeb0c0008eb014602eb0c0001eb014605eb034602eb0b0008eb014603eb0b0004eb014607eb0a000deb09000eeb080007eb050e02eb0700125403001654" }, { "filename": "head-zebra", - "data": "0x00061b14060a0001010123090001000223035e0101012301010123010102230100035e040001000201035e0101012301010123010101230200035e040001000223055e0123035e0123045e040001000201065e0323055e040001000223065e0323055e040001000201075e0123065e040001000223075e0123065e040001000201075e0123065e0400010002230e5e0400010002010c5e0623010002230d5e012301010123010101230301025e0101012301010123010101230101035e062303230d5e052303010d5e0523" - }, + "data": "0x00061b14060a00010201230a000223035e0102012301020123010202230100035e05000202035e0102012301020123010201230200035e05000223055e0123035e0123045e05000202065e0323055e05000223065e0323055e05000202075e0123065e05000223075e0123065e05000202075e0123065e050002230e5e050002020c5e0623010002230d5e012301020123010201230302025e0102012301020123010201230102035e09230d5e052303020d5e0523" + } + ], + "glasses": [ { - "filename": "head-thumbsup-reversed", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_000", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_001", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_002", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_003", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_004", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_005", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_006", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_007", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_008", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_009", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_010", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_011", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_012", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_013", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_014", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_015", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_016", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_017", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_018", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_019", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_020", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_021", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_022", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_023", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_024", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_025", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_026", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_027", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_028", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_029", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_030", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_031", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_032", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_033", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_034", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_035", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_036", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_037", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_038", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_039", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_040", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_041", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_042", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_043", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_044", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_045", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_046", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_047", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_048", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_049", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_050", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_051", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_052", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_053", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_054", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_055", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_056", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_057", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_058", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_059", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_060", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_061", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_062", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_063", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_064", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_065", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_066", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_067", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_068", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_069", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_070", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_071", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_072", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_073", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_074", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_075", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_076", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_077", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_078", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_079", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_080", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_081", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_082", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_083", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_084", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_085", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_086", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_087", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_088", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_089", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_090", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_091", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_092", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_093", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_094", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_095", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_096", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_097", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_098", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_099", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - } - ], - "glasses": [ - { - "filename": "glasses-hip-rose", - "data": "0x000b1710070300062001000620030001200201022301200100012002010223012004200201022303200201022301200420020102230320020102230120012002000120020102230120010001200201022301200300062001000620" + "filename": "glasses-hip-rose", + "data": "0x000b1710070300062001000620030001200202022301200100012002020223052002020223032002020223052002020223032002020223022002000120020202230120010001200202022301200300062001000620" }, { "filename": "glasses-square-black-eyes-red", - "data": "0x000b17100703000623010006230300012302010264012301000123020102640123042302010264032302010264012301230200012302010264012301000123020102640123012302000123020102640123010001230201026401230300062301000623" + "data": "0x000b17100703000623010006230300012302020264012301000123020202640523020202640323020202640223020001230202026401230100012302020264022302000123020202640123010001230202026401230300062301000623" }, { "filename": "glasses-square-black-rgb", - "data": "0x000b171007030006230100062303000323016402230100032301640223102301230200012301650223015a01230100012301650223015a0123012302000623010006230300062301000623" + "data": "0x000b1710070300062301000623030003230164022301000323016413230200012301650223015a01230100012301650223015a022302000623010006230300062301000623" }, { "filename": "glasses-square-black", - "data": "0x000b171007030006230100062303000123020103230100012302010323042302010523020103230123020001230201032301000123020103230123020001230201032301000123020103230300062301000623" + "data": "0x000b171007030006230100062303000123020203230100012302020723020205230202042302000123020203230100012302020423020001230202032301000123020203230300062301000623" }, { "filename": "glasses-square-blue-med-saturated", - "data": "0x000b17100703000643010006430300014302010223014301000143020102230143044302010223034302010223014301430200014302010223014301000143020102230143014302000143020102230143010001430201022301430300064301000643" + "data": "0x000b17100703000643010006430300014302020223014301000143020202230543020202230343020202230243020001430202022301430100014302020223024302000143020202230143010001430202022301430300064301000643" }, { "filename": "glasses-square-blue", - "data": "0x000b17100703000607010006070300010702010223010701000107020102230107040702010223030702010223010701070200010702010223010701000107020102230107010702000107020102230107010001070201022301070300060701000607" + "data": "0x000b17100703000607010006070300010702020223010701000107020202230507020202230307020202230207020001070202022301070100010702020223020702000107020202230107010001070202022301070300060701000607" }, { "filename": "glasses-square-frog-green", - "data": "0x000b171007030006c0010006c0030001c00201022301c0010001c00201022301c004c00201022303c00201022301c001c0020001c00201022301c0010001c00201022301c001c0020001c00201022301c0010001c00201022301c0030006c0010006c0" + "data": "0x000b171007030006bf010006bf030001bf0202022301bf010001bf0202022305bf0202022303bf0202022302bf020001bf0202022301bf010001bf0202022302bf020001bf0202022301bf010001bf0202022301bf030006bf010006bf" }, { "filename": "glasses-square-fullblack", - "data": "0x000b1710070300062301000623030004230101012301000423010101230723010106230101012301230200062301000623012302000623010006230300062301000623" + "data": "0x000b1710070300062301000623030004230102012301000423010208230102062301020223020006230100072302000623010006230300062301000623" }, { "filename": "glasses-square-green-blue-multi", - "data": "0x000b1710070300060f0100068b0300010f02010223010f0100018b02010223018b034a010f02010223010f014a018b02010223018b018b0200010f02010223010f0100018b02010223018b018b0200010f02010223010f0100018b02010223018b0300060f0100068b" + "data": "0x000b1710070300060f0100068b0300010f02020223010f0100018b02020223018b034a010f02020223010f014a018b02020223028b0200010f02020223010f0100018b02020223028b0200010f02020223010f0100018b02020223018b0300060f0100068b" }, { "filename": "glasses-square-grey-light", - "data": "0x000b171007030006c8010006c8030001c80201022301c8010001c80201022301c804c80201022303c80201022301c801c8020001c80201022301c8010001c80201022301c801c8020001c80201022301c8010001c80201022301c8030006c8010006c8" + "data": "0x000b171007030006c7010006c7030001c70202022301c7010001c70202022305c70202022303c70202022302c7020001c70202022301c7010001c70202022302c7020001c70202022301c7010001c70202022301c7030006c7010006c7" }, { "filename": "glasses-square-guava", - "data": "0x000b17100703000637010006370300013702010223013701000137020102230137043702010223033702010223013701370200013702010223013701000137020102230137013702000137020102230137010001370201022301370300063701000637" + "data": "0x000b17100703000637010006370300013702020223013701000137020202230537020202230337020202230237020001370202022301370100013702020223023702000137020202230137010001370202022301370300063701000637" }, { "filename": "glasses-square-honey", - "data": "0x000b171007030006de010006de030001de0201022301de010001de0201022301de04de0201022303de0201022301de01de020001de0201022301de010001de0201022301de01de020001de0201022301de010001de0201022301de030006de010006de" + "data": "0x000b171007030006dd010006dd030001dd0202022301dd010001dd0202022305dd0202022303dd0202022302dd020001dd0202022301dd010001dd0202022302dd020001dd0202022301dd010001dd0202022301dd030006dd010006dd" }, { "filename": "glasses-square-magenta", - "data": "0x000b17100703000609010006090300010902010223010901000109020102230109040902010223030902010223010901090200010902010223010901000109020102230109010902000109020102230109010001090201022301090300060901000609" + "data": "0x000b17100703000609010006090300010902020223010901000109020202230509020202230309020202230209020001090202022301090100010902020223020902000109020202230109010001090202022301090300060901000609" }, { "filename": "glasses-square-orange", - "data": "0x000b17100703000614010006140300011402010223011401000114020102230114041402010223031402010223011401140200011402010223011401000114020102230114011402000114020102230114010001140201022301140300061401000614" + "data": "0x000b17100703000614010006140300011402020223011401000114020202230514020202230314020202230214020001140202022301140100011402020223021402000114020202230114010001140202022301140300061401000614" }, { "filename": "glasses-square-pink-purple-multi", - "data": "0x000b171007030006200100069a030001200201022301200100019a02010223019a036e0120020102230120016e019a02010223019a019a020001200201022301200100019a02010223019a019a020001200201022301200100019a02010223019a030006200100069a" + "data": "0x000b171007030006200100069a030001200202022301200100019a02020223019a036e0120020202230120016e019a02020223029a020001200202022301200100019a02020223029a020001200202022301200100019a02020223019a030006200100069a" }, { "filename": "glasses-square-red", - "data": "0x000b17100703000624010006240300012402010223012401000124020102230124042402010223032402010223012401240200012402010223012401000124020102230124012402000124020102230124010001240201022301240300062401000624" + "data": "0x000b17100703000624010006240300012402020223012401000124020202230524020202230324020202230224020001240202022301240100012402020223022402000124020202230124010001240202022301240300062401000624" }, { "filename": "glasses-square-smoke", - "data": "0x000b17100703000659010006590300015902660223015901000159026602230159045902660223035902660223015901590200015902660223015901000159026602230159015902000159026602230159010001590266022301590300065901000659" + "data": "0x000b17100703000659010006590300015902660223015901000159026602230559026602230359026602230259020001590266022301590100015902660223025902000159026602230159010001590266022301590300065901000659" }, { "filename": "glasses-square-teal", - "data": "0x000b1710070300061c0100061c0300011c02010223011c0100011c02010223011c041c02010223031c02010223011c011c0200011c02010223011c0100011c02010223011c011c0200011c02010223011c0100011c02010223011c0300061c0100061c" + "data": "0x000b1710070300061c0100061c0300011c02020223011c0100011c02020223051c02020223031c02020223021c0200011c02020223011c0100011c02020223021c0200011c02020223011c0100011c02020223011c0300061c0100061c" }, { "filename": "glasses-square-watermelon", - "data": "0x000b17100703000637010006370300013702010223013701000137020102230137043702010223033702010223013701370200013702010223013701000137020102230137013702000137020102230137010001370201022301370300063701000637" + "data": "0x000b17100703000637010006370300013702020223013701000137020202230537020202230337020202230237020001370202022301370100013702020223023702000137020202230137010001370202022301370300063701000637" }, { "filename": "glasses-square-yellow-orange-multi", - "data": "0x000b17100703000626010006130300012602010223012601000113020102230113034201260201022301260142011302010223011301260200012602010223012601000113020102230113012602000126020102230126010001130201022301130300062601000613" + "data": "0x000b17100703000626010006130300012602020223012601000113020202230113034201260202022301260142011302020223011301260200012602020223012601000113020202230113012602000126020202230126010001130202022301130300062601000613" }, { "filename": "glasses-square-yellow-saturated", - "data": "0x000b17100703000628010006280300012802010223012801000128020102230128042802010223032802010223012801280200012802010223012801000128020102230128012802000128020102230128010001280201022301280300062801000628" - }, - { - "filename": "glasses-hip-rose-reversed_reversed", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_000", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_001", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_002", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_003", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_004", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_005", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_006", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_007", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_008", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_009", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_010", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_011", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_012", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_013", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_014", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_015", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_016", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_017", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_018", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_019", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_020", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_021", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_022", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_023", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_024", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_025", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_026", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_027", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_028", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_029", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_030", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_031", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_032", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_033", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_034", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_035", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_036", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_037", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_038", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_039", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_040", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_041", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_042", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_043", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_044", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_045", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_046", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_047", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_048", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_049", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_050", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_051", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_052", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_053", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_054", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_055", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_056", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_057", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_058", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_059", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_060", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_061", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_062", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_063", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_064", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_065", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_066", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_067", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_068", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_069", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_070", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_071", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_072", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_073", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_074", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_075", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_076", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_077", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_078", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_079", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_080", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_081", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_082", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_083", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_084", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_085", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_086", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_087", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_088", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_089", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_090", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_091", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_092", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_093", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_094", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_095", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_096", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_097", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_098", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_099", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" + "data": "0x000b17100703000628010006280300012802020223012801000128020202230528020202230328020202230228020001280202022301280100012802020223022802000128020202230128010001280202022301280300062801000628" } ] } -} +} \ No newline at end of file diff --git a/packages/nouns-contracts/files/image-data.json b/packages/nouns-contracts/files/image-data-v1.json similarity index 100% rename from packages/nouns-contracts/files/image-data.json rename to packages/nouns-contracts/files/image-data-v1.json diff --git a/packages/nouns-assets/src/image-data_v2.json b/packages/nouns-contracts/files/image-data-v2.json similarity index 100% rename from packages/nouns-assets/src/image-data_v2.json rename to packages/nouns-contracts/files/image-data-v2.json diff --git a/packages/nouns-contracts/files/image-data_v2.json b/packages/nouns-contracts/files/image-data_v2.json deleted file mode 100644 index a63cb77239..0000000000 --- a/packages/nouns-contracts/files/image-data_v2.json +++ /dev/null @@ -1,1945 +0,0 @@ -{ - "bgcolors": [ - "d5d7e1", - "e1d7d5" - ], - "palette": [ - "", - "c5b9a1", - "ffffff", - "cfc2ab", - "63a0f9", - "807f7e", - "caeff9", - "5648ed", - "5a423f", - "b9185c", - "b87b11", - "fffdf2", - "4b4949", - "343235", - "1f1d29", - "068940", - "867c1d", - "ae3208", - "9f21a0", - "f98f30", - "fe500c", - "d26451", - "fd8b5b", - "5a65fa", - "d22209", - "e9265c", - "c54e38", - "80a72d", - "4bea69", - "34ac80", - "eed811", - "62616d", - "ff638d", - "8bc0c5", - "c4da53", - "000000", - "f3322c", - "ffae1a", - "ffc110", - "505a5c", - "ffef16", - "fff671", - "fff449", - "db8323", - "df2c39", - "f938d8", - "5c25fb", - "2a86fd", - "45faff", - "38dd56", - "ff3a0e", - "d32a09", - "903707", - "6e3206", - "552e05", - "e8705b", - "f38b7c", - "e4a499", - "667af9", - "648df9", - "7cc4f2", - "97f2fb", - "a3efd0", - "87e4d9", - "71bde4", - "ff1a0b", - "f78a18", - "2b83f6", - "d62149", - "834398", - "ffc925", - "d9391f", - "bd2d24", - "ff7216", - "254efb", - "e5e5de", - "00a556", - "c5030e", - "abf131", - "fb4694", - "e7a32c", - "fff0ee", - "009c59", - "0385eb", - "00499c", - "e11833", - "26b1f3", - "fff0be", - "d8dadf", - "d7d3cd", - "1929f4", - "eab118", - "0b5027", - "f9f5cb", - "cfc9b8", - "feb9d5", - "f8d689", - "5d6061", - "76858b", - "757576", - "ff0e0e", - "0adc4d", - "fdf8ff", - "70e890", - "f7913d", - "ff1ad2", - "ff82ad", - "535a15", - "fa6fe2", - "ffe939", - "ab36be", - "adc8cc", - "604666", - "f20422", - "abaaa8", - "4b65f7", - "a19c9a", - "58565c", - "da42cb", - "027c92", - "cec189", - "909b0e", - "74580d", - "027ee6", - "b2958d", - "efad81", - "7d635e", - "eff2fa", - "6f597a", - "d4b7b2", - "d18687", - "cd916d", - "6b3f39", - "4d271b", - "85634f", - "f9f4e6", - "f8ddb0", - "b92b3c", - "d08b11", - "257ced", - "a3baed", - "5fd4fb", - "c16710", - "a28ef4", - "3a085b", - "67b1e3", - "1e3445", - "ffd067", - "962236", - "769ca9", - "5a6b7b", - "7e5243", - "a86f60", - "8f785e", - "cc0595", - "42ffb0", - "d56333", - "b8ced2", - "f39713", - "e8e8e2", - "ec5b43", - "235476", - "b2a8a5", - "d6c3be", - "49b38b", - "fccf25", - "f59b34", - "375dfc", - "99e6de", - "27a463", - "554543", - "b19e00", - "d4a015", - "9f4b27", - "f9e8dd", - "6b7212", - "9d8e6e", - "4243f8", - "fa5e20", - "f82905", - "555353", - "876f69", - "410d66", - "552d1d", - "f71248", - "fee3f3", - "c16923", - "2b2834", - "0079fc", - "d31e14", - "f83001", - "8dd122", - "fffdf4", - "ffa21e", - "e4afa3", - "fbc311", - "aa940c", - "eedc00", - "fff006", - "9cb4b8", - "a38654", - "ae6c0a", - "2bb26b", - "e2c8c0", - "f89865", - "f86100", - "dcd8d3", - "049d43", - "d0aea9", - "f39d44", - "eeb78c", - "f9f5e9", - "5d3500", - "c3a199", - "aaa6a4", - "caa26a", - "fde7f5", - "fdf008", - "fdcef2", - "f681e6", - "018146", - "d19a54", - "9eb5e1", - "f5fcff", - "3f9323", - "00fcff", - "4a5358", - "fbc800", - "d596a6", - "ffb913", - "e9ba12", - "767c0e", - "f9f6d1", - "d29607", - "f8ce47", - "395ed1", - "ffc5f0", - "cbc1bc", - "d4cfc0" - ], - "images": { - "bodies": [ - { - "filename": "body-bege-bsod", - "data": "0x0015171f093a0101000d0101000d0101000d0101000d0101000d0101000d0101000b01" - }, - { - "filename": "body-bege-crt", - "data": "0x0015171f093a0301000d0301000d0301000d0301000d0301000d0301000d0301000b03" - }, - { - "filename": "body-blue-sky", - "data": "0x0015171f093a0401000d0401000d0401000d0401000d0401000d0401000d0401000b04" - }, - { - "filename": "body-bluegrey", - "data": "0x0015171f093a0501000d0501000d0501000d0501000d0501000d0501000d0501000b05" - }, - { - "filename": "body-cold", - "data": "0x0015171f093a0601000d0601000d0601000d0601000d0601000d0601000d0601000b06" - }, - { - "filename": "body-computerblue", - "data": "0x0015171f093a0701000d0701000d0701000d0701000d0701000d0701000d0701000b07" - }, - { - "filename": "body-darkbrown", - "data": "0x0015171f093a0801000d0801000d0801000d0801000d0801000d0801000d0801000b08" - }, - { - "filename": "body-darkpink", - "data": "0x0015171f093a0901000d0901000d0901000d0901000d0901000d0901000d0901000b09" - }, - { - "filename": "body-foggrey", - "data": "0x0015171f093a0301000d0301000d0301000d0301000d0301000d0301000d0301000b03" - }, - { - "filename": "body-gold", - "data": "0x0015171f093a0a01000d0a01000d0a01000d0a01000d0a01000d0a01000d0a01000b0a" - }, - { - "filename": "body-grayscale-1", - "data": "0x0015171f093a0b01000d0b01000d0b01000d0b01000d0b01000d0b01000d0b01000b0b" - }, - { - "filename": "body-grayscale-7", - "data": "0x0015171f093a0c01000d0c01000d0c01000d0c01000d0c01000d0c01000d0c01000b0c" - }, - { - "filename": "body-grayscale-8", - "data": "0x0015171f093a0d01000d0d01000d0d01000d0d01000d0d01000d0d01000d0d01000b0d" - }, - { - "filename": "body-grayscale-9", - "data": "0x0015171f093a0e01000d0e01000d0e01000d0e01000d0e01000d0e01000d0e01000b0e" - }, - { - "filename": "body-green", - "data": "0x0015171f093a0f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f01000b0f" - }, - { - "filename": "body-gunk", - "data": "0x0015171f093a1001000d1001000d1001000d1001000d1001000d1001000d1001000b10" - }, - { - "filename": "body-hotbrown", - "data": "0x0015171f093a1101000d1101000d1101000d1101000d1101000d1101000d1101000b11" - }, - { - "filename": "body-magenta", - "data": "0x0015171f093a1201000d1201000d1201000d1201000d1201000d1201000d1201000b12" - }, - { - "filename": "body-orange-yellow", - "data": "0x0015171f093a1301000d1301000d1301000d1301000d1301000d1301000d1301000b13" - }, - { - "filename": "body-orange", - "data": "0x0015171f093a1401000d1401000d1401000d1401000d1401000d1401000d1401000b14" - }, - { - "filename": "body-peachy-B", - "data": "0x0015171f093a1501000d1501000d1501000d1501000d1501000d1501000d1501000b15" - }, - { - "filename": "body-peachy-a", - "data": "0x0015171f093a1601000d1601000d1601000d1601000d1601000d1601000d1601000b16" - }, - { - "filename": "body-purple", - "data": "0x0015171f093a1701000d1701000d1701000d1701000d1701000d1701000d1701000b17" - }, - { - "filename": "body-red", - "data": "0x0015171f093a1801000d1801000d1801000d1801000d1801000d1801000d1801000b18" - }, - { - "filename": "body-redpinkish", - "data": "0x0015171f093a1901000d1901000d1901000d1901000d1901000d1901000d1901000b19" - }, - { - "filename": "body-rust", - "data": "0x0015171f093a1a01000d1a01000d1a01000d1a01000d1a01000d1a01000d1a01000b1a" - }, - { - "filename": "body-slimegreen", - "data": "0x0015171f093a1b01000d1b01000d1b01000d1b01000d1b01000d1b01000d1b01000b1b" - }, - { - "filename": "body-teal-light", - "data": "0x0015171f093a1c01000d1c01000d1c01000d1c01000d1c01000d1c01000d1c01000b1c" - }, - { - "filename": "body-teal", - "data": "0x0015171f093a1d01000d1d01000d1d01000d1d01000d1d01000d1d01000d1d01000b1d" - }, - { - "filename": "body-yellow", - "data": "0x0015171f093a1e01000d1e01000d1e01000d1e01000d1e01000d1e01000d1e01000b1e" - } - ], - "accessories": [ - { - "filename": "accessory-1n", - "data": "0x0017141e0d0100011f0500021f0600011f0300011f0200011f0200011f0500011f0500011f0200021f0100011f0200011f0100011f0400011f0100011f" - }, - { - "filename": "accessory-aardvark", - "data": "0x0018151a0d02000320010001200200052002000120010001200100012001000220" - }, - { - "filename": "accessory-axe", - "data": "0x0017141d0e010205210102042101000102032102000102012101000121020001020200012105000121050001210200" - }, - { - "filename": "accessory-belly-chameleon", - "data": "0x0017121e0d0100012201000122060002220100022205000222010002220500022201000122020001220300" - }, - { - "filename": "accessory-bird-flying", - "data": "0x0018151a0d0100022302000223010001230200022302000123030002230300" - }, - { - "filename": "accessory-bird-side", - "data": "0x0017131c0d040001240400022401000424012301250100042403000324020001240400" - }, - { - "filename": "accessory-bling-anchor", - "data": "0x0015141d0d0126050001260100012603000126030001260100012605000126060001260500032605000126040001260100012601000126030003260200" - }, - { - "filename": "accessory-bling-anvil", - "data": "0x0015161e0b012709000127010001270700012703000127050001270500012703000127070003270900010d0700020d05270500020d03270700030d0700020d03270300" - }, - { - "filename": "accessory-bling-arrow", - "data": "0x0018141e0d04000326050002260400012601000126030001260400022604000326050001260500" - }, - { - "filename": "accessory-bling-cheese", - "data": "0x0015141e0c0126060001260100012604000126030001260200012605000226050001260200012603000626030001260128012601280126040004260500012601280126060002260100" - }, - { - "filename": "accessory-bling-gold-ingot", - "data": "0x0015141b0c0126060001260100012604000126030001260200012605000226040006290200042602290200042602290100" - }, - { - "filename": "accessory-bling-love", - "data": "0x0015141d0c0126060001260100012604000126030001260200012605000226050001260200012603000126012804260200062603000426050002260300" - }, - { - "filename": "accessory-bling-mask", - "data": "0x0015141e0c012606000126010001260400012603000126020001260500022604000626020001260100022601000126020006260300042603000126010002260100012602000126040001260100" - }, - { - "filename": "accessory-bling-rings", - "data": "0x0017141d0d0300032a0300012a0300012a0100032a0200022a0100012a0100012a0100022a0200032a0100012a0300012a0300032a0300" - }, - { - "filename": "accessory-bling-scissors", - "data": "0x0016131c0e012b0300022b0300012b0100012b0100012b0200012b0100012b0300012b0200022b0100042b0100022b" - }, - { - "filename": "accessory-bling-sparkles", - "data": "0x0016141d0c01000126060003260100012602000126010001260200012606000326030007260300032606000126070001260300" - }, - { - "filename": "accessory-body-gradient-checkerdisco", - "data": "0x0015171f09022c0223022c0223022c0223042c0223022c0223022c0223022c0223022d0223022d0223022d0423022d0223022d0223022d0223022e01000123022e0223022e0223042e01000123022e0223022e0223022e02230100012f0223022f0223022f04230100012f0223022f0223022f022302300100012302300223023002230430010001230230022302300223023002230100013102230231022302310223" - }, - { - "filename": "accessory-body-gradient-dawn", - "data": "0x0015171f091c321c33021101000d1101000b11023401000d3401000b34023501000d3501000b35023601000b36" - }, - { - "filename": "accessory-body-gradient-dusk", - "data": "0x0015171f091c321c24023701000d3701000d3701000d3701000b37023801000d3801000b38023901000b39" - }, - { - "filename": "accessory-body-gradient-glacier", - "data": "0x0015171f090f3a013b013a013b013a013b013a013b013a013b013a013b013a103b0104013b0104013b0104013b0104013b0104013b0104013b030401000d0401000d0401000c04013c0100013c0104013c0104013c0104013c0104013c0104033c01000c3c013d0100013d013c013d013c013d013c013d013c013d013c033d01000b3d" - }, - { - "filename": "accessory-body-gradient-ice", - "data": "0x0015171f091c3e1e3f01000d3f01000b3f023c01000d3c01000d3c01000d3c01000b3c024001000b40" - }, - { - "filename": "accessory-body-gradient-pride", - "data": "0x0015171f091c411c42022a01000d2a01000b2a020f01000d0f01000b0f024301000d4301000b43021201000b12" - }, - { - "filename": "accessory-body-gradient-redpink", - "data": "0x0015171f092a44100901000d0901000d0901000d0901000d0901000b09024501000d4501000b45" - }, - { - "filename": "accessory-body-gradient-sunset", - "data": "0x0015171f092a460e25024201000b42021401000b14024701000d4701000b47024801000d4801000d4801000b48" - }, - { - "filename": "accessory-carrot", - "data": "0x0018131d0e0200011d0100011d0300011d030002490200024903000149030001490400" - }, - { - "filename": "accessory-chain-logo", - "data": "0x0018171c09012601000326010003260100032602000126030001260300012603000326020003260100032601000226010001260300012603000126030002260200022601000326010003260100" - }, - { - "filename": "accessory-checker-RGB", - "data": "0x0015171f090224021c024a0224021c024a0424021c024a0224021c024a0224024a0224021c024a0224021c044a0224021c024a0224021c024a021c0100014a0224021c024a0224041c0100014a0224021c024a0224021c02240100011c024a0224021c024a04240100011c024a0224021c024a0224024a01000124021c024a0224021c044a01000124021c024a0224021c024a021c0100014a0224021c024a0224021c" - }, - { - "filename": "accessory-checker-bigwalk-blue-prime", - "data": "0x0015171f090400030701000307010005070100030701000307030003070100030707000307070003070700030701000307040002070100030701000307010001070200020701000307050001070200020707000307070003070100020704000307010003070100040702000307010003070300" - }, - { - "filename": "accessory-checker-bigwalk-greylight", - "data": "0x0015171f090400034b0100034b0100054b0100034b0100034b0300034b0100034b0700034b0700034b0700034b0100034b0400024b0100034b0100034b0100014b0200024b0100034b0500014b0200024b0700034b0700034b0100024b0400034b0100034b0100044b0200034b0100034b0300" - }, - { - "filename": "accessory-checker-bigwalk-rainbow", - "data": "0x0015171f090400034c010003460100021403120100034c01000346030003120100034c040006120400034d01000312030003140100034d010003120246010003140100034d040002460100031404000346010002460400034c01000346040002120100034c010003460100014d020002120100034c04000112014d020002120400034d01000112" - }, - { - "filename": "accessory-checker-spaced-black", - "data": "0x0015171f09030002230400022306000223040002231100022304000223040004230400022304000223110002230400022306000223040002231100022304000223040004230400022304000223" - }, - { - "filename": "accessory-checker-spaced-white", - "data": "0x0015171f09030002020400020206000202040002021100020204000202040004020400020204000202110002020400020206000202040002021100020204000202040004020400020204000202" - }, - { - "filename": "accessory-checker-vibrant", - "data": "0x0015171f09024e0243024f024e0243024f044e0243024f024e0243024f024e024f024e0243024f024e0243044f024e0243024f024e0243024f02430100014f024e0243024f024e04430100014f024e0243024f024e0243024e01000143024f024e0243024f044e01000143024f024e0243024f024e024f0100014e0243024f024e0243044f0100014e0243024f024e0243024f02430100014f024e0243024f024e0243" - }, - { - "filename": "accessory-checkers-big-green", - "data": "0x0015171f09030f0300030f0300050f0300030f0300050f0300030f0300020f0300030f0300030f0500030f0300030f0500030f0300030f0200020f0400030f0300040f0400030f0300040f0400030f0300020f0300030f0300030f0500030f0300030f0200" - }, - { - "filename": "accessory-checkers-big-red-cold", - "data": "0x0015171f09031903000319030005190300031903000519030003190300021903000319030003190500031903000319050003190300031902000219040003190300041904000319030004190400031903000219030003190300031905000319030003190200" - }, - { - "filename": "accessory-checkers-black", - "data": "0x0015171f09020002230200022302000223040002230200022302000223020002230200022302000223020004230200022302000223020002230300012302000223020002230500012302000223020002230200022302000223020002230200042302000223020002230200022303000123020002230200022305000123020002230200022302000223020002230200022302000223" - }, - { - "filename": "accessory-checkers-blue", - "data": "0x0015171f09024a0200024a0200024a0200044a0200024a0200024a0200024a0200024a0200024a0200024a0400024a0200024a0200024a0200024a0200024a0200024a0200044a0200024a0200024a0200024a0300014a0200024a0200024a0500014a0200024a0200024a0200024a0200024a0200024a0200044a0200024a0200024a0200024a0300014a0200024a0200024a0200" - }, - { - "filename": "accessory-checkers-magenta-80", - "data": "0x0015171f09020002200200022002000220040002200200022002000220020002200200022002000220020004200200022002000220020002200300012002000220020002200500012002000220020002200200022002000220020002200200042002000220020002200200022003000120020002200200022005000120020002200200022002000220020002200200022002000220" - }, - { - "filename": "accessory-chicken", - "data": "0x0018131d0d0300024701000202020001020150010004020300020204000102050001500300" - }, - { - "filename": "accessory-cloud", - "data": "0x0018131a0d0200030202000b02" - }, - { - "filename": "accessory-clover", - "data": "0x0017151e0d0200021d0600031d0400011d0100011d0100021d0100031d0100031d0100021d0100011d0100011d0400031d0500021d0100011d0800021d" - }, - { - "filename": "accessory-collar-sunset", - "data": "0x00151717090e190e260e42" - }, - { - "filename": "accessory-cow", - "data": "0x0018141c0d05000151020003510123015101380151010001510123025101000151010001510238015103000151020001510100" - }, - { - "filename": "accessory-decay-gray-dark", - "data": "0x0015171f090e27020006270300032702000b2702000927010002270100022701000127010003270200062701000827030001270200012702000327080008270600012704000227010002270200012701000b2703000b27" - }, - { - "filename": "accessory-decay-pride", - "data": "0x0015171f090e27024106270341032702420b2702420927014202270142022701000127012a0327022a062701000827032a0127010f01000127020f0327070f01000827030f02430100012704430227014302270243012701000b27021201000b27" - }, - { - "filename": "accessory-dinosaur", - "data": "0x0017131d0d0200035203000152010001520300045202000352010001520100035201000652030001520200" - }, - { - "filename": "accessory-dollar-bling", - "data": "0x0015141e0c012606000226060001260100012604000126030004260500022605000426040002260800022604000426050002260300" - }, - { - "filename": "accessory-dragon", - "data": "0x0017141e0d020f0100030f0200030f0100040f0300010f0400030f0200020f0400010f0300020f0200030f0200010f0200010f0400" - }, - { - "filename": "accessory-ducky", - "data": "0x0018131a0e012801000228020003280114010003280100" - }, - { - "filename": "accessory-eth", - "data": "0x0018131d0e020001530400015303000153015401530100055401000353030001530200" - }, - { - "filename": "accessory-eye", - "data": "0x0018151c0d020004540300015401000254010001540100015402000254020001540100015404000154030004540200" - }, - { - "filename": "accessory-flash", - "data": "0x0017151d0d010001020800020207000302020008020200030207000202080001020100" - }, - { - "filename": "accessory-fries", - "data": "0x0017131d0e0126010a0126010a0226010a0126010a01260655032602550226035501260855" - }, - { - "filename": "accessory-glasses-logo-sun", - "data": "0x0018161a0d072302000323010008230100032301000123" - }, - { - "filename": "accessory-glasses-logo", - "data": "0x0018161a0d0756020001560100015601000156010006560100035601000156" - }, - { - "filename": "accessory-glasses", - "data": "0x0017141d0d0856010002560100025602000256010002560700081d0100021d0100021d0200021d0100021d" - }, - { - "filename": "accessory-grid-simple-bege", - "data": "0x0016171e090157010001570100015701000157010001570100015701000157100001570100015701000157010001570100015701000157010001570e0001570300015701000157010001570100015701000157100001570100015701000157010001570100015701000157010001570e00015703000157010001570100015701000157010001570100" - }, - { - "filename": "accessory-heart", - "data": "0x0018141d0d010002580100025801000e580100055803000358050001580300" - }, - { - "filename": "accessory-hoodiestrings-uneven", - "data": "0x0016121b0f0102010002020100020201000202010001590102020001590200" - }, - { - "filename": "accessory-id", - "data": "0x0017151a1002000102020005260a02" - }, - { - "filename": "accessory-infinity", - "data": "0x0017141e0d0100020b0400010b0200010b0300010b0700030b0600030b0700010b0300010b0200010b0400020b0100" - }, - { - "filename": "accessory-insignia", - "data": "0x0016131d0e0200015b0300015b012b015b0300015b0300035b0100015b032b035b022b025b032b015b0100035b0100" - }, - { - "filename": "accessory-leaf", - "data": "0x0018141d0d0300045c0200055c0200055c0200055c0200045c0100025c0500" - }, - { - "filename": "accessory-lightbulb", - "data": "0x0017121c0e0c5d0100025d0200025e0200025e0100" - }, - { - "filename": "accessory-lines-45-greens", - "data": "0x0015171f090200010f0200010f0200010f0200010f0200015c0200015c0200015c0200015c0200015c0200010f0200010f0200010f0200010f0200010f0200015c0200015c0200015c0200015c0200010f0200010f0200010f0200010f0200010f0200015c0200015c0200015c0200015c0200015c0500010f0200010f0200010f0200015c0200015c0200015c0200015c0200015c0200010f0200010f0200010f0200010f0200010f0500015c0200015c0200015c0200010f0200010f0200010f0200010f0200010f0100" - }, - { - "filename": "accessory-lines-45-rose", - "data": "0x0015171f090200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0500015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0500015f0200015f0200015f0200015f0200015f0200015f0200015f0200015f0100" - }, - { - "filename": "accessory-lp", - "data": "0x0016161e0d03000323040007230200072301000323030206230102010001020623030203230100072302000723040003230300" - }, - { - "filename": "accessory-marsface", - "data": "0x0018131d0e0400032301000223030002230200032303000723" - }, - { - "filename": "accessory-matrix-white", - "data": "0x0018131c0e010b0100010b0100010b0500010b0100010b0100010b0500010b0100010b0100010b" - }, - { - "filename": "accessory-moon-block", - "data": "0x0017131d0e0660010001600100016001000160010001600100016001000160010001600100016001000160010003600100026001000360" - }, - { - "filename": "accessory-none", - "data": "0x0000000000" - }, - { - "filename": "accessory-oldshirt", - "data": "0x0015171f09206107581161026201000261035802610158056101000161015803610258046102620100036101580961010001610258016104580361026201000d610100016107580361026201000b61" - }, - { - "filename": "accessory-pizza-bling", - "data": "0x0015141d0c012606000126010001260400012603000126020001260500022606000226050004260400042603000626020006260100" - }, - { - "filename": "accessory-pocket-pencil", - "data": "0x0017151910010001370400010203000563" - }, - { - "filename": "accessory-rain", - "data": "0x0018131d0e04000143010001430200014301000143060001430100014302000143010001430400" - }, - { - "filename": "accessory-rainbow-steps", - "data": "0x0017171c090b000312070004180312030004140418031202460100041404180300024601000414070002460c00" - }, - { - "filename": "accessory-rgb", - "data": "0x0018151e0d030002640500046404000464030002650264025a01000465045a0465045a010002650200025a0100" - }, - { - "filename": "accessory-robot", - "data": "0x0019171b090123020001230200012302000123020001230f00022301000b23" - }, - { - "filename": "accessory-safety-vest", - "data": "0x0015171f0b0413030009130300091303000913030005130100036603000566010003660300056601000366030005660100036603000566010003130300051301000313030005130100031303000513" - }, - { - "filename": "accessory-scarf-clown", - "data": "0x0015151f0c031c0300061c0300061c0300031c0323030006230300062303000323031c0300061c0300061c0300031c03230300062303000323" - }, - { - "filename": "accessory-secret-x", - "data": "0x0018121b0e01670200016701000267020002670100016702000167" - }, - { - "filename": "accessory-shirt-black", - "data": "0x0015151f0c0e23010005230100022302000323020001230168030001230300022307000223070002230700022307000123016807000223070002230400" - }, - { - "filename": "accessory-shrimp", - "data": "0x0018121c0e0100025f0100035f0100025f0300015f0220020001200100" - }, - { - "filename": "accessory-slimesplat", - "data": "0x0017121d0d0200014e0100024e0100024e0200034e0200024e0100024e0100014e0500014e0200014e0300" - }, - { - "filename": "accessory-small-bling", - "data": "0x001514170d0126050001260100012603000126030003260200" - }, - { - "filename": "accessory-snowflake", - "data": "0x0017141d0d010001020300010201000202010001020100020202000302030005020300030202000202010001020100020201000102030001020100" - }, - { - "filename": "accessory-stains-blood", - "data": "0x0016151d0d05000219030001190100041904000419050002190100011901000219060002190d0001190600" - }, - { - "filename": "accessory-stains-zombie", - "data": "0x0017151e0d0100010f1000020f0400010f0100020f0900020f0500040f0200010f0100040f0500020f0100" - }, - { - "filename": "accessory-stripes-and-checks", - "data": "0x0015171f090e690e430e280e1c020201000123020202230202022304020100012302020223020202230202022301000102022302020223020204230100010202230202022302020223026901000b69024301000b43022801000b28" - }, - { - "filename": "accessory-stripes-big-red", - "data": "0x0015171d092a242a00022401000d2401000d2401000b24" - }, - { - "filename": "accessory-stripes-blit", - "data": "0x0015171b092a5a0e00026a01000b6a0e00022a01000b2a" - }, - { - "filename": "accessory-stripes-blue-med", - "data": "0x0015171f090e430e000e430e00024301000b430e00024301000b430e00024301000b430e00024301000b43" - }, - { - "filename": "accessory-stripes-brown", - "data": "0x0015171f090e350e000e350e00023501000b350e00023501000b350e00023501000b350e00023501000b35" - }, - { - "filename": "accessory-stripes-olive", - "data": "0x0015171f090e6b0e000e6b0e00026b01000b6b0e00026b01000b6b0e00026b01000b6b0e00026b01000b6b" - }, - { - "filename": "accessory-stripes-red-cold", - "data": "0x0015171f090e190e000e190e00021901000b190e00021901000b190e00021901000b190e00021901000b19" - }, - { - "filename": "accessory-sunset", - "data": "0x0017141a0d03000126040001260300012603000326020001260100032601000126" - }, - { - "filename": "accessory-taxi-checkers", - "data": "0x0017171a090266020d0266020d0266020d0466020d0266020d0266020d0266020d01000166020d0266020d0266040d01000166020d0266020d0266020d" - }, - { - "filename": "accessory-tee-yo", - "data": "0x0015171f09022802000128040001280300032803000428040004280900052809000428020001280100012803000128010004280300012801000228010001280100042803000128010002280300042808000128010004280a0004280a0004280a000228" - }, - { - "filename": "accessory-text-yolo", - "data": "0x0017131d0d014e0100014e010002570100014e020002570100014e02000257060001570200024e010001570200024e010002570100024e0100" - }, - { - "filename": "accessory-think", - "data": "0x0018131c0e0302020003020900010206000102" - }, - { - "filename": "accessory-tie-black-on-white", - "data": "0x0015121f0e0423014b0223024b0223024b0223024b0223024b0223024b0223024b0223024b0223024b0223024b0223014b" - }, - { - "filename": "accessory-tie-dye", - "data": "0x0016151f0b0200023b0100016c0200016c0100013b0100033b0200016c0300013b0300013b0200026c0300026d0100013b0100026c0200016d0100011c016d013b0100016c0200016d0100011c016c013b0100016c0100011c0100016d0100011c0100026c0400016d0200011c0300011c0300016d0200031c0100011c0100016d0200016d0100021c0200" - }, - { - "filename": "accessory-tie-purple-on-white", - "data": "0x0015121f0e046e014b026e024b026e024b026e024b026e024b026e024b026e024b026e024b026e024b026e024b026e014b" - }, - { - "filename": "accessory-tie-red", - "data": "0x0016111e0f044102000c41" - }, - { - "filename": "accessory-txt-a2+b2", - "data": "0x0017151d0d0200016f0500026f0600026f0100016f0600036f0600016f0100016f0100016f0500026f0600026f0100" - }, - { - "filename": "accessory-txt-cc", - "data": "0x0017151d0c01000770010001700700027001000270010002700100027001000170020001700200027001000270010002700100027007000170010007700100" - }, - { - "filename": "accessory-txt-cc2", - "data": "0x0017141c0d037101000471030001710200017103000171020001710300017102000171030001710200037101000371" - }, - { - "filename": "accessory-txt-copy", - "data": "0x0017131d0d027201000272010001720200027201000272010002720700027201000172010003720100027201000172020001720200" - }, - { - "filename": "accessory-txt-dao-black", - "data": "0x0018151b0c022302000123020001230100012301000223010002230100022301000523010003230100012301000123010001230100" - }, - { - "filename": "accessory-txt-doom", - "data": "0x0016161d0b0200012308000323080001230100032307000223010003230700022301000323070002230100032308000123010001230a000123" - }, - { - "filename": "accessory-txt-dope-text", - "data": "0x0017131d0d010001730200017301000273010001730100037302000173070002730100017302000273010002730100017302000373" - }, - { - "filename": "accessory-txt-foo-black", - "data": "0x0019151b0d05230100042301000223010003230200022301000223" - }, - { - "filename": "accessory-txt-ico", - "data": "0x0019171d09027401000d7401000d7401000d7401000d7401000b74" - }, - { - "filename": "accessory-txt-io", - "data": "0x0018131c0d0156030001560100015602000156020001560100015601000256010001560200035603000256" - }, - { - "filename": "accessory-txt-lmao", - "data": "0x0017131d0d013e0300033e0200023e0100023e0100013e0900013e0200033e0100013e0100033e0100013e0100023e" - }, - { - "filename": "accessory-txt-lol", - "data": "0x001715190d01020200020201000102010001020200020201000102010002020100020201000202" - }, - { - "filename": "accessory-txt-mint", - "data": "0x0016141c0d06000114070002140100011402000214010001140100011401000114070002140200041401000114020001140100" - }, - { - "filename": "accessory-txt-nil-grey-dark", - "data": "0x0018151a0d037501000175010001750100017501000175010001750100017501000175010001750100017501000275" - }, - { - "filename": "accessory-txt-noun-f0f", - "data": "0x0017131e0d0100026901000169020001690100026907000269010001690100036901000369070002690100016902000169010002690100" - }, - { - "filename": "accessory-txt-noun-green", - "data": "0x0017131e0d0100023e0100013e0200013e0100023e0700023e0100013e0100033e0100033e0700023e0100013e0200013e0100023e0100" - }, - { - "filename": "accessory-txt-noun-multicolor", - "data": "0x0017131e0d010002170100011702000117010002170700027601000114010001140276010003140700020f0100010f0200010f0100020f0100" - }, - { - "filename": "accessory-txt-noun", - "data": "0x0016131d0d0100026c0100016c0200016c0100026c0700026c0100016c0100036c0100036c0700026c0100016c0200016c0100026c0100" - }, - { - "filename": "accessory-txt-pi", - "data": "0x0018131b0d0100061f0100011f0100011f0300011f0100011f0300011f0200011f" - }, - { - "filename": "accessory-txt-pop", - "data": "0x0017131d0d0228040002280400012801000228040002280600022804000228040001280100" - }, - { - "filename": "accessory-txt-rofl", - "data": "0x0017131d0d02020200027702020200027701020100010201000277060003370100012601000237020001260100013703000226" - }, - { - "filename": "accessory-txt-we", - "data": "0x0018151d0c0700011c050001560100011c0100011c02000156010001560100031c015601000156010001560100011c0200015601000156010001560200011c02000156010001560500" - }, - { - "filename": "accessory-txt-yay", - "data": "0x0018151a0c0143010001430100011c0100014301000143010001430100031c01000143020001430100011c0100011c010001430100" - }, - { - "filename": "accessory-wall", - "data": "0x0015171f090a0001620d0001620300026201000b62040001620d0001620900026201000462010006620a0001620d0001620300026201000b62040001620d0001620900" - }, - { - "filename": "accessory-wave", - "data": "0x0017151b0d01000356040002560200015605000156020001560400015603000256010001560600" - }, - { - "filename": "accessory-wet-money", - "data": "0x0018141e0d01780279017805790178017a017804790178017a01780579017802790178010001040100010401000104020001040a0001040100" - }, - { - "filename": "accessory-woolweave-bicolor", - "data": "0x0015171f09037b010003140100037b0100027b0e00017b010003140100037b01000314020001140300017b030001140300017b01140200027b010003140100037b0f00027b020003140100037b01000214030001140300017b030001140200017b01140200037b010003140100027b0e00017b0200027b010003140100037b0100" - }, - { - "filename": "accessory-woolweave-dirt", - "data": "0x0015171f09037c0100037c0100037c0100027c0e00017c0100037c0100037c0100037c0200017c0300017c0300017c0300027c0200027c0100037c0100037c0f00027c0200037c0100037c0100027c0300017c0300017c0300017c0200027c0200037c0100037c0100027c0e00017c0200027c0100037c0100037c0100" - }, - { - "filename": "accessory-yingyang", - "data": "0x0018121b0e060d024b020d064b" - }, - { - "filename": "body-bege", - "data": "0x0015171f093a0101000d0101000d0101000d0101000d0101000d0101000d0101000b01" - }, - { - "filename": "body-gray-scale-1", - "data": "0x0015171f093a0b01000d0b01000d0b01000d0b01000d0b01000d0b01000d0b01000b0b" - }, - { - "filename": "body-gray-scale-9", - "data": "0x0015171f093a0e01000d0e01000d0e01000d0e01000d0e01000d0e01000d0e01000b0e" - }, - { - "filename": "body-ice-cold", - "data": "0x0015171f093a0601000d0601000d0601000d0601000d0601000d0601000d0601000b06" - } - ], - "heads": [ - { - "filename": "head-aardvark", - "data": "0x00021e14060500013702000137130002370200023711000337020003370f000437020004370f00033702000337110002370200023713000137020001370f000d370b000d370b000d370b000d370b000d370b000d370b000d370600057d0d370600017d017e017d017e017d0b37097d017e017d017e017d0b370d7d0a370523097d0b370d7d" - }, - { - "filename": "head-abstract", - "data": "0x00041a1405045c01000447010004470100017f01000114010001140100045c01230447012304470123017f01230114012301140123045c01230447012304470123017f01230114012301140123045c01230447012304470123017f01230114012301140123045c01230447012304470123017f01230114012301140123010015230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f0123044601230158012301580123017f012304460123047f012304460100132301000123015401230154012301540123040701230455012304550123015401230154012301540123040701230455012304550123015401230154012301540123010703540123045501230455012301540123015401230154012304070123045501230455012301540123015401230154012304070123045501230455" - }, - { - "filename": "head-ape", - "data": "0x0005191406030004800e00098009000e8006000f800300108004000f8004000f80040001800e81040001800e81040001800e81040001800e81020003800e8102000180018101800f8101000180018103800d8206800d81018002001180" - }, - { - "filename": "head-bag", - "data": "0x00031c140306000e3a0b000e3a0900023a0e00023a0700023a0e00023a0700023a0e00023a05000207023a0e07023a0207030001070126023a040706260407023a01260107020001260107022606070426060702260107020001260807062608070200013a16070100013a0100013a15070100013a0100013a15070100013a0107013a1607013a0107013a1607010018070100070703760e0701001807020016070100" - }, - { - "filename": "head-bagpipe", - "data": "0x00011d19050a0001831700030f150001830200010f010001831200020f0300010f017a11000108010f017a020f0108017a010f1000020f017a020f0183017a020f06000183080001830100017a010f010001080100020f01830600010807000108040001080200010f017a010f06000108060001080300010803000183017a010f070001080500010803000108020001080100017a010f0200010f0200017a030f017a030f010803000108020001080200020f017a0200010f017a030f017a030f017a03000108010001080400010f017a010f0100010f017a030f017a030f017a010f01000108020001080400010f0300010f017a030f017a030f017a020f0108010001080900010f017a030f017a030f017a030f017a020f0800010f017a030f017a030f017a030f017a030f017a06000108017a030f017a030f017a030f017a030f017a010f050001080200020f017a030f0211020f017a030f017a010f050001080400017a030f017a030f017a030f017a010f050001080400017a030f017a030f017a030f017a060001080500030f017a030f017a030f017a060001080700010f017a030f017a020f0800010817000183160003831500" - }, - { - "filename": "head-banana", - "data": "0x00041d140304000523047903260f000323047905260f000123047907260f00037909260e0002790226012b07260e0001790326012b0326022b02260e000226012b0526022b02260700012606000826022b02260600032605000826022b02260500052604000c2604000426012b022602000e2602000626012b022601000e2601000826012b1226012b032601001426012b032603000a26032b09260500062601570626015706260700042603570526025704260400" - }, - { - "filename": "head-bank", - "data": "0x00031c15040b00021f1400061f1000031f0472031f0c00021f020c011f0472011f020c021f0800021f020c031f0472031f020c021f0400161f020016720300031f0272041f0272041f0272031f0400011f010c011f0272041f0272041f0272011f010c011f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400031f0272041f0272041f0272031f0400011f1272011f0300161f0100021f1472021f" - }, - { - "filename": "head-baseball-gameball", - "data": "0x00041a17060800040b0e00080b0a0001240b0b0700020b01240a0b0124010b0400030b01240a0b0124010b0400030b01240a0b0124010b0300040b01240a0b0124020b0200030b01240c0b0124010b0100040b01240c0b0124050b01240e0b0124040b01240e0b0124040b01240e0b0124010b0100030b01240c0b0124010b0200030b01240c0b0124010b0300030b01240a0b0124010b0400040b0224060b0224020b0500050b0624030b07000c0b0a00080b0e00040b0800" - }, - { - "filename": "head-basketball", - "data": "0x00031a160607000542011a0c000442011a0242011a024208000242021a0542011a044205000542011a0442011a0442011a04000142011a0442011a0342011a0342011a014203000842011a0242011a0242011a034202000142011a0742051a044201000c42011a1342011a1342011a0742141a0c42011a1342011a074201000b42011a064202000942051a0442030004420166010e0166010e0166010e011a0242011a024204000642011a0342011a0342011a014205000442011a0442011a04420800021a0542011a02420c000542011a0700" - }, - { - "filename": "head-bat", - "data": "0x00031e14020900018408000184120001840800018411000384060003840c000184020002840185018406000184018502840200018408000584018502840400028401850584070001840185038401850a8401850384018501840600058401850a840185058405000184018514840185018404000184018514840185018403000184018516840185018402000184018516840185018402000184018516840185018402000184018516840185018401000184018518840185028401851884018508840185048402230162012301620223018401850984030002840185038403230102012301020123028401850284030003840500108405000184" - }, - { - "filename": "head-bear", - "data": "0x000518150805860600068602370286060002860237a1860208028602080223018701230187022301080286020802860208072301080286020802860208028602080286020802860208028602080286020802860208028601000e080100" - }, - { - "filename": "head-beer", - "data": "0x000219140605000287020003870b000b8707000f8704000f87030011870200018701420c87016d02870300024201680287016802470587016d018701000388024201680247016802470168014702870168016d0187010003880342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701680247016802470268016d0200028801000342024701420247016802470268016d0200028801000342024701420247016802470268016d020003880342024701420247016802470268016d030002880342024701420247014202470268016d05000c420168016d050005880785028805000e880200" - }, - { - "filename": "head-beet", - "data": "0x00021a14060400031d020002800d00011d0119021d0280010c01800c00021d0119011d0180010c02800d00021d0119010c02800f00011d0119010c0180110002850d001089030009190189011901890119018901190389010014890319108901193a890219288902190f89031901000a89022006890300041901890119078901190189011905000e890300" - }, - { - "filename": "head-bell", - "data": "0x00011c14040b00022616000226130008260f000226010207260d000226010209260b00022601020b260a000e260a000e2609001026080010260800102608001026080010260800108a0800108a06001426040001260102122602000c2603372126010016260100" - }, - { - "filename": "head-bigfoot-yeti", - "data": "0x00021d14020d00047f1700067f1400037f0156017f0156017f1400027f0156015a0156015a017f1400027f028b0156018b017f1100057f018b0156015a0156017f10000b7f0f000b7f0f000d7f0d000e7f018c0b00047f01000a7f038c0800047f02000a7f058c0500047f02000b7f078c0100047f03000c7f0300058c037f04000c7f0400018c0100018c08000b7f1000087f028d027f1000028c0a7f0e00068c087f0600" - }, - { - "filename": "head-bigfoot", - "data": "0x00021d14020d0004341700063414000334012b0134012b013414000234012b0136012b0136013414000234028e012b018e013411000534018e012b0136012b013410000b340f000b340f000d340d000e3401360b00043401000a3403360800043402000a3405360500043402000b3407360100043403000c3403000536033404000c34040001360100013608000b341000083402160234100002360a340e00063608340600" - }, - { - "filename": "head-blackhole", - "data": "0x00011d17030e00018f1800018f1000018f1800018f0600015f0600015f0400018f0600018f0500015f0600015f0600018f0a00015f0300045f0300015f0e00015f01190120015f032003190c00015f0200015f01190220045f0220025f0b00015f0100015f01190120025f0490025f01200119015f0a00015f0100015f0120015f029004230290015f01200119015f0100015f0500015f0200025f0120015f019006230190015f022001190300018f06000119025f019008230190025f01190400028f0500025f019008230190015f0120015f01190300028f0400015f0120015f019008230190015f0120015f0600018f0300015f0120015f019008230190015f0120015f0a00015f01190120015f019006230190015f02200119015f0700015f0200035f029004230290025f02190100015f0700025f02190120025f0490025f0220015f01190100015f0a00015f01190220045f0120015f01200119015f0c000219055f0320015f02190200015f0600018f0700015f01000319015f0d00018f0900015f0900018f1800018f0300" - }, - { - "filename": "head-blueberry", - "data": "0x00041a1706070006430c000543069107000143019101560591035403910500024306910154037701540391040001430691025404770154029103000243079101540477015403910200014301560891045404910100024312910343119103431191024312910243129102431291010001430391067708910200014304910292099101430191030002430e91040004430c91060002430991014308000543069101430b0006430700" - }, - { - "filename": "head-bomb", - "data": "0x00041c16070f00010d0b00060d0200030d02830600040d0172090d010001830400020d02720a0d030001830200030d0272090d040001830100100d030001830100100d03000193120d02000141120d0300120d0300120d0300120d0300120d0400100d0500100d0600060d0572030d08000c0d0a000a0d0d00060d0900" - }, - { - "filename": "head-bonsai", - "data": "0x00021e15030c00070f1200030f031c040f0f00050f031c010f021c020f0c00040f011c020f031c010f021c020f0b00100f0c000e0f0200030f0c00080f0300020f011c020f0200070f0600027c03000a0f021c060f0400037c060f021c040f021c010f011c050f0400017c070f021c0d0f0400037c080f01000b0f0300097c0500080f087c0c00030f047c0300047c1500067c1400087c0e001294090005940d0e090012940b000e940700" - }, - { - "filename": "head-boombox", - "data": "0x00041b1f060400025815000258150002580d00089502580795040001950900025804000195040001950b0002580200019502000296136f0296016f011c016f0195016f090e016f0195016f0124016f0296136f0296036f030e026f0195016f0195026f030e036f0296026f050e056f050e026f0296016f070e016f0195016f070e016f0296016f070e036f070e016f0296016f070e016f0195016f070e016f0296026f050e056f050e026f0296036f030e026f0195016f0195026f030e036f0296136f1200020e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e0100" - }, - { - "filename": "head-boot", - "data": "0x00061c140701000697030002970a00069702080100019701980a0007970208019701980a0008970108019701980a000b970a000b970a000b9709000d9708000e970700149701002e9703262397010013830100" - }, - { - "filename": "head-box", - "data": "0x00061c1403040003970f990108050004970f9901080400049701080f9902080300049701080f9902080200049702080f9902080100059702080f990308040003080f990308040003080f99070003080f990700029901080f990700029901080f9907000299010805990a010700030805990a010700030805990a01070003080f990300" - }, - { - "filename": "head-boxingglove", - "data": "0x000418140504000d5504000a550438025502004d550189015506070b550189015506070b550189015506070b550189015506070b550189015506070955030001550607095503000f55050003550b260500035501260502012301020326050003550b2605000e550100" - }, - { - "filename": "head-brain", - "data": "0x00051a14060600086a0900036a0320016a0420036a0500016a0320036a0120046a0320016a0300016a0120026a0120016a0120016a0120016a0120026a0120026a0120016a0200016a0120016a0120026a0120026a0120026a0120056a0100066a0120036a0120026a0120026a0120016a0120026a0120046a0120066a0120046a0120026a0120026a0120026a0120036a0120066a0120056a0120026a0120046a0120016a0220026a0120026a0120026a0120036a0120096a0120026a0120036a0120056a0120066a0120076a0120056a0220046a0120016a0100126a0200016a0120036a0220026a0120056a0220016a0300016a0120016a0120026a0220046a0220026a05000e6a0300" - }, - { - "filename": "head-bubble-speech", - "data": "0x00041b160504000e0206001202030014020200140201009a0201001402020014020300120206000f02120003021300020213000202140001020700" - }, - { - "filename": "head-bubblegum", - "data": "0x00021b1705080006690e000369029a05690a000269029a04690202046907000269019a05690402046905000269019a06690402056904000a69020202690202026903000f6902020369020002690102116901008469010014690200146903000a69019a076904000b69019a066905000169019a0769019a0469019a016907000169039a0669039a01690a000a9a0e00069a0800" - }, - { - "filename": "head-burger-dollarmenu", - "data": "0x00071a14060600080a0a00060a0125050a0700040a0125050a0125030a0500020a01250d0a04000e0a0125010a0300120a0200120a020012260100082601970626029701260197012601970226019704260e9701260c9701260497010012970300100a0400100a0200" - }, - { - "filename": "head-cake", - "data": "0x00021a14060500013704000137030001370900013701290137020001370129013701000137012901370800013701290126020001370129012601000137012901260900012604000126030001260900033c0200033c0100033c08000156023c02000156023c01000156023c0600102003000520060207200200042008020620020004200802052001020200010203200902032002020200020202200e020200020202200e020200020201200f0202001202020012020200012001020220020205200202022002020120010001200102012002020220050202200202022001021520" - }, - { - "filename": "head-calculator", - "data": "0x00051a16060200120302001203020001030488010303880103070701030200060303880103070701030200010304880d03020006030388010303880103038801030200010304880d03020006030388010303880103038801030200010304180d0302000103041801030388010303880103038801030200120302000103105c010302080103015c019b035c019b035c019b015c019b015c029b015c010302080103015c039b015c029b025c019b015c019b015c029b015c010302080103015c019b015c019b015c039b015c019b015c019b015c029b015c010302080103105c010302000103109c010302001203" - }, - { - "filename": "head-calendar", - "data": "0x00041a14050100029d0200029d0200029d0200029d0200029d02000202019d0302019d0302019d0302019d0302019d180201230102012301020123010201230102012301020123010201230102059e1002029e0102029e02020d9f0102019e0102019e0102019e0302019f0102019f0102019f0102019f0102019f0102019f0202059e02020d9f0102059e0302019f0102019f0102019f0102019f0102019f0102019f0202059e02020d9f0102059e0302019f0102019f0102019f0102019f0102019f0102019f0202059e02020d9f0102059e0302019f0102019f0102019f0102019f0102019f0102019f0202059e02020d9f0102059e0302019f0102019f0102019f0623019f0102059e02020d9f0102059e1602" - }, - { - "filename": "head-camcorder", - "data": "0x00091c14050400047e0500047e060001230100117c03000223017e017c01240f7c02000323017e117c027e03230100117c027e02230200117c027e02230200117c027e022302001123027e022302001123027e022302000e23027e0123027e0223020001230b7c0223027e0123020002230200112303000123" - }, - { - "filename": "head-cannedham", - "data": "0x00041a14060f00017a10000383017a1200027a0f00047a0c00067a030002390200097a0500053901001483508c14a12d07010e0151010e0151010e0151010e01511b071483" - }, - { - "filename": "head-car", - "data": "0x00091c1406050008550d000155080401550b00035508040155090005550804015507000755060401a20104015505000e5502a20455020014550157010014550157045501230227095502270123045502a20155012702a20127015502230455012702a20127025504a20100012702a2012707a2012702a20127010002a205000227090002270500" - }, - { - "filename": "head-cash-register", - "data": "0x00021a1408010004580e000158026201580e00045802000a27010001610158016202580261012708430127026104580261012701430654014301270261016f0262016f02610127084301270261046f0261012701430354044301270261042702610127084301278e61022a026102870161028701610287016102870161042a026102870161028701610287016102870161042a1361" - }, - { - "filename": "head-cassettetape", - "data": "0x00071b14050100140e0100020e1202040e0102010e1002030e0102010e0102010e1002020e05a3010203a3020203a3010205a3020e04a3030203a3010202a3030204a3020e04a3030203a3010202a3030204a3020e05a3010203a3020203a3010205a3020e14a3020e1426020e1426010e060c0a1f0b0c021f0100061f0100021f090c0e1f040c" - }, - { - "filename": "head-cat", - "data": "0x00031a14060100020e0d00020e0300040e0900040e0300010e0106040e0500040e0106010e0300010e0306020e0500020e0306010e0300010e0406070e0406010e0300010e0306090e0306010e0300010e01060d0e0106010e0300110e0400100e0400100e0400100e0400100e0400100e0400100e0200053c0506026c0406043c02000806019607060200053c030604960406043c020010060200" - }, - { - "filename": "head-cd", - "data": "0x00031b1805080006a30e0002a3066702a30a0002a30a6702a3070001a30e6701a3050001a301220f6701a3040001a302220e6701a3030001a305220b67024301a3020001a30622016704080367044301a3010001a304200322010804a30108074302a30620010806a30108064302a30620010802a3020002a30108064302a30620010802a3020002a30108069a02a30626010806a30108069a02a30726010804a30108026e059a01a3010001a30426036704080167046e029a01a3020001a302260b67056e01a3030001a30d67036e01a3040001a30f67016e01a3050001a30e6701a3070002a30a6702a30a0002a3066702a30e0006a30800" - }, - { - "filename": "head-chain", - "data": "0x00051e1602030004840100068401000684010003840600049301840693018406930184039306000484010a0684010a0684010a038407000184010a0184010a018402000184010a0184010a018402000184010a0184010a01840700038401930684019306840193068404000393018401020593018401020593018401020593040003840100068401000684010006847500068401000684010006840100048402000184010205930184010205930184010205930184010203930100018401930684010a0684010a06840193048401000184010a0184010a018402000184010a0184010a018402000184010a0184010a018402000184010a0184010a01840100048401930684019306840193068401930184010004930184069301840693018406930184020004840100068401000684010006840300" - }, - { - "filename": "head-chainsaw", - "data": "0x00051d16040300036315000163030001631400016303000163120008630200010d0200010d0200010d0200010d05000863010d0100020d0100020d0100020d0100020d04000863020d0263010d0263010d0263010d0263020d0300010d06630e0d0163020d08630e0d0163010d0200010d06630f0d020008630e0d0163020d0100010d06630e0d0163010d010008630f0d020008630e0d0163020d03630102010d0102010d01630e0d0163010d02000263010d0102010d010201630f0d04000863010d0263010d0263010d0263010d0263010d05000563020d0100020d0100020d0100020d0100020d070004630100010d0200010d0200010d0200010d0200010d0300" - }, - { - "filename": "head-chameleon", - "data": "0x00021c16040b00021d1600021d1500041d1300061d0e000184031d0184041d0184031d01840800030f0184031d0484031d0184030f0500010f0222020f0184011d0184041d0184011d0184050f0300010f0423010f0184021d0484021d0184060f0200010f012202230122020f0184061d0184050f02220200020f0222030f0184061d0184040f03230200070f0184061d0184040f012202230200070f0184061d0184050f02220300040f0284081d0284040f050003840c1d03840500141d0300161d0200041d048406230484041d0100021d03840e220384031d01840522010f0122060f0122010f05220184011d01001622030003220e0003220200" - }, - { - "filename": "head-chart-bars", - "data": "0x00041a1406100004730800041c040004730800041c040004730800041c0469047304000428041c0469047304000428041c0469047304000428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428041c0469047304190428011c06230169047304190428041c0469047304190428041c04690473" - }, - { - "filename": "head-cheese", - "data": "0x00031a140605000226012b022602290d00052602290d00052603290b000226012902260229012b01290b0001260129022b01260129012b03290a0001260129022b012601290126032909000526032902260229080005260729080005260829060005260929060005260a29050005260a29040005260c29030005260c2903000126012903260d29010001260129012b02260429012b012903230529010001260129012b02260229022607290126032905260f29" - }, - { - "filename": "head-chefhat", - "data": "0x00051c14040500060210000b020c00090203a308020300060204a30c020200030203a310020100250201a3060201a3030201000b0201a3050202a303020300030201a3060201a3030202a304020500030201a3050201a3020201a3050208000e7c0a000ea30a000ea30a0001020c5501020a000e020a000e020500" - }, - { - "filename": "head-cherry", - "data": "0x00011b15050900030f0e00010f0200070f0d000b0f0b00010f0100070f0e00010f0200030f1000010f0300010f1200010f0300010f1100010f0400010f0d000318010f01180400010f0441060009180941030009180b4102000918094101020141010009180d4109180d4109180d4109180d4109180d410100091806410318024102000918054101180202034103000918094106000518040005410400" - }, - { - "filename": "head-chicken", - "data": "0x000318140805000155010003550a000755080008550700028707550387030006870455048702000987015504870100888704130c8706130a8704550c8704550487" - }, - { - "filename": "head-chilli", - "data": "0x00041c16050600081c0d000a1c0b00081c0e000a1c0d00071c0224011c0c00041c07240c00011c0a240d000a240d000a240d000b240c000b240d000b240900012402000c240700022403000d240400032404000524052309240500112407000f2409000c240e0007240600" - }, - { - "filename": "head-chipboard", - "data": "0x00061c140513a4040001a401a503a402a601a408a701a401a501a4040005a402a606a401a806a4030001a403a901a402a601a40aaa02a4030001a401a901aa01a902a401a806a401a807a401ab01a501a403a901a401a804a401a803a401a805a401a802a505a401a803a401a805a401a803a401a801a401ab01a505a401a803a401a805a401a802a401a802a402a502a410a803a401ab01a501a401a803a401a80fa4020001a401a802a410a801a401ab01a501a401a801a401a810a401a802a503a401a801a402aa01a402aa01a402aa01a402aa01a402aa02a401ab01a501a401a501a401a801a402aa01a402aa01a402aa01a402aa01a402aa02a402a515a401ab01a5" - }, - { - "filename": "head-chips", - "data": "0x00021c19040d0001231600010702231400030702231200020701020207022310000287050702230e000487050702230c000287010203870507034209000287010205870507024208000a8705070142012306000c870507022304000e8705070223020001070f8705070123010003070f870407010005070f870207020006070f87040006070d87020001420300060703870214068702000242040006070987020003420500060707874c00034215000242160001420200" - }, - { - "filename": "head-chocolate", - "data": "0x000319140701000185010e03970185039709000185010e02850197038501970900020e098507000185010e0397018503970185019707000185010e02850197038501970385019701850400020e0c8504000185010e03970185039701850397018502970100038c0f065a8c010002890e190200101902001019020003190c890119020010190100" - }, - { - "filename": "head-cloud", - "data": "0x00041c14040b000502110009020e000b020c000d020a000f0207001102050014020300150203001502020016020200170201003002010017020100170202001502050012020200" - }, - { - "filename": "head-clover", - "data": "0x00041d16070400031d0500031c0a00051d0300051c0900051d0300051c0700031c051d0100061c021d0400041c061d041c051d0300051c051d031c061d0300061c010f021d031c010f061d0400061c010f011d021c010f061d0700051c010f011c010f051d0a00021d031c010f031c021d0a00051d010f011c010f051c0700061d010f021c011d010f061c0400061d010f031c021d010f061c0300061d031c051d051c0300051d041c011d055c041c0100020f0100021d061c010f051d031c040f0300051c030f051d050f0400051c0300051d0a00031c0500031d0700" - }, - { - "filename": "head-clutch", - "data": "0x00071b14030b0004120b0009760412097602000876015b0412015b087602000876065b087602000812015b04ac015b0812010001120876015b0412015b087601000112097604120976015b0100097604120976015b0100097604120976020009760412097602000976041209760200097601020123010201230102087602000976041209760200097604120976" - }, - { - "filename": "head-coffeebean", - "data": "0x0005191608040004ad010004ad060005ad01340135013405ad030002ad013403ad01340123013406ad010002ad013404ad01340123013408ad013405ad01340123013408ad013405ad01340123013408ad013405ad0134012301340ead0134012301340ead0134012301340ead0134012301340ead0134012301340ead0134012301340ead0134012301340bad03230134012301340ead01340123013407ad010006ad01340123013406ad030005ad01340135013405ad060004ad010004ad0400" - }, - { - "filename": "head-cone", - "data": "0x000319140708000224100002240f0004240e0004240e0004240d0006240c0006ae0c0006ae0b0008ae0a0008240a00082409000a2408000aae08000aae07000cae06000c24030004240c481424" - }, - { - "filename": "head-console-handheld", - "data": "0x000319140713031010020301100f7902030110077901af07790203011005790510017901af011001af017902030110067903af0279011001af01100179020301100179021001790110017901af017901af027901af011001af0179020301100f79020301100f79020301100f79020301100f79020301100f79020301100f79150301b0100303b0020301b0010301b0010303b101030324030301b0020301b0010301b0020303b1010303241303" - }, - { - "filename": "head-cookie", - "data": "0x00031a1606070006980c000a9808000e98050007980185089804000d98018502980300129802001298010073980285039801000e9802850298020003980285029801850a98030002980285029805850598040006980185099805000498018504980185049808000a980c0006980700" - }, - { - "filename": "head-cordlessphone", - "data": "0x000a1d1402020009030db00303020005030389010301b0028801b0028801b0028802b0018901b003030200020301b002030389010301b0028801b0028801b0028802b0018901b0030302000503038901030db0010301230103020005030389010301b0028801b0028801b0028804b00103012301030200010301b0010301b001030389010301b0028801b0028801b0028804b0010301230103020005030389010301b0028801b0028801b0028804b001030123010302230503038901030db00103012301030223020301b002030389010301b0028801b0028801b0028802b0018801b0010301230103020005030389010301b0028801b0028801b0028802b0018801b00303020009030db00303" - }, - { - "filename": "head-cottonball", - "data": "0x00021c16040a00010216000302014b0202020001020a00010202000202014b07020c000502014b0402014b03020200010206000102014b0402014b0502014b040207000202014b0a02014b020207000302014b0602014b0302014b030206000102014b0202014b0602014b0402014b010204000202014b0302014b0602014b070204000502014b0d02014b04000402014b0f0204001102014b02020100010201001202014b03020100010201000302014b0d02014b020205000102014b0d02014b020206000402014b0202014b0202014b0302014b030207000302014b0302024b07020100010205000302014b0302014b0202014b0402014b01020900014b0d020c000802014b010210000102014b0302014b0900" - }, - { - "filename": "head-cow", - "data": "0x00061914060300017f0323057f05230500017f0323057f05230300037f0323057f0523017f01000c7f0523197f02230d7f030003230b7f05000323047f0323047f0500077f0323047f0500077f0323047f0500027f0e5f03000123017f045f0208035f0208035f030002230e5f03000223035f0908025f030002230e5f" - }, - { - "filename": "head-crab", - "data": "0x00021b14050400041306000413060007130400071303000913020009130100031302b20c0002b20d130200131304000b13010005130600051301000413070001230200012307000413010010130100041301001013010044130300101306001013060010130600061304b2061306001013060010130300" - }, - { - "filename": "head-crane", - "data": "0x00061f1405060005b313000ab30f000cb30d0003b3050206230b0002b306020823090001b30802092308000902072304b506000a02052308b50300060209230bb5050207230e00040208230f0002020a230f0002020323040205230d0002020d230c0002020c230800" - }, - { - "filename": "head-croc-hat", - "data": "0x00061e150801000e2308000e230700102307000e1d08000e1d08000e1d08000e1d08000e1d08000e1d08000e1d0800151d0100151d0100031d0323021d0423021d0423031d0100051d0123021d0123021d0123021d0123021d0123031d0100051d0423021d0423021d0323011d0100151d" - }, - { - "filename": "head-crown", - "data": "0x00041a14060100015b0700025b0700015b0200015b0700025b0700015b0200025b0500045b0500025b0100028b012b015b0300015b041d015b0300015b012b0241018b0154012b025b0100025b011d029b010f025b0100025b012b011801410254012b055b021d020f055b012b02180100125b0200125b0200125b0200125b0200125b0200125b0200125b0200125b03000135052b0435052b01350300125b0200125b0100" - }, - { - "filename": "head-crt-bsod", - "data": "0x00051a15040400120104001201020004010166025a01660a5a0801025a01660b5a08010166025a01660a5a08010e5a08010e5a08010e5a08010e5a020102b004010e5a08010e5a020102b004010e5a08010e5a020102b004010e5a0f01012301010123060102000a0101230101012301010123050104001201" - }, - { - "filename": "head-crystalball", - "data": "0x00021a14060700062d0c00022d06b6022d0900012d0ab6012d0700012d07b6012d04b6012d0500012d03b6012d0ab6012d0300012d03b6012d01b6012d05b6012d04b6012d0200012d04b6012d05b6032d03b6012d0100012d0cb6012d05b6022d07b6012d0ab6022d12b6022d12b6022d12b6022d12b6012d0100012d10b6012d0200012d10b6012d0300012d0eb6012d040010b7040005b7072304b7040010b70200" - }, - { - "filename": "head-diamond-blue", - "data": "0x00051a18060500024a0104044a0104024a0900034a0104044a0104034a0700034a0104064a0104034a0500044a0104064a0104044a0300044a0102084a0104044a01000204010201040302010401020b04054a0102084a01040a4a0104084a01040a4a0104084a01040a4a0104084a0104054a14040100054a0104064a0104054a0300044a0104064a0104044a0500044a0104044a0104044a0700034a0104044a0104034a0900024a0104044a0104024a0b00024a0104024a0104024a0d00014a0104024a0104014a0f000104024a01041100024a0900" - }, - { - "filename": "head-diamond-red", - "data": "0x00051a1806050002b8014204b8014202b8090003b8014204b8014203b8070003b8014206b8014203b8050004b8014206b8014204b8030004b8010208b8014204b801000242010201420302014201020b4205b8010208b801420ab8014208b801420ab8014208b801420ab8014208b8014205b81442010005b8014206b8014205b8030004b8014206b8014204b8050004b8014204b8014204b8070003b8014204b8014203b8090002b8014204b8014202b80b0002b8014202b8014202b80d0001b8014202b8014201b80f00014202b80142110002b80900" - }, - { - "filename": "head-dictionary", - "data": "0x00051b150501000802040008020100014a01020372010203720102020001020372010203720102024a1402024a010203720102037204020372010203720102024a1402024a010203720102037204020372010203720102024a1402024a010203720d0202720102024a1402024a010203720d0202720102024a1402024a010203720d0202720102024a070206410702024a1402024a14020b4a02020a4a0900044a0900" - }, - { - "filename": "head-dino", - "data": "0x00071d15080300061d0f00061d0c00bd1d0100051d0302011d0302011d0302011d03020100051d0302011d0302011d0302011d03020100141d0100141d" - }, - { - "filename": "head-dna", - "data": "0x00091d160304431200045501000126010004430c000455010001510200012601000155010004430800035501430100012601000151020001260100015501000143010001510243060002550143010001430100012601000151020001260100015501000143010001510100024304000255010001430100014301000126010001510200012601000155010001430100015101000343020002550143010001430100014301000126010001510200012601000155010001430100015101000143010002430255010001430100014301000143010001260100015102000143010001510100012601000155010001430200025502000143010001430100015501000143010001550200014301000151010001260100015501000143010002550243010001430100014301000155010001430100015502000143010001510100012601000155010001430255020003430100014301000155010001430100015502000143010001510100012601000155010002550400024301000143010001550100014301000155020001430100015101000126010003550600034301000155010001430100015502000143010005550a000543010001550100055510000543" - }, - { - "filename": "head-dog", - "data": "0x00061a140603000e97040004850d970185010005850d9706850e9706850e9706850e9706850e9706850e970685049706380497068504970638049706850397083803970685019708380223020d0138028502000397083804230138040003970438022301020323010201230138040003970d380200" - }, - { - "filename": "head-doughnut", - "data": "0x00031a160607000156056c0c00026c0156046c01b9026c08000a6c01b9036c0500086c016d056c02190400026c02b9016c0119036c016d066c0300076c0119016c0138056c0156026c0200076c0538026c0156036c0100046c016d026c013804000138066c011c016c021c016c016d016c013806000138026d036c011c066c0138060001380c6c013806000138086c0156036c013806000138036c02b9036c0156036c023804000138026c0156046c0100076c0538036c0156026c0200046c01b9066c0219056c0300026c01b9046c0156086c0400076c0156040e016d036c0500026c0119096c016d016c08000119096c0c00016c021c036c0700" - }, - { - "filename": "head-drill", - "data": "0x00071c140502000e1401a307000f1401a3017e06000f1401a3017e017c017e017c017e017c101401a3027e017c017e017c017e101401a3017e06000f1401a307000f1401a308000e1401a30b00057e01a31100057e02a31000057e03a30f00077e0f00011401230126012301260123081409000e140500" - }, - { - "filename": "head-duck", - "data": "0x00041d1407070006020e0005020c001002060011020500110205001102050011020500110205001102050011020500110205001102050011020500050210460100050204460142014601420a4605021146010005021046" - }, - { - "filename": "head-ducky", - "data": "0x00031c14040c0008260e000526045102260c00052602510223025101260c000526025102230251012601140b0006260451022603140100022607000a2603140200052605000a2603001626020017260100482601001726010017260200162602000b26018a092604000726038a0926070010260300" - }, - { - "filename": "head-earth", - "data": "0x00031a1606070006430c000a4308000343011c0543011c0243021c05000243031c0543061c04000243021c0543071c0300011c0243031c0343091c0200021c0243011c0443091c0100031c08430c1c0d43081c07430e1c0543091c0143061c0443081c0243061c0443071c03430100031c0643071c02430200021c0843041c04430300011c0943041c02430400011c0443081c034305000e4308000a430c0006430700" - }, - { - "filename": "head-egg", - "data": "0x0001191507070004020c00020202ae04020900010201ae010202ae020202ae010207000c020500010201ae020201ae020201ae06020400010201ae060202ae020201ae01020300010201ae020201ae040202ae030201ae01020200010201ae0c0201ae01020200010201ae0b0201ae02020100100201ae060201ae0a0201ae030201ae0a0201ae020201ae030201ae0a0201ae020201ae330202ae0202010010020200030201ae080201ae030203000502021e070205000c020800050201ae02020500" - }, - { - "filename": "head-faberge", - "data": "0x0001191406080003260d0001260207012601070126020701260a00020701260307012602070900010f0407010f0407010f07000d070600010701260407012604070126010705000107012601890126020701260189012602070126018901260107040002070126040701260407012602070300110702001126010013260100118a020011070200110703000f0704000f0704000f0705000d0706000626032303260900098a0500" - }, - { - "filename": "head-factory-dark", - "data": "0x00031a14080300057c0b00010e0300087c0600020e0b00047c010002241000020e0400010e0300010e0300010e0300020e0300020e0200020e0200020e0200040e0100030e0100030e0100030e0200100e0200100e0200100e0200100e0200100e0200100e0200100e0200100e0200020e0172010e026d010e026d010e0172050e0200100e0200100e0200" - }, - { - "filename": "head-fan", - "data": "0x00031a1606070006510c0003510100015102000351080003510200015102000151020003510500035102000151027e0151027e0151020002510400025102000151027e0151027e0151027e01510100015103000251020001510100017e0151027e0151027e0151017e01000251020001510200015102000151027e0151027e0151017e01000151010001510100025101000151020001510100017e0262017e0151017e010001510200035101000151027e015102000462020001510200015101000351027e0151027e06620151027e0151020002510100017e0151027e01510662027e0151017e0100035101000151027e0151027e0462027e0151027e0151010003510100017e0151027e0151017e0262027e0151027e0151017e02510100015101000151027e0151027e01510100017e0151027e0151027e0151020002510100017e0151027e01510100017e0151027e0151027e02510300015101000151027e015102000151027e0151017e01000251040002510200015102000151027e015102000351050003510200015102000151020003510800035102000151010003510c0006510700" - }, - { - "filename": "head-fence", - "data": "0x00041d1403020001ba060001ba060001ba06000134030003ba0400013402ba040003ba040001ba013401ba010005ba020001ba013403ba020005ba020002ba013407ba020001ba013403ba020003ba013401ba020002ba013405ba013401ba020001ba013403ba020003ba013401ba020008ba013401ba023401ba013403ba023403ba013401ba023402ba013405ba013401ba023401ba013403ba023405ba023408ba013401ba023401ba013403ba023405ba023408ba013401ba020005ba020005ba020005ba013404ba020005ba020001ba013403ba020003ba013401ba013404ba020005ba020001ba013403ba020003ba013401ba013402ba013401ba023405ba023401ba013403ba023403ba013401ba013404ba023405ba023401ba013403ba023401ba013401ba013401ba013404ba023405ba023401ba013403ba023403ba013401ba013404ba020005ba02000585020003ba013406ba020003ba013401ba02000585020003ba013406ba020003ba013401ba020001ba013403ba020005ba" - }, - { - "filename": "head-film-35mm", - "data": "0x0003181405080006230d0006230800102303420726078702260100014201000726078702260342072607870226034207260787022603420726078702260342072607870226034207260787022603420726078702260342072607870226034207260787022603420726078702260342072607870226010001420100022603ad022607870226034207260787022603001023" - }, - { - "filename": "head-film-strip", - "data": "0x00051b140516bb010002bb010002bb010002bb010002bb010002bb010002bb010002bb010016bb02bc01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb03bc017b01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb04bc01bb10bc01bb02bc16bb010002bb010002bb010002bb010002bb010002bb010002bb010002bb010016bb" - }, - { - "filename": "head-fir", - "data": "0x00011f18010e00020f1b00040f1900060f1700030f015c040f1500030f015c060f1300030f015c040f015c030f11000a0f015c030f0f000c0f015c030f0d00120f0b00140f0900160f0700180f05001a0f03001c0f01001e0f0600120f0b00140f0900160f0700060f065c0c0f05001a0f2700010f0e00010f0d00020f0e00020f0b00030f0e00030f0500" - }, - { - "filename": "head-firehydrant", - "data": "0x00021c14040b0002bd140006bd110002be01bd02be01bd02be0f0003be01bd02be01bd03be0d0003be01bd04be01bd03be0c0003be01bd04be01bd03be0b0003be01bd06be01bd03be0a0003be01bd06be01bd03be080012bd060012bd08000ebe0a000ebe060002be012310bd012302be020002be012310bd012302be010001bd02be012310bd012302be02bd02be012310bd012302be01bd010002be012303bd0b2302bd012302be020002be012310bd012302be06000ebe0500" - }, - { - "filename": "head-flamingo", - "data": "0x00031b14050c00042003b90d00062001b9012301b901200b00072003b902200900042005000320025f070004200800035f070004200800025f010e070005200800020e080006200600020e090008200300010e0b0009200e0009200f0008201000062002002b6a0b2006091b20010014200100" - }, - { - "filename": "head-flower", - "data": "0x00031b18050a00024f1300044f0d0002b90200019a044f019a020002b9070005b9019a044f019a05b9050007b9019a024f019a07b9040007b9041307b9050004b90213046d021304b9060003b90113086d011303b90500029a02b90113086d011302b9029a0300034f019a01130a6d0113019a034f0100054f01130a6d01130a4f01130a6d0113054f0100034f019a01130a6d0113019a034f0300029a02b90113086d011302b9029a050003b90113086d011303b9060004b90213016d0385021304b9050007b9041307b9040007b9019a024f019a07b9050005b9019a044f019a05b9070002b90200019a044f019a020002b90d00044f1300024f0a00" - }, - { - "filename": "head-fox", - "data": "0x00031c190405000302140005021200014205020800022301000223040002420502080002420100024203000442030209000642010007420400022306420111014201110742070006020a4209000b02054209000a020100054209000902020004420a00080204000f42050204001042040204001142030204001242020204000542070207420102040005420623020206420500054209020442060001420e000242040004420e000142050001421100024204000123120002420223010001231600" - }, - { - "filename": "head-frog", - "data": "0x00061914070300051c0300041c0500071c0100061c0300041c020f0a1c0200041c020f0a1c02000d1c020f011c02000d1c020f011c0200101c0200101c0200020f0e1c0100011c020f331c14670e5c0267010010670100" - }, - { - "filename": "head-garlic", - "data": "0x00051914070700010b0100010b0100010b0e00030b0f00030b0e000157030b015709000157030b0157030b0157030b0500010b0157030b0157030b0157030b01570300020b0157030b0157030b0157030b0157010b0100030b0157030b0157030b0157030b0157050b0157030b0157030b0157030b0157050b0157030b0157030b0157030b0157050b0157030b0157030b0157030b0157050b0157030b0157030b0157030b0157050b0157010b01bf010b0157030b0157030b0157050b0157020b04bf010b0157030b0157020b0100020b0157030b0157030b0157030b0157010b0300010b0157030b0157030b0157030b01570200" - }, - { - "filename": "head-gavel", - "data": "0x000419140108000f3409000f340a000d230b000d260b000126015d0b260b000126015d0b260200013401000234010004340d2604000134020004340d2603000234010005340d260b000d260b000d260b000d260a000f3409000f230800118e0700118e07001123" - }, - { - "filename": "head-ghost-B", - "data": "0x00051b16030c00028c1500048c0b00028c0700058c0600028c0200048c0400028c0104018c0104018c0400048c0200068c0200068c0200068c0300148c0400148c0400148c0400148c0500128c0600128c0600118c0700118c08000f8c07000f8c0600118c0b00028c1400048c1200" - }, - { - "filename": "head-glasses-big", - "data": "0x00091c120204000a8002000a800400018005020480020001800502048004000180050204800200018005020980050207800502098005020780050205800300018005020480020001800502058003000180050204800200018005020580030001800502048002000180050204800400018005020480020001800502048004000a8002000a80" - }, - { - "filename": "head-gnome", - "data": "0x00011a14060900024112000241110004410f0006410e0006410d0008410c0008410b000a4108000ec0030001c1010001c00ec101c0010003c101c00ec101c004c101c00ec101c004c101c00ec101c002c10200104c0400104c0400104c0400104c040003c10123010201230102012301020123010201230102012302c1040003c10b4102c10500088a018e078a0100" - }, - { - "filename": "head-goat", - "data": "0x00051d1805030001b00c00040d060002b00e0004b0030002b00e0002b0017e022301b0020002b00e0002b0017e04b001000fb0017e02b0017e02b0029802000eb0017e02b0017e01b0017e02b003000eb0027e02b0010002b0030010b0030001b0040010b0080010b0080011b0070011b0060005b0017e0cb0060005b0017e01230102012301020123010207b0050004b0017e0ab0010003b0050003b001000ab0040001b0040002b0110001b0030003b0100002b0030001b0120001b0040001b0120001b00400" - }, - { - "filename": "head-goldcoin", - "data": "0x00031a1606070006260c000326042b032608000326022b0426022b032605000226022b0826022b022604000126012b0c26012b012603000226012b0c26012b022602000126012b092603290226012b012601000226012b032603290826012b0326012b1026012b0226012b1026012b0226012b1026012b0226012b1026012b0326012b112601000126012b102602000226012b0f2603000126012b02260129012604290426012b012604000226022b0826022b022605000326022b0426022b032608000326042b03260c0006260700" - }, - { - "filename": "head-goldfish", - "data": "0x00051b1405020012210500109504001421010029210151032112070151010702211407022112070151010702211407022114070221140703210807032507070221010001210707011401250123022506070121020002210707032506070221030003210c07032106000e210400" - }, - { - "filename": "head-grouper", - "data": "0x00061d1602090001080100010801000108010001080100010810000c080e000f0807000208020004080e7a040004080200137a03000408157a01000508157a02000408117a0108047a02000308107a02c4047a010004080e7a02c4047a0282020003080d7a01c4047a0282030004080c7a01c4047a018204000508057a0208047a010801c4037a018205c401000408047a0108057a020801c4027a018201c4047a010004080200077a040801c4077a030002080600027a0508027a01c4047a100003080c00" - }, - { - "filename": "head-hair", - "data": "0x00031e15020800068e0100058e0f00018e0626018e0526018e0d00018e0126068e0126058e0126018e0900018e0100018e0126018e0626018e0526018e0126018e0100018e0700018e0126018e0126068e0126058e0126018e0126018e0800018e0126018e0126018e0500018e0400018e0126018e0126018e0800018e0126018e0126018e0a00018e0126018e0126018e0800018e0126018e0126018e0a00018e0126018e0126018e0600018e0100018e0126018e0126018e0a00018e0126018e0126018e0100018e0500018e0126018e0126018e0c00018e0126018e0126018e0600018e0126018e0126018e0c00018e0126018e0126018e0600018e0126018e0126018e0c00018e0126018e0126018e0600018e0126018e0126018e0c00018e0126018e0126018e0400018e0100018e0126018e0126018e0c00018e0126018e0126018e0100018e0300018e0126018e0126018e0e00018e0126018e0126018e0400018e0126018e0126018e0e00018e0126018e0126018e0400018e0126018e0126018e0e00018e0126018e0126018e0400018e0126018e0126018e0e00018e0126018e0126018e0200028e0100018e0100018e1000018e0100018e0100028e" - }, - { - "filename": "head-hardhat", - "data": "0x00041d1405050005c505c60d0006c601c505c60b0006c502c601c505c6090007c601c502c601c505c6080008c601c501c601c505c6070009c601c502c605c501c6060009c601c508c6060009c601c508c6060009c601c508c6060009c601c508c6060009c601c508c6060009c601c508c6060009c601c508c6060003c60fc5050004c601c50d2301c509c601c50dc601c51dc6" - }, - { - "filename": "head-heart", - "data": "0x00041c1704050005240400052408000924010008240500062402020624020204240300092401020524020201240102032402001324010202240100142401024b2401001624020016240300142404001424050012240700072402020123062409000e240b000c240d000a2410000624140002240b00" - }, - { - "filename": "head-helicopter", - "data": "0x00031d14020d0002231000016104620261062302610462016110000223190002231600072007560400022006000220019a0120019a0120019a012008560300032004000320019a0120019a0120019a01200956020002620e200556030202560162022301620d200556030202560162022301620d200556030202560100026202000c200a5606000b2008560102015607000a20085601020156080009200656020201560a00082008560c000e200f0001230200012312000e230600" - }, - { - "filename": "head-highheel", - "data": "0x00061b14050200031812000518110006180f0008180e0008180e0008180e0008180e0009180d000b180c000c180b0004180200081809000218040009180700021805000a180500021806000318042304180300025b07000a5b" - }, - { - "filename": "head-hockeypuck", - "data": "0x00051b1505070008050b000305081f0305060002050e1f020503000105121f010501000105141f0205141f0205141f0105010d0105121f0105011f020d02050e1f0205010c011f040d0305081f0305020c021f070d0805060c011f040d030c020d010c010d090c021f070d0e0c011f0100030d030c020d0b0c011f0300050d030c0105010d0205010d050c0600030c020d090c0b00080c0700" - }, - { - "filename": "head-horse-deepfried", - "data": "0x00061b15050900018e0100028e0d0003ac0100068e010003ac0600028e03ac068e020003ac0600028e07ac018e06ac0500038e06ac036d05ac0600028e07ac016d06ac0600028e07ac016d06ac0500038e07ac016d06ac0600028e07ac016d06ac0600028e07ac016d06ac0500038e128a0200028e0e8a0123018a0123018a0100038e028a016d0123016d0123016d0123016d098a048e128a0100038e128a0100018e0100018e0e8a0400" - }, - { - "filename": "head-hotdog", - "data": "0x0003171409050004890700018301390689013901830300028301390689013902830100028301390289016d021903890139048301390389026d011902890139048301390589016d011901890139048301390389026d011902890139048301390289016d021903890139048301390389026d011902890139048301390589016d011901890139048301390389026d011902890139048301390289016d021903890139048301390389026d011902890139048301390589016d011901890139048301390389026d011902890139048301390289016d021903890139048301390389026d011902890139048301390589016d0119018901390283" - }, - { - "filename": "head-house", - "data": "0x00031c1505080001830f00027c04000183015101830e00021103000183035101830d0002110200018302510183025101830c000211010001830251018301c70183025101830711040002110183035103830351018307110300011101830b5101830711020001830d510183071101830f5107831a51051103510b830451051103510183031103c7031101830451051103510183021105c7021101830451051103510183011107c70111018304510311012601110351018306c7017c02c70183045105110351018305c7027c02c7018304510111032301110351018304c7037c02c701830451051103510b830351077c0e51" - }, - { - "filename": "head-icepop-b", - "data": "0x00071c19020500061c089305190600021c059b0802031603190500011c019b051c08930319020202190400011c019b051c08930319020202190400071c089305190116011904c8071c089305190116011904c8071c0893071904c8071c089305190116011904c8071c0893071904c8071c089307190400071c089307190400011c029b041c089307190400011c029b041c0193020201930102039306190600061c089305190a00021c0c0002190a00011c0d00011919000119330001190300" - }, - { - "filename": "head-igloo", - "data": "0x00051e14050800060210000402013c0202023c03020c000102033c0302013c0302023c01020a000102013c0602013c0502013c010208000102033c0102043c0102013c0102053c010207000602013c0602013c040206000102013c1002013c010205000502053c0102063c03020500140204001202013c0102013c020202000102023c0902063c0102013c040201000302013c0402013c0502013c0202013c0102013c0202013c010201000302013c0402013c0502013c0302013c0202023a013c0202023c0102053c0102033c0202043c0202023a013c0202013c0302013c0502013c0402013c0102013c0202033c010201000402013c0502013c0402013c0102013c05020100" - }, - { - "filename": "head-island", - "data": "0x00021b14060400040f1000060f0100061c0c00020f091c0800080f031c01c9031c0500040f01c9030f031c01c90200031c0400020f020002c90100010f021c02c90300021c0400010f040002c90100021c01c90400021c090002c90200011c01c90500011c0400060f01c9020002c90900080f01c9010002c90900080f01c9010002c90900080f01c9010002c90900080f01c9010002c909000e260600102604000d2601460426020002260146012602290226022902260146032601460326010006260229062601460526010014260100" - }, - { - "filename": "head-jellyfish", - "data": "0x00031c1b050700055f016a035f0b00016a0e5f0600065f016a0c5f0400135f0300085f0576055f016a025f0200015f016a045f0976065f0100055f0d76065f016a025f0f76025f016a055f0f76075f1176065f1176035f0100015f1376015f0200015f1376015f0200015f1376015f0200015f036e0176036e0176036e0176036e0176036e015f0200156e0200016a086e0690066e0200016a0200016a0e6e016a0100016a0200016a0200016a0e00016a0100016a0200016a0200016a0e00016a0100016a0100016a0200016a0f00016a0200026a0200016a1000016a0100026a1300016a0100026a1500026a1500016a" - }, - { - "filename": "head-jupiter", - "data": "0x00011d1a030900088210000c820e000982037d0b00107d02370700057d0f3706000b370938040005370a380937020006380a37087d020009370f7d01000637147d04377c7d0237167d0437147d0637010001370b7d0c3702000e3704250337038204000b3702250223022503820600048208370425048206001482070012820b000c8210000882120008820900" - }, - { - "filename": "head-kangaroo", - "data": "0x00051a1406037e0a00037e0400017e0238017e0800017e0238017e0400017e0338017e0600017e0338017e0500017e0338017e0400017e0338017e0700017e0238027e0200027e0238017e09000a7e0a00087e0c00087e0c00087e0c00087e0c00067e088103230300067e088103230300067e0b810300067e022309810300067e0b810300067e0b81" - }, - { - "filename": "head-ketchup", - "data": "0x0002181408070002240e0002240d0004240c0004240b0006890a0006230600022402890224028902240289022402000e23010082240389022403890a2404891824" - }, - { - "filename": "head-laptop", - "data": "0x00061b1605171f010b013c120b021f1456021f1456021f1456021f1456021f1456021f1456021f1456021f1456021f1456021f1456041f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e041f130e031f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e011f010e041f130e181f" - }, - { - "filename": "head-lightning-bolt", - "data": "0x00021e19050800031e1500081e11000c1e0c000c1e0d000b1e0d000b1e0e000a1e0e000a1e0f00091e0f00091e1000081e1000171e0200161e0200151e0400131e0500121e0c000b1e0d000a1e0f00081e1000071e1200051e1300041e1500021e1600011e1700" - }, - { - "filename": "head-lint", - "data": "0x00021b16050a00018c1400018c0f0001910600018c04000140080001910300018c0200038c014001000240090002910200028c0191028c03400400029106000340028c0191018c014001910240018c020001910300018c0200014001910340018c0191018c024001910240028c0300038c034001910340038c024001910140018c0500018c0100018c024001910340018c0191028c014001910140028c0600018c0191024001910240028c0191028c02400191028c010001910100028c0191018c024001910240028c0191028c0240038c010001910200018c0140028c014001910240058c0240028c0191018c01910100058c0740038c01400191038c010001910100038c01910840028c01400191028c020001910200018c01910a40018c0191028c0500038c0140018c01910640018c0191038c0191050001910140028c0191014004230140048c010002910300048c01910740028c0191028c0500018c010002910740028c0191018c0191090001910100014001000340018c0191018c0100018c0e0001400191010001910900" - }, - { - "filename": "head-lips", - "data": "0x00051d150307000424040004240c0007240200072409000d240202032407000e2403020324050013240102022403001824020006240c02062401000524100209241202072414021d240100182402001824030016240500082404020824080010240d000a240800" - }, - { - "filename": "head-lipstick2", - "data": "0x0001181408060003240b0007240800013709240500012401370a24040002240137062401370224040003240437020203240400072402370324040007240237032402000b2a01020f2a01020f2a0102042a0b0d01050f0d01050f0d01050f0d01050f0d01050f0d01050a0d0223030d01050f0d0105040d0b0501020405" - }, - { - "filename": "head-lock", - "data": "0x00031814080400081f07000a1f0500031f0600031f0400021f0800021f0400011f010d0800011f010d0400020d0800020d0200107a718a026d0a8a026d028a026d048a0223048a026d088a0223178a" - }, - { - "filename": "head-macaroni", - "data": "0x00081d1403010008290800082901000229060a022906000229060a02290126082901260600012608290b2606000b26012808260600082601280226012809260400082602281826012802260100182602001526012802260300162605000626020a0126020a0126020a0626070012260a000e260600" - }, - { - "filename": "head-mailbox", - "data": "0x00071c14050700058912000589150002890b000a050289030508000a050289030508000a050289030508000a050289030508000a0502890305060202000a05028903050402013a010202000a0502890305060202000a0502890305060202000a050289030501020423010202000f05060202001705" - }, - { - "filename": "head-maze", - "data": "0x00061b14050aca01000cca0b0001ca040001ca030002ca01000bca010001ca010004ca010002ca010001ca030001ca070001ca040001ca010002ca030001ca030007ca010004ca010007ca010002ca030001ca080002ca010001ca050001ca010001ca010001ca010006ca010002ca010005ca010001ca010003ca080002ca050001ca050001ca010009ca010003ca010003ca010001ca080001ca010002ca030001ca010001ca010001ca010008ca010001ca010004ca010001ca100002ca010001ca010004ca010007ca010006ca030001ca080001ca070015ca010001ca" - }, - { - "filename": "head-microwave", - "data": "0x00071a1f05010002950f06012102060100029501060e9201210143010e0100029501060e920121010e01430100029501060e92012102c70100029501060e92012102060100029501060e92012102c70100029501060e92012102060100029501060e92012102c70100029501060e92012102060100029501060e92012102c70100010e019501060e9201210206020e019501060e92012102c7020e01950f06012102c7010e02950f0601210206010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400010e1400" - }, - { - "filename": "head-milk", - "data": "0x00031b14080100014a0d7f0500014a067f0524027f0400034a057f09240289034a097f05240289034a0d430300034a0143017f0143027f0143047f0143017f01430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d430300034a0d43030003c70d7f0300034a0d430300034a0d430300" - }, - { - "filename": "head-mirror", - "data": "0x00041a1406159702060102010603020a060102029701060102010603020b06010202970102010603020c0601020297010603020d060102029703020106063c0106063c0102029702020206013c0406013c0106013c0406013c010202970102043c0406033c0406013c010202970106013c0206013c0406013c0106013c0406013c010202970106013c0206013c0406013c0106013c0406013c010202970406063c0106063c0102029711060102029711060102029711060102029711060102029712021597" - }, - { - "filename": "head-mixer", - "data": "0x00021a140603000223030002240300022407000172030001230172030001240172030001240300150c030f020c030f020c030f020c0123010c0123020c010f015c010f020c010f015c010f020c010f015c010f020c0124010c0123110c014e010c01af030c0123040c0123030c0302020c014e010c014e030c0123040c0123030c0372020c014e010c014e030c0123040c0123040c0123090c0123040c0123040c0123090c0123040c0123040c0123050c011f030c0123040c0123040c0123090c0123040c0123040c0123050c011f030c0123040c0123040c0123090c0123040c0123040c0123050c011f020c0302030c0123040c0123080c0372020c0302030c0123040c021f030c0123030c0372030c0123040c021f150c" - }, - { - "filename": "head-moon", - "data": "0x00031a1606070006870c000387035e048708000487035e078705000487025e0687015e038704000e87015e01870300128702000587015e0887015e038701000287015e1287025e1287015e4e870100128702000f87015e02870300058702230687025e018704000b87035e028705000687015e0387015e038708000a870c0006870700" - }, - { - "filename": "head-moose", - "data": "0x00051c15040383010002830c00028301000683010002830c85028301000683010002830c85028301000683010002830c85028301000a830b850d830b850d830b85068304000e850a000f8509000f8509000f85090005850d98060005850d980600058506980284029802840198060005850d980600058501980b8401980b000d980200" - }, - { - "filename": "head-mosquito", - "data": "0x00011f14030c0002351800023503000235140001350300023515000135030001351700013502000135180001350200013518000135020001351400091112000211014909110f00021101490b110d00021101490d110c0011110a00131109000211014910110900141109001b110200151108000a1107850c000211078507110d000f110800" - }, - { - "filename": "head-mountain-snowcap", - "data": "0x00031c15040a00040213000102028d030211000102018d060210000102018d06020f000a020e000102018d0602018d01020d000c020c000c020b000e020a000e020900021d0202021d0402021d0302011d0800021d0102041d0202041d0102021d0700021d0202051d0102041d0202021d0600021d02020a1d0202021d0500031d0202051d0102041d0202031d0300021d01020f1d0102031d01000b1d0302071d0102021d0100161d0400061d0600061d0300" - }, - { - "filename": "head-mouse", - "data": "0x00031e1407070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e0500070e0400070e07000e0509000e0509000e0509000e0509000e050400030e02000e050400030e02000e050400030e0200120505000e05011f0105011f010505000805024b0105024b0505050012050300" - }, - { - "filename": "head-mug", - "data": "0x00031b14020900067f0200017f0e00037f0400017f0300027f0100017f0900017f0200037f0300037f0e00027f0100017f2a00160203000102016f014b1102014b010201000102014b0102016f014b1102014b030201000102016f024b1002014b020202000102016f024b1002014b020202000102016f024b1002014b030201000102016f024b1002014b010201000102014b0102016f024b120202000102014b0102016f014b110205000102016f014b110206000102016f014b040204370402014b020208000102016f014b040202370402014b02020a000102016f024b0602024b02020400" - }, - { - "filename": "head-mushroom", - "data": "0x00021c1504080008550d000855025104550800035501510455025104550251025505000855045105550151025503000a5502510a550200035502510c55035102550100035504510655025102550551035501510255025103550151035502510255055103550151105503511b55010016550400125508000eae0a000eae0a000eae0a000eae0a000eae0a0002ae045508ae0a0002ae01550223015508ae0c0004550d00" - }, - { - "filename": "head-mustard", - "data": "0x0002181408070002260e0002260d0004260c0004260b00068a0a00062306000226028a0226028a0226028a022602000e2301008246038a0246038a0a46048a1846" - }, - { - "filename": "head-nigiri", - "data": "0x00051c1404040002cd01cc03cd01cc03cd01cc03cd01cc01cd060001cc03cd01cc03cd01cc03cd01cc03cd01cc03cd020002cd01cc04cd01cc03cd01cc03cd01cc03cd01cc07cd01cc03cd01cc03cd01cc03cd01cc03cd01cc07cd01cc03cd01cc03cd01cc03cd01cc03cd01cc07cd120203cd0100160202001602030014020300160202001602030014020300160202000a0203ce090203001402050012020300" - }, - { - "filename": "head-noodles", - "data": "0x00021e1402100001361b0001360500013614000136040002360b0001cf010001cf010001cf05000136020002360c0001cf015c01cf015c01cf015c01cf02000298038803160a0001cf015c01cf025c0316039806880216080001cf015c01cf025c02160419038803c1028801160298060001cf015c01cf015c02160619018801c1034601c101880116039803001c0b01001a0b02001a89030018890400180b050016890600160b0700140b0900070b0789040b0b00100b0e000c0b0800" - }, - { - "filename": "head-onion", - "data": "0x00041a14060a00019c1100019c0100019c0100019c1000039c10000137039c01370900029c0137039c0137039c0137039c0137019c0300039c0137039c0137039c0137039c0137029c0100049c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c0137039c0137039c0137039c0137079c01c7019c0123019c0137039c0137029c01c70137039c0100039c0137029c0423019c0137039c0137029c0300029c0137039c0137039c0137039c0137019c0500019c0137039c0137039c0137039c01370300" - }, - { - "filename": "head-orangutan", - "data": "0x0002181406070001240e000b2406000b2407000c2404000e2403000624070e042403000424070e0424030002240c0e0124030002240c0e0124030002240c0e0124030002240c0e0124030002240c0e01240300100e0200040e0a08020e0200030e0c08010e0200030e010801240208010e0108010e030801240108010e0200030e01240a080124010e0200030e01240a230124010e0200030e0c24010e" - }, - { - "filename": "head-orca", - "data": "0x00021b14010d00010d1900020d1800030d1700040d1600050d1500060d12000b0d0d000e0d0b00100d0300030d0300110d0400030d0100130d0300170d0400160d0300180d0200030d0100140d0100030d0200130d0100030d0400080d090b0a00060d090b0c00040d090b0400" - }, - { - "filename": "head-otter", - "data": "0x000918140704000b8604000e8603000f8602000f8602000f860100328602000286047f0623037f020001d00486017f0623017f0286020002d0037f04d0012303d0027f020008d0012301d0012304d0" - }, - { - "filename": "head-outlet", - "data": "0x0004181608245108a3075102a3012304a3012302a3065102a3012304a3012302a3065101a3037c02a3037c01a3065104a3022304a3065104a3022304a3075108a3185108a3075102a3012304a3012302a3065102a3012304a3012302a3065101a3037c02a3037c01a3065104a3022304a3065104a3022304a3075108a32451" - }, - { - "filename": "head-owl", - "data": "0x000218140507000ad1080001d10ad201d1060001d101d204d302d204d301d201d1050001d101d20ad301d201d1050001d101d201d302d401d202d301d202d401d301d201d1050001d101d203d301d202d301d203d301d201d1050001d101d204d302d204d301d201d1050002d101d208d302d201d10400042b01d208d301d201d10300062b08d301d201d10300062b01d107d301d201d10200072b01d107d301d201d10200072b01d107d301d201d10200072b01d107d301d201d10200062b02d107d301d10300052b03d106d301d10400032b04d106d301d1040001d1012b07d106d303000bd107d30100" - }, - { - "filename": "head-oyster", - "data": "0x00021d14040a00058111000481038204810e000181098201810c000381098203810a00018105820398058201810700048102820998028204810400018105820998058201810400018102820f980282018102000381018211980182048103821198038202810282139802820281048206980351079803820181010002810382049805510498038202810400028101820398075103980182028108000181019802550751025501980181090001810f5501810700048103550581035504810600018102d5058103d5058102d50181070011d50400" - }, - { - "filename": "head-paintbrush", - "data": "0x00091c18020700036d0572097502240600046d027201b00272097502240600046d0572087503240100096d0572087503240a6d0572087503240a6d0572087503240a6d0572077504240a6d0572077504240100096d0572077504240600046d0572077504240600036d0224017201b00272067505240700036d05720675052416000124010002241800022418000124190001240100" - }, - { - "filename": "head-panda", - "data": "0x000519140601000423090004230100062307000c23090209230b0207230d020223010002230e02012303001002030010020300100203001002030010020300100203000a020423020203000a02042302020300070206230302030010020100" - }, - { - "filename": "head-paperclip", - "data": "0x00091d14031bd6180002d6180002d6180002d6030010d6050002d6030001d6140002d6030001d6140002d6030001d6140002d6030001d6140002d6030017d6190014d60600" - }, - { - "filename": "head-peanut", - "data": "0x00041b1605040005d70f0002d7036004d70c0002d7016003c8036002d70b0002d7016001c802d7016002c8016001d70a0002d7026003d7016002d7016002d7090001d7016002c8036001d7046002d7080001d7016002d7016003d7016001d702c8016005d7040001d701600bd7016006d7020002d7016012d7020001d7016010d7016001d7020002d7016012d7020002d701600dd7026002d703000fd702c8016001d7040005d7036005d7016002d7016001d7050002d7016002d702c8056001d7026002d7060002d7026002d7016004c8016002c801d7090002d7036004d7016003d70b0003d7046003d70f0005d70400" - }, - { - "filename": "head-pencil-tip", - "data": "0x0003171409060002230c0002230b0004230a000423090006230800022301570323070002230357032306000757012305000a5704000a5703000c5702000c5701001e57042605570326015706260357072608371126" - }, - { - "filename": "head-peyote", - "data": "0x00021e14030a0001d8020001d9020001d8140001d801da010001d9010001da01d8120001d8020001da01db01d901db01da020001d8110002da05db02da0e0001d8010002a901dc02a903dc02a901dc02a9010001d8090002d802a901dc04a901dc04a901dc02a902d8090002a901dc02a902d801a901dc01a902d802a901dc02a9090002a901dc02a902d802a901dc02a902d802a901dc02a9070002a901dc0fa901dc02a9050017a9020001d8010017a9010001d8010001d817a901d8010002d817a902d8010001d817a901d8010001d8010017a9010001d8020002a901d911a901d902a9050001a913d901a9060015a9080011a90500" - }, - { - "filename": "head-piano", - "data": "0x00041b15080400050e0c00020e010501590105040e0900020e0105080e08000b0e07000d0e06000d0e06000e0e05000e0e05000f0e0400110e02004d0e0159070e0159050e0159040e0159010e0159010e0159010e0159010e0159010e0159010e0159010e0159010e0159020e1159140e" - }, - { - "filename": "head-pickle", - "data": "0x00031b15050400040f1000080f0d00030f01bf060f0c00030f015c030f01bf020f0b00020f01bf060f015c020f0a00020f015c030f01bf070f0800060f015c040f01bf015c050f0400010f01bf120f0200010f015c130f0100150f0100160f0100150f0100130f01bf010f0100020f01bf100f015c010f0200010f015c120f02000b0f012302bf015c040f0400030f01bf015c010f01bf040f025c050f0600050f015c090f09000b0f0400" - }, - { - "filename": "head-pie", - "data": "0x00011c14040b0002cb100002cb030002cb050002cb0b0002cb030002cb030002cb0b0002cb030002cb050002cb0b0002cb080002cb0b0002cb04000209040002cb0b0002cb0200020901190109020002cb0f0001dd040901dd0e0002dd010903dd020903dd010902dd080012dd050001dd010910dd010901dd030016dd020001dd04ba01dd04ba01dd04ba01dd04ba01dd01ba010033ba029503ba0196019503ba0195019603ba029505ba01950196029501960295019202950196029501960295019602950196029501ba010001950196029501960295099201960295019602950300019602950196029501920295019602950196029501960295019601950400019602950196029501960295019602950196029501960295019601950200" - }, - { - "filename": "head-piggybank", - "data": "0x00041d14020c0003421700014203930142050002760c00036c012503930125026c02000176016c01760a000276026c017605120176026c0176026c017609000176106c0176060001760100036c01020f6c0176040001760259146c0176030001760159136c0112016c03760100017601590176166c0176015901000276166c017603000176146c037603000276156c0176030001590176146c017605000376106c0276070013760900067601120202011206760d000c760700" - }, - { - "filename": "head-pill", - "data": "0x00061d140305000924071d08000c24081d0500062401020724081d0300032402020a24091d0200032402020b24081d01001124091d1124091d1124091d1124091d1124091d01001024061d010f011d02000f24071d010f011d03000a2403230124061d010f011d05000c24081d08000924071d0500" - }, - { - "filename": "head-pillow", - "data": "0x000319160702de0e0002df0dde05df010002de0edf020003de0ddf020003de08df03de02df020003de0ddf020003de02df02de09df020003de0ddf020003de0ddf020003de0ddf020003de0ddf020003de0ddf020003de0ddf020003de0ddf020003de0ddf020003de05df04de04df020003de0ddf020002de0edf01000dde05df02de0e0002df" - }, - { - "filename": "head-pineapple", - "data": "0x00031914070600010f010002e00100010f0a0001e00100020f02e0020f010001e0080003e0010f02e0010f03e00a0006e00a00022802260228022602280600022802260228022602280226022804000228022602280226022802260228030001280226022802260228022602280226012802000128022602280226022802260228022601280200012602280226022802260228022602280126020001260228022602280226022802260228012602001126010010260200102601001226010002260342012604420126034202260200022603420126044201260342022603000e260200" - }, - { - "filename": "head-pipe", - "data": "0x00061c150509160e0009980e0009980f00030804981000030804981000030804981000030804981000030804980c0003160100030804980c160398010003081398010003081398010004081298010006080123010201230102012308080398020015080300140814000308" - }, - { - "filename": "head-pirateship", - "data": "0x00011f14030c0002231b00019813000198030008230f00022304000823020002230b00019805000123015101230251012301510123020001980900025501980500032302510323010003550800035505000423015103230200035507000455030002230151042301510123010003550700065501000923030001980b00019807000198070001980b000198070001980700019806000d2601980700019806000c97012601980700019806000197022309970126089701980100052601970223099701260198010001970100019701000197010001980126049701000c970a2603970500049701231097080002970323019701230197012301970123019701230197012304970a00029701230e970c000f970800" - }, - { - "filename": "head-pizza", - "data": "0x000319140708000237100002370f000137022801370e000137022801370d000137042801370c00013701280237012801370b00013702280237022801370a0001370628013709000137082801370800013708280137070001370a280137060001370a280137050001370c280137040001370c280137030001370328033708280137020001370128013701280337052802370128013701000137082803230528023710280137" - }, - { - "filename": "head-plane", - "data": "0x00041e14030d000202180005021300090210000b020e000c0246000bc710000bc710000bc710000cc70f000cc7090002c7040012c70200010202c7040005c7060207c7020001020ac7090205c7010001c701020924020206230202052402000102010007c70b0205c702000102" - }, - { - "filename": "head-pop", - "data": "0x000318140802000ca20300061405280314010005140128031404280314022802140128011401280314042804140128021401280414052803140128081404280114022805140128031404280b1405280b1404280b1405280b1404280b1404280b1404280a140528091404280b1403280314012801230202012301280214010002280c1403000ca20200" - }, - { - "filename": "head-porkbao", - "data": "0x00051914070500025701000257010002570a0002570183025701830257090002570183025701830257018301570800015701830257018302570183025706000e5704000e5703001057020010570200105701005157037d1857010010570100" - }, - { - "filename": "head-potato", - "data": "0x00061d15040f0001c81600077a1000037a01c8077a0b000b7a02c8027a07000f7a01c8027a0400167a0200177a0100187a0100187a0100187a01c8187a0100107a02c8057a0300097a01230102012301020123017a02c8057a0400057a02c80d7a0600047a02c80b7a0b000a7a0900" - }, - { - "filename": "head-pufferfish", - "data": "0x00041c160509000168020001681000016801000668010001680700034903000568014904680700054902680349076806000449036803490368024903680500034904680349036802490468040003491068060012680500126805001268030005490d680649046801930b6801930468064902930968029306490a680449076806490293046801490235014902680193054903000693026804490168039308000e930a000c930d0008930800" - }, - { - "filename": "head-pumpkin", - "data": "0x00051b1406080003af01c401af100003af01c401af100003af01c401af0b00072401af072406000724014807240300022401480724014807240148042401480724014807240148042401480724014807240148042401480724014807240148042401480724014807240148042401480724014807240148042401480724014807240148042401480724014807240148042401480585016d0385016d058501480424014807240148072401480424014807240148072401480224" - }, - { - "filename": "head-pyramid", - "data": "0x00031e14030800018601b01900028601b01700038602b01600038603b01400058603b01300058604b0110002860284028601b0028602b01000078605b00e00088606b00d00088607b00b000a8607b00a000a8608b008000b8609b007000c8606b0028601b005000d860ab004000186038401860184078607b0038601b002000986032303860bb001000f860cb0" - }, - { - "filename": "head-queencrown", - "data": "0x00021b14050a00025b1300015b01180141015b1200015b01410118015b0e00035b0200025b0200035b0900015b0300015b0100025b0100015b0300015b0500035b0500045b0500035b0100015b0200015b03000241015b018b0154015b02410300015b0200025b0200015b01000441015b0254015b04410100015b0200025b01000141015b0541015b0154018b015b0541015b01410100015b0100015b0141015b0541045b0541015b0141015b0200015b0141015b0641025b0641015b0141015b0200015b0241015b0441045b0441015b0241015b0300015b0241015b0341015b028a015b0341015b0241015b0400015b0241015b0341015b028a015b0341015b0241015b0300025b0141035b0241015b028a015b0241035b0141025b0300125b050010350500055b0841055b0400125b0200" - }, - { - "filename": "head-rabbit", - "data": "0x0004171509037208000672080006720800067208000672080065721e050b2304050202040502021f05" - }, - { - "filename": "head-rainbow", - "data": "0x00041a140608000c1807000d18060003180b14050004180b140400021803140b460300031803140b4602000118031403460b0f01000218031403460b0f031803140346030f0854031803140346030f0854031803140346030f03540512031803140346030f03540512031803140346030f035403120200031803140346030f035403120200031803140346030f032303120200031803140346030f035403120200031803140346030f035403120200" - }, - { - "filename": "head-rangefinder", - "data": "0x00061b1405020002050100020501000d7202050b7203050172020e0102010e01720205027201050372020c037203050172040e017202050172020511720105010e010c0205110c020e140c020e140c020e140c020e140c020e140c020e140c020e120c0205020e080c0505050c0205020e140c010e010514720105" - }, - { - "filename": "head-raven", - "data": "0x00041e14080100080e1100070e0c000c0e0b000c0e09000e0e08000e0e08000f0e0600100e0600100e0600100e0600100e0600090e070d0600080e0c0d0200070e0f0d070e0f0d070e0d0d0200080e090d0500" - }, - { - "filename": "head-retainer", - "data": "0x00091d150504000320150001200119062010000320011906200d00052001190220011904200b00092001190620080002200119032001190620011903200600022002190320011903200219012003190120060002200f190220040002201119012004000120031904a3011904a3011904a30119022002a302200219012001a30120011901a3011901a3021901a3011901a30119012001a30320010001a3052001a3022003a3022003a3022006a3030003a31200" - }, - { - "filename": "head-rgb", - "data": "0x00011c16040900066410000a640d000c640b000e640a000e640900106408000164062802640669016407000165072802020769015a05000265062804020669025a03000365052806020569035a02000365052806020569035a01000565032808020369055a0565032808020369055a0665022808020269065a0765012808020169075a086501e1060201e1085a086508e1085a0100086506e1085a0200086506e1085a0300086504e1085a0500086502e1085a080006650200065a0500" - }, - { - "filename": "head-ring", - "data": "0x00021a15060600084f0c00024f0102024f016c024f0d00034f016c024f0c00032a044f032a0800022a021e022a024f022a021e022a0500012a021e0a2a021e012a0300052a011e0700052a0200032a011e0b00032a0100032a021e0c00042a0102012a011e0d00062a011e0d00062a011e0d00062a011e0d00012a0102042a011e0d00012a0102042a011e0d00032a0100032a021e0a00032a0200052a081e052a0300102a05000e2a08000a2a0500" - }, - { - "filename": "head-road", - "data": "0x00061c1403020017e2020017e2020017d3020017e2020017e2010017e2020017e2020017e2020017e2020017e2010018e2010017e3020017e2020001e203e303e203e303e203e303e203e301e2020017e20200" - }, - { - "filename": "head-robot", - "data": "0x00031c140405000e1f0a000e1f0800120506000105011f0205011f0205011f0205011f0205011f0205011f0105060012050600120506000105101f010504000105010012050400010501001205010001050100031f1205010001050100010e021f1205061f1205021f020e021f1205061f1205021f010e03000105010e0259010e0259010e0259010e0259010e0259010e0105031f03000105010e020b010e020b010e020b010e020b010e020b010e010506000105100e0105060012050300" - }, - { - "filename": "head-rock", - "data": "0x00031b14050b00030c1200010c031f020c0f00010c011f010c041f020c0c00020c021f010c051f020c0500050c051f010c061f010c0300010c121f010c0100010c051f040c0a1f010c0100010c091f010c091f010c0100010c021f010c101f010c0100010c071f020c011f070c021f010c0100010c051f020c0c1f020c141f020c041f010c0e1f030c041f010c081f020c011f030c0300010c041f010c041f030c021f010c021f010c0400010c051f030c041f010c021f010c0600050c041f030c031f010c0700010c0c1f010c0400" - }, - { - "filename": "head-rosebud", - "data": "0x00021c14040c00019415000119010002941300021904941000041906940d00041908940b0005190994090006190a94080005190b94070006190394011d0894060006190394011d08940300011d020006190294021d08940200011d0100011d010007190194021d08940100011d0200041d05190194021d0694041d0300051d03190194021d0494051d0500051d0219041d0294051d0700041d0119011d0123021d0123011d0194041d0900031d0119021d0223021d0194031d0b000c1d0c000c1d0600" - }, - { - "filename": "head-ruler-triangular", - "data": "0x00021c1508019a1300019a014f1200029a014f1100019a034f1000019a044f0f00029a044f0e00019a064f0d00019a074f0c00029a074f0b00019a094f0a00019a034f0100064f0900029a024f0200064f0800019a034f0300064f0700019a034f0400064f0600029a024f0500064f0500019a034f0600064f0400019a104f0300029a094f049a034f0200019a0a4f049a044f0100019a134f" - }, - { - "filename": "head-saguaro", - "data": "0x00031c14040c000479140005790a000479050005790a00047902000279010005790a00047902000279010005790700027901000479020002790100057907000279010004790200017902af057902000279010002790100017901af04790500057902000279010002790300047905000579010003790100027904000379050004790200037901af01790100027902000479020001790100047902000379030002790200047902000179010004790200027904000279020004790200017901af0479020002790400037901000479030001af0479010003790500027901af047904af0479010003790600017901af077902af037901000279090002790323037901af037901af02790a00077901af037901af02790500" - }, - { - "filename": "head-sailboat", - "data": "0x00011c14040d0001021600020201000102130003020100010212000402010002021000020202de0102010002020f00030202de0102010003020d000702010003020c000802010004020a0009020100040209000a020100050207000b020100050206000c020100060204000d020100060203000e02010007021a00188301000183149801830300018301981083019801830500018310980183070010830400" - }, - { - "filename": "head-sandwich", - "data": "0x00041d14030d000188180003e0170002e0011a170003e0100008830188078308000783017d028301880483017d048305000283017d088301880183017d088303000883017d0a83017d048302001883020018e4020018550200016d0655016d0855016d07550100011c186d041c066d081c056d041c0100041c0298051c0398051c0298011c0100011c0400069808230698070012980400" - }, - { - "filename": "head-saturn", - "data": "0x00051c16030b0004e5130008e50f000ce50200023a030005510ee50100023a0200015105000ee505000151040002140de5011404000151040003140ce50114050001510200025503140be502140500015101000255041409e50314060001510355061405e504140700015102550f140800015104550b140151020001e5050001550251055506140255010001510800025502510a5503000151040002e50100045503510755040001510200013a02e50200065503510355050001510200023a050007550351050001510b000455040005510100" - }, - { - "filename": "head-saw", - "data": "0x00091e15020c9710a201000b9710a2020003970100069710a2020002970300059710a2020002970300059710a2020002970300059710a2020002970300059710a202000297030005970ea2010001a202000297030005970ca2010001a20400039701000297012602970ba2010001a20500099703a2025105a2010001a20600099702a2025105a2010001a2100008a20c00" - }, - { - "filename": "head-scorpion", - "data": "0x00031e1403060008e6130008e6130008e6100004e6050003e60f0004e6020003e703e60f0004e6020001e7010002e702e60d0003e6070003e70e0003e6180003e6170003e6180003e6180003e6180003e603000de7080003e6020010e70300039e05e610e703e6019e030004e602e702e802e702e802e702e801e707e6030004e604e702e802e702e804e706e608000ee7010003e6039e" - }, - { - "filename": "head-shark", - "data": "0x00031c14030a0004eb160005eb150005eb140005eb080001eb0b0006eb080001eb08000b43050002eb05000e43040003eb02001143040003eb01001243030004eb1343030003eb1343030003eb104301eb0143040003eb104301eb0143030003eb01001143040002eb02001143040001eb0300034301eb014301eb0243023c0102013c0102013c0102013c040001eb0400024301eb014301eb0243023c0102013c0102013c0102023c09000643093c0400" - }, - { - "filename": "head-shower", - "data": "0x00011c19040b00020d1600020d1300080d0e000c0d0b000e0d0900101f0800081f010b011f030b031f0800101f09000e430a000e430900104308001043080010430700124306001243060012430500144304001443040014430300164302000143010001431000014301000143020004430e0004430100014301000143010001430e0001430100014301000143190001430100014310000143010001430100" - }, - { - "filename": "head-skateboard", - "data": "0x00091e1402030016bf040003bf016a0369016a0abf016a0369016a03bf020001bf011b01bf016a0369016a0abf016a0369016a01bf011b01bf010002bf011b01bf016a0369016a0abf016a0369016a01bf011b04bf011b03bf017c0ebf017c03bf011b04bf011b03bf017c0ebf017c03bf011b04bf011b03bf017c0ebf017c03bf011b04bf011b03bf017c0ebf017c03bf011b04bf011b01bf016a0369016a0abf016a0369016a01bf011b02bf010001bf011b01bf016a0369016a05bf030e02bf016a0369016a01bf011b01bf020003bf016a0369016a0abf016a0369016a03bf040016bf0300" - }, - { - "filename": "head-skeleton-hat", - "data": "0x000519150704000a43050010430200104301002443010010ae020010ae020010ae020010ae020010ae020010ae020010ae020007ae01b001ae01b006ae04000cae060002ae01b001ae016d01ae01b001ae01b001ae01b001ae060003ae01b001ae01b001ae01b001ae01b001ae01b007000bae0300" - }, - { - "filename": "head-skilift", - "data": "0x00011e1403010001230100142301000123010001230800012301000123100001230200152301000123070001231a0001231a0002231900042318000b230c001488060001880a77018809770188050001880a7701880777016601770188050001880a7701880777016601770188050001880a7701880777016601770188050001880a770188097701880500163305001688050016330500063306230a3305001633070012330500" - }, - { - "filename": "head-smile", - "data": "0x00051d140306000424060004240a00082402000824040001240200142402000824020208240202082401021624010202240402102404020324160205241402032401000324120203240200042410020424030004240e020424040006240a0206240500142407000a2402020624090010240c000c240700" - }, - { - "filename": "head-snowglobe", - "data": "0x00051914080600048c0a00038c0151038c0151038c0400018c0151058c0151068c01510200048c0151018c0351028c0151038c0100038c0151018c0197025101970251038c0151028c0151048c025103970251098c025105970251038c0151038c0251039701260197012601970251078c0997088c04970126019701260297088c09970151068c015109970251028c1151010004510411075102000f0802000f080100" - }, - { - "filename": "head-snowmobile", - "data": "0x00071e15050c0001041800010414000305010002041600010502041600010502041600012301040226140003230426080003230600032302260155052605000c23012603550104052603000b23022602550804020002230902022602550804020005020123110202000602032301020b05030001040a020a05030001040200012301050123010501230105012301000e040200" - }, - { - "filename": "head-spaghetti", - "data": "0x00041a1c060c0003840a00038403000184038501840800038401850484028501cf028406000184028501cf018404850284048505000485018404850184058505000f850500015503850255028501cf02550385015504001055040010550300037d0c55027d0300127d0100297d0202017d0102017d0702017d0302017d0102027d0402017d0702017d0302017d0102027d0c02017d0502027d010010020100027d0100017d0e00017d0100027d0100017d0e00017d0100027d0100017d0e00017d0100027d0100017d0e00017d0100027d0100017d0e00017d0100017d0200017d0e00017d0400017d0e00017d0400017d0e00017d0200" - }, - { - "filename": "head-sponge", - "data": "0x0004191408010003290200022902000429030001290222032901220929010001290222092903220229010007290222022903220229010003290222022902220229032202290100032902220a290100102901001029010054290100012902220d2901000129022203290523042903000d290122012902000e290200" - }, - { - "filename": "head-squid", - "data": "0x00011c1a020d00026a1700046a1500036a01ec026a1300056a01ec026a1100076a01ec026a0f000c6a0d000e6a0b00014f0e6a014f0900024f0e6a024f0700024f106a024f0500034f106a034f0300044f106a014f01ec024f0200044f106a024f01ec014f0200044f106a044f0200044f106a044f0300034f106a034f0200014f0200034f0e6a034f0200014f016a014f03000245014f0123010201230102012301020123010201230102014f02450400014f016a014f020003450c4f03450300014f016a014f010014450300014f0145010001450100024501000245060002450100024501000245030003450100014502000145080001450200014502000145040001451300014f01451800014f01451800014f01451800014f0200" - }, - { - "filename": "head-stapler", - "data": "0x00081c140407000d2408001224040016240100172401001724010017240100172405181272010006181172010004180124021811000518122401003018" - }, - { - "filename": "head-star-sparkles", - "data": "0x00021b17050a0002ac10000129020001ac022901ac120001ac022901ac110001ac042901ac030001290100012905000129040001ac042901ac0400012905000329020001ac062901ac020001290100012905000129030001ac062901ac0c0002ac082902ac080002ac0c2902ac040002ac102902ac010001ac142902ac142901ac010002ac102902ac040002ac0c2902ac080001ac0a2901ac0a0001ac0a2901ac06000129020001ac072903ac022901ac080001ac0c2901ac070001ac062902ac062901ac060001ac042902ac020002ac042901ac060001ac022902ac060002ac022901ac070002ac0a0002ac0400" - }, - { - "filename": "head-steak", - "data": "0x00071b160504000e51060002510618033805180251030001510918013808180151020001510918013808180151010001510a180138091802510a180138091802510a180138091802510a180138091802510a180138091802510138091801380918035102380518033801180351051801510100035108380118015101380151041802510200085102380118035104180151050007510238051803510b000a510d0007510400" - }, - { - "filename": "head-sunset", - "data": "0x00031d1403090008491000044901420249014204490c00054901420149024201490142054909000149014201490c4201490142014907000149014201490442012601420226014201260442014901420149050001490142014903420a2603420149014201490400024903420326012801260228012601280326034202490300024903420326082803260342024902000249024203260a2803260242024901000349024202260c28022602420549024202260e2802260242034901420149024202260d2801260242014901420349024202260e28022602420449024202260e2802260242034901420149024202260c2802260242014901420349024202260628020201260528022602420549024202260c2802260242034901000349024202260a280226024203490100" - }, - { - "filename": "head-taco-classic", - "data": "0x00051d14030a00038e0167028e1200038e0167018e0167048e0e00038e0167018e015701670157018e0167028e0167018e0b00018e0267018e0367011102570367038e0a00028e026708500157038e0800018e0167018e015702110150018a0350018a025002110267028e0600028e01670650018a0750038e0600018e01110d50018a02500167018e0500018e015701110150018a0e5001110157018e03000167018e1450018e040001670450018a0c50018a0250026703000111145001110200016701000350018a0d50018a0150018a0250030001671650016703000550018a0550018a0750018a0250010001670300145001670200" - }, - { - "filename": "head-taxi", - "data": "0x00041c170405000ee50a0001e503c7040205c701e5090001e503c7040207c701e5080001e502c7040208c701e5070001e502c7040204c7034303c701e5060001e501c7040204c7014303c7014302c701e5040016e5020016e5020016e5020016e5020016e5020016e5020016e5020002e5011f10e5011f02e50100011f0137141f01370a1f061d091f010008e5061d08e50300020e0500061d0500020e0400020d1000020d0400020d1000020d0200" - }, - { - "filename": "head-thumbsup", - "data": "0x00011a14050a00012b02e5120001e5012b02e5110001e5012b02e51100012b03e5100005e50f0006e50e0006e50e0006e5012b07e5040008e5012b07e5012b0ce5012b07e5012b0ee5012b06e5012b0de5072b01000ae5012b14e5012b08e5012b0be5012b09e5012b0ce5082b010001e5022b05e5012b02e5012b08e5010008e5042b06e5012b01e5040004e5012b03e5012b07e5012b050008e5072b0200" - }, - { - "filename": "head-toaster", - "data": "0x00031a1f0504000e84060002840cd702840500018403d7089903d70184060001840cd701840700018402d7089902d701840600010b0e72010b0500010b0e72010b0500010b0e72010b020d0300010b0e72010b020d0300010b0e72010b0500010b0e72010b0500010b0e72010b0500010b0e72010b0500010b0e72010b0500010b0e72010b0400120d0100021f120d0100011f0100120d0100011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400011f1400" - }, - { - "filename": "head-toiletpaper-full", - "data": "0x00071a1605010002ed1102020002ed1102010004ed110204ed110204ed110201ed017c010d01ed110201ed017c010d01ed110201ed017c010d01ed110201ed017c010d01ed110204ed110204ed110204ed1102010002ed027c01ed010201ed010201ed010201ed010201ed010201ed010201ed0102030002ed017c100205000c020a0008020800" - }, - { - "filename": "head-tooth", - "data": "0x00041917060a0005570700045701000257050202570400015704020157030201570502015702000157060203570702015701000157100202571102025711020257110202571102025711020257110201570100015710020157020001570e020157030001570e020157040001570202097c02020157040001570d020157050001570402035704020157060001570302015703000157030201570700015702020157040001570202015708000257060002570300" - }, - { - "filename": "head-toothbrush-fresh", - "data": "0x00021914011000016716000167011c016715000167021c046711000167061c01670d000667021c0102011c01670a000367081c0102011c0167090001670d1c0167090001670d1c016709000102011c0102011c0102011c0102011c0102011c0102011c0102011c010209000f0209000f0209000f0209000f0209000f0201000143010002430100134302000143020013430100024301000543012301460123014601230a430700114307001143" - }, - { - "filename": "head-tornado", - "data": "0x00031c150406000c8109000281017c0281047e057c038106000281027c0b81017c0381050003810f7c03810300168103000b7c0181017c0781060011810900047c0181017c0181017c05810a000c810b000d810a000b810b000b810c00098110000a8108000181080008810600018105000181010001810100017c049c0281017c0681010001810300018101000481067c08810700128106000481080004810500" - }, - { - "filename": "head-trashcan", - "data": "0x00031b1405090005050f000205040001050f0001050200090505001105050008050723010d0700010d08230a0d020006050323030d0505010d04000205031f0205031f0205031f02050100010d02000305031f0205031f0205031f03050200010501000205031f0205031f0205031f02050100010503000205031f0205031f0205031f020505000205031f0205031f0205031f020505000205031f0205031f0205031f020505000205031f0205031f0205031f020505000205031f0205031f0205031f020505000205011f0523021f0205031f020505000205031f0205031f0205031f0205050011050300" - }, - { - "filename": "head-turing", - "data": "0x00041d190315000189070012610189016105000289016101cb01820161018201cb01610282016101cb0182016101cb018201610182018901610400018901940261028201610282016101cb018201610282016102820161018201cb0289030001890194146101890300018901000261018201cb016102820161018201cb0161018201cb01610282016102820161018903000189010002890282016101cb01820161028201610282016101cb0182016101cb018201610189020002890194016101891261018901940100038901610189018201cb01610282016101cb01820161018201cb016102820161018201cb016101890100028901000189016101890282016101cb018201610282016102820161018201cb016102820161018901000289010001890161018912610189010002890100018901610189018201cb016102820161028201610282016101cb01820161028201610189010002890100038902820161018201cb0161018201cb0161018201cb01610282016101cb0182016101890100028901000189146101890100028901000189026102020161020201610202016102020161020201610202016102000289010001890261020201610202016102020161020201610202016102020161018901000289010001891461018901000289010001890194110001940100028901000189020002891100018904000189010002891600018901000194180002891600" - }, - { - "filename": "head-ufo", - "data": "0x00021e15020e00014f1a00034f1a00014f1800064f14000a4f10000e430d000a4301060143020602430c000c43020602430b0012430a0012430a0012430900144308001443080014430800144f0600184f0300054f026d014f026d014f026d014f026d014f026d014f026d044f0100064f026d014f026d014f026d014f026d014f026d014f026d054f0400144f0d000a4f0900" - }, - { - "filename": "head-undead", - "data": "0x00021b16050600027903261100047902000279032607000126030002790300057908000126017902000279020003790b000126017902000279020003790b00027902000279020002790200018003000126050002790200037901000279050001790226040002790300057905000479010001800200027902000579060003790100028001000279020005790700027904000a79040004790500107906000f790200028005000a7904000280070008790a000180030008790d0001800179012301250123012501230279018003000180070003800679038009000e80090001800100038002000280010001800e000180090001800300" - }, - { - "filename": "head-unicorn", - "data": "0x00041b16040b00021c1200011c0300021c060001260b00021c0100021c04000226080003660100051c020003260600031c0366071c032601660400011c0100031c0766011c042602660500031c01200766042603660600011c02200766032604660600032007660226056605000420076601260666060003200e66060003200e6606000320125f01000220023a0e5f0120015f0120015f0100043a035f012001660123016601230166012301660120065f0200033a125f0200033a125f0300023a1600013a1200" - }, - { - "filename": "head-vent", - "data": "0x00081c140433020123010201230102012301020123020201230102012301020123010201230802011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f0802011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f010201230602011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f010201230402011f0102011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f010201230102011f0402011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f010201230602011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f010202010502011f0102011f0102011f0102011f0202011f0102011f0102011f0102011f08020101010201010102010101020101020201010102010101020101010201013502" - }, - { - "filename": "head-void", - "data": "0x00051b14050123020001230200012302000123020001230200012302000123020001232c000123140001232c000123140001232c000123140001232c000123140001232c00012302000123020001230200012302000123020001230200012302000123" - }, - { - "filename": "head-volcano", - "data": "0x00031c15040800081f1000011f0641011f0f00021f0642021f0e00011f014106280141011f0d00021f0341031f0241021f0c00021f0141041f0141021f0141011f0b00021f01410b1f0a00041f010c051f010c031f0900051f010c051f010c041f0800051f010c051f010c041f0700051f010c071f010c041f0600051f010c071f010c041f0500061f010c071f010c051f0400051f010c091f010c041f0300021f020c0f1f010c021f0200021f020c051f010c0c1f01000a1f010c0341010c041f020c091f010c021f010c091f020c031f0200141f0200" - }, - { - "filename": "head-volleyball", - "data": "0x00031b1505090004d30f0001d301ee02d3020202d301ee01d30a0003d301ee02d3020202d301ee03d3070001d301ee03d301ee04d301ee03d301ee01d3050003d301ee02d301ee04d301ee02d301ee03d3040004d30aee02d3010201d3030004d301ee0ad301ee04d3020003d301ee0cd301ee01d3010201d3020003d301ee0cd301ee01d3010201d3010004d301ee0cd301ee01d3010206d301ee0cd301ee02d3010205d301ee0cd301ee02d3010205d301ee0cd301ee04d3010003d301ee0cd301ee04d3010003d301ee0cd301ee03d3020001d3010202d301ee0ad301ee04d3030001d3010202d30aee04d3040003d301ee02d301ee04d301ee02d301ee03d3050001d301ee03d301ee04d301ee03d301ee01d30300" - }, - { - "filename": "head-wall", - "data": "0x00031a15060237041a01830237011a01370f1a0183131a0183131a01830d1a0100128301000237011a0137091a01830237111a0183131a0183131a0183061a0100128301000237041a01830137121a0183131a0183131a01830d1a0100128301000237011a0137091a018302370b1a0337031a0183131a0183131a0183061a" - }, - { - "filename": "head-wallet", - "data": "0x00081d1403020008a30e8c0200029701a308510ec70297012301a308510ec70e9701080d970ba30197010801970a43029701a3057c05a3019701080d9701a3017c03a3017c05a30197010801970a26029701a3017c03a3017c05a3019701080d9701a3027c01a3027c05a30197010801970a98029701a3017c03a3017c05a30197010801970a98029701a3057c01a3034701a3019701080d970ba301970108199701080c97" - }, - { - "filename": "head-wallsafe", - "data": "0x00091d14041a08117e010805240208017e0f08017e010805240208017e0f08017e0808017e0f08017e0108012401080124010801240208017e0f08017e0808017e0f08017e0108012401080124010801240208017e010801a30d08017e0808017e01a3010801a30c08017e0108012401080124010801240208017e010801a30208010201230102012301020123010201230308017e0808117e010801a301080124010801a31a08" - }, - { - "filename": "head-washingmachine", - "data": "0x0003191f0402000fed060002ed017201ed017201ed017401ed017201ed015101ed0155017402ed050002ed017401ed017401ed017201ed017403ed0143017402ed0500037210510200037206510472065102000372045102720475027204510200037203510172087501720351020003720351017208750172035102000372025101720a750172025102000372025101720a750172025102000372025101720a750172025102000372025101720a75017202510200037203510172087501720351020003720351017208750172035102000372045102720475027204510223037201510243035104720651012301000372105101230100037210510123140001231400012314000123140001231400012314000123140001231400012314000123140001231400" - }, - { - "filename": "head-watch", - "data": "0x00041a150802000c0a05000826011e0126021e0226030001260e51012602000126065102780651012602000126035101780651017803510126020001260e51012602000126015101780a51017801510126020001260e5101260100010a01260e510126010a02260e510126020a01260e510126010a02260e5101260100010a0126045101780451017804510126020001260e510126020001260651027806510126020001260e51012603000e2605000c0a0400" - }, - { - "filename": "head-watermelon", - "data": "0x00031b15050400051d1000051d02240e00051d0124011802240d00041d0224012303240b00041d08240a00031d06240123011802240800041d02240123011807240700031d0d240600031d0e240500031d0f240400031d10240300031d11240300021d12240200031d1124011d0200021d1024011d0400021d042401230118012301180624011d0600031d0a24021d0800041d0624021d0d00071d0700" - }, - { - "filename": "head-wave", - "data": "0x00021c1401120004de13000ade0f0002de014a0ade0d0005de024a0243014a02de014a02de0b0002de024a01de024a0143054a02de014a01de090002de024a01de024a01de034a01de0143024a03de090001de034a01de024a01de024a01de064a01de080002de024a01de024a01de034a01de024a0300014a01de080001de034a01de024a01de054a040001de080001de0d4a0d0001de0d4a0c0002de0d4a0c0001de0e4a0b0001de0f4a0b0001de0f4a0a0001de074a0143024a0143034a0143014a0a0001de044a01de024a0143034a0143034a0143014a050001de020001de044a01de044a0143034a0243054a040002de164a0100014a" - }, - { - "filename": "head-weed", - "data": "0x00011d15020d00010f1900020f1900020f0100010f1600040f1000010f0600040f0700010f0800020f0600030f0100010f0400020f0800030f0100010f0200050f0400030f0900040f0200060f0100040f0a00050f0200040f0100050f0b00050f0100040f0100040f0600010f06000d0f0600010f0100020f0100010f03000b0f0500020f0200040f0200130f0300170f0600130f09000f0f1000030f015c030f015c010f1100050f035c030f0e000f0f0b00110f0900020f0f00020f0400" - }, - { - "filename": "head-weight", - "data": "0x00021a140506000127089601950b0001270196072701950b0001270196060001270195070003270d960195040003270396010e0196010e0196020e04960195040003270396020e0296010e05960195040003270396010e0196010e0196010e0196010e03960195040003270396010e0196010e0296020e03960195030003270f960195020003270f960195020003270f960195020003270f960195020003270f960195020003270f960195010003271196019503271196019503270496092704960195032711960195032711960195" - }, - { - "filename": "head-werewolf", - "data": "0x00061c1404030005970700059707000597070005970700059707000597070011260700110707001126070002970e810197070002970e810197060003970e810197050004970e810197040005971181029703000297018101d5018101d50f8102000397018101d5018101d5018104230102012301020323038102000497018101d5018101d502230102062301020223018102000597018101d5018101d50c820300" - }, - { - "filename": "head-whale-alive", - "data": "0x00021e15021100044a1700064a1500084a13000a4a1100064a010e054a0300014a0400014a0600064a010e014a010e054a0200024a0200024a05000f4a01560100064a05000f4a01560200044a07000d4a03560200034a07000c4a04560200054a05000b4a055602000156134a065603000156114a0756030003560e4a0756050005560a4a085605000656084a085607000556014a030e034a085609000356074a08560b000156064a0856100009560900" - }, - { - "filename": "head-whale", - "data": "0x00041a1606080009d50a000cd5070005d5080d060005d5010d097c040005d5010d037c0281017c0281017c0181030005d5010d017c0281017c0281017c0281017c0181020005d5010d0481017c0281017c0281017c0181010005d5010d0581017c0281017c0281017c018106d5010d0581017c0281017c0281017c018106d5010d0581017c0281017c0281017c018106d5010d0581017c0281017c0281017c018106d5010d0481017c0381017c0281017c018106d5010d0381017c0381017c0381017c018103d5010d02d5010d0281017c0381017c0381017c028102d5030d01d502980181017c0281017c0381017c038103d5010d02d50398017c0281017c0281017c0381010006d50398017c0281017c0281017c028108000398110003980b00" - }, - { - "filename": "head-wine", - "data": "0x00051b14053f6f0102156f0102156f0102036f129401190194026f1494026f1494026f1494026f1494026f1494036f1294026f0100016f1294016f0200026f069404190694026f0300036f0c94036f06000e6f0400" - }, - { - "filename": "head-wizardhat", - "data": "0x00041b1404030008eb0e0006eb014604eb0c0001eb020002eb034604eb0b000146030002eb014606eb08000546020004eb014604eb08000346040002eb014601eb014601eb014602eb0700014601000146050002eb014606eb0e000aeb0c0008eb014602eb0c0001eb014605eb034602eb0b0008eb014603eb0b0004eb014607eb0a000deb09000eeb080007eb050e02eb0700125403001654" - }, - { - "filename": "head-zebra", - "data": "0x00061b14060a00010201230a000223035e0102012301020123010202230100035e05000202035e0102012301020123010201230200035e05000223055e0123035e0123045e05000202065e0323055e05000223065e0323055e05000202075e0123065e05000223075e0123065e05000202075e0123065e050002230e5e050002020c5e0623010002230d5e012301020123010201230302025e0102012301020123010201230102035e09230d5e052303020d5e0523" - } - ], - "glasses": [ - { - "filename": "glasses-hip-rose", - "data": "0x000b1710070300062001000620030001200202022301200100012002020223052002020223032002020223052002020223032002020223022002000120020202230120010001200202022301200300062001000620" - }, - { - "filename": "glasses-square-black-eyes-red", - "data": "0x000b17100703000623010006230300012302020264012301000123020202640523020202640323020202640223020001230202026401230100012302020264022302000123020202640123010001230202026401230300062301000623" - }, - { - "filename": "glasses-square-black-rgb", - "data": "0x000b1710070300062301000623030003230164022301000323016413230200012301650223015a01230100012301650223015a022302000623010006230300062301000623" - }, - { - "filename": "glasses-square-black", - "data": "0x000b171007030006230100062303000123020203230100012302020723020205230202042302000123020203230100012302020423020001230202032301000123020203230300062301000623" - }, - { - "filename": "glasses-square-blue-med-saturated", - "data": "0x000b17100703000643010006430300014302020223014301000143020202230543020202230343020202230243020001430202022301430100014302020223024302000143020202230143010001430202022301430300064301000643" - }, - { - "filename": "glasses-square-blue", - "data": "0x000b17100703000607010006070300010702020223010701000107020202230507020202230307020202230207020001070202022301070100010702020223020702000107020202230107010001070202022301070300060701000607" - }, - { - "filename": "glasses-square-frog-green", - "data": "0x000b171007030006bf010006bf030001bf0202022301bf010001bf0202022305bf0202022303bf0202022302bf020001bf0202022301bf010001bf0202022302bf020001bf0202022301bf010001bf0202022301bf030006bf010006bf" - }, - { - "filename": "glasses-square-fullblack", - "data": "0x000b1710070300062301000623030004230102012301000423010208230102062301020223020006230100072302000623010006230300062301000623" - }, - { - "filename": "glasses-square-green-blue-multi", - "data": "0x000b1710070300060f0100068b0300010f02020223010f0100018b02020223018b034a010f02020223010f014a018b02020223028b0200010f02020223010f0100018b02020223028b0200010f02020223010f0100018b02020223018b0300060f0100068b" - }, - { - "filename": "glasses-square-grey-light", - "data": "0x000b171007030006c7010006c7030001c70202022301c7010001c70202022305c70202022303c70202022302c7020001c70202022301c7010001c70202022302c7020001c70202022301c7010001c70202022301c7030006c7010006c7" - }, - { - "filename": "glasses-square-guava", - "data": "0x000b17100703000637010006370300013702020223013701000137020202230537020202230337020202230237020001370202022301370100013702020223023702000137020202230137010001370202022301370300063701000637" - }, - { - "filename": "glasses-square-honey", - "data": "0x000b171007030006dd010006dd030001dd0202022301dd010001dd0202022305dd0202022303dd0202022302dd020001dd0202022301dd010001dd0202022302dd020001dd0202022301dd010001dd0202022301dd030006dd010006dd" - }, - { - "filename": "glasses-square-magenta", - "data": "0x000b17100703000609010006090300010902020223010901000109020202230509020202230309020202230209020001090202022301090100010902020223020902000109020202230109010001090202022301090300060901000609" - }, - { - "filename": "glasses-square-orange", - "data": "0x000b17100703000614010006140300011402020223011401000114020202230514020202230314020202230214020001140202022301140100011402020223021402000114020202230114010001140202022301140300061401000614" - }, - { - "filename": "glasses-square-pink-purple-multi", - "data": "0x000b171007030006200100069a030001200202022301200100019a02020223019a036e0120020202230120016e019a02020223029a020001200202022301200100019a02020223029a020001200202022301200100019a02020223019a030006200100069a" - }, - { - "filename": "glasses-square-red", - "data": "0x000b17100703000624010006240300012402020223012401000124020202230524020202230324020202230224020001240202022301240100012402020223022402000124020202230124010001240202022301240300062401000624" - }, - { - "filename": "glasses-square-smoke", - "data": "0x000b17100703000659010006590300015902660223015901000159026602230559026602230359026602230259020001590266022301590100015902660223025902000159026602230159010001590266022301590300065901000659" - }, - { - "filename": "glasses-square-teal", - "data": "0x000b1710070300061c0100061c0300011c02020223011c0100011c02020223051c02020223031c02020223021c0200011c02020223011c0100011c02020223021c0200011c02020223011c0100011c02020223011c0300061c0100061c" - }, - { - "filename": "glasses-square-watermelon", - "data": "0x000b17100703000637010006370300013702020223013701000137020202230537020202230337020202230237020001370202022301370100013702020223023702000137020202230137010001370202022301370300063701000637" - }, - { - "filename": "glasses-square-yellow-orange-multi", - "data": "0x000b17100703000626010006130300012602020223012601000113020202230113034201260202022301260142011302020223011301260200012602020223012601000113020202230113012602000126020202230126010001130202022301130300062601000613" - }, - { - "filename": "glasses-square-yellow-saturated", - "data": "0x000b17100703000628010006280300012802020223012801000128020202230528020202230328020202230228020001280202022301280100012802020223022802000128020202230128010001280202022301280300062801000628" - } - ] - } -} \ No newline at end of file diff --git a/packages/nouns-contracts/tasks/descriptor-art-to-console.ts b/packages/nouns-contracts/tasks/descriptor-art-to-console.ts index db0176f0cf..6dda33f15a 100644 --- a/packages/nouns-contracts/tasks/descriptor-art-to-console.ts +++ b/packages/nouns-contracts/tasks/descriptor-art-to-console.ts @@ -1,6 +1,6 @@ import { writeFileSync } from 'fs'; import { task, types } from 'hardhat/config'; -import ImageData from '../files/image-data_v2.json'; +import ImageData from '../files/image-data-v2.json'; import { dataToDescriptorInput } from './utils'; import path from 'path'; import { ethers } from 'ethers'; diff --git a/packages/nouns-contracts/tasks/descriptor-v1-export-abi.ts b/packages/nouns-contracts/tasks/descriptor-v1-export-abi.ts index 269c351c4e..cd18bf07ad 100644 --- a/packages/nouns-contracts/tasks/descriptor-v1-export-abi.ts +++ b/packages/nouns-contracts/tasks/descriptor-v1-export-abi.ts @@ -1,7 +1,7 @@ import { writeFileSync } from 'fs'; import { task, types } from 'hardhat/config'; import path from 'path'; -import ImageData from '../files/image-data.json'; +import ImageData from '../files/image-data-v1.json'; task( 'descriptor-v1-export-abi', diff --git a/packages/nouns-contracts/tasks/populate-descriptor-v1.ts b/packages/nouns-contracts/tasks/populate-descriptor-v1.ts index cabf9d66bf..93f7415f5f 100644 --- a/packages/nouns-contracts/tasks/populate-descriptor-v1.ts +++ b/packages/nouns-contracts/tasks/populate-descriptor-v1.ts @@ -1,5 +1,5 @@ import { task, types } from 'hardhat/config'; -import ImageData from '../files/image-data.json'; +import ImageData from '../files/image-data-v1.json'; import { chunkArray } from '../utils'; task('populate-descriptor-v1', 'Populates the descriptor with color palettes and Noun parts') diff --git a/packages/nouns-contracts/tasks/populate-descriptor.ts b/packages/nouns-contracts/tasks/populate-descriptor.ts index f856842537..abf0d60e2f 100644 --- a/packages/nouns-contracts/tasks/populate-descriptor.ts +++ b/packages/nouns-contracts/tasks/populate-descriptor.ts @@ -1,5 +1,5 @@ import { task, types } from 'hardhat/config'; -import ImageData from '../files/image-data_v2.json'; +import ImageData from '../files/image-data-v2.json'; import { dataToDescriptorInput } from './utils'; task('populate-descriptor', 'Populates the descriptor with color palettes and Noun parts') diff --git a/packages/nouns-contracts/test/descriptor.test.ts b/packages/nouns-contracts/test/descriptor.test.ts index 85d339aa67..9147dc1285 100644 --- a/packages/nouns-contracts/test/descriptor.test.ts +++ b/packages/nouns-contracts/test/descriptor.test.ts @@ -1,7 +1,7 @@ import chai from 'chai'; import { solidity } from 'ethereum-waffle'; import { NounsDescriptor } from '../typechain'; -import ImageData from '../files/image-data.json'; +import ImageData from '../files/image-data-v1.json'; import { LongestPart } from './types'; import { deployNounsDescriptor, populateDescriptor } from './utils'; import { ethers } from 'hardhat'; diff --git a/packages/nouns-contracts/test/descriptorV2.test.ts b/packages/nouns-contracts/test/descriptorV2.test.ts index 7b35f9c8f2..59b9ec8b63 100644 --- a/packages/nouns-contracts/test/descriptorV2.test.ts +++ b/packages/nouns-contracts/test/descriptorV2.test.ts @@ -1,7 +1,7 @@ import chai from 'chai'; import { solidity } from 'ethereum-waffle'; import { NounsDescriptorV2 } from '../typechain'; -import ImageData from '../files/image-data_v2.json'; +import ImageData from '../files/image-data-v2.json'; import { LongestPart } from './types'; import { deployNounsDescriptorV2, populateDescriptorV2 } from './utils'; import { ethers } from 'hardhat'; diff --git a/packages/nouns-contracts/test/utils.ts b/packages/nouns-contracts/test/utils.ts index cc20a477b7..d34a3565b1 100644 --- a/packages/nouns-contracts/test/utils.ts +++ b/packages/nouns-contracts/test/utils.ts @@ -20,8 +20,8 @@ import { NounsDAOExecutor, Inflator__factory, } from '../typechain'; -import ImageData from '../files/image-data.json'; -import ImageDataV2 from '../files/image-data_v2.json'; +import ImageData from '../files/image-data-v1.json'; +import ImageDataV2 from '../files/image-data-v2.json'; import { Block } from '@ethersproject/abstract-provider'; import { deflateRawSync } from 'zlib'; import { chunkArray } from '../utils'; From 353ebfe1535cc5d40197638cfb60f7b684e1e9fd Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Wed, 13 Jul 2022 19:09:59 +0200 Subject: [PATCH 100/116] fix a trait images, these will affect already minted nouns as well --- .../images/1-bodies/body-foggrey.png | Bin 2073 -> 2174 bytes .../nouns-assets/images/3-heads/head-beer.png | Bin 3952 -> 3999 bytes .../images/3-heads/head-piggybank.png | Bin 2023 -> 2106 bytes .../glasses-square-green-blue-multi.png | Bin 1908 -> 1903 bytes .../glasses-square-pink-purple-multi.png | Bin 1908 -> 1902 bytes .../4-glasses/glasses-square-watermelon.png | Bin 1897 -> 2088 bytes .../glasses-square-yellow-orange-multi.png | Bin 1910 -> 1910 bytes packages/nouns-assets/src/image-data.json | 808 +++++++++--------- .../nouns-contracts/files/image-data-v2.json | 808 +++++++++--------- .../test/foundry/DescriptorUpgrade.t.sol | 14 + .../files/descriptor_v2/accessoriesPage.abi | 2 +- .../files/descriptor_v2/bodiesPage.abi | 2 +- .../files/descriptor_v2/glassesPage.abi | 2 +- .../foundry/files/descriptor_v2/headsPage.abi | 2 +- .../descriptor_v2/paletteAndBackgrounds.abi | 2 +- 15 files changed, 827 insertions(+), 813 deletions(-) diff --git a/packages/nouns-assets/images/1-bodies/body-foggrey.png b/packages/nouns-assets/images/1-bodies/body-foggrey.png index f70f41b059e768495bb789c5b9b4f79ea766571e..1d4327652812c9854580c04179232dcc3a331256 100644 GIT binary patch delta 425 zcmbO!@K0cZCF7-uRy`W#dPcg*1_lNS=9YSmKLeHMwaFlx+bZ~hPsxPDJi;! zCTYnQhN;FTiAgDw8(5?!$FSI`B&L`eCYc(h>86>cnd_Pur&#DFrY0upnx`3=n;IFU zq!}9|ZEj%kWpX9PekFzC64$a4tMZK0JXJh_BTd2$+iWM1w>ZCwTi zh9FND$B>BDd6G}p>Hl!Ddr>|ka%P{Qu;k;Cc(&~ye*S3j3^P6l&Db7+P4F8d(`yPCm~hiz)br$xOWxelJ#`;b6Mw<&;$VZqi#k3 diff --git a/packages/nouns-assets/images/3-heads/head-beer.png b/packages/nouns-assets/images/3-heads/head-beer.png index 3cdf8838c5280f56f184ce97498890a8d5050e8a..05e0132feb305a49f52ed6042693105eb9fa6592 100644 GIT binary patch delta 570 zcmew$H(!2&C8Oy?s~!z=JtN&@0|NsEb4xu_GqcpBWK$glBLgENeFIZ{14~^4b1New zDBVo9P)Vo9p4637HJ#giv8 zn@#?}ETv*@l4O!(ZkVELnUrFrn`CN|sB39#W~6JHm}-`mXk=)bnrgUNk7Y842Qey@ z6pBk+%Sx=uGg9-g+6#2X=c`5nj#gqSXN^Fkebz!VOv{CLi0|TRg zr;B4qL~HV&|Nrd|J1{L{+&Z_hv9VR;=>C0n|IZ%)f@8WTJI=U^DT^8iNwc1qCdjnJ zqD_N+LXzdmKFJRz4i^}w{Fo>4*QNEq{!BNO=ri9;XK0kN6f;V1S9#3O*7o1P-5_;t zv-PWsRb^}-(0cdy$5-m7>ly9e=N^$N;g8XklmLP!OoB-U#}CMS%AY03?7TyIcRKf#A)xQ!d3BmbF~hi*XQARljJhP*N0<*-fX^(PPawT nE?bx&rd?rN%qLOGu$GZQ(<;(JvNEBM0SG)@{an^LB{Ts5Vwl70 delta 557 zcmbO)|3PkoC1b)ws~!zAJp2mF1RLq=Yvq|& zT#}fVoa*Ufs|2(}FEca6$|BJ)H96TZP1nf6AW_%EEX_>U(#XJA*Vri8#MHpTG|kK? z8K&PQKe;qFHLnDuKQSdgX|pU#HHQarCKQ*rmX%nQXQbv~^$yT?lLdLSnT_;JCfoBU zZ`S8^VXWWpvnif|fnl4ci(^Pc>)XqQe69`x4T;AmXiPb`pnygE^3KlJ8e4?^ddpqi zFlnOVn%Fd_lrH;7uFtB;%nTg!-ducmui@eKrp(_y_d6M1Y}kB*(e7}q;d}NwlJA-d znErHMsLz=GiNS}>AUy4~``Mj-k1eGieB%1GjH!pI;KjX}!H-fHg3TD_2^PGTdi3Ec zm&gaL2G-BI2OjE9U<){+nb4fboFMW*#Jpi0^XbVi41WFZV2nv(_E^Tis^P%MCBZn| Xn(e@@%lfB)USRNa^>bP0l+XkKGsC=V diff --git a/packages/nouns-assets/images/3-heads/head-piggybank.png b/packages/nouns-assets/images/3-heads/head-piggybank.png index 5de578c722bd9ef117f577a3ac8682a6fa5135ea..b80093337b6cfb83e005f486f297d20154461d78 100644 GIT binary patch delta 602 zcmaFPze`|(C1c-2s~!z=JtN&@0|NsEb4xu_GqcpBWK$glBLgENeFIZ{14~^4b1New zDHL@@_G&j?=FiW-2HB2!v z(oISQaxD!F%ni(wQc@EQ(l*a#&Sr8ULZOmEafxeLiB)+BDgcm4$ajF2h3{qsyc8xUOGt7akVv4y!#+{W$44LQ?i79lep zd|D%%BAGZ%`$dv#6FY*IWU&b8|i&{Q5Ce!cxE7FGYX>f5ZcU2{cDPvq1n zHe6>kh!0@muw+mcKTz{$_XEQ_Mb|htrC2*ShRfusIkMj=v->PRJG)-oM(s9Zi%jEI z83(_DDNRdfe>-?{``q(?+{-z_*af_HE@{ZHR|h)GLnFc4UxP2;ZuX%L{e2mX22Kp| zT}xR&?#Vv!XbtxYN!|h;9v3%8o(o1I7tS7w7CG$HDAg*+%v{zlsKcqbNs{vcSLmYG zOeFOp4@n2@Z00f?{elF{r5}E+7e$V*; delta 536 zcmdlb@SJ~wCF9PCRy`VKdIq}51_ovd=9YRXiAjmcNl7{iMg~TP`UWQYh9T$-DjR|3<&xr;fNNtp-( zCL6Mfb0K+1kxg%M1FPEPVz$V7##tAqGB7Y)@pN$viQr8B@&CX5VTYu)Kz5!;_L}#T ze()bIDQCEGiTh*@4^GlJ#|zvfuOw_w@P1%+Q2 ziy5}XG+t%A(ovn{%yf<+vPbvo<+F@e{Qln1QIlZZ@yYJ4b3@omhG;*92&SOb21;7e zkBV8A&UmzoLALpmInRMtOhGzoJI$6%>vx}>vY1bz^uP*cH(7%hG7Jp+614pdeyj}v PdXT}>)z4*}Q$iB}z%aTW diff --git a/packages/nouns-assets/images/4-glasses/glasses-square-green-blue-multi.png b/packages/nouns-assets/images/4-glasses/glasses-square-green-blue-multi.png index b711361fa359f8fa04cb4a85dd87b5e8df68e9f2..6352f403abc19fb717c7b8f9747d3cf94089336b 100644 GIT binary patch delta 399 zcmeyu_nvQpC1b}#s~!z=JtN&@0|NsEb4xu_GqcpBWK$glBLgENeFIZ{14~^4b1New zDsDY&ojwl3jSd-n;gw7rIKQ4Zeg05WT2a5Vriml zX>MYoo0yuM2DHx9GSwnE#njZ)Wb;hsG$vPKR4OSHm$;UdSe0j_=GiKNT!`+NJuG^R z#*>$^Do>ul7FnMWe=v-JfuYya#W5tJHTlo~|MrI+n3geat-Zpym`|egzzSxzX6A?w zo~y3zYu+sXi7i=o^HclvsVNBw2eispM|Mn9VqefaKlQhy1PDkfKHF4kr4Zewv^?tb zG!0`;%Z3@Vx)$B)nPGB(ttZ Y;~_YL=X6ZfQDsCUZ}HK}LQ_esM;Aft5>sa%paAUWsE~a%yo& zeo?WVf=y9Mnw3*xI+T@@X;+b3pqG-FVr6DwWMFP+Zls%PY?P*JVql!6n`mxmshehL zkz{U|WME=wnP{UA(hk%FF$YO^nyIBpl7*p}ZmN%^k%4ZSk%@t>rGasZZkkzgvYBzJ zv8kzLGLm+%K@fN7<8kn2C6@b)uEcm#FRtXg3=%KrZMUTf=&qP5Z zJTosPzr1*I6I)?DbC1Xw1_p*QPZ!6Kh}Psk|Nq+`c3@h@xV82Q<6=IE(gQ1)*_xRn zK6viyEp&YLNNclX;Ym*Yn}!z>D}y%^hHlJ3KKc6~f~ z`3j>6YtN5c%wIfODr6n_4ITs@RDzW1ryuWiB>%tW_kv?$p!{y3g(u2DTzsm$w^5%3PuJ-hWZ93`i3UD1_oBf zmR2Sv8{b`I6fo2^FxNFO4KcK^GBvO=F`j&$NfuM^50jaCK}LQ_esM;Aft9DTb3jpk zT4qkFtx|E2yOV;atFxJ*rJ0$ok)GjX17;bOGy}`Dw4^kk$teaYx+cb^#<~_psVTZ? zMv2Lmrm03rsY%9@3z&O0pJKVgNSta1RuNuQmnO0rPxfb1oNUV;S@z?7Tpt4iLzJhB zV@Sl|w^w|*7z9LGFK+jry&-3Jg@ne_?H7!HT#=0}@^A?~YQzLo%D_;j&h~!G^w4tA zfVL&6mZk|;WErj0v&?3ehBG`fPvH9TO7IguSRn($dLc&N)ay3p(Z<~%5l>e?mvv4F FO#tiaaX0_~ diff --git a/packages/nouns-assets/images/4-glasses/glasses-square-yellow-orange-multi.png b/packages/nouns-assets/images/4-glasses/glasses-square-yellow-orange-multi.png index 90a2baefb98a092a3debce82c56755ceb5f73fc1..04782f5572820ce510313d74acda9cf9f7e287bd 100644 GIT binary patch delta 402 zcmeyy_l<9YC1cM-s~!z=JtN&@0|NsEb4xu_GqcpBWK$glBLgENeFIZ{14~^4b1New zDnPf2q|1p_Oj%AioNi#K1PBcum)J;h>PSZ6r zH%Zk^G)pnjHAzY_G%`=LOg1z!+&r5(gUOW`l}ZZ5C9Y*9R^=I~dA3R*7ot06AB!HN z@#Iyk%9H1?Mb?`n<}YAiV3^?P;usRqn*8VgfBVA@Ov@Oz)?Q&;%qLNLUf? z>nzSY&fn-M&|190Oj(WBz{$|Aa+X!YvWAH-zA^L)DSp)DTOcU$K?7`$o27E|yalUaR1Mt(_taYlZDm8Y|FKv8~L zW=^WDQgM*GlY*zKvzei#nVGJUo}rRLMQ(wwua#$BaYWvefnq^ZAf2! Date: Thu, 14 Jul 2022 08:35:17 +0200 Subject: [PATCH 101/116] remove unneeded test minter, just use token harness for testing --- .../contracts/test/NounsTestMinter.sol | 20 ------- .../contracts/test/NounsTokenHarness.sol | 25 +++++++++ .../tasks/deploy-test-minter.ts | 35 ------------ .../tasks/deploy-test-token.ts | 56 +++++++++++++++++++ packages/nouns-contracts/tasks/index.ts | 2 +- 5 files changed, 82 insertions(+), 56 deletions(-) delete mode 100644 packages/nouns-contracts/contracts/test/NounsTestMinter.sol delete mode 100644 packages/nouns-contracts/tasks/deploy-test-minter.ts create mode 100644 packages/nouns-contracts/tasks/deploy-test-token.ts diff --git a/packages/nouns-contracts/contracts/test/NounsTestMinter.sol b/packages/nouns-contracts/contracts/test/NounsTestMinter.sol deleted file mode 100644 index 5198a5b2f7..0000000000 --- a/packages/nouns-contracts/contracts/test/NounsTestMinter.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity ^0.8.15; - -import { INounsToken } from '../interfaces/INounsToken.sol'; -import { NounsTokenHarness } from './NounsTokenHarness.sol'; - -contract NounsTestMinter { - NounsTokenHarness public nouns; - - constructor(NounsTokenHarness nouns_) { - nouns = nouns_; - } - - function mintMany(address to, uint256 amount) public { - for (uint256 i = 0; i < amount; i++) { - nouns.mintTo(to); - } - } -} diff --git a/packages/nouns-contracts/contracts/test/NounsTokenHarness.sol b/packages/nouns-contracts/contracts/test/NounsTokenHarness.sol index f49d4a5d28..931307b8b8 100644 --- a/packages/nouns-contracts/contracts/test/NounsTokenHarness.sol +++ b/packages/nouns-contracts/contracts/test/NounsTokenHarness.sol @@ -21,4 +21,29 @@ contract NounsTokenHarness is NounsToken { function mintTo(address to) public { _mintTo(to, currentNounId++); } + + function mintMany(address to, uint256 amount) public { + for (uint256 i = 0; i < amount; i++) { + mintTo(to); + } + } + + function mintSeed( + address to, + uint48 background, + uint48 body, + uint48 accessory, + uint48 head, + uint48 glasses + ) public { + seeds[currentNounId] = INounsSeeder.Seed({ + background: background, + body: body, + accessory: accessory, + head: head, + glasses: glasses + }); + + _mint(owner(), to, currentNounId++); + } } diff --git a/packages/nouns-contracts/tasks/deploy-test-minter.ts b/packages/nouns-contracts/tasks/deploy-test-minter.ts deleted file mode 100644 index 68f6c2ec60..0000000000 --- a/packages/nouns-contracts/tasks/deploy-test-minter.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { task } from 'hardhat/config'; - -task('deploy-test-minter', 'Deploy NounsTestMinter given a descriptor') - .addParam('descriptorAddress', 'Address of a deployed descriptor contractor') - .addParam('seederAddress', 'Address of a deployed seeder contract') - .setAction(async ({ descriptorAddress, seederAddress }, { ethers, run, network }) => { - const [deployer] = await ethers.getSigners(); - console.log(`Deploying from address ${deployer.address}`); - - const nonce = await deployer.getTransactionCount(); - const expectedTokenAddress = ethers.utils.getContractAddress({ - from: deployer.address, - nonce: nonce + 1, - }); - - const proxyRegistryAddress = '0xa5409ec958c83c3f309868babaca7c86dcb077c1'; - - const minter = await ( - await ethers.getContractFactory('NounsTestMinter', deployer) - ).deploy(expectedTokenAddress); - console.log(`NounsTestMinter deployed to ${minter.address}`); - - const token = await ( - await ethers.getContractFactory('NounsTokenHarness', deployer) - ).deploy( - deployer.address, - minter.address, - descriptorAddress, - seederAddress, - proxyRegistryAddress, - ); - console.log(`NounsTokenHarness deployed to: ${token.address}`); - - console.log('Done'); - }); diff --git a/packages/nouns-contracts/tasks/deploy-test-token.ts b/packages/nouns-contracts/tasks/deploy-test-token.ts new file mode 100644 index 0000000000..696818d119 --- /dev/null +++ b/packages/nouns-contracts/tasks/deploy-test-token.ts @@ -0,0 +1,56 @@ +import { task } from 'hardhat/config'; +import { ContractName, DeployedContract } from './types'; + +async function delay(seconds: number) { + return new Promise(resolve => setTimeout(resolve, 1000 * seconds)); +} + +task('deploy-test-token', 'Deploy NounsTokenHarness given a descriptor') + .addParam('descriptorAddress', 'Address of a deployed descriptor contractor') + .addParam('seederAddress', 'Address of a deployed seeder contract') + .setAction(async ({ descriptorAddress, seederAddress }, { ethers, run, network }) => { + const [deployer] = await ethers.getSigners(); + console.log(`Deploying from address ${deployer.address}`); + + const proxyRegistryAddress = '0xa5409ec958c83c3f309868babaca7c86dcb077c1'; + + const token = await ( + await ethers.getContractFactory('NounsTokenHarness', deployer) + ).deploy( + deployer.address, + deployer.address, + descriptorAddress, + seederAddress, + proxyRegistryAddress, + ); + console.log(`NounsTokenHarness deployed to: ${token.address}`); + + if (network.name !== 'localhost') { + console.log('Waiting 1 minute before verifying contracts on Etherscan'); + await delay(60); + + console.log('Verifying contracts on Etherscan...'); + const contracts: Record = {} as Record; + + contracts.NounsTokenHarness = { + name: 'NounsTokenHarness', + address: token.address, + constructorArguments: [ + deployer.address, + deployer.address, + descriptorAddress, + seederAddress, + proxyRegistryAddress, + ], + instance: token, + libraries: {}, + }; + + await run('verify-etherscan', { + contracts, + }); + console.log('Verify complete.'); + } + + console.log('Done'); + }); diff --git a/packages/nouns-contracts/tasks/index.ts b/packages/nouns-contracts/tasks/index.ts index ba16dc6aff..bdd8b0b97d 100644 --- a/packages/nouns-contracts/tasks/index.ts +++ b/packages/nouns-contracts/tasks/index.ts @@ -15,6 +15,6 @@ export * from './deploy-descriptor-v2'; export * from './deploy-short-times-descriptorv1'; export * from './deploy-and-configure-short-times-descriptorv1'; export * from './populate-descriptor-via-proposal'; -export * from './deploy-test-minter'; +export * from './deploy-test-token'; export * from './populate-descriptor-v1'; export * from './upgrade-descriptor-via-proposal'; From 9ff4625f7ce799ca16279e9c6c5272f2c255bc3a Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Thu, 14 Jul 2022 08:38:16 +0200 Subject: [PATCH 102/116] update body-foggrey.png --- .../images/1-bodies/body-foggrey.png | Bin 2174 -> 2174 bytes packages/nouns-assets/src/image-data.json | 10 +++++----- .../nouns-contracts/files/image-data-v2.json | 10 +++++----- .../foundry/files/descriptor_v2/headsPage.abi | 2 +- .../descriptor_v2/paletteAndBackgrounds.abi | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/nouns-assets/images/1-bodies/body-foggrey.png b/packages/nouns-assets/images/1-bodies/body-foggrey.png index 1d4327652812c9854580c04179232dcc3a331256..411b454372fc7de99df34bb0a77bb62fad7202dd 100644 GIT binary patch delta 203 zcmew-@K0dF5hiX!;}An*DQA1`Udyt?eY3}85e`ExtKtm(NZoK@>-5R~9MU4Yde|N0_d2;V0D-5gpUXO@geCwQ C-Z^yu delta 204 zcmew-@K0dF5hiW}ix5L2D^o)&6Vu7(nUqlYf0zPPQp`;Z3{%aGbd607(sT`yO%inz z4O5eJ4bxH#%?-^H6OD~bHy1E(V0I-&rIJE%iECMjRe45go~@FRfsv7}fw?ZS8}72| zO`gnN%aS`$TX(VuhauOls)q`Zy5YIZ)sy`>q(u&tuseL@u=>CN1fH&bF6*2UngA=@ BI*9-P diff --git a/packages/nouns-assets/src/image-data.json b/packages/nouns-assets/src/image-data.json index 0bc160408b..e8ca4a12cc 100644 --- a/packages/nouns-assets/src/image-data.json +++ b/packages/nouns-assets/src/image-data.json @@ -14,7 +14,7 @@ "5648ed", "5a423f", "b9185c", - "d4cfc0", + "cbc1bc", "b87b11", "fffdf2", "4b4949", @@ -242,7 +242,7 @@ "f8ce47", "395ed1", "ffc5f0", - "cbc1bc" + "d4cfc0" ], "images": { "bodies": [ @@ -1744,7 +1744,7 @@ }, { "filename": "head-toiletpaper-full", - "data": "0x00071a1605010002ee1102020002ee1102010004ee110204ee110204ee110201ee017d010e01ee110201ee017d010e01ee110201ee017d010e01ee110201ee017d010e01ee110204ee110204ee110204ee1102010002ee027d01ee010201ee010201ee010201ee010201ee010201ee010201ee0102030002ee017d100205000c020a0008020800" + "data": "0x00071a16050100020a11020200020a11020100040a1102040a1102040a1102010a017d010e010a1102010a017d010e010a1102010a017d010e010a1102010a017d010e010a1102040a1102040a1102040a11020100020a027d010a0102010a0102010a0102010a0102010a0102010a0102010a01020300020a017d100205000c020a0008020800" }, { "filename": "head-tooth", @@ -1792,7 +1792,7 @@ }, { "filename": "head-volleyball", - "data": "0x00031b1505090004d40f0001d4010a02d4020202d4010a01d40a0003d4010a02d4020202d4010a03d4070001d4010a03d4010a04d4010a03d4010a01d4050003d4010a02d4010a04d4010a02d4010a03d4040004d40a0a02d4010201d4030004d4010a0ad4010a04d4020003d4010a0cd4010a01d4010201d4020003d4010a0cd4010a01d4010201d4010004d4010a0cd4010a01d4010206d4010a0cd4010a02d4010205d4010a0cd4010a02d4010205d4010a0cd4010a04d4010003d4010a0cd4010a04d4010003d4010a0cd4010a03d4020001d4010202d4010a0ad4010a04d4030001d4010202d40a0a04d4040003d4010a02d4010a04d4010a02d4010a03d4050001d4010a03d4010a04d4010a03d4010a01d40300" + "data": "0x00031b1505090004d40f0001d401ee02d4020202d401ee01d40a0003d401ee02d4020202d401ee03d4070001d401ee03d401ee04d401ee03d401ee01d4050003d401ee02d401ee04d401ee02d401ee03d4040004d40aee02d4010201d4030004d401ee0ad401ee04d4020003d401ee0cd401ee01d4010201d4020003d401ee0cd401ee01d4010201d4010004d401ee0cd401ee01d4010206d401ee0cd401ee02d4010205d401ee0cd401ee02d4010205d401ee0cd401ee04d4010003d401ee0cd401ee04d4010003d401ee0cd401ee03d4020001d4010202d401ee0ad401ee04d4030001d4010202d40aee04d4040003d401ee02d401ee04d401ee02d401ee03d4050001d401ee03d401ee04d401ee03d401ee01d40300" }, { "filename": "head-wall", @@ -1808,7 +1808,7 @@ }, { "filename": "head-washingmachine", - "data": "0x0003191f0402000fee060002ee017301ee017301ee017501ee017301ee015201ee0156017502ee050002ee017501ee017501ee017301ee017503ee0144017502ee0500037310520200037306520473065202000373045202730476027304520200037303520173087601730352020003730352017308760173035202000373025201730a760173025202000373025201730a760173025202000373025201730a760173025202000373025201730a76017302520200037303520173087601730352020003730352017308760173035202000373045202730476027304520224037301520244035204730652012401000373105201240100037310520124140001241400012414000124140001241400012414000124140001241400012414000124140001241400" + "data": "0x0003191f0402000f0a0600020a0173010a0173010a0175010a0173010a0152010a01560175020a0500020a0175010a0175010a0173010a0175030a01440175020a0500037310520200037306520473065202000373045202730476027304520200037303520173087601730352020003730352017308760173035202000373025201730a760173025202000373025201730a760173025202000373025201730a760173025202000373025201730a76017302520200037303520173087601730352020003730352017308760173035202000373045202730476027304520224037301520244035204730652012401000373105201240100037310520124140001241400012414000124140001241400012414000124140001241400012414000124140001241400" }, { "filename": "head-watch", diff --git a/packages/nouns-contracts/files/image-data-v2.json b/packages/nouns-contracts/files/image-data-v2.json index 0bc160408b..e8ca4a12cc 100644 --- a/packages/nouns-contracts/files/image-data-v2.json +++ b/packages/nouns-contracts/files/image-data-v2.json @@ -14,7 +14,7 @@ "5648ed", "5a423f", "b9185c", - "d4cfc0", + "cbc1bc", "b87b11", "fffdf2", "4b4949", @@ -242,7 +242,7 @@ "f8ce47", "395ed1", "ffc5f0", - "cbc1bc" + "d4cfc0" ], "images": { "bodies": [ @@ -1744,7 +1744,7 @@ }, { "filename": "head-toiletpaper-full", - "data": "0x00071a1605010002ee1102020002ee1102010004ee110204ee110204ee110201ee017d010e01ee110201ee017d010e01ee110201ee017d010e01ee110201ee017d010e01ee110204ee110204ee110204ee1102010002ee027d01ee010201ee010201ee010201ee010201ee010201ee010201ee0102030002ee017d100205000c020a0008020800" + "data": "0x00071a16050100020a11020200020a11020100040a1102040a1102040a1102010a017d010e010a1102010a017d010e010a1102010a017d010e010a1102010a017d010e010a1102040a1102040a1102040a11020100020a027d010a0102010a0102010a0102010a0102010a0102010a0102010a01020300020a017d100205000c020a0008020800" }, { "filename": "head-tooth", @@ -1792,7 +1792,7 @@ }, { "filename": "head-volleyball", - "data": "0x00031b1505090004d40f0001d4010a02d4020202d4010a01d40a0003d4010a02d4020202d4010a03d4070001d4010a03d4010a04d4010a03d4010a01d4050003d4010a02d4010a04d4010a02d4010a03d4040004d40a0a02d4010201d4030004d4010a0ad4010a04d4020003d4010a0cd4010a01d4010201d4020003d4010a0cd4010a01d4010201d4010004d4010a0cd4010a01d4010206d4010a0cd4010a02d4010205d4010a0cd4010a02d4010205d4010a0cd4010a04d4010003d4010a0cd4010a04d4010003d4010a0cd4010a03d4020001d4010202d4010a0ad4010a04d4030001d4010202d40a0a04d4040003d4010a02d4010a04d4010a02d4010a03d4050001d4010a03d4010a04d4010a03d4010a01d40300" + "data": "0x00031b1505090004d40f0001d401ee02d4020202d401ee01d40a0003d401ee02d4020202d401ee03d4070001d401ee03d401ee04d401ee03d401ee01d4050003d401ee02d401ee04d401ee02d401ee03d4040004d40aee02d4010201d4030004d401ee0ad401ee04d4020003d401ee0cd401ee01d4010201d4020003d401ee0cd401ee01d4010201d4010004d401ee0cd401ee01d4010206d401ee0cd401ee02d4010205d401ee0cd401ee02d4010205d401ee0cd401ee04d4010003d401ee0cd401ee04d4010003d401ee0cd401ee03d4020001d4010202d401ee0ad401ee04d4030001d4010202d40aee04d4040003d401ee02d401ee04d401ee02d401ee03d4050001d401ee03d401ee04d401ee03d401ee01d40300" }, { "filename": "head-wall", @@ -1808,7 +1808,7 @@ }, { "filename": "head-washingmachine", - "data": "0x0003191f0402000fee060002ee017301ee017301ee017501ee017301ee015201ee0156017502ee050002ee017501ee017501ee017301ee017503ee0144017502ee0500037310520200037306520473065202000373045202730476027304520200037303520173087601730352020003730352017308760173035202000373025201730a760173025202000373025201730a760173025202000373025201730a760173025202000373025201730a76017302520200037303520173087601730352020003730352017308760173035202000373045202730476027304520224037301520244035204730652012401000373105201240100037310520124140001241400012414000124140001241400012414000124140001241400012414000124140001241400" + "data": "0x0003191f0402000f0a0600020a0173010a0173010a0175010a0173010a0152010a01560175020a0500020a0175010a0175010a0173010a0175030a01440175020a0500037310520200037306520473065202000373045202730476027304520200037303520173087601730352020003730352017308760173035202000373025201730a760173025202000373025201730a760173025202000373025201730a760173025202000373025201730a76017302520200037303520173087601730352020003730352017308760173035202000373045202730476027304520224037301520244035204730652012401000373105201240100037310520124140001241400012414000124140001241400012414000124140001241400012414000124140001241400" }, { "filename": "head-watch", diff --git a/packages/nouns-contracts/test/foundry/files/descriptor_v2/headsPage.abi b/packages/nouns-contracts/test/foundry/files/descriptor_v2/headsPage.abi index 644d0ec42c..1a1f8e8a4f 100644 --- a/packages/nouns-contracts/test/foundry/files/descriptor_v2/headsPage.abi +++ b/packages/nouns-contracts/test/foundry/files/descriptor_v2/headsPage.abi @@ -1 +1 @@ -0x0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000ebc000000000000000000000000000000000000000000000000000000000000000ea0000000000000000000000000000000000000000000000000000000000004f37ccbd7b941d57792fb8bf6fef5d8ff3a8537dfa74b7bae56eb5ecd31c4bd670b34284653c9e315207138bdc88ce754b801d3a3660d91ac96414a3604552eb2d4b080761d92d8c83722d871b136374e1866002087209e27193009e60428244922b933b24b3f2c75d5959b3ee5af3fbbeaad37dbad53aa7bb4d66e6acf5abefb91f55b56bef6f9faada654cdbdf707bb3f96fedcd83b7b7b70f75c87ec5d9f6f6e1e1f6f6951df2bffe727bfb0d17dadbeb1dd28f7448ff9a0ef64687fc6f9c686f5f75b6bd7d7587f437b5379b9b2eb7b7afb9d0defedac9f6f67f33d1defe33edcde6672eb7b7ff6c87f43f3bd9defebadb3bd83b94bf76b883bd43f9afef50feeb3b94bfaebdd9dc32dcdefe8689f6f65b3be47feb647bfbff7c7b7bfb6d1df2bfed427bfbffd2a1fcfff56c7bfb1b3b94bffef6f6f60d13ededa31dd2fffc7007fb85f6f6374db6b7dfd1de6cee38dbdefee6cbededbf70a1bdfdcec9f6f68dedcde62d9dec1dcaffc50ef67f7b7b7bfb2f0d77b077c8ffadedcd66ac43f96397dbdb7f79b2bdfddf0d77b05f686fbfeb6c7bfbf8ededed9b3b94bfa583fd6d1dec6f6f6f366f9f686fbffbf60ef6cbededbfd2a1fc5f39dbdefecee10ef60beded131df2ffd50ef67b27dbdbefbbbdbdfdddc3ededefb9dcde7effd9f6f6ad13eded0f7428ffc1f666f36087f2b75d686fffdf3ad8b7dfdedebe63a2bdfda1f666f3d0d9f6f6f776c8ffd786dbdbfff70ef69d9dec17dadb7fbd83fd7d1decbb26dbdb7f63b8bdfdfdedcde6fd1df27fe4f6f6f6dd1dcaffcd0ee9f74cb4b7efed907edf647bfb6407fbfeb3eded0726dadb0f0e77b077c8ff5087fc0fb7379b2317dadb8f76c8ff5887fc8f4db6b73f3adcc17ea1bdfd7807fb890ef60f4cb6b79fec60ff6087fc1feb90feb76e6f6fff507bb3f9d0e5f6f65367dbdb3f7ca1bdfdf10ee94f0fb7b73fd1de6c9eb8dcde3ed521ffa90ee9cf4cb6b77fa4bdd97ce46c7bfb5317dadb3fdac1fef4647bfb6fb7379bdfee90fe6367dbdbcf0eb7b7ffceed1dec97dbdbfffd85f6f673edcde65c87fc9f9d6c6fffdddbdbdb3f3ed1defe1fda9bcdef75c8ffb9e10ef60beded9f986c6ffffdf666f3fb67dbdb9fef90ff2727dadb5f186e6fff5487fc3f75b9bdfdfc85f6f6ff38d1c1de21ff4f77c8ff3367dbdbffd3647bfb1fb4379b3fb8dcdefed90ef63fec60ffdcd9f6f6173ba4ff7c87f47f34d1defe850ef62f0e77b05f6e6fffd285f6f60b93eded5f3edbdefe95dbdbdbff78b883fd427bfb7fee50fe5727dadbff64b2bdfd6bc3eded173be47ff1427bfbd72fb7b77fa343fa6f0db7b7ff97dbdbdbffb443fa3fbddcdefe671dec7f7eb6bdfddb93ededdf99686fffeeededed2f7548ff1767dbdbbfd721fdcb93ededdfef60ff417bb3f9c1d9f6f6bfea60ffebcbeded3f9c6c6fbf34d1de7ef9f6f6f61f9d6d6fff9b0ee5ff6d87fcff6ea2bdfdbf76487fa583fd95e1f6f61fb7379bbf9fe860bfdcdefedfce7628e0b0e1a15ae00dad63a0db3028afeb3216d4aeab1807ea4033b92bb777e7fe15535e57bc0602e3f7ca96f6d2be0cc575710b5fde5b58e7ebb1721d2a79ed1fed326ea0e6dd3d64dc9b33d024d09301fa3a740ae8ebd0297e5a7a323d757a1b6580dedd01e4f45f596fba513ab477cdc085c0788685e829b4772d2ec58c7ea127e81ee3fb6b81356e7f62e2fdb149f607a6b2df9a74bf03cd40fb9303576fd1de744bfbe900edaf1c20e5ecfef2c1607f191a365dfb3b97ff8cb1d7d56c60925b8b406cf8d60408e7506f38040770680d85d4e05b5d18341c34d4a010b5906d23081dc0b926824724dcadbd216a77aba0672e17aab549cd32200cedae447936a27b153ffa9ca1c17e5f3074a8cfd8b40714f54951f2a1aae1d40abfbbcb50249453d0dd94a6b0a87448b6b8420f4500d2ecd6941189fd10f45108e06c449a27aca213d80c8744273e3ed7b1a616ada40076db54316de5ac6ccdcf3691a59292d2bc0e2dd6ac4e9cdbed2c9bee112cf1ecfcd4125da51348edafd652eaa7eb6653aef22cbd33f379cfd5067a1ce66ac2e95a688da23e1cb55e630ff52cf004ff27e3066bd6195f778fd806fa61500f8a6bf09150e447e2065af02368936b4270042f5a631bbc86450fde2b8f7a340213291f18dbf039ef8d6f3853021c7cb9c1260102e5093cc18fd654354f3235a5d6141a764d8cb4f0db9221447abb05656d71c86be1bfbfc7f5d9e38a86876b26184e8d1d763bed70093297093c81f270a4726613d999de615c3b3b2dfc79a7cb01bba16142ba195d26bbabfcfeb5651aaea26c8b7a92ecdb4e1e5ef4b5adbfcf617ceb0b22e34a89894ab8ce478a25f45a251a29005442c9f3f2e871739e4bacfa92ea49f5c27b2001dc1c2a3e33fead69edacb25c894702804b6843a560c4a25e25d430424d5d295ae0fe7dd7d881de20347e032d2f19872d2b70c637f072d1ba0dde643487a19cb339688335d1744ad1b1fa841bbcf89912f8ee1ce186daf2d2344fa6081ac03f565f2b35b89f2ad3c8f3742698559e37d3b5919a6a3d794349eb192eeafcfe8bb1433546ff7518bdc3e16a4e117f1dc6557ab8041ebdd2613a42900994218b8f57dea9cd1f0ed56681424ec5dfe7b23fecd55e53bd6be1adf2bdcaf30278527e99969dd1087087b94ef72142b80f14728c7c59eb61ebc4a4604d831684baa45a9f851d1fc40fcb7a227f3430c151c49ea00cfa3b473962419d8e21ff63a0990c842dfcb581be2d5ac0c84b15c3fd121ff3315c09c78aa6782c349563885b8e59d3051dcadf503a463b1832da1d247eb3870cbdb18f42f36652d09bc576b59edf8c16b603e7f85132ffef69afae01ced8553a6fcabaf58f8647f8516f924779516d5b7e270c0fd402f44c43a8cbfeb2a1211ae021de8f5e793f7a7948d040129b4ae02aea251e986f1c299bf4b835f1001da769d8e3188b8edb8114fc1b8ef3c08d40053299c2715e19c0dfa95f98fba3eed02de577bfa1eb6a323e357a816e8c86151955396c9495c68da2d262a380d152109bb4115d8d13820023a8935892ab18654b0dbb6e2546d5dec6d263c0670d0fd6b86cdc649f09266bc64ed26652d40c0b7d874225fe00f80fd06497f193f481dc36999ae26445519e2c9b64924e16911b8ee4a43d89716792c1f9935eb9e264781223c8a43525c09fb493881d008296e05d446ed1247f9041f964613231c1c9683258f2deb5ecdf5aecdf5aecdf5a5a430aec91d09b152af163e01fa3b5d8bfb5f4586e5b8bfd5b5b5194d762ffd6d2cdd8bfb5d8bfb5f666ecdf5aecdf5a7fb357aeb836bc19fbb716fb07f89bed5aec1f809c00ec1f728bd6721f83f2cd85b5d8bf9ba3b5af62ffe831c4ef7d1671db6f2d03d29ca2af9f10b88cff2d9fcbc223069840fb066802e926d0c25742b3d20e60b49860d5f04a37c12b79a22852eec313ee433c01df019a2834f548c91f7275fe10e516d17acd477d27e843419d6065586d569b01583e14410b3a801108b56b6ab21cc5937fcbe5f9b75aa4fe761e7d617a3f5acba389506b62f33af2040f48fd10ff0897ef116b89a22f4cefbbe6a439a08f19f0383ac86780f32318eadea3b798407ff45b187b27e2fcb82fbe8ff8b8c667a1094631fa8f06a790f7289da2cdfe94bdcb9ec291818eeeb2bf019cc21181c47739487c0ac7683484cda98d25dde6e894bbcb9d42c4385a3d6547bb14c23781bd1cb5a782df88d4df9de20fc7a7a43cc92b41fe6eb4740a23e4a86823ad0f8d1651b7c5c524adbf3dc65dd71ba2474e904f8273913066862ea19d7122b34c9cff84771612ab334f58a1773a9b4c5597d3c7ab484bebabe067c3c18e8820c1f89ef89d36894c2929984252861c2fa07e9fc0a8d1634b264cab987bd94197568c07c5ec7390534494298136e5a249a14b3033b5a0116693ac76467a1cb73d98d9c02f48315eed09c03900f3b7410f0ded092195d516614e5a44ea780fe65169b4a784fc1c52bb3d3d26d85333d19ec4544fc7c69f2e57627045939c5eda39f827e396afc0f8c96febc95136d113fcb6f009d4e88918b25001c6a1b7e1183f812bf7c9eef7f293f45e1a049ea0f7c6958c226e7f6f66b3efb515ce744f30780b1dbfd7573cc09a36ccd308cd64dbc2b7da5ad3cd976ff77bab862b3584520bc16247c25f36c175b5904c30857339550065f947608ace144c28bc72d114e55c71aa89d894a722934c85a63645e6b553b6710368f7a1c5d5e0a0948ff9b99daa7c44e6ff4e29ae449458f90847769a6370ac1c19af9c859f6da161bee58fd055d47fa440629f4b917a91476cf6ef01e396d5bc33e571670ae3ee161e67f38be38899c683b0d881c6e3b8b2735a19f7c68e171bb2a586d7a8df369aba647c89110e158d47fc1898685b6cec36f4e3dbdc4abb0d231478bb8d563ad5a11ee019a016f0b48ecd5c9dc06f43bb01b5b37c33ea8020a7ad696caef72d7ec8ff2a9fb885f7799a5079ced390a9e6f5b2797ab135f725ab87f88a0d4770dbd2cef3ade83f7a717e130e4c95ada93103643e02643c7a61d82a8cfe93bb0d2b7025f2c2faab0f63f6dbe723133c9818fb203fe51f2c1806750f32bb07d1761f24e81c78af7c001eb229c0ce0ab41d50a4153b773d48e61050835c83ad803421fc8b9a16e75d6542fef414217f7ad0426fc163d4780af1d8530bfde721fb3d60c2ac7d15d17714e935be181aa7945e638ba83368b988e3074a451cab2267c8fe199b0a1a3c85785e8179c0946b24e04b00ae7b5345af9422755a5cfccc29fbfd48e74f727f067dfc3ab48d758855d6d1eaecfe8b50ca6994d146ae6fe47acc4748e71c480bdede86b1ef36443fb7c17f3343922de93630e94a44bd2b030e57a2b75a19719053bf92d0567045af8c019c35b4115e99cca2b4b2025acd4192029e5ebc578a9554472a7bd5a1b5734fa737e83afcfe01fd436f80326d06b2ee51b2160843821cb4f0622b4feb9a68abef2fe794e6d8b2b2d27bc04764e91efaa8cd410a169adbacca3cafada9b31fa579ec9abf94f37456e6a20f0ff5e8fd314494bfcd5783e9b7ed1c2ccbffaf991ffe6329f3c770663fc65c3e0bddc79a405a91af025a40eeebff3ff3c18c42754d5bef222ec6f79bf83a191fdd3e8cedfb02b9e366ba10e9719df6d11e1aa9ecc1f504be6b0fefb36ae37d5ce7ab697d364d4029e7a95edcc3996c321f5cabf585d5efe7e5fc0688cf77a7c61ea2dd88b576578cdb5d32c16ed4f20d6ce2dddef837a0473db4e964eddfff4f2162acb1562c0f6b8716ddaea67f47e5f8a07f8ac631971a8f1c8d1731e60b45f4ab3434e178e0e819022f91003fe31063d4c6690be956ee27f28df138df28f715f9191aa71bb1bd91c659ee352acfe3ee19f41fca87cfe476c3cfa07fbe1131f08d7ec9f53f2dfd2b2232f736cca5dfc6f711a8431c5d40fe742fbd8dee43547d2fdd188da2d47b9df298c5dd452a23febd0f98b1bf37b3dbbb5c26dfd8b47df05ebe89efe563340b6e5e5df7bd8b39fee172b9be6b889cb9526557418bafa46c95663c57fc39f4dde730ca82fa735c71e7acf20ceae691e7fad7040d0155827261b858e661c44e7a6f232e27c3aebcd4e3ff14e6e1b540ea5e06102d63bee44051f7c05570cd8192ca3640bdc427975d10024d5b3cada7a09ca7e9aa60e49d176cfc6d3ee0ed2e701801a3809e0c03d1d9c03d99e9d260619dc4bf18bb7c99c43fe712c3e782ad7c0ef1cfb90228629373c9563a87b1fb1cdd50018751f81cdf203ad4f39cbfa1b89547a1011fdc405b5d64b7a2d59c43bb3b8718f706cc22ce51148e22d7951405e0839c67a4e1f9e4a72037725ff06123cb831ff24fe5f936504684b21ee2a7b292b951dcea1fca6a54de6a1fca6a89da3e94d55c6a1be67b54c8f71051d6b9054659b4d6f8a15ec498ee30da4b0eb9b7e11ea7c3410efb7820f66290c366f7338a19f81a3c663f87e9f1601a9843212fb4d7595b275ed32507871f6ee171d56739ce49235be42596c783997a3deeb2fb1f1dead5ca4b09ad75a4c755d7b2ef029e757482c38b18e609f1da60afb3c6beabc7d0bb7016df55cb69d544ef425d9256a09f7e1725b8da66c18967c2b0cc80e55f9b2478579210f848699647f0ae0a68945b68da4bf28d66d9ecbbd0ff248ae9f4927bae85afd3faf01c60bc7a175f554bc4e5efa239fb237875f3dfff61f8ba5ef97f7fa857fe49326ea8db0443180b0edb213aec86321ac97d7d704e252bf7ff53be81a1a3dc4ba8d7a7135c9da067f83274813e094137205e50ff40fd90d630b636d7b8d4d6e53fa8a624fe33b2f8e30a4af97034c4b07ab933382477d26a43d6f40ea1fda0b4a0eea426d80b7b38b9c16a4dfd0d527600500a5e6a697a9197bd01b3b51b16d2c33dabf1456adcaf47c60dbab9f441f7ebe057b5e1067e5a1c0d228ebb867de9e7ffd33afe787d52821bbcba6c7cbeb5abf5cece6ad1d21a824422ad912dadb1ab0bad32bc634d23de11b850b7d1ea00db58b785d55eb70edbd26a9b6f25b56d945793c9f2e586d3d26cddb7e818f9865a8a6f54562f66ff761b7f5dcd7913706a8a5c3298bf9d8bd01f0718e74b98a7c9b89f329911c62804206e861ffa7e8d05d052a6f57c0e3377953dc04a2393ec2998e45c06e2d2383178c5c262b2a70d2deff19897a6893e3114a665534c8bfa0c5398eb6c9ae64ffe5473da25d7195036b61f9efdc2bbf58189fbe3f516dbe27a561ebdcc7a02575e3f17a20dd6db7e564fbf9efa11ed68da18f978e4e8d72fe43996371abbac26cf3f8d635c1b2f20d68d100b63c43c168edb6338cec7dcb83b86328e11289963c75cad742ca815a02fa96d3167f3eadf36f97fde07261a2c9bc2601134012d9b70904768b0846b341c29191a2c8cc09ea3084d51696c68844d6904f51db1a63c82d112f023be1e8f78d3057d053ea591c484234bbacb455efe1ff5ddcfe20c3d4bbf6b9fe58fd3b3d17f109ea0f3908367e9f7826771569fb5cf91da0b9f6095e939fa043dc76aa7df0b9fa5df9754e245bfe7000b78807fd7b74842497d5bb5ace0dfe56753d1694e99b5f22c4b59bf27169ab60852cd3bcb8f3f3117dcf4cdfde7f3e0dfed51afa59fdfcf627cea47784df55e4321d76bc6628b595e88681d5c8a96e641316b515a828ce805bcdd102bef45bf21320550da40f5c094d4d3994429f63eac880db3570bce85643c28723781c8d896e549870d68cda13dc63d01247d26268ce5a9880d38c76178ec2de07aa0473d372c7c827d1457b0fc7f4f4710b14fd1113b152bcf4768ca02d8874a7c246cb1839b0a67f908e888836709db564f014f61bf4e5682b79fc4d8783c19406c9fc30e948e93f24bbfff7e07ae3f793ec07317fad644fbd832fabf0a87a60b7da0fcbfdaa360d30bf4a17ffd19a04fc1d07bfdbf6ca9bfbfc615de1bcaf315e89b070b88b625228c738a1879d063cc0f06118fc03318728399055b4838a372676c48ee8fc1a6120db14a21bce4de172287a182c97c2cf29132723df2477c22f7c8b00d101588243e2221ef2129dd83f3289786fc3dd8ca1d37e41668be72bf4e6a83886a48eeb165be05a935f66821ff409f94f9af2d1ad75d34f12ed71def42fcb98bee76dd7477a47c9051c8ee79e8bad1d6ba673c44cad2d1dd64e6723c0f9df9372cbacabef8f3f7658c35bd72bfe89398177c1223cf27692dbd9ed6fa4f5ac3e0adc8755a1bc02eb2cbe5e893e2d39e4f16498b9fb4f5d99a10a506d335b02db50bf21a2fe659cff97ebfa8d77f84f1073dd948c5388c3519ca26c03815bc20c0b8f642c14423821863187ab31704a129bd80fe0c63971b29fd426d64f1e53fafe577dbb48b2d75551e916df8087d2a54ce3fe2bb08127501aa091eb19fe24754eeca34d88a4fe607f02cff4a876d8fa5f3a9b5e7219d2785fd8fc08805dfd471aeeb5ec254e7a1fcf9cae04cc914ce205e3be34d78868e44679c2983f2196baa671820b3f30c1fb1a00928436795d291027c58797fc4235d005d8c7c1c68069c0be41f9c59f43d6e92a845ee43c5b67cde5a36dedae3bacf8f36c1e7e938a98db363714d7b96b62cc7ac4ef3e6e5a66d3473bcafe9d3267d7d4e59f56bd6ed516a935f6697ba67fbbfe8d34b3d3a7f95d8bb5762f3b7b0dea71159ffdf7f4b88f108f1fa5b1c60d51600999ce943f52b68da50f308d45790f972ae9334c44efd9b7e2164c9a72c76231e1568bab254921aa39b7a2b6f734fc6a847d37ca0e9384756725613d41825485a9fcb994f5613440ac8a164229552cd513c16f2dc48f3b7c704fa7e0a4d62c635e9eb7e9ac3dc27e7e48da21268ff24d7cb93d0d78b935e9ec49f14e07a9a43793291a7b390ce4d70641572c720d1ad9d8823cee5cef5db6578b9de7fa8058ab0e600cc536a6833351cd11a7f1a31dfa7cb90bb612b42e7e1e7415d0d7192de5f08c193495597d151e491c2af89a0e63e1d4ccb0b6f880f9860450df30fff996e53f84cc5943e8339d9673c0775cc9e3f137054c759fa4cc4713d427c14d6dd1f04a6c0be1efd81cc41e37af10f3cb4e8efe15941cb2ae816c7113e6570658968b9545fdc5ddd99dfaf210ae989d0a7218704c7210592a1e89ae841b424b043b68e9849612123e6013f1b99dee57e183b35ede2ea97fdbf82167e37ae4380eee6593cdf8d7e1660c424fc015a4377a365dded86324a6b783d7d80ee0215fbdd88dd3e8a782ce3d7503fad67d8fcdd3cc4a917ef7e5c8fc8f5da40aeaff76b1c40afb7b9eed5bca1f47ee3077a9c335512b07144f7f33be8fec23b22125a049dd124b3c0c4e75d1bbe42b8c68000f916725ee0b5ac85d5ef19bdbf8ef1f1b56867af0d3ecbaf457b7d6de1b3f45a1cffd786a00e40aff05afbd94c6f739e449fdb71ce32bfcfdacc06b9a4326b1e05d0ea2c643e699e36cdf34d243f93fe21fad43fc4b5f287c22f7d6e20bfefe1f82f93ffb7369273006f8c8dcd79bb31543e501eed2ce7dd462b3c47999f61879ed5a167052d3a9f5b0ac07cd46fac395c17795e3ecb2bcf372b2343d8528fb8a57e45e53360de9bf3b4b16232aecbc83e2c7aff3f471b1cc09fc3fee7bcfd5ca87ca03cea96f3ee7356788e323fcc69b1ff1bb0ffa0c50d3eb71480f9a8ff5c6d03f63fcfcb6779e5f9666564085bea11b7d4afa87c06ec7fced3e72a26e3b0ff9f5bf8fe3f63fcf21e4f18239d8c93723cd9eecca04f7434f98d88c2a66d6e11fa32f382e49083f561aeaf717123fa7a9c47b7887339dfef36130ef64432d7ac0025f305ed9371ae5a318fa63624e8983d7dc1c483bdd68d568d1bd7ff63e519db8c1fd3b742f59f3f371ac9736fa39947ab4575633c1a18ceecd7f491a77e9d78994e7e76945b736be329944767e5d9eaddf49a4e25f9f28c5f33ddf87cbe24beadb9b6f5967ced023c791cc7a0839f1d0fb2bce6d8fd78c1f85cefc753f09ddbcfc3261890f82f99428c75a42cff2e190f1a1c49e6819b0a6e712dd44e45b7585002c51c20a15b304b32a27575ba459e0a75d0e32ac8fe31504df996c5f4e8ff773e7fa3cd7e3b46a8edb4d96da717793b665ca076bb37d176dae1b7b33c89bf9d5fa4ed3460a109b65b1382877c8b472ad820fb5b2407d80d72d9011e35a25b82ed3448db19a01de28fa8ff16de01afc120974a398db2d4ca5b94665566cd25af9b9662f312a5ae01eae6511bd85f84bc39daeea4669b5d857648fda11f88b5e4c80857325217bb7d6173c95d26bcaee6d9243d729fba822ded0b724a7b9a4821f3b49cb6786569224d5f347e1f9debc296cfa1f5ecb3e72a26dc5731faa67f2343d413c377e1cf9b6c96f77743c4179c609e543229663bf2bfe042e039bd03ad91dd1de8ff81c21d9ebb5493765a3779faf7b0bcffee30476a24f2a6ef18374a72876b0cad758c66f1d45334817ad81e5c878d50def2edc1acb5e18533bd0d367db8fade0cf4295875c5069d881b38a70d0b8a08bbb19869ec33cdff27d0ab16a4171da5415cc383e8b506e5ed090b49fe595479341c449434285a3b1a0fa2b7024f830e3c7a85c168b434581e8d06c3d104bed0494ac8ac146947c52b00c7d2d3c1df412f39c6e0a4f725f5b7a3de24a84b01757a35ef4ec8ef8f0df5f7e0fc3b96790cbfe064d6caf40246c4174496e76c4bd96c187286006335296595d17f4cdb1d74364bafba520b5fcc7cd0c6242dbd8039bdfa16f2b4adfcebb2bce12bf700e98548ed166d8b5784a84f892399d7bfc00bbc8f77addfc7b1ffb500e7b58158a6c1a1aca390d182dcc3685895e4fd7d1766084d390c740d06978342af321dcf7368a1143acda7e92beb3774856cbad042bb81ae139cc9d057e09bc16b1941c3d66d2336f189a5efe309b97f8cf8c3ef29ca734826da8391be52346e0f65ff69569cc99f5152b082a7815ed0d869b03e9bd40e5ca19d54e11d1968a76fb12de1471f6f5e7f632563c7b2b8c08ee17c497c90c38ef9a6bc2f87e1311cf7d9ba7d3a3e8fd95c0fbed5b28f9afe4db458b294e29147269a9aefa3693b376ba7a5bbfb78dacfe63905f7cdd46da6ece0be66192de9f7b9fb666a6c5bbca5cc997af158b3662dfbb76ff6516849db62631c859694a6f518b8d6e3b06fcef19d73fca576e883c696dc07d1415d3f02797d3e98c15a6bece7d12ed732b6ca7d9ed602c67f9e95b7a0c233f8b04567d52fd3fb9c9f6b8b32ba36d7afcdf56b5bd24cdb50c6dab9fe2d3aad43065aeb727e7679d7d6739eafbfaa2e9a66963edfff796d73cbf147b23282967d9e4f37731c977af2e4f72179be409e2fac9781c8a475bb216c84c764750e440526e39bba9f16cdf286fc499e6d47f98babffd3987fd67cef1f21b736e8fd23fe02fd510ab86b50fb05facdf61e73297fa173a99deb7fc2d08a6594184e971b97f69b20957576e81e97f6280dd2ee5ca67b6cda650a4a2ba6a4b46caa69d1d4d2d8f4625c5b967a33905a735d4a66280d66d98234b8a7a4f606c6c2449f6de154ca2deab331f2ccd9527e9f379cbdbffec59a09bed865f84bf4c50c156373de7ea9acbc53bed4c217950f942fb4f091a97e11f5ff22e266e8932f05926f3dfd22d5f94bdcc2a31d7db1c5d2c2d31749fdec178b75be2a5d803c17b6bf3b8d45fbc28c7ca57d1157c84a7a1171fa8bb4b268426878650c0b7ad7953c11ca9b2cc6e69427a8121a2f5c0557d74a19b56313ad9451ba68e2950950819c1a7907e6a66dc59541bc7c2599dacac5fd1bfa3ff4f960c43a9bba8ddb8473fa227a86a7dc267a0afbfb226af06226f917bd09c133f8f04544d32fba5a089d7b916b6e07f022e6bc2f522dda41350b3d3fc5b9841c9f427f8e74542b40a6a7c01bbf29930a39853cc7c7cec9c3b7e41f68b9989f1d91927d5e1bd75243df52f370ce5e95b1a7ddd8e3c2028ecf97313fe9777277a78678b38a7e479e2ac39cd9c8132a9c49d217e9da2c16d17320bdde06d8eae0aae8a7aae106995f1536c4a6c81edb82fce3031a23b6751b0afadf57053939936e7072770af93853ddc072ef6a43c8e106522ea83307bada4ccc6e03c6c90d893ee7e24065cd17fdef0d32c9f3371b58d75feb5d546bb8fab759ee3f85fa0c04466a1ce941795a43784e0b98e134697950df549ea6690ef4114821ef30bf6eb0b635b987b722a6dfbaf036fadf657d36cc4f64d59f0ce86b4ae81b40698b2dd19638a719bc78b5c880ac46344b93af20344be77f0a32f2bd4073745c72d33ad4639ebad8ab6abc9848f97ee3fa6b1499cada18289872bd68ca0d7d16f4578ad314ad7f2dc97a14c6ad2d3734b252ceaaceaf9514332864b96134ef7a2cccb0c85175e6f710c6d75e8bb9e5c91ee34ea29f3f893ee5247ab393a8c1495c2527c99102ed18ba601ad6d4a09b813755a41374218fae93d867d08aca926f0de9ab8baedf61135f57c5d555d8cf80acec87eb107c4667cb3110b650bfdfceb27792e7e6277256ee528fae318f191aa805b1e1f5b8e6d77719b7be6282f5095036d1fa12503485f51807bf8cba7c05d7cf9793afd097d1febf92716e0ee5afe0bafd45370bf09df77d3bfe8ad88aebf92bde4427e8b1f0c4e2efc47d0d3dcb328fba9dc71899a05d9c4f8c3b6f95f279cc71ea749ea725779e4c45b40a790624c925526a21b3c846f8f4bce48b7d381f29bacea3dd9c0f8c876f29a7ad7b149ec778065d01e92d780b5a407ac983cf7781621c3b9f6ade74beaafa265deaefcf9af3db06e29a865b631bf25f04af7180bc9fcea0d94a78ba2ecf9a1220efca72cecb8a78a28ff5d96eb191da2ce4285b156f4d9aad96372f15bbfc17412ab3a6ade8bbb8eab39a1a6eb5d37c5d4b5d7c4b1da3bcde980736163f0fdcaef1379beaf5dea44fe03abf9eccaaeb314bbfbe1a627e19f2f535a095cf60af8f42fb9a103cea7e7d18520fbd062df2354148d7632fa0b1e0f97a9cb1eb4bf046c476fd52ced25731daf5ca7f62ba8e632b52538a125389105dc8da0951b21b3d18b8eedd181da39edde857b1154bd76e8a1c381ba5bbf9ab0e16f1168e0f8ab6bc9b94977425e5e920c6fbc8ef66a443695fb5d0f8af4a3a91454f5f65e828cf8d4db8db4117ca3b9511aea2dd3e62cd2945fea525ec77fe23c43f433d887182c7b03f8f550c3d1634e8310f94c15303fa8607e8b15864d5cdf8082fba30d7b7fa0ba2693dfcc1bb16b9d55658803e68297fae4df4be452ecd4df753d0bb39e597e6946f5be4646eba9f821ead3e2b1f489b75816ee9275f7e1f96ff673c62ce3ff15fc3fce56b045a34c19fb072b10941333e321128291f9a58f51e72a07cb4046abf56f913f4c890ca75fa13d19681c1af2da6fe0f1b775d1fe277afef0d44261e21138d78138c209606dc88151d7bf0046a4770058332fc6aa01b417ba1eb855f0d79d490b63a129a50fcebc1486c9291a229e99b0b988b8dd40c435ef8eff3c6eafa61f2a43cddebeee37b11e583d2bd1867eafd402f668ae166f4be32075c8919d234a2cde8dd56620c9ea58d37a325dc97acf49b2df3665df3f0bef2fc12fcd89456163607a688dc300a6e0e4d21e770ac56069bb1979b314381ae64929595fc79adaa49ea0b7bdfe26d26d0feddf65711c977613681596b7f320b717fd914fb4ba6d45f4434cbd0219ee977d0a36fedf7a600703fda43bfabbb7eabcf1e15ee5ed8f13da3cf178426f245637d346c3d8ea24f8659620e5f1d268febc4d72067809ce4fa614e324f5da135c952cbeaae6112f920d39539813589559b4087c841b5c5b2acaeeac14b8ec823f165ec012c71b968a2f24247ca4fe0f8c9fb47d9b55c36f679d2bed83e8ffd780c5b5cf7191f3e8fbee9798cccd8da1dbea9db11b470629dab9b6dad9e907e243981782803747c8276809f467cc2c18fd4bbd9e32427961603fdb3b17db51857f9f15056e37a43709cde4087708e731e54793e4e3b58d6557c8383648ff30e1ae05cf2b0e93a8af3d8feff998e17bca2c13fc9fac35ed6bfae18dea32b978dd12144c35559bdcc8247df516559dd6c2c03e65a55ca65ba98d1b0ea440b7fab6942490db9a8bca42e2b8752c6c2430363be6ac78a879c52a4aada8b16b6a6cc557f915b64aa8617496578354875c145dac317677c90229761af673eeea26df129a266e19e646c71ede74b26bcae9fd19f0f468ffb01b4e541ffd1886d9f1dc0783f481ff5d0db016679fe60ae1c6a1aeaa301f7f5b97cd84617e66943cd933fea66f1f438faccc7e50ded00f5c9ea5540bd64a53fc42483889b06fa81d7195987b0c38f305b1ed2ffd73995a7906f43cd6fb35c9227a34009e0dbb2e7a9e9b600f000215e133bb1bb8d54f6b7c97ddc20f771d973d3b7a599cd78b507c84bde0772f244b4a6cb9ed5e6db62d848d3e913d242b51c9ef6533acb66b3f4b76635ce6a60c1bb696de6e3f334593e56f37173f4e017d7285a7edf96e7930344e62946e754febbc27948e3c14856d71ba46fc89b3c2e0555097da9dccb4fd1077e838caec9f70df44583fafea6ea185ee0063142c11b2dea1bd2ce9ce4fd0d4915235f12bf8e5cd2084c8a5955b94177b86ce67507e99bb402bac366c0ac8a57239ebec367eb9b2f72ffa5ff588ef1cf4fd0362beb6d6e4b26d02a2195269ce99eb0269af0bbc4cad9da9cdbdc44bc0b76a4280b85beb28b413d6838d1055dd72eabeb7076efcad6f39c4bed43b46b0ea0ef794856138b1e0a3e142827481e9275c6325e6533bfdcd45594b2f2a9ea795b774e7b14b46d71c7e724cede80c5793988f9dc41c42207eddea249f7f23a1cb3bd9575888cd6c5b720765c57b8255ec726b8a5b02edacb265e57d98b73b3aeb6d7adfb4d78f782d6f606bada55716f099ec93af71abbce6226575cc7af61cc4dedc1c0b88311f40e5ced6068aa07113ba2e4e8601558ca93868feafa73765fc1d87d4eee49df42fba29c8a6c6f91278932ea73dad487eac7fb7044d53f3605e413ed2bcd42b02f3a60ebb685160fc896ebf18119a97860099537f27e322fabc91c7a04631aa26837520230c3385e3001624c1ee1e32d40dc49e6c008c655a030e28e2f5bc23b55adbfa388af7a7ddf3095e8b66a89876b9b1702374c15ea0037dc5db10bf45b36bcd4fadf6f78a81fe3835dd163a2155da6b40271f40ac4d38ac4141415132bd0d280be1598cf003d2bd003acc07c0669c45ffcc41eae40acbea2db38e4c92b7a0dade85b6af5e831f4bfbdf2fd8f933500d7ef29b4c69368816f442b3d8528e424fadc93f4465cc16f449f7a8ae51fe1537cd2be11bd2c7ced1b4526f138c56f14ef662ad15868c4ca6a452ae465556f55079f933e5ffd99a7fd597323f84b5d345f4d2d16e5c55f56b99d957766b56a6349f746ce6be54f72b39648e54f866fd43d3a65f37c404f454d6fdd034d7faa90d7c66747007ca05bf1f726aba16c5d1d90b783b1e7a0a7c2bc36d99e712e4bca58cb93a3d93c32b2e7891e2ba9cbe27b98fb8d1fecb121ae49a7d726e6bd406cca98ff5acc8393110beaf339b335cb600f464a985be3488ca41c8f54391ca9f12064b12d834f2ffca311c711e6e3a9ce9c97faf68cbc1f45e83fd04ed0678423b2c6a0ac0c8099fc3af40ee83d681d6ab28eb39503d6499d9decc3ba19caa67813712587bba988f95f651e1412aedb9c7749d1c37701b7807f49d75f70261ac69c7518677a38906f8898ec9b21fa3d9024d2adac541cc96ac526ddfd6b2778470160c09de03ab02302ed3bb1d8e3f3b089066b964cb41a11cf6ab496d54111c82935a0431c22b4085a6cd0aa48bfc342ab1083ac92e726a306af5a96c96619e2941ee5e5794bf9be0a172987fcfb5bd515e617b312c3c3fa7c2cc6dae3e8738ea3bf395e3405cfc731dbee400344a7198738f1569a968279389cabba785454d7b78847152ee9ff17856f92297d13d1d33771c6be898810721120c001ac3cfaa56f86b98fe8aceac2dc279cd645b9bf57bf26823c1f9fcb56fdfcb45facba0c92c74c193379442d75a26fa6793933e50779f952cf1eb575daffef9b706085accff84425a0eb5956427b8282e4c3743d8dca6ac8d352459fb8cf25ccea66f8e0d5e991f3b48567f88bc26b9d2e5265ba760b5ec7b9b6c0f37f429edf90fffb379627711e3606937e8427d19b6cf493316212bb31160d6879d4ca1b43a33449a30cb8c98c176d7929db8bfa2e678b6629bfafeafb7b3d5338364c81e502284f512e153349f9526eb15c560eb3b300f33e0124ccda02ccc8006a524de9c0db1919745ebf6be85d4b095dc1fcdb2af74c2d69d7e547fdfafe9cbed7aa6bc830c62cdaa96fbfca7624db5ad353b6294f03560034a57b289d878e88bdab4cbf04fa290bde01b68cd978a6fba516ddceb93a417c0ddecbff864bb4a1eedcb4475a6e53664d277569ca3d0b5c11f160f3fee4b192b1c7ec3bddb1c838d0f018e6cdc7f89dc1317aa73d266bb5d03be99835d5636c3cf848f5242bbcbc133a80def96f218bbd025ebe47e38f713d808d90be883c197966f909644518cc3e8ebdbae7db0f1a7f5d8fb3fa2f6249fe493441c61f69c7170e158f94730487b077470aa672249e863f523e134c6f83337c98016ad1d19922e4a2299f7975ef471e46f45d93e7275ebf0c40fb7d3d7a2fa53d4ae9f57d00e249d867d39a89ab55f9d7efceb85a515aac969596ab25d3552d98ee6aac720a5a03965731ba5771dcabe111f917313c122245a5baf4e84cd72fc3f12f18c7ddf25fd2072d77c97f4f1f0cb2f7e1412ba6c049ced30789cba6c498c370315fa70b751c42ef33e400793b2e92eff0b083ce81f250a8769feb782850b9a0bcacd23263b34356d356007937ba88fc42cd834cafac2e83b4b2e6cce2ce8f1daa856105d164c59bc55144cf3e9e03a74fd9cfa555efc193de9520f091e7b710e0c157fdab5961f01519dfe4a9b549b499c9c4c8177308e30ecb574a27319f80deca38045ba65b6d7ab3f73dde4b6fe9d2950d48573698d1e4ab29bc97df924eaff830bf34dbb335277e4b35f39cced74f9719e49c63b72e5b99219ad670ae29e4f922de7b8b3c47b7d4df3386d17e235d3f381ae73137ae6f5282b282c7656d6137e6a1e3716b0ad015e45d42d0d2b81d635d77cd8d0599ef98553f566a5b74297c97c3b777dc992aca485e285c057e01a52b95b58709bcbce9b9e4a56df537fdff8b7e8db16c5c0379368a263891ffffd2c01c6406d9ff2f77d8130c14ee7027962df84daff97fbfa3ebff61eef3a7f45f6c0be84f7196676932b07aba39faf02abf6be9aa0caa2b5df5ead706ec557c81ed9fc52a7bfd22c1abfb7d41be5f2c7dddcdcb01b4e19bd17fdf8cfdbd19b3893fa71ca2c79edd5c12f99e194077c63e6afb0ab99eefb17df64cf028f745d31aee7303f0f90a3f4a7d8cb1a7999afb82017a94be62efa0af80229d35d795c80c94d80c1cc74cfdb833cb4adef41e0f4c6f2934b5526cc25278dc958a262d25a6b4906f245245e34bd4ef69f4eb4f538ed45880d6d9a7e57b00fc74c635414fa33f99a3838f717374e1bfbe7c11f5add34c1d2e2a6732c9b558ec3c7be10dcdd12dbeb53c2dd79fbc3f3b9298e20866e0884f4b234efe5731c108c6095d3b2aa33c52aad00268aaef6d1522797fcb564a1129a58846183c68c582a7a67ea4205293af37f91268e7fa6f97fb2b54369420d24e96199bf41997f41a9ff49820a99a6252364952d4af2c59a02bc1889690e906df07be1774997eb7894c2d91bbe70c9b5067a2242e15e43b4b257936302e2da517ff25132fab85882f8fe2981eb5a672947390f959503eea2683ba95d1efdbee2881c78827fa6f6324fc3662e66f336c113802dcb7175bfe3ee396f546f5b1e85c38c6e79003c0e782593c9db37b1820f0ee1c43dfa421d22d7b1569eb1defa6fe9fd2fe7c680adf418ff29dc277e93be841be43df752f314090bdca85169e5ee2ff83becbd080b6e8ed4b99d6b6e85af361c81164fa8e336e8df0a2473b5f33c3d17742e5d9840be083352c3c52fa35f63bc14b92b35de3720ee5af09c15b5314af25b41ef9fe2b0fd610bffa035dc61db007dd01c4aa07e2837400f321507b007ddf017fd09ef1d085f0e183f119869f537dac7ae1f960057a92ef861fa0835d67e8a0e4d775c61e64d8ba61e303ee6070c68e85d0d101cc46a4bc337ecca90fc60ca4b367c2318bb47c00e7eb009de1f150628c33a813e4ca7856073bee0177209072ff023cc07f21b6aebf58dc5574dac4d72d93d5ae76f89df1fb183d94dbc13be93c4f4b7e67f43e3b4226ceb9c23c347c9f9ba699a77059ea8cb33b187371c937789f1fc9ca13ae57e6e8e8d9962968a45fe585ffdea9df77c7d8528f01ccf2eae85febb1acecc461bdccd99b1c09e34a3729cf8f02bb3ab7d090d163a8ad734d7edec48335bbfc7ba8ff3490f27b5e297dafd696f67dafdfd4bef76abe4ff94ff9f795fccb9803be6c7fd5bd8c99ddcbf4abf6ebf657f9e5a2f2f475d9f2d7c1bd8ce8f265fe552bb202ad4a6d16360739ca64c94152be2ca9fccb4eb54520789935cf2aa8e8d2cc6b5a27b48c1250175379392b536a67914b962fbdec4d56367fdd4b5a7081d64ab4eeeb5a53d42bdb1ba947d158d4cd620fa5268bfbdda5cf1f217f59c7ab5e441b29685b917719d136b658b417ae5bd0c0845ba8ee4d618b03ac296d6180ccd016d7f05bac7e65dc6e091bd1baaec6c2cbff67890f2dfa90efe378fd25f07dc487dfa71f208afa4be007f4fd6a66fb01fd15347f453f109f2ec33ff07fc53f48c4d7f073f4d7fc9cfdeb8c22d5f77174be2f92cbc1cfb1e8728e40e9b9cc839f9bd1cfa6a1ea2bca7bd3f71c6b597d9abf009c940dca2df28c0f4bfabfec02243d3dd7fd97f45c607a9e8b4cd7730bff03fed7d07e7b22b4904a49de2df7f476f2f20d0ee1a34a648a9845972b8122c1cc5a50c1ecba0b31cc2f56e8ed21e00107500770a5ebedb505c43cadbf4f60fedce3b3e74b2259ef3ba50b415ad2772e8597f723597588c8d382f0aa0fd3489e1991f7322fd03dfafd4670d56c35fe7bba53323d406f4ebbc52bd5b5692fa4d97f90ea27fec51491c005c9c969e962a50b2e65e41a180faf388de1b5a43930ad687e5ff85b298018f35bb83abf55cc79dbc237f5514e315ec52ee7d116621aa018f45b15433f7431fd10f3cd1f526c7fc8002c3f8c4cf5876827e053807e88d9d80f597c3f3f1bf21ef8eb3ecf4fd8cfd39324db27e8490bd92bc7193ecc337c134837e3117fb8c9a1b7bd662afd72e5dc7c5aac9dffdb3bafefb7a387d275a7ede3f29e1eef82bc9d5e03e935b20a0deda2edb40b6d7a1783fa6e522a406fbb2b159df8481aae40428d77b1a9898feabbb753376d77b256f0aedeeda261a562ad6db7a0bcab274f27a9d04e902bef0a4c374a08765137337507bb4aa6b46bb1ffb63e6c02ec9f37f148381461e6120dc9b3d5c4213844fc23cc85917888952b4247a60bf25c904947646d66826705390987f176c4623692e9bde61d69398b79d358d6efee0df9125adbe5f2257f19c7e6527219f5b954d66d74d95ee21619fca5b8455ef8d65f7697dcb42ca5909112b3b2177958a77f7fabebff06fabd01fe913c9386b1e247d213f08f64a56afa5164ec8fd01f00f647982d01bc8a1b1982165ee0e6c86811b364b9e7cbf3eb1ab353ea77fce6d1c9bb44f21e510a5ad57791ec066a38c06e607dcaad55b62669bcbaffc7b799e0ba1e1ff725263e23a8181bb933e935b6e897fb28e3fa6425611b754f6f5d246b0c07d1cc1b615164cfb091d5db6a510d5e4ba81e7537ffbfaf2f377406d2196b7425d13ae6b7fa3db522745eee478d91ac739451e8625943ed8cace3ca63f2e536abff3c7a8962c7e46b2c761c91feb87ee96dcc692a525d308e085bbed07646720e73b4f2813c739873f225c8264f535c8f214753984f18df68ca22d1540bce645f8f2c4d151a764abe294bf5740afdfe14ea097e2edc14da246832553295a9c51dc6679beb6fafc3f8b30e63c73ab4b375494ecbf2dd49d0927c4b721503b4aea836563bae9575c1aaec9b94d1aaec1b9442b1bfeb0aa0414ee5fb95a555d9372c85ca772ced2aabbeac790bec3a9f97419a8fad8b9c425e42cbc87fdb8d43fc272bc92e339ebb4dacdf41494c89df648a17d369942e5600b4898bce542fea73b9e0fcc58043950a1763f672b7fc22712cefb660a6e247f41f74135e2cc226fce2ebf7a83ebf8248f719ccce7bfc2a597bcbf7e058f43800c7193ce5b20315d9657eab22e8083e4dff22f4c55934430172acbcd57468ff72054a5ee8af4a3d88b59f596a2fa1f3bf10632e22f50c05a18732c42d3c1da22d681f2d326f414c89683f41b49f22dacf40e6ad5becde65a0c277fa3d84f1b1c7a1dd7ebdd784f236de6efa7ab8bb688abbf9ebbc3b3415c8bcdb99dedd6cfa7693593683af0b4de1e7775b13ef6e7953557538fba0e5dd98458316916761f7e29feffa847e9f05d7c703681f0fa400fa40801ec01cfc4e6bfc0374a703efefe407ec9de10328ed4e0bce3ec0007a275833c93d80b8e2ce141e55e83320fd9de50702d8e8f122e0c0f3e3f103fc787067e10127f94186f54e7e3d000f8f3283c719367ac03e1e99e4f182293d5e36d1e34bbb0bf93979bf54d6f7fa147d953e95cea1f2cc187d4abe1d03fa0ba1fe872a3483fb57e2fd1159b98276805ed38f17f85ceb49b9ff88a1898ed2f97ec3d8f6197b94cff7626bcfd78cc7b61b5b771e73c6a37c583c40cfa7263ceacf27263a1a9cc7d13d1a9e47fbc1b6806d741ef3aaa3f1f9d094609514de948fea9bd047ed6194743884a7959c4c7cd4d6edd1a2bc977db4747ed1a7875ea7eb87e39abcbb5bd68beea7f5747755b8f5e0ef4e8cd535a631dadd8d369aad29ad6b4d673cda5fbefeb4551dab9e9187ae3a7d37afb7f92ad5ac291d2c0c3d68ae0785ce4b8abb9026e3d44a592da0714d6d960b68b09e81199d94e8e0a7f9afcfeaa654e41339159f6be8e59d365a6f95173dea0d99ef9615aebd495fef8dbf3b5aef915e56bc5ecc6f95717d3db1dd89387f0edebd73c817ebce330b562c7189b917f4fe0f22ff7eccc3f51d3df4eec6618b58b3dff614efc02c40298e13a8bda328916cce59a5368deeba9ab377f9eef979dbcde61a52bd8d4da5c5fe76e7ef2fb23c03079477b22feeb49e7672f60553c8bc93bc3e6da37aa73a4117f4f028832b73a5760d5461e74a54f6de2b572b238daf21ed42eaf7cb123f4464a24a97092b98c1558a406c924aa4a8540293ce415c099300294a09234d25c950962f2356e264710de1d3261e94ff3fecca1ef97ef640b03295f75141cbc68332e056ca8a45a28be40dd681cc2e54de6865952d28adb480e82a48276fbc7641c63503bd3b47d3409a73acfe744ecac416e09c92eaad7ccffb1c6a004f9b233887b6786e716b847cc1d075bd2e36c1bb53537877d994de5d34c9bb0b406cd277a3df7d77b08adf1d3c48ef464cf99e701573f820bd03f1c67b82558e8307f91d28f33d7e55c0fe41fb0e6ee11147bdc7ae8ad83ee8df31c305ef6170fc60f08ef03d88a0981e0cdf11bd87fe2660fa9b085c842dcef67b0250ce296614ef71a01e94c5cb201713bc632167f205c3033df27df94d98a36c4254b989b6f3a6b2acc5048af9d24d6e93bd09e7ed265e016cca28e265d0024037618cbf89562042b8097b07ae285b8057948cbb09d7087465135cb5257dda7a36d74c59902d728c5678e49fa2bc047528dcb4f84eea97e5fb6e16b1d5dfe678a9c9d38cee6f6774cb44ff77994c7f6bffceb68072bfc5fcbea4ebdba2fec36833c391a97acc39e4dde27940b05573904f213bf185dca4a4d40e3739aa30f800e0616ee175354ff43dfcf6ab81be6a38b796ae06656557b2ba74be9ffd67babe19ce7919a376d90e7319b1aebc075d76e0d1a6e44bcc650f1e631828950300e597aba0d803e85cb990f3f17006e1255d9af321d2d370a8ba2c0df2066a80832e19b64a23f5b39abfd33a584d23709a2ef31339407dc46ec1e3da457ee2b3d8df1febfa75987f9e46ff378031e27437ae28773ac5b8189c2e631b9d2e1a3f109f461f3250381d812f9ec62c7dc09ea6a1e87430cda1ce43b86a07f8344342eb1b22453840aa21b5bb21af7270dac977d286ac4aeeb41fc2f11d42c9430c3e841f6a937f070414de312245f49d432cbad37608e3c410c68ba157737749deafe7eb7a227a0ad1db53b4a96a18db2e23ebb7a5bae25a051ab709f3f5a702f42af45428fd0cb698a53f156f2a986c35b860532cabbd6dc2fe6f8a4cb6fa5bb02954ce810bd4eac179d5e1a8414f4fa5ba4a5cbcc941272bbc15c039e487fa6c5a50f5a9275f7fda3d8258f99102a8cf29c6fc47680e1f2a9d4fa647f8533ed70be44b5b595e4d9dcdf3c6f5ab32c64cc892d6665fe6828ef3bc28d7dbab7492ae45f7a9a6ceaa1d6d081ad29c59ad2e9703f50e51cbacf4586a549792ad7e13ac60c2697e31bdecc7f4fe4059bfef947d51a9db644ff555e53d5ee8525957fa12295f812de32d974da854bf8f04df828995e6ebe37128df79050d4c0954d69c2e2bb52691ff3478c02c3b24efb9d7cec87a0198bd9f49013a84167228050d4d7aa8f3f5fca4fe3f8ffa3fbaccd81ff5c97faccb3183fa516aa243f468782832e121dacbe01da843eee0f78a8d945af1db5b501ba346c07f0564c5ff1dc138ed888050be0330b86c871b0c7644837e877c65d00df2193f68013e43ba429e7cb72caacb37caaa6716de0f7dd7f8eb7ae5fb8257ba4d74a5624a57d01e6e45cf30965cc111bf5556e9c5e87305474556f6ed295f2144e6c2db9e1278af2bfaf23822f42bac927ee3a027be627b02592d793ce8f1575c4f287ee3959e48d28e177b742d60c9759cc73c7cf41b0e63917c7361ac306eb3d25003376ec7c27197ad1d7c2ba3760134f23fa6967bab37e1b8ac2f4c63d807f8f9b1c53da7f121130ff570692a7d864c115bf9ba015a89723c85e3b0602e410e342d9554729a1b4f5183a78aaaf1269eb2cf609f55422c3dc5d312dacc338b5d6be9499dbf23fe7aa53b07468e57309f7da5028abdf97193a31fa3263fe6571025bd12428fb9f12b68b3aff4e5b4096bca3f8e40d9a43f46ecf931ff0ae82bf4312bb9fc98ffbe09fa71f88ae85c2ebb1f07af60ce805290c7c7165afff3d27f5af4913fe935fe273d00fad19fa095fca46802a591298ee2aaf989ac598fe3f913365d4a11cf8ca2fc9f74cbfb2df9361da59f905a33ceaa9ff8739e8e7e62650d7ed8e8273ccaf9fa0619c4aa5fe798c7cab761fc1d8d6f5bec082ffd5bbfdcff4cd0bf25383f49624a09e60009e27fc47391bc393c6c4b167c3a8c79d728e2bc51d846a31cb89e47831cded4b00f19ace91d6d7ecb24cd29faf5d104a096efa1242d7cff1cffced7ca2bb83ef4c9d60b38aa17689b7d90b615726a2fa0fc0b741dcdd1e73ac3d7b0390079ed4900bb4479be7c51deacfaf80bb6c2b3eac4f3ec83c3be2dfd29dd878defef099d29e0dca438fe6877a60ea42ff03511be40e709085e70fa7d4fcee41d94eb3304c6ce923360547b6131b5fd38a23e797f53eeeed4ea19a57a94d354d763ea515ebea537a09075a35c7d9929d64ba6f6287af1470bbf418fc680cff9f037e87e5a849ca5edfd3920a7c1cf05f582c83f87f6fd734bff3ec12ee307a5ffd3a7c1f4fba92cef06eb77bf6bca33674084a1ef183b4e013bd2cb7e042d7b04fdd54855d7ed72232967cfcb262cef2b0723050e4670cd8d84a6a0eb7de1ba1c29e9f7c417fa7b46ee1f44a8dbc982bca53d96c1c99bd7631e084eea7affd8d2493bc699877ac2638ac7042289c59d040f3906f5b9deaa8e1aa4e0b1f0643c159d74b986c1c75359291869904b17c64737e6aa214aad448257f3f53b59df2d1ceaf198bfb86540cd58f99fcbf5620ed8b2ad93e3464dbe2829ab3dd603b927d9a071f9f24aa94e0d3b4ece372cda1b37783c72725733e626ef99ea5dcc12b9d5898bb2ee962b7041a9ac258699e80c4ce21637bffe67ccb0ae0b4ac61ec6f9398c3c0fdb237418b53c4c47dc613e427fce877105284787dd110610751f119e0e7bf0952312c5d823885cc41b1c210e4915186bf696c679af35d5bd6456ed4584bb17e3c95e44ae7badf2bcd7cd9111adeef5a0fa9d132394f6a20fdfbb781e7167cebb3974e1c768b7ac0f8c366257e3ac006e358ed16abec1aea61be2d5a47cbcdadec0e043f09cf356f9d9720134cdf1eff2b4e59cdad5be2e7943be01b249562fa88e3488f17540d6bfdbd667dc36ccc6b6d13fc89a2e5e6997099522aedd5636c936cc1a3725db48668ba08c19226f4ab7c9cc10f3cd6d326b74a0b40969301f746aa37fa09c77d3d4e6fe38be80455e198f714666946f0237df8ab79bf84d2ef742aa379536d937d95c46ef9cf16fc2f1005811e4548032d58672de14e554801cdfd4ad2997cdd92ee408de6622ccbf42531e894c157d1efa48d3370bbebfba1311717f17b6ae1ffd6a7f17fab42a6c3fd3df39ffffcbf0f23eb93ff37c2ae7d9d0f3680dcf57738a99fef30e54da94b4035c49ab5dae732a5b4d1340e6161f9beb4ac8375a0d8096409d94030abfe76ba035f850ae73b90f8eddf36889cf17721ae4f50a575bad93d84ba0a196c15a4ea07562d481b56e81d69f65ed3b4d8376f4bcece3e2ffff79d684fa7c6d3286bcc6827e7b8befcfbeae12f7d32d517ff6cd94262f73a402f8183e9da86c05185590a7bd85c0f9feec9b2b112470b7604ce997afb544f0113bce2fe65261960233aac21866d963afe21be8b44ad6a794f591eec4bce44edac080bbb3643c28ddc9006df077c686542e6dc86898cbf29c0fd200facc8fea7c6eb31b0af22c50e66718b26d903c4304d02a2bcf07dd69737d94cb387f28d3360a9059ea622c646e94e4f923d443f844799bd78f1b65c953cbb12d7637af6f96cf8c6fb00a3d7ec3b7e45e6aa6c84b2e4ccb4bfbfdb3c63f18bb1ea3adfc58552901eeb1a4c96fc1760ba95d64f4818f31a8dd4a55de62b7dac7d072a189de4a5b6cb63aaea6e22abd954e5880dfca55466a59e991b606d0846fb5d93ab6d5b2da2585ae8fbb853455f256d02dba662d2cb5b7eaaab35b1d2ca52cbfadb27e20f4b276e0561c0b68252752aba4ea459e984743f65a9e96624487545b173e7ebd90afdf9a5cc1f57ec55e74f294cb9538e743f0d8e32b0c3e021fe6bcbb68472d64ece3155299441e65e8d0475ee16b82afd0700ac87f17344ceb6a406138188a87c9445782a1e88a7c1f0bf1ef90d76f677192024dbaf8fb8b1f93f5db657da4357ca52ab505ed9aa16bec95d4f82b15135c4972d09a10fb1029a535a59c2680d8ca57c235640ae06a80781581583d2358707cd678cd5dadc8c7693a392eee8a9497e5e76109d774de9faf1a3bb042fa3f44597cb8f4321ff61283bd1c7dc4be4c1a7995404389c0a0e34c574a76927ea9a1957262afe2e6fa5c8b3a534d304e0ccb56d660cd686dc158faefa809077a2566fe478971658b5116db26e81f690f25d4919b9506f9f01ed8f85a401b44ca54bf8327df0f59fa1bfa9f464cd017148cdf121aa7cf472176dd82ab7d0be2da2d886921cb1729680be2f72d8873e1435b52f874cd8ba63d4b93481e39953c99e33d9cf365c95bcbb15a5660b2f26c4e43f56fa69367b3e4792cf4788bdabfe70df7d728951e497aaa41dada03ca836e2baeaead01e4b20920e3b882473fbc35ca79f4315bcbb3a9e8af89d854ae02e55fb825d3adfff5306826fb5144947764288c86a64bb1f8f3f73bbabe42604a0762793f6c0f1f70fbfc1e7b0047ea00ef2942630f200a3b5001b5a61728ee2168437874218d5349e00f14904bd194418ba0c50325131f484d41df348b4ca46f937979eb2cc31ef7b49418a86c55e70e047ba203a1a9c2d7218d3bf0eabece28ef27cafdc5d8785f31acf7412b322b35b1f7a64b574208eb94a0ad2451bd80fe37f0b66e13ef753d2d6f8767805aca7ba62d3a8b7c489feb98e387b9e96c9dff29c834eceb7c4d7bd7d25671e02ee306fb2ddaf4711cf57be938dd8bbcb1a56fd1416c0f82decb07a7e5a6161e3896c7e934ab75c6635a424a3e6ed5a7867c9533dc9aa37233b2ea9a7ec7e7c9b1b506c7596a795a38adf569c41052ebe357d5786e799a3b492992cbbcf56ed6a5d5b33a479e5defd9f9343dedf1b9fb7955eda6f3acb5f038a64cf3a3a3c7fc39d269f456a7a7f307857cdce5c7ba57299d5ea6fce27e1f363cd423ebaf6c1ac03c780074990936d54c61536a92d1b2298c52807e2be0d19229292d9aea6821476c6aa3d10c36056619e6cf7e13efa079e0f44eeffc36bfc9213dcadbb4b86758ffbbae2f19c8ddcc46577e87d436d01fc837521e415d1e89e45b26aa973baac53912e7bc80e47b3df2cd95ec9eac913ba1f0952f9f684e72b716c7797fe6ed1f0932affd94cba1de892d0072a73785bd2239eff7aae3fda1891e296829d12365507a04fdff6b32f0235a3a7cecfee011bb3f3609001fc8ac65d07e9c25d52da6a7f89abcff29f72f06115d0eca5ac6b2da9fc8a4eb1ab3fca3773fc6a341ec73037b3468ef0f073113bb5fd7cb861cde4f83aec1f7631419a495e1fdae61ef0f64ad6bf0b6e1c05b70dcf0f070e0a811a82e69d95627489ef4ba3599a09594c1b85bad70f763ff67b03298403d6eade65bd4f756b4ee5b17ff5da7fc471bf4ff91d7cdfd72d11c3962448d2de0397227bbe4112cc0c75dad9bd74fe85cdfa595c9182c3bee1b510b788ebcf655bda0739f7edf27fb6ac4b5b006a875a0edd2bf9afa7d4fe327b98f87187138584fc3883386830d3c8cab6d98d607ab08ba3274763d46eaf53c5c024feb1d2094868b2a17870bc6e9934ef21414e2959c77c3510b1f2a1f2a1fb4f0984fe6bc1f76aa8fb3a7979037972bfac4122b2fb6126638f2c4945d9f3d6515e74f34c5b2021cfc6ac30b3e65d4a7efaf220e7c0971d54b54e0979819945e422cdc22db9742b58bcee5945ef2b94fa6cbfcd0fbbd54109ee9256b445f503bab6f49d3896dae4ceadb94839c977cfc3c3c7ca7d3b7f216f94a7a9e2ed7e67201bc9ba7be7e9efd5a780fbb0ff3df9e80d7b9e57488d7d1725a5701d79da3bc1c735159574e2db1fa74b5d88369bba4a775d50e698bcbed3a3b2b7da7fa3dabebbfb289ce2527e5d9063a178d2517e56dac8c4ba6282a4f15cf11284d1546c5c3eff12a97c163fe00f8a6bdc17374e283b92a30ed7366ae4f53e7e167df4c79baaccc7ea0b4f4f51dcdc7657d05371075eda3c8cbfa36fb2a402b1f4deb74cd9b917c1d9cb636d073e5dc8efa422a5dc30b74ce5862355d975a73ef73034b9da053c3d8fe158e4de51f0399f3efa40c0fe7740c18a787f91fbd581f6eb13c6cff11734fb5d89da97cb57b6730e600e1dc18ef74ef63a190ec18ed8cde473bed3c12432a40e2454aedf26c29bd6e77d2188f5aad99bec188baced09a592896fafbb471033df27e5bd1cbaac72ba8c12b58bf7f978c65efb8e288bd3fc879ec87f0efb7b9dcf4c179787f01a0163d22b662ce1539f39c23671e0ee972cccab3b55cd1c9bbb21ef55cdcbff94fe7eb13f8a1549e0f1d49b0459becd7b5f621a3bd8e14c14523e8ef8702c8628b721bf587b216cb50595668194a46643dc58aaca53d948e586cbbe48da9a1ea082b2fcfa7322c3484b872c8697a01721d92f485111e929c03d0b20987167217fe5fe4f95aaa1a77a9db142e616cbe441b0b97cac65fe28d3c4a1b45e64b1883219360d4ab8e2ec533ba4b16c02c66a38536939a960088e678c2cf90ea677cfd46c4c3aa296f2ceb1671806ee952b211b38a4b957c8b08ff52b8514aa3515d0f58352eaf9d9dd662dcb9c4b9c5a99647a514bed4bb51d61b5ed8f9fd1222f11e468dd27ec30a7947bc57d7a3a03400c5b89d620fc15bb5c9f74da29cc7ac45578dc0f80f5ebe8fe2d202742cdf44012dcafa11cabb34d0fcca69fe2ebaa6b7a6987afd5e8aa4ef86dc077b37f2aba0fc7c0d8c7b28ed423ef61ef94e78057976c1ce29cee502d6a4f83359bf579e49bf317a929ec011be919e0c6f6c72a2a727d0426f2ceb5a0df646fb245548c11537ade30a43e7aff2c960e7e819fea2430bbfb1a2ab3c2c8ca2d7bab14bd2e55bf7647ca36b9165bbb0b33af3fb1d797fc1c91389e1bce8c25cb72bcc284f250768aa4971be95cafbd942d1074c751d90a71b31161fa0bf10540ee8f392b944075c3e8ad9ba85c54d5b18ba405650afcbfa557e5a5f3af86ad7473cafff3f60e6beb1cf041b7b4cb411d7f9c62ef0385f7a1d3a59755b65521dfa188537958db49960c938d4776368ca1b2d380baeb4d181f3b016377a70b4b97b63b019396eeeda18ca97f33627a0ff4f67e7929c300c83615bb29dc7806999964d579de11e5d66c19ac9d257f005d8f40e2c72905e25a7f021fa4bc94032eda2941921f34908875162c7838537be6f4f3574e86b687cabbd3df18ed16ee0534123d7fa00fd649afec11db6f61de3cb21d4a6195bb319117dac2366fea38dcdc5a9e6cbb46e2babb0acc4dec84449a95b31abccaf58f83771ba4ebc243c139efa0542220b4a9f3472446e0c767ee764997c79b87f06b8092b22d5cb7878863cf25f89bf3dce7a7ff9912dbdcec2797fb5b22b22bffc10b151c6954b7c32b22887abecd3a08c7cc81bd88389f991117630ee4dcecfba44138aed5cc1885010b930dac89c0ee71bb8fc16d677c851f5c1d1774eb99d850aaed31d7ad6f9d93f9a16b16ab5494c581093105318434bacaab4665b1a1311b32a7e2771f6673687f3dffaff25fb1b8356cb3db652e92adde7b2521b8d13fa434b2af7dc4a8f3e59f13f3af509894184df5a54c11a94dd5a0b16f5f52605adc1b64d8b3934515acfab3935f0f0b0c8f3e200be01000000000000000000 \ No newline at end of file +0x0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000ebc000000000000000000000000000000000000000000000000000000000000000ea0000000000000000000000000000000000000000000000000000000000004f34ccbd7b941d57792fb8bf6fef5d8ff3a8537dfa74b7bae56eb5ecd31c4bd6305921c2321ecf18a98389456e44e7ba25c00e1d1bb06c8d64328a51b022a9f59625844158760be3a05ccbe1c6c4185db8219800820c413c6e12c0134c48904872657287ccacfc715756d6acbbd6fcbeafea749f6eb5cee96e933b73d6fad5f7dc8faadab5f7b74f55ed32a6ed6fb8bdd9fc97f6e6c1dbdbdb873a64bfe26c7bfbf0707bfbca0ef95f7fb9bdfd860bededf50ee9473aa47f4d077ba343fe374eb4b7af3adbdebeba43fa9bda9bcd4d97dbdbd75c686f7fed647bfbff38d1defe73edcde6e72eb7b7ff7c87f43f3fd9defebadb3bd83b94bf76b883bd43f9afef50feeb3b94bfaebdd9dc32dcdefe8689f6f65b3be47feb647bfbff747b7bfb6d1df2bfed427bfbffdca1fcffe56c7bfb1b3b94bffef6f6f60d13ededa31dd2ffe27007fb85f6f6374db6b7dfd1de6cee38dbdefee6cbededbf74a1bdfdcec9f6f68dedcde62d9dec1dcaffe50ef67f737b7bfbaf0c77b077c8ffadedcd66ac43f96397dbdb7f75b2bdfddf0e77b05f686fbfeb6c7bfbf8ededed9b3b94bfa583fd6d1dec6f6f6f366f9f686fbffbf60ef6cbededbfd6a1fc5f3bdbdefecee10ef60beded131df2fff50ef67b27dbdbefbbbdbdfdddc3ededefb9dcde7effd9f6f6ad13eded0f7428ffc1f666f36087f2b75d686fff5f3bd8b7dfdedebe63a2bdfda1f666f3d0d9f6f6f776c8ff3786dbdbffb70ef69d9dec17dadb7fb383fd7d1decbb26dbdb7f6bb8bdfdfdedcde6fd1df27fe4f6f6f6dd1dcaffed0ee9f74cb4b7efed907edf647bfb6407fbfeb3eded0726dadb0f0e77b077c8ff5087fc0fb7379b2317dadb8f76c8ff5887fc8f4db6b73f3adcc17ea1bdfd7807fb890ef60f4cb6b79fec60ff6087fc1feb90fe43b7b7b77fb8bdd97cf8727bfba9b3eded1fb9d0defe7887f4a787dbdb9f686f364f5c6e6f9fea90ff5487f46726dbdb3fdade6c3e7ab6bdfda90beded1feb607f7ab2bdfd77da9bcdef7448fff1b3eded6787dbdb7ff7f60ef6cbededffee427bfbb9f66673ae43fecf4eb6b7ffdeededed9f98686ffff7edcde6f73be4ffdc7007fb85f6f64f4eb6b7ff417bb3f983b3ededcf77c8ff5313eded2f0cb7b77fba43fe9fbedcde7efe427bfb7f98e860ef90ff673ae4ffd9b3ededff71b2bdfd0fdb9bcd1f5e6e6fff5c07fb1f75b07ffe6c7bfb8b1dd27fa143fa3f9e686fff6207fb97863bd82fb7b77ff9427bfb85c9f6f6af9c6d6fffeaededed7f32dcc17ea1bdfd7fef50fed726dadbff74b2bdfdebc3eded173be47ff1427bfb372eb7b77fb343fa6f0fb7b7ffa7dbdbdbffac43fa3fbbdcdefee71dec7f71b6bdfd3b93ededdf9d686fffdeededed2f7548ff9767dbdbbfdf21fdcb93eded3fe860ff617bb3f9e1d9f6f6bfee60ff9bcbeded3f9a6c6fbf34d1de7ef9f6f6f61f9f6d6fffdb0ee5ff5d87fcff7ea2bdfd3f77487fa583fd95e1f6f69fb4379b7f98e860bfdcdefe5fce7628e0b0e1a15ae00dad63a0db3028afeb3216d4aeab1807ea4033b92bb777e7fe15535e57bc0602e3f7ca96f6d2be0cc575710b5fde5b58e7ebb1721d2a79ed1fed326ea0e6dd3d64dc9b33d024d09301fa3a740ae8ebd0297e567a323d757a1b6580dedd01e4f45f596fba513ab477cdc085c0788685e829b4772d2ec58c7ea127e81ee3fb6b81356e7f62e2fdb149f607a6b2df9a74bf03cd40fb9303576fd1de744bfbe900edaf1c20e5ecfef2c1607f191a365dfb3b97ff8cb1d7d56c60925b8b406cf8d60408e7506f38040770680d85d4e05b5d18341c34d4a010b5906d23081dc0b926824724dcadbd216a77aba0672e17aab549cd32200cedae447936a27b153ffabca1c17e5f3074a8cfd8b40714f54951f2a1aae1d40abfbbcb50249453d0dd94a6b0a87448b6b8420f4500d2ecd6941189fd10f45108e06c449a27aca213d80c8744273e3ed7b1a616ada40076db54316de5ac6ccdcf3691a59292d2bc0e2dd6ac4e9cdbed2c9bee112cf1ecfcd4125da51348edafd652eaa7eb6653aef22cbd33f379cfd5067a1ce66ac2e95a688da23e1cb55e630ff52cf004ff47e3066bd6195f778fd806fa61500f8a6bf09150e447e2065af02368936b4270042f5a631bbc86450fde2b8f7a340213291f18dbf039ef8d6f3853021c7cb9c1260102e5093cc18fd654354f3235a5d6141a764d8cb4f0db9221447abb05656d71c86be1bf7fc0f5d9e38a86876b26184e8d1d763bed70093297093c81f270a4726613d999de615c3b3b2dfc79a7cb01bba16142ba195d26bbabfcfeb5651aaea26c8b7a92ecdb4e1e5ef4b5adbfcf637ceb0b22e34a89894ab8ce478a25f45a251a29005442c9f3f2e871739e4bacfa92ea49f5c27b2001dc1c2a3e33fead69edacb25c894702804b6843a560c4a25e25d430424d5d295ae0fe7dcfd881de20347e032d2f19872d2b70c637f072d1ba0dde643487a19cb339688335d1744ad1b1fa841bbcf89912f8ee1ce186daf2d2344fa6081ac03f565f2b35b89f2ad3c8f3742698559e37d3b5919a6a3d794349eb192eeafcfe8bb1433546ff7518bdc3e16a4e117f1dc6557ab8041ebdd2613a42900994218b8f57dea9cd1f0ed56681424ec5dfe7b23fecd55e53bd6be1adf2bdcaf30278527e99969dd1087087b94ef72142b80f14728c7c59eb61ebc4a4604d831684baa45a9f851d1fc40fcb7a227f3430c151c49ea00cfabb473962419d8e21ff63a0990c842dfcb581be2d5ac0c84b15c3fd121ff3315c09c78aa6782c349563885b8e59d3051dcadf503a463b1832da1d247eb3870cbdb18f42f36652d09bc576b59edf8c16b603e7f85132fffdb457d70067ec2a9d3765ddfa47c323fca837c9a3bca8b62dbf1386076a017aa621d4657fd9d0100df010ef47afbc1fbd3c246820894d257015f5120fcc378e944d7adc9a78808ed334ec718c45c7ed400afe0dc779e046a002994ce138af0ce0efd42fccfd5177e896f2bbdfd07535199f1abd403746c38a8caa1c36ca4ae3465169b151c06829884dda88aec609418011d4492cc9558cb2a5865db712a36a6f63e931e0b386076b5c366eb2cf04933563276933296a8685be43a1127f00fc0768b2cbf849fa406e9b4c4d71b2a2284f964d3249278bc80d4772d29ec4b833c9e0fc49af5c71323c891164d29a12e04fda49c40e00414bf02e22b768923fc8a07cb2309998e06434192c79ef5af66f2df66f2df66f2dad2105f648e8cd0a95f831f08fd15aecdf5a7a2cb7adc5feadad28ca6bb17f6be966ecdf5aecdf5a7b33f66f2df66fadbfd92b575c1bde8cfd5b8bfd03fccd762df60f404e00f60fb9456bb98f41f9e6c25aecdfcdd1da57b17ff418e2f73e8bb8ed43cb8034a7e8eb27042ee33fe4735978c4001368df004d20dd045af84a6856da018c1613ac1a5ee92678254f1445ca7d78c27d9827e03b401385a61e29f9c3aece1fa6dc225aaff9a8ef047d38a813ac0cabcd6a3300cb87236841073002a1764d4d96a378f2875c9e7fab45ea6fe7d117a6f7a3b53c9a08b52636af234ff080d40ff18f70f91eb19628fac2f4be6b4e9a03fa98018fa3837c06383f82a1ee3d7a8b09f4471fc2d83b11e7c77df17dc427343e0b4d308ad17f343885bc47e9146df6a7ec5df6148e0c747497fd2de0148e0824becb41e2533846a3216c4e6d2ce93647a7dc5dee1422c6d1ea293bdaa510be09ece5a83d15fc56a4feee147f243e25e5495e09f277a3a553182147451b697d68b488ba2d2e2669fded31eebade103d72827c129c8b8431337409ed8c139965e2fc27bcb390589d79c20abdd3d964aaba9c3e5e455a5a5f053f1b0e76440409c6f7c4efb449644a49c1149232e47801f5fb24468d1e5b32615ac5dccb0ebab4623c28669f839c22a24c09b429174d0a5d8299a9058d309b64b533d2e3b8edc1cc067e418af16a4f00ce0198bf0d7a68684f08a9acb60873d22252c77b308f4aa33d25e4e790daede931c19e9a89f624a67a3a36fe74b912832b9ae4f4d2cec13f19b77c05c64f7e5b4f8eb2899ee0b7854fa0464fc490850a300ebd0dc7f8095cb94f76bf979fa4f7d220f004bd37ae641471fb7b339b7dafad70a67b82c15be8f8bdbee201d6b4619e466826db16bed5d69a6ebe7cbbdf5b355ca921945a08163b12feaa09aeab856482299ccba90228cb3f025374a66042e1958ba628e78a534dc4a63c1599642a34b52932af9db28d1b40bb0f2dae0607a57ccccfed54e5a332ff774a7125a2c4ca4739b2d31c8363e5c878e52cfc6c0b0df32d7f94aea2fea30512fb5c8ad48b3c62b37f0f18b7ace69d298f3b531877b7f0389b5f1e47cc341e84c50e341ec7959dd3cab83776bcd8902d35bc46fdb6d1d425e34b8c70a8683ce2c7c044db6263b7a11fdfe656da6d18a1c0db6db4d2a90ef500cf00b580a7756ce6ea047e1bda0da89de59b510704396d4d6373bd6ff143fe57f9c42dbccfd384ca739e864c35af97cdd38badb92f593dc4576c3882db96769e6f45ffd18bf39b7060aa6c4d8d1920f35120e3d10bc35661f49fdc6d58812b9117d65f7d04b3df3e1f99e0c1c4d807f929ff60c130a87b90d93d88b6fb2041e7c07be503f0904d017656a0ed8022add8b9eb413287801ae41a6c05a409e15fd4b438ef2a13f2a7a708f9d383167a0b1ea3c65388c79e5ae83f0fd9ef011366edab88bea348aff1c5d038a5f41a5b449d41cb451c3f502ae258153943f6cfd854d0e029c4f30acc03a65c23015f0270dd9b2a7aa514a9d3e2e2674ed9efc73a7f92fb33e8e3d7a16dac43acb28e5667f75f84524ea38c36727d23d7633e423ae7405af0f6368c7db721fab90dfe9b19926c49b781495722ea5d1970b812bdd5ca88839cfa9584b6822b7a650ce0aca18df0ca6416a59515d06a0e9214f0f4e2bd52aca43a52d9ab0ead9d7b3abd41d7e1f78fe81f7a0394693390758f92b5401812e4a085175b795ad7445b7d7f39a734c7969595de033e224bf7d0c76c0e52b0d0dc6655e6796d4d9dfd18cd63d7fca59ca7b332177d78a847ef8f21a2fc1dbe1a4cbf63e76059fe7fcdfcf01f4f993f8e33fb71e6f259e83ede04d28a7c15d002725fffff990f6614aa6bda7a177131bedfc4d7c9f8e8f6616cdf17c81d37d385488febb48ff6d048650fae27f05d7b789f551befe33a5f4debb369024a394ff5e21ece6493f9e05aad2fac7ebf28e737407cbe3b35f610ed46acb5bb62dcee920976a3966f6013eff6c6bf013deaa14d276bffee7f0811638db56279583bb4e87635fd3b2ac707fd53348eb9d478e468bc88315f28a25fa5a109c70347cf10788904f8198718a3364e5b48b7723f916f8cc7f946b9afc8cfd038dd88ed8d34ce72af51791e77cfa0ff503e7c26b71b7e06fdf38d88816ff44baeff69e95f1191b9b7612efd36be8f401de2e802f2a77be96d741fa2ea7be9c66814a5deeb94c72cee2e5219f1ef7dc08cfdbd99dddee532f9c6a6ed83f7f24d7c2f1fa35970f3eabaef5dccf10f97cbf55d43e4cc952abb0a5a7c2565ab34e3b9e2cfa1ef3e875116d49fe38a3b67956750378f3cd7bf266808a812940bc3c5320f2376d27b1b71391976e5a51effa7300faf0552f732806819f325078aba07ae826b0e9454b601ea253eb9ec821068dae2693d05e53c4d570523efbc60e36ff3016f7781c3081805f4641888ce06eec94c97060beb24fec5d8e5cb24fe3997183e176ce573887fce1540119b9c4bb6d2398cdde7e8860a388cc2e7f806d1a19ee7fc0dc5ad3c0a0df8e006daea22bb15ade61cdadd39c4b8376016718ea27014b9aea428001fe43c230dcf273f05b991fb820f1b591efc907f2acfb781322294f5103f9595cc8de256ff5056a3f256fb50564bd4f6a1ace652db30dfa342be8788b2ce2d30caa2b5c60ff522c67487d15e72c8bd0df7381d0e72d8c703b117831c36bb9f51ccc0d7e031fb394c8f07d3c01c0a79a1bdceda3af19a2e3938fc700b8fab3ecb714e1ad9222fb13c1eccd4eb7197ddffe850af565e4a68ad233daeba967d17f0aca3131c5ec4304f88d7067b9d35f65d3d86de85b3f8ae5a4eab267a17ea92b402fdf4bb28c1d5360b4e3c138665062cffda24c1bb9284c0474ab33c82775540a3dc42d35e926f34cb66df85fe27514ca797dc732d7c9dd687e700e3d5bbf8aa5a222e7f17cdd91fc1ab9bfffe37c3d7f5cafffb43bdf24f927143dd2618c25870d80ed1613794d148eeeb83732a59b9ff9ff20d0c1de55e42bd3e9de0ea043dc397a10bf44908ba01f182fa07ea87b486b1b5b9c6a5b62eff413525f19f91c51f5750ca87a32186d5cb9dc121b993561bb2a67708ed07a505752735c15ed8c3c90d566bea6f90b2038052f0524bd38bbcec0d98adddb0901eee598d2f52e37e33326ed0cda50fbadf04bfaa0d37f0b3e2681071dc35ec4b3fff9fd1f1c7eb9312dce0d565e3f3ad5dad7776568b96d6102412698d6c698d5d5d6895e11d6b1af18ec085ba8d5607d8c6ba2dacf6ba75d89656db7c2ba96da3bc9a4c962f379c9666ebbe45c7c837d4527ca3b27a31fbb7dbf8eb6ace9b805353e492c1fced5c84fe38c0385fc23c4dc6fd94c98c304621007133fcd0f76b2c809632ade77398b9abec01561a99644fc124e7321097c689c12b1616933d6d68798fc7bc344df489a1302d9b625ad46798c25c67d3347ff2a79ad32eb9ce80b2b1fdf0ec17dead0f4cdc1fafb7d816d7b3f2e865d613b8f2fab9106db0def6b37afaf5d48f6847d3c6c8c72347bf7e21cfb1bcd1d8653579fe691ce3da7801b16e84581823e6b170dc1ec3713ee6c6dd3194718c40c91c3be66aa56341ad007d496d8b399b57ffb6c9fff33e30d160d914068ba00968d984833c4283255ca3e148c9d0606104f61c45688a4a6343236c4a23a8ef8835e5118c96801ff1f578c49b2ee82bf0298d24261c59d25d2ef2f2ffa8ef7e1667e859fa3dfb2c7f829e8dfebdf0049d871c3c4bbf1f3c8bb3faac7d8ed45ef824ab4ccfd127e939563bfd7ef82cfd81a4122ffa7d0758c003fc7bbe45124aeadbaa6505ff1e3f9b8a4e73caac956759cafa7db1d0b445906ade597efcc9b9e0a66fee3f9f07ff5e8f7a2dfdfc7e0ee3533fc26baaf71a0ab95e33165bccf24244ebe052b4340f8a598bd21264442fe0ed8658792ffa0d912980d206aa07a6a49ece244ab1f761456c98bd5a702e24e34191bb0944c6b62c4f3a6c406b0eed31ee0920e93331612c4f456cc0390ec3636f01d7033deab961e113eca3b882e5ff7b3a82887d8a8ed8a958793e425316c03e54e223618b1ddc5438cb4740471c3c4bd8b67a0a780afb75b212bcfd24c6c6e3c90062fb1c76a0749c945ffafdf73b70fdc9f3019ebbd0b726dac796d1ff5538345de803e5ffd51e059b5ea00ffdebcf017d0a86deebff654bfdfd0daef0de509eaf40df3c5840b42d11619c53c4c8831e637e308878049ec1901bcc2cd842c219953b6343727f0c36956888550ae125f7be10390c154ce663918f9491eb913fe213b947866d80a84024f11109790f49e91e9c47b934e4efc156eeb821b740f395fb75521b445443728f2df32d48adb1470bf907faa4cc7f6dd1b8eea28977b9ee7817e2cf5d74b7eba6bb23e5838c4276cf43d78db6d63de32152968eee263397e379e8ccbf61d155f6c59fbfaf60ace995fb459fc2bce05318793e456be9f5b4d67fca1a066f45aed3da0076915d2e479f129ff67cb2485afc94adcfd684283598ae816da95d90d77831cf7acef7fb65bdfe238c3fe8c9462ac661acc9503601c6a9e00501c6b5170a261a11c418c3d09bbd20084de905f46718bbdc48e9976a238b2fff792dbfdba65d6ca9abf2886cc347e8d3a172fe11df4590a80b504df088fd343fa27257a6c1567c323f8067f9573a6c7b2c9d4fad3d0fe93c29ec7f00462cf8a68e735df712a63a0fe5cf5706674aa67006f1da196fc23374243ae34c1994cf58533dc300999d67f888054d40193aab948e14e0c3cafb231ee902e862e4e34033e05c20ffe0cca2ef7193442d721f2ab6e5f3d6b2f1d61ed77d7eb4093e4fc7496d9c1d8b6bdab3b4653966759a372f376da399e37d4d9f36e9eb73caaa5fb36e8f529bfc32bbd43ddbff459f5eead1f9abc4debd129bbf85f53e8dc8fafffe5b428c4788d7dfe200abb600c8e44c1faa5f41d3869a47a0be82cc97739da42176eadff40b214b3e65b11bf1a840d395a592d418ddd45b799b7b32463d9ae6034dc739b292b39aa0c62841d2fa5cce7cb29a2052400e2513a9946a8ee2b190e7469abf3d26d0f753681233ae495ff7d31ce63e39276f149540fb27b95e9e84be5e9cf4f224fea400d7d31cca93893c9d85746e8223ab903b06896eed441c712e77aedf2ec3cbf5fe432d50843507609e52439ba9e188d6f83388f93e5386dc0d5b113a0f3f0fea6a8893f4fe42089e4caaba8c8e228f147e4d0435f799605a5e78437cc0042b6a987ff8cf769bc2672ba6f459ccc93eeb39a863f6fcd980a33aced267238eeb11e2a3b0eefe303005f6f5e80f650e1ad78b7fe8a1457f0fcf0a5a5641b7388ef029832b4b44cba5fae2eeeacefc7e0351484f843e0d3924380e29900c45d7440fa225811db275c44c0a0b19310ff8d9c8f42ef7c3d8a9691757bfecff15b4f0bb711d027437cfe2f96ef4b3002326e10fd01aba1b2deb6e3794515ac3ebe9037417a8d8ef46ecf631c46319bf86fa693dc3e6efe6214ebd78f7e37a44aed706727dbd5fe3007abdcd75afe60da5f71b3fd0e39ca992808d23ba9fdf41f717de1191d022e88c269905263eefdaf015c2350604c8b790f302af652dac7ecfe8fd758c8faf453b7b6df0397e2ddaeb6b0b9fa3d7e2f8bf360475007a85d7dacf657a9bf324fadc8e7396f97dce6636c8259559f32880566721f349f3b4699e6f22f999f48fd0a7fe11ae953f127ee97303f97d1fc77f99fcbfb5919c0378636c6ccedb8da1f281f2686739ef365ae139cafc0c3bf4ac0e3d2b68d1f9dc5200e6a37e63cde1bac8f3f2595e79be591919c2967ac42df52b2a9f01f3de9ca78d1593715d46f661d1fbff79dae000fe3cf63fe7ede743e503e551b79c779fb7c27394f9614e8bfddf80fd072d6ef0b9a500cc47fde76b1bb0ff795e3ecb2bcf372b2343d8528fb8a57e45e53360ff739e3e5f311987fdfffcc2f7ff19e397f778c218e9649c94e3c97667067da2a3c96f4414366d738bd097991724871cac0f737d8d8b1bd1d7e33cba459ccbf97eb79970b02792b9660528992f6a9f8c73d58a7934b52141c7ece98b261eecb56eb46adcb8fe1f2bcfd866fc98be15aafffcb9d1489e7b1bcd3c5a2daa1be3d1c07066bfa68f3cf5ebc4cb74f2b3a3dc9a5b1b4fa13c3a2bcf56efa6d7742ac99767fc9ae9c6e7f325f16dcdb5adb7e46b17e0c9e338061dfcec7890e535c7eec70bc6e77a3f9e82efdc7e1e36c180c47fc91462ac2365f977c978d0e048320fdc54708b6ba1762abac5821228e60009dd82599211adabd32df254a8831e5741f68f816acab72ca647ff7ff2f91b6df6db31426da7cd6e3bbdc8db31e302b5dbbd89b6d30ebf9de549fcedfc226da7010b4db0dd9a103ce45b3c52c106d9df2239c06e90cb0ef0a811dd126ca741dace00ed107f44fdb7f00e780d06b954ca6994a556dea234ab326b2e79ddb4149b9728750d50378fdac0fe22e4cdd1762735dbec2ab443ea0ffd40ac254746b89291bad8ed0b9b4bee32e17535cf26e991fbd4156c695f9053dad3440a99a7e5b4c52b4b1369faa2f1fbe85c17b67c0ead679f3d5731e1be8ad137fd1b19a29e18be0b7fde64b3bcbf1b22bee004f3a4924931db91ff051702cfe91d688decee40ff0f14eef0dca59ab4d3bac9d3bf87e5fd778739522391377dc7b851923b5c6368ad63348ba79ea209d4c3f6e03a6c84f2966f0f66ad0d2f9ce96db0e9c3d5f766a04fc1aa2b36e844dcc0396d585044d88dc54c639f69fe3f815eb520bde8280de21a1e44af35286f4f5848f2cfa2caa3e120a2a441d1dad17810bd15781a74e0d12b0c46a3a5c1f26834188e26f0854e524266a5483b2a5e0138969e0efe0e7ac9310627bd2fa9bf1df526415d0aa8d3ab7977427e7f62a8bf07e7dfb1cc63f80527b356a6173022be20b23c675bca66c390330418ab4929ab8cfe63daeea0b3597ad5955af862e683362669e905cce9d5b790a76de55f97e50d5fb907482f446ab7685bbc22447d4a1cc9bcfe055ee07dbc6bfd3e81fdaf0538af0dc4320d0e651d858c16e41e46c3aa24efefbb304368ca61a06b30b81c147a95e9789e430ba5d0693e4d5f59bfa12b64d38516da0d749de04c86be02df0c5ecb081ab66e1bb1894f2c7d1f4fc8fd63c41f7e4f519e4332d11e8cf495a2717b28fb4fb3e24cfe8c9282153c0df482c64e83f5d9a476e00aeda40aefc8403b7d8b6d093ffa44f3fa1b2b193b96c505760ce74be2831c76cc37e57d390c8fe1b8cfd6edd3f179cce67af0ad967dd4f46fa2c592a5148f3c32d1d47c1f4ddbb9593b2dddddc7d37e36cf29b86fa66e336507f735cb6849bfcfdd375363dbe22d65ced48bc79a356bd9bf7db38f424bda161be328b4a434adc7c0b51e877d738eef9ce32fb5431f34b6e43e880eeafa11c8eb0bc10cd65a63bf8076b996b155ee0bb41630fe0bacbc05159ec1872d3aab7e99dee7fc5c5b94d1b5b97e6dae5fdb9266da8632d6cef56fd1691d32d05a97f3b3cbbbb69ef37cfd5575d134b3f4f9fecf6b9b5b8e3f929511b4ecf37cba99e3b8d49327bf0fcbf305f27c61bd0c4426addb0d61233c26ab73202a3019dfd4fdac689637e44ff16c3bca5f5cfd9fc6fcb3e67bff18b9b541ef1ff317e98f53c05d83da2fd26fb7f7984bf98b9d4bed5cff1386562ca3c470badcb8b4df04a9acb343f7b8b447699076e732dd63d32e53505a3125a565534d8ba696c6a617e3dab2d49b81d49aeb5232436930cb16a4c13d25b537301626fa6c0ba7526e519f8d9167ce96f2fb82e1ecfdf52fd54cf0a52ec35fa62f65a8189bf3f6cb65e59df2a516bea87ca07ca1858f4cf54ba8ff971037439f7c39907cebe997a8ce5fe6161eede84b2d96169ebe44ea67bf54acf355e902e4b9b0fddd692cda1766e42bed8bb84256d28b88d35fa495451342c32b6358d0bbaee48950de643136a73c4195d078e12ab8ba56caa81d9b68a58cd24513af4c800ae4d4c83b30376d2bae0ce2e52bc9d4562eeedfd0ffa6cf0723d6d9d46ddc269cd317d1333ce536d153d8df1751831733c9bfe84d089ec1872f229a7ed1d542e8dc8b5c733b801731e77d916ad10eaa59e8f929ce25e4f814fa73a4a35a01323d05def84d9954c829e4393e764e1ebe25ff40cbc5fcec8894ecf3dab8961afa969a8773f6aa8c3dedc61e1716707cbe82f949bf93bb3b35c49b55f43bf25419e6cc469e50e14c92be48d766b1889e03e9f536c0560757453f550d37c8fcaab0213645f6d816e41f1fd018b1addb50d0ffbe2ac8c999748393bb53c8c799ea06967b571b420e379072419d39d0d56662761b304e6e48f43917072a6bbee87f6f90499ebfd9c0bafe5aefa25ac3d5bfcd72ff29d467203052e3480fcad31ac2735ac00ca749cb83faa6f2344d73a08f400a7987f97583b5adc93dbc1531fdd685b7d1ff2aebb3617e22abfe64405f5342df004a5b6c89b6c439cde0c5ab45066435a2599a7c05a1593aff339091ef059aa3e3929bd6a11ef3d4c55e55e3c544caf71bd75fa3c854d6c640c194eb45536ee8b3a0bf569ca668fd6b49d6a3306e6db9a191957256757eada4984121cb0da379d7636186458eaa33bf8730bef65acc2d4ff6187712fdfc49f42927d19b9d440d4ee22a39498e1468c7d005d3b0a606dd0cbca9229da00b79749dc43e835654967c6b485f5d74fd0e9bf8ba2aaeaec27e0664653f5c87e0333a5b8e81b085fafd7696bd933c373f91b372977a748d79ccd0402d880dafc735bfbecbb8f51513ac4f80b289d69780a229acc738f815d4e5abb87ebe927c95be82f6ffd58c7373287f15d7ed2fbb5980efbcefdbf157c5565ccf5ff5263a418f8527167f27eeebe8599679d4ed3cc6c804ede27c62dc79ab94cf638e53a7f33c2db9f3642aa255c83320492e91520b994536c2a7e7255fecc3f948d1751eede67c603c7c4b396ddda3f03cc633e80a486fc15bd002d24b1e7cbe0b14e3d8f954f3a6f355d537e9527f7fde9cdf3610d734dc1adb90ff22788d03e4fd7406cd56c2d37579d69400795796735e56c4137daccf768b8dd4662147d9aa786bd26cb5bc79a9d8e5bf085299356d45dfc5559fd5d470ab9de6eb5aeae25bea18e5f5c63cb0b1f879e0768dbfd954aff7267d02d7f9f564565d8f59faf5d510f3cb90afaf01ad7c067b7d14dad784e051f7ebc3907ae8356891af0942ba1e7b018d05cfd7e38c5d5f823722b6eb977296be86d1ae57fe13d3751c5b919a5294984a84e842d64e8892dde8c1c075efc6e818f5ec46bf8aad58ba7653e4c0d928ddcd5f73b088b7707c50b4e5dda4bca42b294f0731de477e37231d4afb9a85c67f4dd2892c7afa1a4347796e6cc2dd0eba50dea98c7015edf6116b4e29f22f2d61bff31f21fe19ea418c133c86fd79ac62e8b1a0418f79a00c9e1ad0373c408fc522ab6ec64778d185b9bed55f104debe10fdeb5c8adb6c202f4414bf9736da2f72d72696eba9f81decd29bf34a77cdb222773d3fd0cf468f559f940daac0b744b3ff9f2fb88fc3fe31173fea9ff3ae62f5f27d0a209fe94958b4d089af191894049f9d0c4aaf79003e5a32550fbf5ca9fa2478654aed39f8ab60c0c7e7d31f57fd8b8ebfa10bf7b7d6f2032f1089968c49b6004b134e046ace8d88327503b822b1894e15703dd08da0b5d2ffc6ac8a386b4d591d084e25f0f4662938c144d49df5cc05c6ca46618f2c27f5f3056d70f9327e5e95e771fdf8b281f94eec53853ef077a31530c37a3f79539e04acc90a6116d46efb61263f02c6dbc192de1be64a5df6c9937eb9a87f795e797e0c7a6b4b2b0393045e486517073680a398763b532d88cbddc8c190a742593acace4cf6b554d525fd8fb166f3381f6efb6bf8a48be0bb309cc5afb935988fbcba6d85f32a5fe22a259860ef14cbf831e7d6bbf370580fbd11efa5dddf55b7df6a870f7c28eef197dbe2034912f1aeba361eb71147d32cc1273f8ea30795c27be063903e424d70f739279ea0aad49965a56770d93c80799aecc09ac49acda043a440eaa2d966575550f5e72441e892f630f6089cb451395173a527e12c74fde3fcaaee5b2b1cf93f6c5f679ecc763d8e2bacff8f079f44dcf6364c6d6eef04ddd8ea08513eb5cdd6c6bf584f423c909c44319a0e313b403fc34e2130e7ea4decd1e2739b1b418e89f8dedabc5b8ca8f87b21ad71b82e3f4063a84739cf3a0caf371dac1b2aee21b1c247b9c77d000e792874dd7519cc7f6ffcf74bce0150dfe49d61ff6b2fe75c5f01e5db96c8c0e211aaecaea65163cfa8e2acbea66631930d7aa522ed3c58c8655275af85b4d134a6ac845e5257559399432161e1a18f3553b563ce4942255d55eb4b03565aefa8bdc225335bc482ac3ab41aa0b2ed21ebe38e38314b90c7b3df371176d8b4f11350bf724638b6b3f5f36e175fd8cfe7c307adc0fa02d0ffa8f456cfbec00c6fb41fa9887de0e30cbf30773e550d3501f0db86fcce5c336ba304f1b6a9efc31378ba7c7d1673e2e6f6807a84f56af02ea252bfd21261944dc34d00fbccec83a841d7e84d9f290febfcea93c857c1b6a7e9be5923c19054a00df963d4f4db705800708f19ad889dd6da4b2bf4deee306b98fcb9e9bbe2dcd6cc6ab3d405ef23e909327a2355df6ac36df16c3469a4e9f9016aae5f0b49fd259369ba5bf35ab7156030bde4d6b331f9fa7c9f2b19a8f9ba307bfb846d1f2fb8e3c9f1c20324f313aa7f2df15ce431a0f46b2bade207d53dee47129a84ae84be55e7e8a3ef09b64744dbe6fa22f1ad4f73755c7f0023788110ade6851df9476e624ef6f4aaa18f992f875e492466052ccaaca0dbac36533af3b48dfa415d01d36036655bc1af1f41d3e5bdf7c91fb2ffdc7728c7f7e82b659596f735b32815609a934e14cf78435d184df2556ced6e6dce626e25db023455928f4955d0cea41c3892ee8ba76595d87b37b57b69ee75c6a1fa25d73007dcf43b29a58f450f0e1403941f290ac3396f12a9bf9e5a6aea294954f55cfdbba73daa3a06d8b3b3e2771f6062ccecb41cce70e22163968f7164dba97d7e198edadac4364b42ebe05b1e3bac22df13a36c12d8575d15e36f1baca5e9c9b75b5bd6edd6fc3bb17b4b637d0d5ae8a7b4bf04cd6b9d7d8751633b9e23a7e0d636e6a0f06c61d8ca077e06a0743533d88d811254707abc0529e347c54d79fb3fb0ac6ee73724ffa16da17e554647b8b3c4994519fd3a63e543fde8723aafeb129209f685f6916827dd1015bb72db47840b65c8f0fcc48c5034ba8bc91f79379594de6d02318d31045bb91128019c6f182091063f2081f6f01e24e32074630ae028511777cd912dea96afd1d457cd5ebfb86a944b7554b3c5cdbbc10b861aa5007b8e1ee8a5da0dfb2e1a5d6ff7ec343fd181fec8a1e13ade832a51588a357209e5624a6a0a89858819606f4adc07c06e859811e6005e6334823fee227f6700562f515ddc6214f5ed16b6845df52ab478fa1ffed95ef7f9cac01b87e4fa1359e440b7c235ae929442127d1e79ea437e20a7e23fad4532cff089fe293f68de865e16bdf283289c7297ea378375389c6422356562b52212fab7aab3af89cf4f9eacf3cedcf9a1bc15feaa2f96a6ab1282ffeb2caedacbc33ab551b4bba37725e2b7f929bb5442a7f327ca3eed1299be7037a2a6a7aeb1e68fa5385bc363e3b02e003dd8abf37590d65ebea80bc1d8c3d073d15e6b5c9f68c735952c65a9e1ccde691913d4ff458495d16dfc3dc6ffc608f0d714d3abd3631ef056253c6fcd7621e9c8c58509fcf99ad59067b3052c2dc1a476224e578a4cae1488d07218b6d197c7ae11f8d388e301f4f75e6bcd4b767e4fd2842ff8176823e231c913506656500cce4d7a17740ef41eb5093759cad1cb04eeaec641fd6cd5036c59b882b39dc4d45ccff2af3a09070dde6bc4b8a1ebe0bb805fc2bbafe8233d130e6acc338d3c3817c43c464df0cd1ef8124916e65a5e248562b36e9eedf38c13b0a0003ee04d7811d1168df89c51e9f874d3458b364a2d5887856a3b5ac0e8a404ea9011de210a145d062835645fa1d165a851864953c37193578d5b24c36cb10a7f4282fcf5bcaf755b84839e4dfdfaaae30bf9895181ed6e76331d61e479f731cfdcdf1a229783e8ed976071a203acd38c489b7d2b414ccc3e15cd5c5a3a2babe453caa7049ffbf287c8b4ce95b889ebe8533f62d4484908b00010e60e5d12f7d2bcc7d44675517e63ee1b42ecafdbdfa3511e4f9f85cb6eae7a7fd62d565903c66ca98c9236aa9137d2bcdcb99293fc8cb977af6a8add3feffc084032b647dc6272a015dcfb212da1314241fa1eb695456439e962afac47d2e615637c307af4e8f9ca72d3cc35f145eeb74912ad3b55bf03aceb5059eff13f2fc86fcdfbfb13c89f3b03198f4233c89de64a39f8c1193d88db16840cba356de181aa5491a65c04d66bc68cb4bd95ed477395b344bf97d4ddfdfeb99c2b1610a2c1740798a72a99849ca97728be5b272989d0598f7092061d61660460650936a4a07decec8a0f3fa5d43ef5a4ae80ae6df56b9676a49bb2e3fead7f7e7f4bd565d43863166d14e7dfb55b623d9d69a9eb24d791ab002a029dd43e93c7444ec5d65fa15d04f5bf00eb065ccc633ddafb4e876ced509e26bf05efe375ca20d75e7a63dd2729b326b3aa94b53ee59e08a88079bf7278f958c3d66dfe98e45c68186c7306f3ec6ef0c8ed13bed3159ab85de49c7aca91e63e3c147aa2759e1e59dd001f4ce7f0359ec15f0f23d1a7f8ceb016c84f445e4c9c833cb4f202bc260f671ecd53ddf7ed0f8eb7a9cd57f114bf24fa20932fe483bbe70a878a49c233884bd3b52309523f134fc91f299607a1b9ce1c30c508b8ece1421174df9ccab7b3ff230a2ef9a3c3ff1fa6500daefebd17b29ed514aafef03104fc23e9bd64c5cadcabf7e77c6d58ad262b5acb45c2d99ae6ac17457639553d01ab0bc8ad1bd8ae35e0d8fc8bf88e19110292ad5a54767ba7e198e7fc138ee96ff923e68b94bfe7bfa6090bd0f0f5a31054e729e3e485c3625c61c868bf93a5da8e3107a9f2107c8db71917c87871d740e948742b5fb5cc74381ca05e5659596199b1db29ab602c8bbd145e4176a1e647a657519a495356716777eec502d0c2b88262bde2c8e227af6f11c387dca7e2ead7a0f9ef4ae04818f3cbf85000fbeea5fcd0a83afc8f8264fad4da2cd4c2646be9843187758be523a89f904f456c621d832dd6ad39bbdeff15e7a4b97ae6c40bab2c18c265f4de1bdfc96747ac587f9a5d99ead39f15baa99e774be7ebacc20e71cbb75d9ca0cd1b486734d21cf17f1de5be439baa5fe9e318cf61be9fac1d1388fb9717d931294153c2e6b0bbb310f1d8f5b5380ae20ef128296c6ed18ebba6b6e2cc87cc7acfab152dba24be1bb1cbebde3ce545146f242e12af00b285da9ac3d4ce0e54dcf252f6dabbfe9ff5ff46b8c65e31ac8b35134c189fcff9706e62033c8fe7fb9c39e60a070873bb16cc16f7acdfffb5d5dff0f739f3fa3ff645b407f86b33c4b9381d5d3cdd18757f95d4b5765505de9aa57bf3660afe20b6cff3c56d9eb17095eddef8bf2fd62e9eb6e5e0ea00ddf8cfefb66ecefcd984dfc05e5103df6ece692c8f7cc00ba33f651db57c8f57c8fedb3678247b92f9ad6709f1b80cf57f951ea638c3dcdd4dc170cd0a3f4557b077d1514e9acb9ae4466a0c466e03866eac79d5956f2a6f778607a4ba1a995621396c2e3ae5434692931a5857c23912a1a5fa27e4fa35f7f9a72a4c602b4ce3e2ddf03e0a733ae097a1afdc91c1d7c8c9ba30bfff5e58ba86f9d66ea7051399349aec562e7d90b6f688e6ef1ade569b9fee4fdd991c414473003477c5a1a71f2bf8a0946304ee8da5119e59152851640537d6fab10c9fb5bb6528a48294534c2e0412b163c35f52305919a7cbdc997403bd77fbbdc5fa1b2a1049176b2ccd8a4cfb8a4d7f8a4c70449d51493b24992a27e65c9025d0946b4844c37f83ef0bda0cbf4bb4d646a89dc3d67d8843a132571a920df592ac9b381716929bdf8af9878592d447c7914c7f4a83595a39c83cccf83f2513719d4ad8c7edf7147093c463cd17f0723e17710337f87618bc011e0beb3d8f2f719b7ac37aa8f45e7c2313e871c003e17cce2e99cddc3008177e718fa260d916ed9ab485bef7837f5ff94f6e74353f82e7a94ef16be47df450ff25dfa9e7b890182ec552eb4f0f412ff1ff43d8606b4456f5fcab4b645d79a0f438e20d3779d716b84173ddaf99a198ebe1b2acf265c001fac61e191d2afb1df0d5e929ced1a9773287f4d08de9aa2782da1f5c8f75f79b086f8d51fe832ee803de80e20563d101fa403980f81da03e8fb0ef883f68c872e840f1f8ccf30fc9cea63d50bcf072bd0937c37fc001dec3a430725bfae33f620c3d60d1b1f70078333762c848e0e603622e59df1634e7d3066209d3d138e59a4e503385f07e80c8f8712639c419d2057c6b33ad8710fb8038194fb97e001fe4bb175fde5e2aea2d326be6e99ac76b5c3ef8cdfc7e8a1dc0ede49e7795af23ba3f7d9113271ce15e6a1e1fbdc34cd3c85cb52679cddc1988b4bbec1fbfc48569e70bd324747cfb64c4123fd2a2ffcf74efdbe3bc6967a0c60965747ff5a8f6565270eeb65cedee4481857ba49797e14d8d5b985868c1e436d9d6bf28b261eacd9e5df47fda78194dff74ae9fbb5b6b4effbfda6f6fd57f37dca7fcabfafe45fc61cf065fbebee65ccec5ea65fb7dfb0bfce2f1795a76fc896bf01ee6544972ff3af5b911568556ab3b039c851264b0e92f26549e55f76aa2d02c1cbac7956414597665ed33aa1659480ba98cacb5999523b8b5cb27ce9656fb2b2f91b5ed2820bb456a275dfd09aa25ed9de483d8ac6a26e167b283559dcef2e7dfe08f9cb3a5ef522da4841db8abccb88b6b1c5a2bd70dd820626dc42756f0a5b1c604d690b036486b6b886df62f52be3764bd888d67535165efe3f4b7c68d187fc00c7ebaf801f203efc01fd1051d45f013fa41f5433db0fe9afa1f96bfaa1f87419fea1ff6bfe6122be869fa3bfe1e7ecdf6414a97e80a3f303915c0e7e8e459773044acf651efcdc8c7e360d555f51de9bbee758cbead3fc05e0a46c506e91677c58d2ff551720e9e9b9eebfa2e702d3f35c64ba9e5bf81ff0bf81f6db13a185544af26eb9a7b793976f70081f552253c42cba5c09140966d6820a66d75d88617eb9426f0f010f38803a802b5d6faf2d20e669fd7d12f3e71e9f3d5f12c97adf295d08d292be7329bcbc1fc9aa43449e1684577d9846f2cc88bc977981eed1ef3782ab66abf1dfd39d92e9017a73da2d5ea9ae4d7b21cdfe83543ff12fa688042e484e4e4b172b5d702923d7c07878c5690caf25cd816945f3fbc2df4e01c498dfc6d5f9ed62cedb16bea98f728af12a76398fb610d300c5a0dfae18fa918be947986ffe8862fb230660f95164aa3f423b019f02f423ccc67ec4e2fb85d990f7c05ff7057ec27e819e24d93e414f5ac85e39cef0119ee19b40ba198ff8234d0ebded3553e9972be7e6d362edfcdfde797dbf1d3d94ae3b6d1f97f7f47817e4edf41a48af91556868176da75d68d3bb18d4779352017adb5da9e8c447d27005126abc8b4d4d7c54dfbd9dba69bb93b58277f56e170d2b156b6dbb05e55d3d793a498576825c795760ba5142b08bba99a93bd85532a55d8bfdb7f5611360ffbc8947c2a108339768489ead260ec121e21f612e8cc443ac5c113a325d90e7824c3a226b33133c2bc849388cb72316b3914cef35ef48cb59cc9bc6b27e776fc897d0da2e972ff9cb38369792cba8cfa5b26ea3cbf612b7c8e02fc52df2c2b7feb2bbe4a66529858c949895bdc8c33afdfb3b5dff37d0ef0df08fe599348c153f969e807f2c2b55d38f23637f8cfe00b03fc66c09e055dcc810b4f0023747468b9825cb3d5f9e5fd7989d52bfe3378f4ede2592f78852d0aabe8b643750c3017603eb536eadb23549e3d5fd3fbecd04d7f5f8b82f31f11941c5d8c89d49afb145bfdc4719d7272b09dba87b7aeb225963388866de088b227b868dacde568b6af05a42f5a8bbf9ff7d7db9a13390ce58a32b89d631bfd5efa915a1f3723f6a8c649da38c4217cb1a6a67641d571e932fb759fde7d14b143b265f63b1e388f4c7f54b6f634e5391ea827144d8f285b633927398a3950fe499c39c932f4136799ae27a0c399ac27cc2f846531689a65a7026fb7a6469aad0b053f24d59aaa753e8f7a7504ff073e1a6d0264193a992a94c2dee303edb5c7f7b1dc69f75183bd6a19dad4b725a96ef4e8296e45b92ab18a07545b5b1da71adac0b5665dfa48c5665dfa0148afd5d57000d722adfaf2cadcabe612954be63695759f565cd5b60d7f9bc0cd27c6c5de414f2125a46fedb6e1ce23f59497699f1dc6d62fd0e4a624afc2653bc984ea374b102a04d5c74a67a519fcb05e72f061caa54b818b397bbe517896379b70533153fa2ffa09bf0621136e1175fbf47f5f91544bacf6076dee357c9da5bbe07c7a2c70138cee029971da8c82ef35b154147f069fa17a12fcea2190a9063e5ada643fb972b50f2427f55ea41acfdcc527b099dff85187311a96728083d94216ee1e9106d41fb6891790b624a44fb09a2fd14d17e06326fdd62f72e0315bed3ef218c8f3d0eedf61bbd2694b7f176d337c2dd4553dccddfe0dda1a940e6ddcef4ee66d3b79bccb2197c43680a3fbfdb9a7877cb9baaaac3d9072defc62c1ab4883c0bbb17ff7cd727f5fb2cb83e1e40fb782005d00702f400e6e0775ae31fa03b1d787f273f60ef0c1f4069775a70f60106d03bc19a49ee01c41577a6f0a8429f01e9ef2c3f10c0468f1701079e1f8f1fe0c7833b0b0f38c90f32ac77f2eb01787894193cceb0d103f6f1c8248f174ce9f1b2891e5fda5dc8cfcbfba5b2bed7a7e96bf4e9740e9567c6e8d3f2ed18d05f0af53f54a119dcbf12ef8fc8ca15b403f49a7ebcc0e75a4fcafd470c4d7494cef71bc6b6cfd8a37cbe175b7bbe663cb6ddd8baf398331ee5c3e2017a3e35e1517f3e31d1d1e03c8eeed1f03cda0fb6056ca3f398571d8dcf87a604aba4f0a67c54df843e6a0fa3a4c3213cade464e2a3b66e8f16e5bdeca3a5f38b3e3df43a5d3f1cd7e4ddddb25e743fada7bbabc2ad077f7762acae318dd1ee6eb4d16c4d695d6b3ae3d1fef2f5a7adea58f58c3c74d5e9bb79bdcd57a9664de96061e841733d28745e52dc853419a756ca6a018d6b6ab35c4083f50ccce8a444073fcd7f7d5637a5229fc8a9f85c432fefb4d17aabbce8516fc87cb7ac70ed4dfa7a6ffcddd17a8ff4b2e2f5627eab8cebeb89ed4ec4f973f0ee9d43be58779e59b062894bccbda0f77f10f9f7631eaeefe8a177370e5bc49afdb6a7780766014a719c40ed1d45896473ce2ab56974d7d59cbdcb77cfcfdb6e36d790ea6d6c2a2df6b73b7f7f91e51938a0bc937d71a7f5b493b32f9842e69de4f5691bd53bd509baa08747195c992bb56ba00a3b57a2b2f75eb95a19697c0d691752bf5f95f821221355ba4c58c10cae52046293542245a51298740ee24a980448514a18692a4986b27c19b112278b6b089f31f1a0fcff6157f6c8f7b3078295a9bc8f0a5a361e9401b752562c125d246fb00e6476a1f2462bab6c4169a5054457413a79e3b50b32ae19e8dd399a06d29c63f5a7735226b600e794546fe57bdee7500378da1cc139b4c5738b5b23e48b86aeeb75b109de9d9ac2bbcba6f4eea249de5d006293be1bfdeebb8355fceee0417a3762caf784ab98c307e91d8837de13ac721c3cc8ef4099eff1ab02f60fda77700b8f38ea3d7655c4f641ff8e192e780f83e307837784ef4104c5f460f88ee83df4b701d3df46e0226c71b6df1380724e31a3788f03f5a02c5e06b998e01d0b39932f181ee891efcb6fc21c6513a2ca4db49d3795652d2650cc976e729bec4d386f37f10a605346112f831600ba0963fc4db40211c24dd83b7045d902bca264dc4db846a02b9be0aa2de9d3d6b3b966ca826c9163b4c223ff14e525a843e1a6c57752bf2adf77b388adfe2ec74b4d9e66747f37a35b26fabfcf64fa3bfbf7b60594fb2de6f7655ddf16f51f469b198e4cd563ce21ef16cf0382ad9a837c0ad9892fe42625a576b8c95185c107000f730bafab79a2efe1b75f0df455c3b9b57435282bbb92d5a5f3fdec3fd7f5cd70cecb18b5cb7698cb8875e53de8b2038f36255f622e7bf018c340a91c0028bf5c05c51e40e7ca859c8f8733082fe9d29c0f919e8643d56569903750031c74c9b0551aa99fd5fc9dd6c16a1a81d374999fc801ea23760b1ed72ef2139fc5fefe44d7afc3fcf334fabf018c11a7bb7145b9d329c6c5e07419dbe874d1f881f834fa9081c2e9087cf13466e903f6340d45a783690e751ec2553bc0a719125adf1029c201520da9dd0d799583d34ebe9336645572a7fd108eef104a1e62f021fc509bfc3b20a0f08e1129a2ef1c62d19db643182786305e0cbd9abb4bf27e3d5fd713d15388de9ea24d55c3d8761959bf2dd515d72ad0b84d98af3f15a057a1a742e967b0c52cfda97853c164abc1059b6259ed6d13f67f5364b2d5df824da1720e5ca0560fceab0e470d7a7a2ad555e2e24d0e3a59e1ad00ce213fd467d382aa4f3df9fad3ee11c4ca8f14407d4e31e63f4273f850e97c323dc29ff6b95e205fdacaf26aea6c9e37ae5f9531664296b436fb3217749ce745b9de5ea593742dba4f377556ed6843d090e6cc6a75b91ca877885a66a5c752a3ba946cf59b6005134ef38be9653faef707cafa7da7ec8b4add267baaaf2aeff14297cabad29748f90a6c196fb96c42a5fa7d24f8164cac345f1f8f43f9ce2b68604aa0b2e67459a93589fca7c10366d92179cfbd7646d60bc0ecfd4c0ad021b49043296868d2439dafe727f5ff79d4ffd165c6feb84ffe635d8e19d48f53131da247c34391090fd15e06ef401d7207bf576ca4d48adfde82da183502fe33202bfeef08c669470484f21d80c1653bdc60b0231af43be42b836e90cff8410bf019d215f2e4bb65515dbe51563db3f07ee87bc65fd72bdf17bcd26da22b1553ba82f6702b7a86b1e40a8ef8adb24a2f469f2b382ab2b26f4ff90a213217def694c07b5dd197c711a15f6195f41b073df115db13c86ac9e3418fbfe27a42f11baff4449276bcd8a36b014baee33ce6e1a3df70188be49b0b6385719b95861ab8713b168ebb6cede05b19b50ba091ff31b5dc5bbd09c7657d611ac33ec0cf8f2dee398d0f9b78a8874b53e933648ad8cad70dd04a94e3291c8705730972a069a9a492d3dc788a1a3c55548d37f1947d06fbac1262e9299e96d0669e59ec5a4b4feafc1df1d72bdd393072bc82f9ec2b1550eccd4f9a1cfd0435f909bf8228e995107acc8d5f419b7da52fa74d5853fe4904ca26fd0962cf8ffb57405fa18f5bc9e527fc0f4dd04fc25744e772d9fd247805730694823c3ebed0fa9f97fed3a28ffc69aff13fed01d08ffe14ade4a74513288d4c711457cd4f65cd7a1ccf9fb2e9528a786614e5ffb45bde6fc9b7e928fd94d49a7156fdc49ff374f4532b6bf0c3463fe551ced737c82056fd3ac73c56be0de3ef687cdb624778e9dffae5fe6782fe2dc1f94912534a30074810ff239e8be4cde1615bb2e0d361ccbb4611e78dc2361ae5c0f53c1ae4f0a6867dc8604def68f35b26694ed1af8f2600b57c0f2569e1fbe7f877be565ec1f5a14fb65ec051bd40dbec83b4ad90537b01e55fa0eb688e3ed719be86cd01c86b4f02d825caf3e58bf266d5c75fb0159e55279e671f1cf66de94fe93e6c7c7f4fe84c01e726c5f147bb3375207d81af89f0053a4f40f082d3ef7b7226efa05c9f213076969c01a3da0b8ba9ed2710f5c9fb9b7277a756cf28d5a39ca6ba1e538ff2f22dbd0185ac1be5eacb4cb15e32b547d18b3f5af82d7a34067cce87bf45f7d322e42c6def2f00390d7e21a81744fe05b4ef5f58faf70976193f28fd9f3e0da6df4f65793758bffb5d539e3903220c7dc7d8710ad8915ef62368d923e8af46aaba6e971b49397b5e3661795f3918297030826b6e2434055def0bd7e54849bf27bed0df3372ff2042dd4e16e42dedb10c4edebc1ef3407052d7fbc7964eda31ce3cd4131e533c2610492cee2478c831a8cff55675d420058f8527e3a9e8a4cb350c3e9eca4ac148835cba303eba31570d516a2512bc9aafdfc9fa6ee1508fc7fcc52d036ac6caff5cae1773c0966d9d1c376af2454959edb11ec83dc9068dcb97574a756ad87172be61d1deb8c1e39193bb9a313779cf54ef6296c8ad4e5c9475b75c810b4a652d31cc44676012b7b8f9f53f6386755d5032f630cecf61e479d81ea1c3a8e5613ae20ef311fa0b3e8c2b40393aec8e3080a8fb88f074d883af1c9128c61e41e422dee0087148aac058b3b734ce7bada9ee25b36a2f22dcbd184ff62272dd6b95e7bd6e8e8c6875af07d5ef9c18a1b4177df8dec5f3883b73decda10b3f46bb657d60b411bb1a670570ab718c56f30d7635dd10af26e5e3d5f606061f82e79cb7cacf960ba0698e7f9ba72de7d4aef675c91bf20d904db27a4175a4418caf03b2feddb63ee3b66136b68dfe51d674f14abb4ca81471edb6b249b661d6b829d946325b0465cc107953ba4d6686986f6e9359a303a54d4883f9a0531bfd23e5bc9ba636f7c7f1052cf2ca788c3332a37c13b8f956bcddc46f72b91752bda9b4c9bec9e6327ae78c7f138e07c08a20a70294a93694f3a628a702e4f8a66e4db96cce762147f0361361fe159af24864aae8f3d0479abe59f0fdd59d8888fbbbb075fde857fbbbd0a75561fbb9fecef9ffdf8697f7c9fd99e75339cf869e476b78be9a53ccf49f77a0d2a6a41de04a5aed729d53d96a9a0032b7f8d85c5742bed16a00b404eaa41c50f83d5f03adc187729dcb7d70ec9e474b7cbe90d320af57b8da6a9dc45e020db50cd67202ad13a30eac750bb4fe2c6bdf691ab4a3e7651f17ffffcfb326d4e76b9331e43516f4db5b7c7ff67595b89f6e89fab36fa63479992315c0c7f0e944652bc0a8823ced2d04cef767df5c892081bb05634abf7cad25828fd8717e31970ab314985115c630cb1e7b15df40a755b23ea5ac8f7427e62577d20606dc9d25e341e94e066883bf3336a472694346c35c96e77c9006d0677e54e7739bdd50906781323fc3906d83e41922805659793ee84e9beba35cc6f94399b65180cc5217632173a324cf1fa11ec227cadbbc7edc284b9e5a8e6db1bb797db37c667c8355e8f11bbe25f75233455e72615a5edaef9f35fec1d8f5186de5c7aa4a09708f254d7e0bb65b48ed22a30f7c8c41ed56aaf216bbd53e86960b4df456da62b3d571351557e9ad74c202fc56ae3252cb4a8fb43580267cabcdd6b1ad96d52e29747ddc2da4a992b7826ed1356b61a9bd55579dddea602965f96d95f503a197b503b7e258402b39915a25552ff2c43c1ab2d7f2b414233aa4dabaf0f1eb857cfdd6e40aaef72bf6a293a75caec4391f82c71e5f61f011f830e7dd453b6a21631faf90ca24f22843873ef20a5f137c85865340febba0615a57030ac3c1503c4c26ba120c4557e4fb58887f87bc7e3b8b931468d2c5df5ffcb8acdf2eeb23ade12b55a92d68d70c5d63afa4c65fa998e04a9283d684d8874829ad29e53401c456be12ae2153005703c4ab08c4ea19c182e3b3c66bee6a453e4ed3c9717157a4bc2c3f0f4bb8a6f3fe7ccdd88115d2ff21cae2c3a597f9b09718ece5e8a3f665d2c8ab041a4a04061d67ba52b293f44b0dad94137b1537d7e75ad4996a82716258b6b2066b466b0bc6d27f474d38d02b317341625cd96294c5b6092ad01e4aa823372b0df2e13db0f1b580368894a97e074fbe1fb2f437f43f8398a02f2818bf25344e9f8f42ecba0557fb16c4b55b10d342962f52d016c4ef5b10e7c287b6a4f0e99a174d7b9626913c722a7932c77b38e7cb92b79663b5acc064e5d99c86eadf4c27cf66c9f358e8f116b57fcf1beeaf512a3d92f45483b4b5079407dd565c5d5b03c8651340c671058f7e786b94f3e863b6966753d15f13b1a95c05cabf704ba65bffeb61d04cf6a38828efc850180d4d9762f1e7ef77757d85c0940ec4f27ed81e3ee0f6f93df6008ed401de5384c61e401476a0026a4d2f50dc43d086f0e8421aa792c01f282097a2298316418b074a263e909a82be69169948df26f3f2d659863dee69293150d9aace1d08f64407425385af431a77e0d57d9d51de4f94fb8bb1f1be6258ef835664566a62ef4d97ae8410d629415b49a27a01fd6fe06ddd26deeb7a5ade0ecf00b594f74c5b7416f9903ed731c70f73d3d93aff339069d8d7f99af6aea5ade2c05dc60df65bb4e9e338eaf7d271ba1779634bdfa683d81e04bd970f4ecb4d2d3c702c8fd36956eb8cc7b484947cdcaa4f0df92a67b83547e56664d535fd8ecf93636b0d8eb3d4f2b4705aebd38821a4d6c7afaaf1dcf234779252249779ebddac4bab67758e3cbbdeb3f3697adae373f7f3aada4de7596be1714c99e647478ff973a4d3e8ad4e4fe70f0af9b8cb8f75af523abd4cf9c5fd3e6278a847d65fd9348079f000e832136caa99c2a6d424a3655318a500fd56c0a32553525a34d5d1428ed8d446a3196c0acc32cc9ffd26de41f3c0e99ddef96d7e93437a94b76971cfb0fe575d5f3290bb998daefc0ea96da03f906fa43c82ba3c12c9b74c542f77548b7324ce7901c9f77ae49b2bd93d59237742e12b5f3ed19ce46e2d8ef3feccdb3f12645efb299743bd135b00e44e6f0a7b4572deef55c7fb43133d52d052a247caa0f408faffd764e047b474f8d8fdc123767f6c12003e9059cba0fd384baa5b4c4ff17579ff53ee5f0c22ba1c94b58c65b53f9149d73566f947ef7e8c4783d8e706f668d0de1f0e622676bfae970d39bc9f065d83efc72832482bc3fb5dc3de1fc85ad7e06dc381b7e0b8e1e1e1c05123505dd2b2ad4e903ce9756b32412b298371b75ae1eec7fecf606530817adc5acdb7a8efad68ddb72efebb4ef98f36e8ff23af9bfbe5a23972c4881a5bc073e44e76c92358808fbb5a37af9fd0b9be4b2b93315876dc37a216f01c79edab7a41e73efdbe4ff6d5886b610d50eb40dba57f35f5fbbec64f721f0f31e270b09e8611670c071b781857db30ad0f56117465e8ec7a8cd4eb79b8049ed63b40280d17552e0e178cd3279de42928c42b39ef86a3163e543e543e68e1319fcc793fec541f674f2f216f2e57f48925565e6c25cc70e48929bb3e7bca2ace9f688a650538f8d586177ccaa84fdf5f451cf812e2aa97e8ffe2979819945e422cdc22db9742b58bcee5945ef2b94fa6cbfcd0fbbd54109ee9256b445f503bab6f49d3896dae4ceadb94839c977cfc3c3c7ca7d3b7f216f94a7a9e2ed7e67201bc9ba7be7e9efd5a780fbb0ff3df9e80d7b9e57488d7d1725a5701d79da3bc1c735159574e2db1fa74b5d88369bba4a775d50e698bcbed3a3b2b7da7fa3dabebbfb289ce2527e5d9063a178d2517e56dac8c4ba6282a4f15cf11284d1546c5c3eff12a97c163fe00f8a6bdc17374e283b92a30ed7366ae4f53e7e167df4c79baaccc7ea0b4f4f51dcd27647d05371075eda3c8cbfa36fb2a402b1f4deb74cd9b917c1d9cb636d073e5dc8efa422a5dc30b74ce5862355d975a73ef73034b9da053c3d8fe158e4da510c89c7f27657838a763c0383dcc052fd6875b2c0fdb02e69e6ab13b53f96af7ce60cc01c2b931dee9dec74221d931da19bd8f76da7924865480c48b94dae5d9527addeea4311eb55a337d8311759da135b3502cf5f719e3067ae4fdb6a297558f57508357b07eff2e19cbde71c5117b7f90f3d80fe1df6f73b9e983f3f0fe02402d7a446cc59c2b72e63947ce3c1cd2e59895676bb9a29377653deab9b87ff39fced727f043a93c1f3a92608b36d9af6bed43467b1d29828b46d0df0f0590c516e536ea0f652d96a1b2acd032948cc87a8a15594b7b281db1d876c91b5343d511565e9e4f6558680871e590d3f402e43a24e90b233c243907a065130e2de42efcbfc8f3b55435ee52b7295cc2d87c8936162e958dbfc41b7994368acc9730064326c1a8571d5d8a6774972c8059cc460b6d26352d0110cdf1849f21d5cff8fa8d88875553de58d62de200ddd2a564236615972af91611fea570a39446a3ba1eb06a5c5e3b3badc5b87389738b532d8f4a297ca977a3ac37bcb0f3fb6544e23d8c1aa5fd8615f28e78afae474169008a713bc51e82b76a93ef9b44398f598bae1a81f11fbc7c1fc5a505e858be89025a94f523947769a0f995d3fc5d744d6f4d31f5fabd1449df0db90ff66ee45741f9f91a18f750da857cec3df29df00af2ec829d539ccb05ac49f1e7b27eaf3c937e63f4243d81237c233d19ded8e4444f4fa085de58d6b51aec8df649aa90822b6e5ac71586ce5fe593c1ced133fc4587167e63455779581845af756397a4cbb7eec9f846d722cb76616775e6f7bbf2fe82932712c379d185b96e5798519e4a0ed05493e27c2b95f7b385a20f98ea3a204f37622c3e407f29a81cd0e72573890eb87c14b3750b8b9bb6307481aca05e97f5abfcb4be74f0d5ae8f785eff7fc0cc7d639f0936f6986823aef38d5de071bef43a74b2eab6caa43af4310a6f2a1b6933c19271a8efc6d094375a70165c69a303e7612d6ef4e06873f7c6603372dcdcb531942fe76d4e40ffdfcece2539611806c3b6643b8f01d3322d9bae3ac33dbacc823593a5afe00bb0e91d58e420bd4a4ee143f497928164da45293342e693100ea3c48e070b6f7cdf9e6ae8d0d7d0f8567b7be21da3ddc0a78246aef501fac934fd833b6ced3bc69743a84d33b6663322fa5847ccfc471b9b8b53cd9769dd5656615989bd91899252b76256995fb1f06fe2749d784978263cf50b844416943e69e488dc18ecfccec932f9f270ff0c70135644aa97f1f00c79e4bf127f7b9cf5fef2235b7a9d85f3fe6a6557447ef92162a38c2b97f86464510e57d9a74119f99037b00713f32323ec60dc9b9c9f75892614dbb98211a1207261b491391dce3770f92dacef90a3ea83a3ef9c723b0b155ca73bf4acf3b37f342d62d56a9398b0202621a6308696585569cdb63426226655fc4ee2eccf6c0ee7bff5ff4bf63706ad967b6ca5d255bacf65a5361a27f4879654eeb9951e7db2e27f74ea13128308bfb5a8823528bbb5162ceaeb4d0a5a836d9b167368a2b49e57736ae0e16191e7c5017c03000000000000000000000000 \ No newline at end of file diff --git a/packages/nouns-contracts/test/foundry/files/descriptor_v2/paletteAndBackgrounds.abi b/packages/nouns-contracts/test/foundry/files/descriptor_v2/paletteAndBackgrounds.abi index 5b026a3e74..e96869e32b 100644 --- a/packages/nouns-contracts/test/foundry/files/descriptor_v2/paletteAndBackgrounds.abi +++ b/packages/nouns-contracts/test/foundry/files/descriptor_v2/paletteAndBackgrounds.abi @@ -1 +1 @@ -0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000002cd000000c5b9a1ffffffcfc2ab63a0f9807f7ecaeff95648ed5a423fb9185cd4cfc0b87b11fffdf24b49493432351f1d29068940867c1dae32089f21a0f98f30fe500cd26451fd8b5b5a65fad22209e9265cc54e3880a72d4bea6934ac80eed81162616dff638d8bc0c5c4da53000000f3322cffae1affc110505a5cffef16fff671fff449db8323df2c39f938d85c25fb2a86fd45faff38dd56ff3a0ed32a099037076e3206552e05e8705bf38b7ce4a499667af9648df97cc4f297f2fba3efd087e4d971bde4ff1a0bf78a182b83f6d62149834398ffc925d9391fbd2d24ff7216254efbe5e5de00a556c5030eabf131fb4694e7a32cfff0ee009c590385eb00499ce1183326b1f3fff0bed8dadfd7d3cd1929f4eab1180b5027f9f5cbcfc9b8feb9d5f8d6895d606176858b757576ff0e0e0adc4dfdf8ff70e890f7913dff1ad2ff82ad535a15fa6fe2ffe939ab36beadc8cc604666f20422abaaa84b65f7a19c9a58565cda42cb027c92cec189909b0e74580d027ee6b2958defad817d635eeff2fa6f597ad4b7b2d18687cd916d6b3f394d271b85634ff9f4e6f8ddb0b92b3cd08b11257ceda3baed5fd4fbc16710a28ef43a085b67b1e31e3445ffd067962236769ca95a6b7b7e5243a86f608f785ecc059542ffb0d56333b8ced2f39713e8e8e2ec5b43235476b2a8a5d6c3be49b38bfccf25f59b34375dfc99e6de27a463554543b19e00d4a0159f4b27f9e8dd6b72129d8e6e4243f8fa5e20f82905555353876f69410d66552d1df71248fee3f3c169232b28340079fcd31e14f830018dd122fffdf4ffa21ee4afa3fbc311aa940ceedc00fff0069cb4b8a38654ae6c0a2bb26be2c8c0f89865f86100dcd8d3049d43d0aea9f39d44eeb78cf9f5e95d3500c3a199aaa6a4caa26afde7f5fdf008fdcef2f681e6018146d19a549eb5e1f5fcff3f932300fcff4a5358fbc800d596a6ffb913e9ba12767c0ef9f6d1d29607f8ce47395ed1ffc5f0cbc1bc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000006643564376531000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066531643764350000000000000000000000000000000000000000000000000000 \ No newline at end of file +0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000002cd000000c5b9a1ffffffcfc2ab63a0f9807f7ecaeff95648ed5a423fb9185ccbc1bcb87b11fffdf24b49493432351f1d29068940867c1dae32089f21a0f98f30fe500cd26451fd8b5b5a65fad22209e9265cc54e3880a72d4bea6934ac80eed81162616dff638d8bc0c5c4da53000000f3322cffae1affc110505a5cffef16fff671fff449db8323df2c39f938d85c25fb2a86fd45faff38dd56ff3a0ed32a099037076e3206552e05e8705bf38b7ce4a499667af9648df97cc4f297f2fba3efd087e4d971bde4ff1a0bf78a182b83f6d62149834398ffc925d9391fbd2d24ff7216254efbe5e5de00a556c5030eabf131fb4694e7a32cfff0ee009c590385eb00499ce1183326b1f3fff0bed8dadfd7d3cd1929f4eab1180b5027f9f5cbcfc9b8feb9d5f8d6895d606176858b757576ff0e0e0adc4dfdf8ff70e890f7913dff1ad2ff82ad535a15fa6fe2ffe939ab36beadc8cc604666f20422abaaa84b65f7a19c9a58565cda42cb027c92cec189909b0e74580d027ee6b2958defad817d635eeff2fa6f597ad4b7b2d18687cd916d6b3f394d271b85634ff9f4e6f8ddb0b92b3cd08b11257ceda3baed5fd4fbc16710a28ef43a085b67b1e31e3445ffd067962236769ca95a6b7b7e5243a86f608f785ecc059542ffb0d56333b8ced2f39713e8e8e2ec5b43235476b2a8a5d6c3be49b38bfccf25f59b34375dfc99e6de27a463554543b19e00d4a0159f4b27f9e8dd6b72129d8e6e4243f8fa5e20f82905555353876f69410d66552d1df71248fee3f3c169232b28340079fcd31e14f830018dd122fffdf4ffa21ee4afa3fbc311aa940ceedc00fff0069cb4b8a38654ae6c0a2bb26be2c8c0f89865f86100dcd8d3049d43d0aea9f39d44eeb78cf9f5e95d3500c3a199aaa6a4caa26afde7f5fdf008fdcef2f681e6018146d19a549eb5e1f5fcff3f932300fcff4a5358fbc800d596a6ffb913e9ba12767c0ef9f6d1d29607f8ce47395ed1ffc5f0d4cfc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000006643564376531000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066531643764350000000000000000000000000000000000000000000000000000 \ No newline at end of file From 14bb588112c0cc0dec7e23861ee602bc3f8f9f90 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Thu, 14 Jul 2022 10:18:17 +0300 Subject: [PATCH 103/116] update rinkeby addresses --- .../nouns-sdk/src/contract/addresses.json | 20 +++++++++---------- packages/nouns-subgraph/config/rinkeby.json | 12 +++++------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/nouns-sdk/src/contract/addresses.json b/packages/nouns-sdk/src/contract/addresses.json index 57ae94825e..36f0a1500e 100644 --- a/packages/nouns-sdk/src/contract/addresses.json +++ b/packages/nouns-sdk/src/contract/addresses.json @@ -12,16 +12,16 @@ "nounsDAOLogicV1": "0xa43aFE317985726E4e194eb061Af77fbCb43F944" }, "4": { - "nounsToken": "0x442961F79C3968f908ed295a5DEbfcD9aC1712B6", - "nounsSeeder": "0x2fb885C03285D409485b33a285D6f13108B8386E", - "nounsDescriptor": "0x9884B2DFEBEf89e9A1a420aF43f7A2cAD54e040D", - "nftDescriptor": "0xE3F474821e6e4F712ba16D64AEbcccFd63373f3D", - "nounsAuctionHouse": "0x3F2e938318f5a9438853D25083DbE7CFB9A0652d", - "nounsAuctionHouseProxy": "0x2e29f14602ca236D001e8C5855939464dCC7AcD9", - "nounsAuctionHouseProxyAdmin": "0xF82152a4322800E15F14eD85e490Fe12b815E6c3", - "nounsDaoExecutor": "0x440afFbe17339a4c955c5dCE232725dA3a3Ff040", - "nounsDAOProxy": "0xe3A8B54A2b0ec636d6310aCcA1b002B80934f741", - "nounsDAOLogicV1": "0xE45C75AcF9F09c93c67a0f9B8dCF99460ce15310" + "nounsToken": "0x59D3356299432c58c80603316786868479753C23", + "nounsSeeder": "0x06f3FbB5E5D7e75Cb5ac3B76945668A466072889", + "nounsDescriptor": "0x99a06F809bFac2934252CeD9d081f656c96a9dEd", + "nftDescriptor": "0x54E9F30BCbA93ef7B577A78E1a05E273Ef96a2c0", + "nounsAuctionHouse": "0x88A97D11E4f5D04Cd59d872e4b186FCC3cAF612d", + "nounsAuctionHouseProxy": "0xDF87852c37D1774100526F92C89608C395785C5d", + "nounsAuctionHouseProxyAdmin": "0xE2c109430870A931473522b84d8E1c655A0E5de2", + "nounsDaoExecutor": "0x8B940C89fea4764D44846Fd6fDBd63d154A45C1f", + "nounsDAOProxy": "0x8c6B7F6F091bb3Ffb086DBa4d1b465E0D896a05e", + "nounsDAOLogicV1": "0x030082246E7381eadeF5cc663Aae4f915Df2F8e2" }, "31337": { "nounsToken": "0x0165878a594ca255338adfa4d48449f69242eb8f", diff --git a/packages/nouns-subgraph/config/rinkeby.json b/packages/nouns-subgraph/config/rinkeby.json index f29ece2902..35b42056e6 100644 --- a/packages/nouns-subgraph/config/rinkeby.json +++ b/packages/nouns-subgraph/config/rinkeby.json @@ -1,15 +1,15 @@ { "network": "rinkeby", "nounsToken": { - "address": "0x442961F79C3968f908ed295a5DEbfcD9aC1712B6", - "startBlock": 11011622 + "address": "0x59D3356299432c58c80603316786868479753C23", + "startBlock": 11021592 }, "nounsAuctionHouse": { - "address": "0x2e29f14602ca236D001e8C5855939464dCC7AcD9", - "startBlock": 11011622 + "address": "0xDF87852c37D1774100526F92C89608C395785C5d", + "startBlock": 11021592 }, "nounsDAO": { - "address": "0xe3A8B54A2b0ec636d6310aCcA1b002B80934f741", - "startBlock": 11011622 + "address": "0x8c6B7F6F091bb3Ffb086DBa4d1b465E0D896a05e", + "startBlock": 11021592 } } From b9316aa93efbcf19a04ec436088db299a2a9bb98 Mon Sep 17 00:00:00 2001 From: eladmallel Date: Thu, 14 Jul 2022 10:32:25 +0300 Subject: [PATCH 104/116] update proposal descriptions to look nicer --- .../nouns-contracts/tasks/populate-descriptor-via-proposal.ts | 2 +- .../nouns-contracts/tasks/upgrade-descriptor-via-proposal.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nouns-contracts/tasks/populate-descriptor-via-proposal.ts b/packages/nouns-contracts/tasks/populate-descriptor-via-proposal.ts index f7058c3b30..830a786347 100644 --- a/packages/nouns-contracts/tasks/populate-descriptor-via-proposal.ts +++ b/packages/nouns-contracts/tasks/populate-descriptor-via-proposal.ts @@ -117,7 +117,7 @@ task( values, signatures, calldatas, - 'Adding art to NounsDescriptorV2.', + '# Add 8/8 Nouniversary Art\nThis proposal adds the art the community designed and voted on to NounsToken.', ); await propTx.wait(); diff --git a/packages/nouns-contracts/tasks/upgrade-descriptor-via-proposal.ts b/packages/nouns-contracts/tasks/upgrade-descriptor-via-proposal.ts index 1cd86cbc64..86455f7710 100644 --- a/packages/nouns-contracts/tasks/upgrade-descriptor-via-proposal.ts +++ b/packages/nouns-contracts/tasks/upgrade-descriptor-via-proposal.ts @@ -16,7 +16,7 @@ task('upgrade-descriptor-via-proposal', 'Upgrade NounsToken to use Descriptor V2 values, signatures, calldatas, - `Setting NounToken's descriptor to NounsDescriptorV2.`, + `# Upgrade NounsToken descriptor to V2\nThis proposal calls a function on NounsToken to set its descriptor to V2.`, ); await propTx.wait(); From acea2fa401c1fb4053bbac972b137d04abe1180f Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Thu, 14 Jul 2022 11:30:08 +0200 Subject: [PATCH 105/116] reencode test file for new art and move to contracts directory --- packages/nouns-assets/src/new-image-data.json | 1628 ----------------- .../files/images-data-test-new-art.json | 1628 +++++++++++++++++ 2 files changed, 1628 insertions(+), 1628 deletions(-) delete mode 100644 packages/nouns-assets/src/new-image-data.json create mode 100644 packages/nouns-contracts/files/images-data-test-new-art.json diff --git a/packages/nouns-assets/src/new-image-data.json b/packages/nouns-assets/src/new-image-data.json deleted file mode 100644 index 3f6aa5aad4..0000000000 --- a/packages/nouns-assets/src/new-image-data.json +++ /dev/null @@ -1,1628 +0,0 @@ -{ - "images": { - "bodies": [ - { - "filename": "body-green-reversed", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_000", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_001", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_002", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_003", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_004", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_005", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_006", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_007", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_008", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_009", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_010", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_011", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_012", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_013", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_014", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_015", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_016", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_017", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_018", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_019", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_020", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_021", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_022", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_023", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_024", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_025", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_026", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_027", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_028", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_029", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_030", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_031", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_032", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_033", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_034", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_035", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_036", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_037", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_038", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_039", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_040", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_041", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_042", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_043", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_044", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_045", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_046", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_047", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_048", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_049", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_050", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_051", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_052", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_053", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_054", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_055", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_056", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_057", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_058", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_059", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_060", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_061", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_062", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_063", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_064", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_065", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_066", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_067", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_068", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_069", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_070", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_071", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_072", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_073", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_074", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_075", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_076", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_077", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_078", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_079", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_080", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_081", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_082", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_083", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_084", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_085", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_086", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_087", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_088", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_089", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_090", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_091", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_092", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_093", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_094", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_095", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_096", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_097", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_098", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - }, - { - "filename": "body-green-reversed_099", - "data": "0x0015171f09430f01000d0f01000d0f01000d0f01000d0f01000d0f01000d0f0100020f" - } - ], - "accessories": [ - { - "filename": "accessory-txt-dao-black-reversed", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_000", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_001", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_002", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_003", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_004", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_005", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_006", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_007", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_008", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_009", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_010", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_011", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_012", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_013", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_014", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_015", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_016", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_017", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_018", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_019", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_020", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_021", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_022", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_023", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_024", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_025", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_026", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_027", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_028", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_029", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_030", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_031", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_032", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_033", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_034", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_035", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_036", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_037", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_038", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_039", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_040", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_041", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_042", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_043", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_044", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_045", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_046", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_047", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_048", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_049", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_050", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_051", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_052", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_053", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_054", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_055", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_056", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_057", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_058", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_059", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_060", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_061", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_062", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_063", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_064", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_065", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_066", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_067", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_068", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_069", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_070", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_071", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_072", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_073", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_074", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_075", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_076", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_077", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_078", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_079", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_080", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_081", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_082", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_083", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_084", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_085", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_086", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_087", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_088", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_089", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_090", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_091", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_092", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_093", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_094", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_095", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_096", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_097", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_098", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - }, - { - "filename": "accessory-txt-dao-black-reversed_099", - "data": "0x0018141b0b010001230200012302000323010002230100022301000223010005230100012301000123010001230100012301000223" - } - ], - "heads": [ - { - "filename": "head-thumbsup-reversed", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_000", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_001", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_002", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_003", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_004", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_005", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_006", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_007", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_008", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_009", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_010", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_011", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_012", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_013", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_014", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_015", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_016", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_017", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_018", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_019", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_020", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_021", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_022", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_023", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_024", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_025", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_026", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_027", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_028", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_029", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_030", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_031", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_032", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_033", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_034", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_035", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_036", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_037", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_038", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_039", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_040", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_041", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_042", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_043", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_044", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_045", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_046", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_047", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_048", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_049", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_050", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_051", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_052", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_053", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_054", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_055", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_056", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_057", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_058", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_059", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_060", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_061", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_062", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_063", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_064", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_065", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_066", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_067", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_068", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_069", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_070", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_071", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_072", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_073", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_074", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_075", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_076", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_077", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_078", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_079", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_080", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_081", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_082", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_083", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_084", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_085", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_086", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_087", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_088", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_089", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_090", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_091", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_092", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_093", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_094", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_095", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_096", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_097", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_098", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - }, - { - "filename": "head-thumbsup-reversed_099", - "data": "0x00011b1406080002e5012b110002e5012b01e5110002e5012b01e5110003e5012b110005e5100006e5100006e5080007e5012b06e5060001e5012b07e5012b08e5030001e5012b07e5012b0be5012b06e5012b0de50100072b17e5012b0be5012b08e5012b0ae5012b09e5012b0ae50100082b0ce5010008e5012b02e5012b05e5022b01e5010001e5012b06e5042b08e50100012b07e5012b03e5012b04e50500072b08e50400" - } - ], - "glasses": [ - { - "filename": "glasses-hip-rose-reversed_reversed", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_000", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_001", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_002", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_003", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_004", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_005", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_006", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_007", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_008", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_009", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_010", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_011", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_012", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_013", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_014", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_015", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_016", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_017", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_018", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_019", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_020", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_021", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_022", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_023", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_024", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_025", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_026", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_027", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_028", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_029", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_030", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_031", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_032", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_033", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_034", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_035", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_036", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_037", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_038", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_039", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_040", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_041", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_042", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_043", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_044", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_045", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_046", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_047", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_048", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_049", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_050", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_051", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_052", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_053", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_054", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_055", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_056", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_057", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_058", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_059", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_060", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_061", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_062", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_063", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_064", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_065", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_066", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_067", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_068", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_069", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_070", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_071", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_072", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_073", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_074", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_075", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_076", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_077", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_078", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_079", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_080", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_081", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_082", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_083", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_084", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_085", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_086", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_087", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_088", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_089", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_090", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_091", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_092", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_093", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_094", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_095", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_096", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_097", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_098", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - }, - { - "filename": "glasses-hip-rose-reversed_reversed_099", - "data": "0x000b1910090620010006200300012002230202012001000120022302020120030001200223020203200223020205200223020203200223020205200223020201200100012002230202012002000720010006200300" - } - ] - } -} \ No newline at end of file diff --git a/packages/nouns-contracts/files/images-data-test-new-art.json b/packages/nouns-contracts/files/images-data-test-new-art.json new file mode 100644 index 0000000000..9ba2c26af7 --- /dev/null +++ b/packages/nouns-contracts/files/images-data-test-new-art.json @@ -0,0 +1,1628 @@ +{ + "images": { + "bodies": [ + { + "filename": "body-green-reversed", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_000", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_001", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_002", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_003", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_004", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_005", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_006", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_007", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_008", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_009", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_010", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_011", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_012", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_013", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_014", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_015", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_016", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_017", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_018", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_019", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_020", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_021", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_022", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_023", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_024", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_025", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_026", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_027", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_028", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_029", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_030", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_031", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_032", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_033", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_034", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_035", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_036", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_037", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_038", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_039", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_040", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_041", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_042", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_043", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_044", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_045", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_046", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_047", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_048", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_049", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_050", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_051", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_052", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_053", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_054", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_055", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_056", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_057", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_058", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_059", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_060", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_061", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_062", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_063", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_064", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_065", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_066", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_067", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_068", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_069", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_070", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_071", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_072", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_073", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_074", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_075", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_076", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_077", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_078", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_079", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_080", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_081", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_082", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_083", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_084", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_085", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_086", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_087", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_088", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_089", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_090", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_091", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_092", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_093", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_094", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_095", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_096", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_097", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_098", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + }, + { + "filename": "body-green-reversed_099", + "data": "0x0015171f09431001000d1001000d1001000d1001000d1001000d1001000d1001000210" + } + ], + "accessories": [ + { + "filename": "accessory-txt-dao-black-reversed", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_000", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_001", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_002", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_003", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_004", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_005", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_006", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_007", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_008", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_009", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_010", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_011", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_012", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_013", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_014", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_015", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_016", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_017", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_018", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_019", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_020", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_021", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_022", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_023", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_024", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_025", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_026", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_027", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_028", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_029", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_030", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_031", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_032", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_033", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_034", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_035", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_036", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_037", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_038", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_039", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_040", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_041", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_042", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_043", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_044", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_045", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_046", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_047", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_048", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_049", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_050", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_051", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_052", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_053", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_054", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_055", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_056", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_057", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_058", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_059", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_060", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_061", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_062", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_063", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_064", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_065", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_066", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_067", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_068", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_069", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_070", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_071", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_072", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_073", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_074", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_075", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_076", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_077", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_078", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_079", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_080", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_081", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_082", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_083", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_084", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_085", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_086", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_087", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_088", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_089", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_090", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_091", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_092", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_093", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_094", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_095", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_096", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_097", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_098", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + }, + { + "filename": "accessory-txt-dao-black-reversed_099", + "data": "0x0018141b0b010001240200012402000324010002240100022401000224010005240100012401000124010001240100012401000224" + } + ], + "heads": [ + { + "filename": "head-thumbsup-reversed", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_000", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_001", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_002", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_003", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_004", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_005", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_006", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_007", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_008", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_009", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_010", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_011", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_012", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_013", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_014", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_015", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_016", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_017", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_018", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_019", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_020", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_021", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_022", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_023", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_024", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_025", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_026", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_027", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_028", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_029", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_030", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_031", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_032", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_033", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_034", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_035", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_036", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_037", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_038", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_039", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_040", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_041", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_042", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_043", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_044", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_045", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_046", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_047", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_048", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_049", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_050", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_051", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_052", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_053", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_054", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_055", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_056", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_057", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_058", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_059", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_060", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_061", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_062", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_063", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_064", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_065", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_066", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_067", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_068", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_069", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_070", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_071", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_072", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_073", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_074", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_075", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_076", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_077", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_078", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_079", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_080", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_081", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_082", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_083", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_084", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_085", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_086", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_087", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_088", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_089", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_090", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_091", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_092", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_093", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_094", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_095", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_096", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_097", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_098", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + }, + { + "filename": "head-thumbsup-reversed_099", + "data": "0x00011b1406080002e6012c110002e6012c01e6110002e6012c01e6110003e6012c110005e6100006e6100006e6080007e6012c06e6060001e6012c07e6012c08e6030001e6012c07e6012c0be6012c06e6012c0de60100072c17e6012c0be6012c08e6012c0ae6012c09e6012c0ae60100082c0ce6010008e6012c02e6012c05e6022c01e6010001e6012c06e6042c08e60100012c07e6012c03e6012c04e60500072c08e60400" + } + ], + "glasses": [ + { + "filename": "glasses-hip-rose-reversed_reversed", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_000", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_001", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_002", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_003", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_004", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_005", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_006", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_007", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_008", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_009", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_010", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_011", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_012", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_013", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_014", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_015", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_016", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_017", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_018", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_019", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_020", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_021", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_022", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_023", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_024", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_025", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_026", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_027", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_028", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_029", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_030", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_031", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_032", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_033", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_034", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_035", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_036", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_037", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_038", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_039", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_040", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_041", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_042", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_043", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_044", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_045", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_046", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_047", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_048", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_049", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_050", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_051", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_052", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_053", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_054", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_055", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_056", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_057", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_058", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_059", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_060", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_061", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_062", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_063", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_064", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_065", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_066", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_067", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_068", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_069", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_070", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_071", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_072", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_073", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_074", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_075", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_076", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_077", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_078", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_079", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_080", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_081", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_082", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_083", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_084", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_085", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_086", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_087", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_088", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_089", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_090", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_091", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_092", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_093", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_094", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_095", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_096", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_097", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_098", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + }, + { + "filename": "glasses-hip-rose-reversed_reversed_099", + "data": "0x000b1910090621010006210300012102240202012101000121022402020121030001210224020203210224020205210224020203210224020205210224020201210100012102240202012102000721010006210300" + } + ] + } +} \ No newline at end of file From b3badda4194e3b6cb4d58a6e7d55596758a0ccfb Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Thu, 14 Jul 2022 11:55:05 +0200 Subject: [PATCH 106/116] add script to merge image-data.json files --- packages/nouns-assets/package.json | 1 + .../nouns-assets/scripts/append-image-data.ts | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 packages/nouns-assets/scripts/append-image-data.ts diff --git a/packages/nouns-assets/package.json b/packages/nouns-assets/package.json index 26eb64bb9a..7b36cd47b8 100644 --- a/packages/nouns-assets/package.json +++ b/packages/nouns-assets/package.json @@ -10,6 +10,7 @@ "scripts": { "encode": "ts-node scripts/encode.ts", "encode-more": "ts-node scripts/encode-more.ts", + "append-image-data": "ts-node scripts/append-image-data.ts", "clean": "rimraf dist tsconfig.build.tsbuildinfo", "build": "tsc -p tsconfig.build.json", "prepare": "yarn build", diff --git a/packages/nouns-assets/scripts/append-image-data.ts b/packages/nouns-assets/scripts/append-image-data.ts new file mode 100644 index 0000000000..d0bfc37c12 --- /dev/null +++ b/packages/nouns-assets/scripts/append-image-data.ts @@ -0,0 +1,21 @@ +import { ImageData } from '@nouns/sdk/src/image/types'; +import { promises as fs } from 'fs'; + +/** + * Appends an image-data.json file to an existing one. + * The purpose is for the webapp to have one file with all the art, not split to pages like in the contracts storage + */ +const merge = async (baseFile: string, newFile: string, destinationFile: string) => { + const baseData: ImageData = JSON.parse((await fs.readFile(baseFile)).toString()); + const newData: ImageData = JSON.parse((await fs.readFile(newFile)).toString()); + // console.log(newData); + + for (const [k, v] of Object.entries(newData.images)) { + baseData.images[k].push(...v); + } + + await fs.writeFile(destinationFile, JSON.stringify(baseData, null, 2)); + console.log(`Wrote merged file to: ${destinationFile}`); +}; + +merge(process.argv[2], process.argv[3], process.argv[4]); From d1ed9610081377fd96446c1a38f4f5938b4b09fe Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Mon, 18 Jul 2022 09:47:36 +0200 Subject: [PATCH 107/116] revert change before going back to master --- netlify.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netlify.toml b/netlify.toml index bdabc5132b..71254cd717 100644 --- a/netlify.toml +++ b/netlify.toml @@ -11,7 +11,7 @@ REACT_APP_ENABLE_HISTORY = "true" [context.deploy-preview.environment] - REACT_APP_CHAIN_ID = "4" + REACT_APP_CHAIN_ID = "1" REACT_APP_ENABLE_HISTORY = "true" [functions] From 1d146acb56200755679ff46ea20d0dab23507819 Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Mon, 18 Jul 2022 09:57:55 +0200 Subject: [PATCH 108/116] rename Image2 to Image and bump sdk package version --- packages/nouns-sdk/package.json | 2 +- packages/nouns-sdk/src/image/image.ts | 264 ++++++------------ packages/nouns-sdk/src/image/image2.ts | 139 --------- .../src/image/png-collection-encoder.ts | 4 +- .../test/{image2.test.ts => image.test.ts} | 10 +- packages/nouns-sdk/test/image.ts | 243 ++++++++++++++++ 6 files changed, 332 insertions(+), 330 deletions(-) delete mode 100644 packages/nouns-sdk/src/image/image2.ts rename packages/nouns-sdk/test/{image2.test.ts => image.test.ts} (94%) create mode 100644 packages/nouns-sdk/test/image.ts diff --git a/packages/nouns-sdk/package.json b/packages/nouns-sdk/package.json index 5b0128820b..0fd011dc53 100644 --- a/packages/nouns-sdk/package.json +++ b/packages/nouns-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@nouns/sdk", - "version": "0.1.6", + "version": "0.1.7", "description": "Useful tooling for interacting with the Nouns protocol", "author": "Nounders", "homepage": "https://nouns.wtf", diff --git a/packages/nouns-sdk/src/image/image.ts b/packages/nouns-sdk/src/image/image.ts index 5e01d1b4af..637ab5676d 100644 --- a/packages/nouns-sdk/src/image/image.ts +++ b/packages/nouns-sdk/src/image/image.ts @@ -1,79 +1,46 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ -import { ImageBounds, ImageRow, ImageRows, Rect, RGBAColor } from './types'; +import { ImageBounds, RGBAColor } from './types'; import { rgbToHex, toPaddedHex } from './utils'; /** * A class used to convert an image into the following RLE format: * Palette Index, Bounds [Top (Y), Right (X), Bottom (Y), Left (X)] (4 Bytes), [Pixel Length (1 Byte), Color Index (1 Byte)][]. + * + * As opposed to the first encoding version, this supports multiline run-length encoding */ export class Image { private _width: number; private _height: number; - private _rows: ImageRows = {}; private _bounds: ImageBounds = { top: 0, bottom: 0, left: 0, right: 0 }; - private _rle: string | undefined; + public tuples: number[][] = []; + private _getRgbaAt: (x: number, y: number) => RGBAColor; - /** - * The image's pixel width - */ - get width(): number { - return this._width; + constructor(width: number, height: number, getRgbaAt: (x: number, y: number) => RGBAColor) { + this._width = width; + this._height = height; + + this._getRgbaAt = getRgbaAt; } - /** - * The image's pixel height - */ get height(): number { return this._height; } - /** - * The number of rows to run-length encode - */ - get rows(): ImageRows { - return this._rows; + get width(): number { + return this._width; } - /** - * The bounds of the inner rect to run-length encode - */ get bounds(): ImageBounds { return this._bounds; } - constructor(width: number, height: number) { - this._width = width; - this._height = height; - } + public toRLE(colors: Map): string { + this._bounds = this.calcBounds(); - /** - * Convert an image to a run-length encoded string using the provided RGBA - * and color palette values. - * @param getRgbaAt A function used to fetch the RGBA values at specific x-y coordinates - * @param colors The color palette map - */ - public toRLE( - getRgbaAt: (x: number, y: number) => RGBAColor, - colors: Map, - ): string { - if (!this._rle) { - this._rle = this.encode(getRgbaAt, colors); - } - return this._rle; - } + const indexes: number[] = []; - /** - * Using the image pixel inforation, run-length encode an image. - * @param getRgbaAt A function used to fetch the RGBA values at specific x-y coordinates - * @param colors The color palette map - */ - private encode( - getRgbaAt: (x: number, y: number) => RGBAColor, - colors: Map, - ): string { - for (let y = 0; y < this._height; y++) { - for (let x = 0; x < this._width; x++) { - const { r, g, b, a } = getRgbaAt(x, y); + for (let y = this.bounds.top; y <= this.bounds.bottom; y++) { + for (let x = this.bounds.left; x < this.bounds.right; x++) { + const { r, g, b, a } = this._getRgbaAt(x, y); const hexColor = rgbToHex(r, g, b); // Insert the color if it does not yet exist @@ -82,160 +49,91 @@ export class Image { } // If alpha is 0, use 'transparent' index, otherwise get color index - const colorIndex = a === 0 ? 0 : colors.get(hexColor)!; - - this.appendPixelToRect(colorIndex, y); + indexes.push(a === 0 ? 0 : colors.get(hexColor)!); } - this.updateImageBounds(y); } - this.deleteEmptyRows(); - - // Set the left and right bounds. Return early if empty - const rowCount = Object.keys(this._rows).length; - if (rowCount) { - this._bounds.left = Math.min(...Object.values(this._rows).map(r => r.bounds.left)); - this._bounds.right = Math.max(...Object.values(this._rows).map(r => r.bounds.right)); - - // Exit early if image is empty - const [rect] = this._rows[0]?.rects || []; - if (rowCount === 1 && this.isEmptyRow(rect)) { - return '0x0000000000'; - } - } - - const encodedBounds = this.getEncodedBounds(this._bounds); - const encodedImage = Object.values(this._rows).reduce((result, row) => { - result += this.getEncodedRow(row, this._bounds); - return result; - }, encodedBounds); - - return encodedImage; + // [palette_index, top, right, bottom, left] + const metadata = [ + 0, + this.bounds.top, + this.bounds.right, + this.bounds.bottom, + this.bounds.left, + ].map(v => toPaddedHex(v)); + return `0x${metadata.join('')}${this.encode(indexes)}`; } /** - * Append a single pixel to a new or existing rect - * @param colorIndex The color array index - * @param y The current `y` coordinate + * Given a numeric array, return a string of padded hex run-length encoded values + * @param data The numeric array to run-length encode */ - private appendPixelToRect(colorIndex: number, y: number): void { - // Create the row if it does not exist yet - const { rects } = (this._rows[y] ||= { - rects: [], - bounds: { left: 0, right: 0 }, - }); - - // First pixel of line or different color than previous - if (!rects.length || rects[rects.length - 1].colorIndex !== colorIndex) { - rects.push({ length: 1, colorIndex }); - return; + private encode(data: number[]) { + const encoding: string[] = []; + let previous = data[0]; + let count = 1; + + for (let i = 1; i < data.length; i++) { + if (data[i] !== previous || count === 255) { + encoding.push(toPaddedHex(count), toPaddedHex(previous)); + this.tuples.push([count, previous]); + count = 1; + previous = data[i]; + } else { + count++; + } } - // Same color as the pixel to the left - rects[rects.length - 1].length++; + if (previous !== undefined) { + encoding.push(toPaddedHex(count), toPaddedHex(previous)); + } + return encoding.join(''); } - /** - * Update the bounds of the provided image - * @param y The current `y` coordinate - */ - private updateImageBounds(y: number): void { - const { rects } = this._rows[y]; - - // Shift top bound to `y` if row is not empty and top bound is 0 - if (!this.isEmptyRow(rects[0]) && this._bounds.top === 0) { - this._bounds.top = y; + calcBounds(): ImageBounds { + let bottom = this.height - 1; + while (bottom > 0 && this._isTransparentRow(bottom)) { + bottom--; } - if (this._bounds.top !== 0) { - // Set bottom bound to `y` if row is empty or we're on the last row. - // Otherwise, reset the bottom bound - if (this.isEmptyRow(rects[0])) { - if (this._bounds.bottom === 0) { - this._bounds.bottom = y - 1; - } - } else if (y === 31) { - this._bounds.bottom = y; - } else { - this._bounds.bottom = 0; - } + let top = 0; + while (top < bottom && this._isTransparentRow(top)) { + top++; } - this._rows[y].bounds = { - left: rects[0].length, - right: this._width - rects[rects.length - 1].length, - }; - } - - /** - * Delete all empty rows. That is, all rows above the top bound or - * below the lower bound - */ - private deleteEmptyRows(): void { - // Delete all rows above the top bound - for (let i = 0; i < this._bounds.top; i++) { - delete this._rows[i]; + let right = this.width - 1; + while (right >= 0 && this._isTransparentColumn(right)) { + right--; } - // Delete all rows below the bottom bound - for (let i = this._height - 1; i > this._bounds.bottom; i--) { - delete this._rows[i]; + let left = 0; + while (left < right && this._isTransparentColumn(left)) { + left++; } - } - /** - * Get the encoded part bounds string - * @param bounds The part bounds - */ - private getEncodedBounds(bounds: ImageBounds) { - const top = toPaddedHex(bounds.top, 2); - const right = toPaddedHex(bounds.right, 2); - const bottom = toPaddedHex(bounds.bottom, 2); - const left = toPaddedHex(bounds.left, 2); - return `0x00${top}${right}${bottom}${left}`; + return { + top: top, + bottom: bottom, + left: left, + right: right + 1, // right bound is calculated to be one pixel outside the content + }; } - /** - * Get a single row encoded as a hex string - * @param row The row data - * @param bounds The image bounds - */ - private getEncodedRow(row: ImageRow, bounds: ImageBounds) { - const rowBuffer = Buffer.from( - row.rects.flatMap(({ length, colorIndex }, i) => { - // Row only contains a single rect - if (i === 0 && i === row.rects.length - 1) { - return [bounds.right - bounds.left, colorIndex]; - } - - // Set left bound - if (i === 0) { - if (length > bounds.left) { - return [length - bounds.left, colorIndex]; - } else if (length === bounds.left) { - return []; - } - } - - // Set right bound - if (i === row.rects.length - 1) { - if (length > this._width - bounds.right) { - return [length - (this._width - bounds.right), colorIndex]; - } else if (length === this._width - bounds.right) { - return []; - } - } - return [length, colorIndex]; - }), - ); - return rowBuffer.toString('hex'); + private _isTransparentColumn(column: number) { + for (let row = 0; row < this.height; row++) { + if (this._getRgbaAt(column, row).a !== 0) { + return false; + } + } + return true; } - /** - * Determine if the provided rect fills the entire row and is transparent - * @param rect The rect to inspect - */ - private isEmptyRow(rect: Rect) { - return rect?.length === this._width && rect?.colorIndex === 0; + private _isTransparentRow(row: number) { + for (let column = 0; column < this.width; column++) { + if (this._getRgbaAt(column, row).a !== 0) { + return false; + } + } + return true; } } diff --git a/packages/nouns-sdk/src/image/image2.ts b/packages/nouns-sdk/src/image/image2.ts deleted file mode 100644 index 684cb16732..0000000000 --- a/packages/nouns-sdk/src/image/image2.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { ImageBounds, RGBAColor } from './types'; -import { rgbToHex, toPaddedHex } from './utils'; - -/** - * A class used to convert an image into the following RLE format: - * Palette Index, Bounds [Top (Y), Right (X), Bottom (Y), Left (X)] (4 Bytes), [Pixel Length (1 Byte), Color Index (1 Byte)][]. - * - * As opposed to the first encoding version, this supports multiline run-length encoding - */ -export class Image2 { - private _width: number; - private _height: number; - private _bounds: ImageBounds = { top: 0, bottom: 0, left: 0, right: 0 }; - public tuples: number[][] = []; - private _getRgbaAt: (x: number, y: number) => RGBAColor; - - constructor(width: number, height: number, getRgbaAt: (x: number, y: number) => RGBAColor) { - this._width = width; - this._height = height; - - this._getRgbaAt = getRgbaAt; - } - - get height(): number { - return this._height; - } - - get width(): number { - return this._width; - } - - get bounds(): ImageBounds { - return this._bounds; - } - - public toRLE(colors: Map): string { - this._bounds = this.calcBounds(); - - const indexes: number[] = []; - - for (let y = this.bounds.top; y <= this.bounds.bottom; y++) { - for (let x = this.bounds.left; x < this.bounds.right; x++) { - const { r, g, b, a } = this._getRgbaAt(x, y); - const hexColor = rgbToHex(r, g, b); - - // Insert the color if it does not yet exist - if (!colors.has(hexColor)) { - colors.set(hexColor, colors.size); - } - - // If alpha is 0, use 'transparent' index, otherwise get color index - indexes.push(a === 0 ? 0 : colors.get(hexColor)!); - } - } - - // [palette_index, top, right, bottom, left] - const metadata = [ - 0, - this.bounds.top, - this.bounds.right, - this.bounds.bottom, - this.bounds.left, - ].map(v => toPaddedHex(v)); - return `0x${metadata.join('')}${this.encode(indexes)}`; - } - - /** - * Given a numeric array, return a string of padded hex run-length encoded values - * @param data The numeric array to run-length encode - */ - private encode(data: number[]) { - const encoding: string[] = []; - let previous = data[0]; - let count = 1; - - for (let i = 1; i < data.length; i++) { - if (data[i] !== previous || count === 255) { - encoding.push(toPaddedHex(count), toPaddedHex(previous)); - this.tuples.push([count, previous]); - count = 1; - previous = data[i]; - } else { - count++; - } - } - - if (previous !== undefined) { - encoding.push(toPaddedHex(count), toPaddedHex(previous)); - } - return encoding.join(''); - } - - calcBounds(): ImageBounds { - let bottom = this.height - 1; - while (bottom > 0 && this._isTransparentRow(bottom)) { - bottom--; - } - - let top = 0; - while (top < bottom && this._isTransparentRow(top)) { - top++; - } - - let right = this.width - 1; - while (right >= 0 && this._isTransparentColumn(right)) { - right--; - } - - let left = 0; - while (left < right && this._isTransparentColumn(left)) { - left++; - } - - return { - top: top, - bottom: bottom, - left: left, - right: right + 1, // right bound is calculated to be one pixel outside the content - }; - } - - private _isTransparentColumn(column: number) { - for (let row = 0; row < this.height; row++) { - if (this._getRgbaAt(column, row).a !== 0) { - return false; - } - } - return true; - } - - private _isTransparentRow(row: number) { - for (let column = 0; column < this.width; column++) { - if (this._getRgbaAt(column, row).a !== 0) { - return false; - } - } - return true; - } -} diff --git a/packages/nouns-sdk/src/image/png-collection-encoder.ts b/packages/nouns-sdk/src/image/png-collection-encoder.ts index cead6174a3..4d84a4bd78 100644 --- a/packages/nouns-sdk/src/image/png-collection-encoder.ts +++ b/packages/nouns-sdk/src/image/png-collection-encoder.ts @@ -1,6 +1,6 @@ import { promises as fs } from 'fs'; import { EncodedImage, IEncoder, ImageData, PngImage } from './types'; -import { Image2 } from './image2'; +import { Image } from './image'; /** * A class used to convert PNG images into the following RLE format: @@ -38,7 +38,7 @@ export class PNGCollectionEncoder implements IEncoder { * @param folder An optional containing folder name */ public encodeImage(name: string, png: PngImage, folder?: string): string { - const image = new Image2(png.width, png.height, png.rgbaAt); + const image = new Image(png.width, png.height, png.rgbaAt); const rle = image.toRLE(this._colors); this._images.set(name, rle); diff --git a/packages/nouns-sdk/test/image2.test.ts b/packages/nouns-sdk/test/image.test.ts similarity index 94% rename from packages/nouns-sdk/test/image2.test.ts rename to packages/nouns-sdk/test/image.test.ts index 9814a9c9bd..47ab3c4ec6 100644 --- a/packages/nouns-sdk/test/image2.test.ts +++ b/packages/nouns-sdk/test/image.test.ts @@ -1,7 +1,7 @@ import { expect } from 'chai'; import { join } from 'path'; -import { Image2 } from '../src/image/image2'; import { Image } from '../src/image/image'; +import { Image as Image1 } from './image'; import { readPngImage } from './lib'; import { buildSVG, RGBAColor } from '../src'; import { glob } from 'glob'; @@ -11,7 +11,7 @@ async function encodeSingleLineRLE(filepath: string) { const transparent: [string, number] = ['', 0]; const colors: Map = new Map([transparent]); const pngImage = await readPngImage(filepath); - const image = new Image(pngImage.width, pngImage.height); + const image = new Image1(pngImage.width, pngImage.height); const rle = image.toRLE(pngImage.rgbaAt, colors); return { rle, colors }; } @@ -20,12 +20,12 @@ async function encodeMultiLineRLE(filepath: string) { const transparent: [string, number] = ['', 0]; const colors: Map = new Map([transparent]); const pngImage = await readPngImage(filepath); - const image = new Image2(pngImage.width, pngImage.height, pngImage.rgbaAt); + const image = new Image(pngImage.width, pngImage.height, pngImage.rgbaAt); const rle = image.toRLE(colors); return { rle, colors }; } -describe('Image2', () => { +describe('Image', () => { describe('Comparing single line RLE to multiline RLE encoding', async () => { it('builds the same svg with both encoders', async () => { const filepath = join(__dirname, `./lib/images/head-cone.png`); @@ -77,7 +77,7 @@ describe('Image2', () => { }); const encodePixels = (pixels: RGBAColor[][], colors: Map) => { - const rle = new Image2(pixels[0].length, pixels.length, (x, y) => pixels[y][x]).toRLE(colors); + const rle = new Image(pixels[0].length, pixels.length, (x, y) => pixels[y][x]).toRLE(colors); const decoded = decodeImage(rle); const colorsArray = Array.from(colors.keys()); return { decoded, colorsArray }; diff --git a/packages/nouns-sdk/test/image.ts b/packages/nouns-sdk/test/image.ts new file mode 100644 index 0000000000..e3a2960feb --- /dev/null +++ b/packages/nouns-sdk/test/image.ts @@ -0,0 +1,243 @@ +// /* eslint-disable @typescript-eslint/no-non-null-assertion */ +import { ImageBounds, ImageRow, ImageRows, Rect, RGBAColor } from '../src/image/types'; +import { rgbToHex, toPaddedHex } from '../src/image/utils'; + +/** + * A class used to convert an image into the following RLE format: + * Palette Index, Bounds [Top (Y), Right (X), Bottom (Y), Left (X)] (4 Bytes), [Pixel Length (1 Byte), Color Index (1 Byte)][]. + * + * This is no longer in active use, here just for testing purposes + */ +export class Image { + private _width: number; + private _height: number; + private _rows: ImageRows = {}; + private _bounds: ImageBounds = { top: 0, bottom: 0, left: 0, right: 0 }; + private _rle: string | undefined; + + /** + * The image's pixel width + */ + get width(): number { + return this._width; + } + + /** + * The image's pixel height + */ + get height(): number { + return this._height; + } + + /** + * The number of rows to run-length encode + */ + get rows(): ImageRows { + return this._rows; + } + + /** + * The bounds of the inner rect to run-length encode + */ + get bounds(): ImageBounds { + return this._bounds; + } + + constructor(width: number, height: number) { + this._width = width; + this._height = height; + } + + /** + * Convert an image to a run-length encoded string using the provided RGBA + * and color palette values. + * @param getRgbaAt A function used to fetch the RGBA values at specific x-y coordinates + * @param colors The color palette map + */ + public toRLE( + getRgbaAt: (x: number, y: number) => RGBAColor, + colors: Map, + ): string { + if (!this._rle) { + this._rle = this.encode(getRgbaAt, colors); + } + return this._rle; + } + + /** + * Using the image pixel inforation, run-length encode an image. + * @param getRgbaAt A function used to fetch the RGBA values at specific x-y coordinates + * @param colors The color palette map + */ + private encode( + getRgbaAt: (x: number, y: number) => RGBAColor, + colors: Map, + ): string { + for (let y = 0; y < this._height; y++) { + for (let x = 0; x < this._width; x++) { + const { r, g, b, a } = getRgbaAt(x, y); + const hexColor = rgbToHex(r, g, b); + + // Insert the color if it does not yet exist + if (!colors.has(hexColor)) { + colors.set(hexColor, colors.size); + } + + // If alpha is 0, use 'transparent' index, otherwise get color index + const colorIndex = a === 0 ? 0 : colors.get(hexColor)!; + + this.appendPixelToRect(colorIndex, y); + } + this.updateImageBounds(y); + } + + this.deleteEmptyRows(); + + // Set the left and right bounds. Return early if empty + const rowCount = Object.keys(this._rows).length; + if (rowCount) { + this._bounds.left = Math.min(...Object.values(this._rows).map(r => r.bounds.left)); + this._bounds.right = Math.max(...Object.values(this._rows).map(r => r.bounds.right)); + + // Exit early if image is empty + const [rect] = this._rows[0]?.rects || []; + if (rowCount === 1 && this.isEmptyRow(rect)) { + return '0x0000000000'; + } + } + + const encodedBounds = this.getEncodedBounds(this._bounds); + const encodedImage = Object.values(this._rows).reduce((result, row) => { + result += this.getEncodedRow(row, this._bounds); + return result; + }, encodedBounds); + + return encodedImage; + } + + /** + * Append a single pixel to a new or existing rect + * @param colorIndex The color array index + * @param y The current `y` coordinate + */ + private appendPixelToRect(colorIndex: number, y: number): void { + // Create the row if it does not exist yet + const { rects } = (this._rows[y] ||= { + rects: [], + bounds: { left: 0, right: 0 }, + }); + + // First pixel of line or different color than previous + if (!rects.length || rects[rects.length - 1].colorIndex !== colorIndex) { + rects.push({ length: 1, colorIndex }); + return; + } + + // Same color as the pixel to the left + rects[rects.length - 1].length++; + } + + /** + * Update the bounds of the provided image + * @param y The current `y` coordinate + */ + private updateImageBounds(y: number): void { + const { rects } = this._rows[y]; + + // Shift top bound to `y` if row is not empty and top bound is 0 + if (!this.isEmptyRow(rects[0]) && this._bounds.top === 0) { + this._bounds.top = y; + } + + if (this._bounds.top !== 0) { + // Set bottom bound to `y` if row is empty or we're on the last row. + // Otherwise, reset the bottom bound + if (this.isEmptyRow(rects[0])) { + if (this._bounds.bottom === 0) { + this._bounds.bottom = y - 1; + } + } else if (y === 31) { + this._bounds.bottom = y; + } else { + this._bounds.bottom = 0; + } + } + + this._rows[y].bounds = { + left: rects[0].length, + right: this._width - rects[rects.length - 1].length, + }; + } + + /** + * Delete all empty rows. That is, all rows above the top bound or + * below the lower bound + */ + private deleteEmptyRows(): void { + // Delete all rows above the top bound + for (let i = 0; i < this._bounds.top; i++) { + delete this._rows[i]; + } + + // Delete all rows below the bottom bound + for (let i = this._height - 1; i > this._bounds.bottom; i--) { + delete this._rows[i]; + } + } + + /** + * Get the encoded part bounds string + * @param bounds The part bounds + */ + private getEncodedBounds(bounds: ImageBounds) { + const top = toPaddedHex(bounds.top, 2); + const right = toPaddedHex(bounds.right, 2); + const bottom = toPaddedHex(bounds.bottom, 2); + const left = toPaddedHex(bounds.left, 2); + return `0x00${top}${right}${bottom}${left}`; + } + + /** + * Get a single row encoded as a hex string + * @param row The row data + * @param bounds The image bounds + */ + private getEncodedRow(row: ImageRow, bounds: ImageBounds) { + const rowBuffer = Buffer.from( + row.rects.flatMap(({ length, colorIndex }, i) => { + // Row only contains a single rect + if (i === 0 && i === row.rects.length - 1) { + return [bounds.right - bounds.left, colorIndex]; + } + + // Set left bound + if (i === 0) { + if (length > bounds.left) { + return [length - bounds.left, colorIndex]; + } else if (length === bounds.left) { + return []; + } + } + + // Set right bound + if (i === row.rects.length - 1) { + if (length > this._width - bounds.right) { + return [length - (this._width - bounds.right), colorIndex]; + } else if (length === this._width - bounds.right) { + return []; + } + } + return [length, colorIndex]; + }), + ); + return rowBuffer.toString('hex'); + } + + /** + * Determine if the provided rect fills the entire row and is transparent + * @param rect The rect to inspect + */ + private isEmptyRow(rect: Rect) { + return rect?.length === this._width && rect?.colorIndex === 0; + } +} From 8a86406719ccbb99d22981ce56bdac19d60d0b7e Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Mon, 18 Jul 2022 17:41:40 +0200 Subject: [PATCH 109/116] bump sdk package to 0.2.0 --- packages/nouns-sdk/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nouns-sdk/package.json b/packages/nouns-sdk/package.json index 0fd011dc53..2ab4c42ea5 100644 --- a/packages/nouns-sdk/package.json +++ b/packages/nouns-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@nouns/sdk", - "version": "0.1.7", + "version": "0.2.0", "description": "Useful tooling for interacting with the Nouns protocol", "author": "Nounders", "homepage": "https://nouns.wtf", From 08faadaa5e5f23f04221d6a9486dcdd3260348dd Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Mon, 18 Jul 2022 17:49:40 +0200 Subject: [PATCH 110/116] update rinkeby subgraph url to point to new contracts --- packages/nouns-webapp/src/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nouns-webapp/src/config.ts b/packages/nouns-webapp/src/config.ts index dcec410033..867c271bd6 100644 --- a/packages/nouns-webapp/src/config.ts +++ b/packages/nouns-webapp/src/config.ts @@ -59,7 +59,7 @@ const app: Record = { [ChainId.Rinkeby]: { jsonRpcUri: createNetworkHttpUrl('rinkeby'), wsRpcUri: createNetworkWsUrl('rinkeby'), - subgraphApiUri: 'https://api.thegraph.com/subgraphs/name/verbsteam/nouns-rinkeby', + subgraphApiUri: 'https://api.thegraph.com/subgraphs/name/nounsdao/nouns-subgraph-rinkeby-v5', enableHistory: process.env.REACT_APP_ENABLE_HISTORY === 'true', }, [ChainId.Mainnet]: { From 1aacd6f7b3f1b7edb59ac264d07fe2457a9bdca8 Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Mon, 18 Jul 2022 18:00:44 +0200 Subject: [PATCH 111/116] update webapp to use sdk version 0.2.0 with multiline rle --- packages/nouns-webapp/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nouns-webapp/package.json b/packages/nouns-webapp/package.json index dacfe726c2..f63fb54595 100644 --- a/packages/nouns-webapp/package.json +++ b/packages/nouns-webapp/package.json @@ -18,7 +18,7 @@ "@fortawesome/react-fontawesome": "0.1.14", "@netlify/functions": "^0.7.2", "@nouns/assets": "^0.2.0", - "@nouns/sdk": "^0.1.4", + "@nouns/sdk": "^0.2.0", "@reduxjs/toolkit": "^1.6.0", "@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.1.0", From 8d657b95ca0b88594299c06ce8144de210e042d5 Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Mon, 18 Jul 2022 18:01:12 +0200 Subject: [PATCH 112/116] bump assets package to 0.3.0 using sdk version 0.2.0 with multiline rle encoding --- packages/nouns-assets/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nouns-assets/package.json b/packages/nouns-assets/package.json index 7b36cd47b8..6c4fa6948c 100644 --- a/packages/nouns-assets/package.json +++ b/packages/nouns-assets/package.json @@ -1,6 +1,6 @@ { "name": "@nouns/assets", - "version": "0.2.0", + "version": "0.3.0", "description": "Nouns run-length encoded image data", "author": "Nounders", "homepage": "https://nouns.wtf", @@ -17,7 +17,7 @@ "test": "mocha -r ts-node/register \"test/**/*.test.ts\"" }, "devDependencies": { - "@nouns/sdk": "^0.1.4", + "@nouns/sdk": "^0.2.0", "@types/pngjs": "^6.0.1", "chai": "^4.2.0", "mocha": "^8.4.0", From f0c5bb1813daf0f07712361df798120ab0c8050b Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Mon, 18 Jul 2022 18:22:22 +0200 Subject: [PATCH 113/116] update webapp to use assets package v0.3.0 --- packages/nouns-webapp/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nouns-webapp/package.json b/packages/nouns-webapp/package.json index f63fb54595..74481b5c07 100644 --- a/packages/nouns-webapp/package.json +++ b/packages/nouns-webapp/package.json @@ -17,7 +17,7 @@ "@fortawesome/free-solid-svg-icons": "5.15.3", "@fortawesome/react-fontawesome": "0.1.14", "@netlify/functions": "^0.7.2", - "@nouns/assets": "^0.2.0", + "@nouns/assets": "^0.3.0", "@nouns/sdk": "^0.2.0", "@reduxjs/toolkit": "^1.6.0", "@testing-library/jest-dom": "^5.11.4", From 2f7176ce32a6e7829ba1474240d784c5a8223337 Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Mon, 18 Jul 2022 18:42:32 +0200 Subject: [PATCH 114/116] cleanups --- packages/nouns-assets/scripts/append-image-data.ts | 1 - packages/nouns-assets/scripts/encode-more.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/nouns-assets/scripts/append-image-data.ts b/packages/nouns-assets/scripts/append-image-data.ts index d0bfc37c12..aba51c2901 100644 --- a/packages/nouns-assets/scripts/append-image-data.ts +++ b/packages/nouns-assets/scripts/append-image-data.ts @@ -8,7 +8,6 @@ import { promises as fs } from 'fs'; const merge = async (baseFile: string, newFile: string, destinationFile: string) => { const baseData: ImageData = JSON.parse((await fs.readFile(baseFile)).toString()); const newData: ImageData = JSON.parse((await fs.readFile(newFile)).toString()); - // console.log(newData); for (const [k, v] of Object.entries(newData.images)) { baseData.images[k].push(...v); diff --git a/packages/nouns-assets/scripts/encode-more.ts b/packages/nouns-assets/scripts/encode-more.ts index 8556506b64..2e0dd52106 100644 --- a/packages/nouns-assets/scripts/encode-more.ts +++ b/packages/nouns-assets/scripts/encode-more.ts @@ -8,7 +8,7 @@ import { palette } from '../src/image-data.json'; * @notice creates an additional art json file. it assumes it's not the first one. * it also assumes the existing palette from the first one has all the needed colors. * @sourceFolder a folder containing subfolders with the names: ['1-bodies', '2-accessories', '3-heads', '4-glasses'] - * @destinationFilepath wher to save the new json file + * @destinationFilepath where to save the new json file */ const encode = async (sourceFolder: string, destinationFilepath: string) => { const encoder = new PNGCollectionEncoder(palette); From b90bc130925e4916e7f2660eb46c75c321959241 Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Mon, 18 Jul 2022 19:22:37 +0200 Subject: [PATCH 115/116] cleanup --- packages/nouns-contracts/tasks/deploy-descriptor-v2.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/nouns-contracts/tasks/deploy-descriptor-v2.ts b/packages/nouns-contracts/tasks/deploy-descriptor-v2.ts index 6bc8bc3340..953cd5d7c1 100644 --- a/packages/nouns-contracts/tasks/deploy-descriptor-v2.ts +++ b/packages/nouns-contracts/tasks/deploy-descriptor-v2.ts @@ -75,7 +75,6 @@ task('deploy-descriptor-v2', 'Deploy NounsDescriptorV2 & populate it with art') const art = await ( await ethers.getContractFactory('NounsArt', deployer) ).deploy(nounsDescriptor.address, inflator.address); - console.log(`actual art address: ${art.address}`); contracts.NounsArt = { name: 'NounsArt', address: art.address, From 4fd4937e6109a75bab83e4215d35ce4db8334e2b Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Tue, 19 Jul 2022 10:04:36 +0200 Subject: [PATCH 116/116] remove default values from deploy-and-configure not specifying default values falls back on the default values in the deploy task --- packages/nouns-contracts/tasks/deploy-and-configure.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/nouns-contracts/tasks/deploy-and-configure.ts b/packages/nouns-contracts/tasks/deploy-and-configure.ts index 8b889dfe64..a2b7f56d5f 100644 --- a/packages/nouns-contracts/tasks/deploy-and-configure.ts +++ b/packages/nouns-contracts/tasks/deploy-and-configure.ts @@ -18,10 +18,10 @@ task('deploy-and-configure', 'Deploy and configure all contracts') 'auctionMinIncrementBidPercentage', 'The auction min increment bid percentage (out of 100)', ) - .addOptionalParam('auctionDuration', 'The auction duration (seconds)', 600, types.int) + .addOptionalParam('auctionDuration', 'The auction duration (seconds)') .addOptionalParam('timelockDelay', 'The timelock delay (seconds)') - .addOptionalParam('votingPeriod', 'The voting period (blocks)', 5760, types.int) - .addOptionalParam('votingDelay', 'The voting delay (blocks)', 1, types.int) + .addOptionalParam('votingPeriod', 'The voting period (blocks)') + .addOptionalParam('votingDelay', 'The voting delay (blocks)') .addOptionalParam('proposalThresholdBps', 'The proposal threshold (basis points)') .addOptionalParam('quorumVotesBps', 'Votes required for quorum (basis points)') .setAction(async (args, { run }) => {