diff --git a/.openzeppelin/polygon-mumbai.json b/.openzeppelin/polygon-mumbai.json
index 443b79e..34d9a44 100644
--- a/.openzeppelin/polygon-mumbai.json
+++ b/.openzeppelin/polygon-mumbai.json
@@ -14,6 +14,16 @@
"address": "0x21d7fBe220958A0F0f7cAE58780fe812EbcB3cd8",
"txHash": "0x6a5a4b2cc5f6595438f4f0304be8b7ac55e8cfefdea857738f4451de48a82066",
"kind": "transparent"
+ },
+ {
+ "address": "0x72b255A13ac5758971Ba365913e432eEd341656D",
+ "txHash": "0x4cddb95c1cc4fb0ab292ad3c26b3053e3b57efb2fcfc681de7487f907a901e19",
+ "kind": "transparent"
+ },
+ {
+ "address": "0x8679f8A4Fb3AaA1E851100D2C0444a729a3D946C",
+ "txHash": "0x41955ba2435182dec361dc060e7f468c52d364da4bb256c980e803ef15a4d0c6",
+ "kind": "transparent"
}
],
"impls": {
@@ -1591,6 +1601,4510 @@
}
}
}
+ },
+ "0ee35be15afd41ab037040716fa18614055b384a3f5d9c8d5c2d48d51a550565": {
+ "address": "0x21aDC5Ff311Ef6350C92aFc40942fcE2b26dF139",
+ "txHash": "0xc6f95369ef95438d0df251a1cf29dc62f7ae614882f8c1af6a0bd8357364dbae",
+ "layout": {
+ "solcVersion": "0.8.7",
+ "storage": [
+ {
+ "label": "_initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint8",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62",
+ "retypedFrom": "bool"
+ },
+ {
+ "label": "_initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ContextUpgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ERC165Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol:41"
+ },
+ {
+ "label": "_name",
+ "offset": 0,
+ "slot": "101",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:25"
+ },
+ {
+ "label": "_symbol",
+ "offset": 0,
+ "slot": "102",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:28"
+ },
+ {
+ "label": "_owners",
+ "offset": 0,
+ "slot": "103",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:31"
+ },
+ {
+ "label": "_balances",
+ "offset": 0,
+ "slot": "104",
+ "type": "t_mapping(t_address,t_uint256)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:34"
+ },
+ {
+ "label": "_tokenApprovals",
+ "offset": 0,
+ "slot": "105",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:37"
+ },
+ {
+ "label": "_operatorApprovals",
+ "offset": 0,
+ "slot": "106",
+ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:40"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "107",
+ "type": "t_array(t_uint256)44_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:514"
+ },
+ {
+ "label": "_collectionRolesVersion",
+ "offset": 0,
+ "slot": "151",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:26"
+ },
+ {
+ "label": "_collectionRoles",
+ "offset": 0,
+ "slot": "152",
+ "type": "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:28"
+ },
+ {
+ "label": "_tokenRolesVersion",
+ "offset": 0,
+ "slot": "153",
+ "type": "t_mapping(t_uint256,t_struct(Counter)2774_storage)",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:30"
+ },
+ {
+ "label": "_tokenRoles",
+ "offset": 0,
+ "slot": "154",
+ "type": "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:32"
+ },
+ {
+ "label": "_tokenIds",
+ "offset": 0,
+ "slot": "155",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:45"
+ },
+ {
+ "label": "_apps",
+ "offset": 0,
+ "slot": "156",
+ "type": "t_mapping(t_uint256,t_struct(App)4607_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:46"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)44_storage": {
+ "label": "uint256[44]",
+ "numberOfBytes": "1408"
+ },
+ "t_array(t_uint256)50_storage": {
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_enum(Roles)3895": {
+ "label": "enum FleekAccessControl.Roles",
+ "members": ["Owner", "Controller"],
+ "numberOfBytes": "1"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_mapping(t_address,t_bool))": {
+ "label": "mapping(address => mapping(address => bool))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)": {
+ "label": "mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_address)": {
+ "label": "mapping(uint256 => address)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))": {
+ "label": "mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))": {
+ "label": "mapping(uint256 => mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(App)4607_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.App)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Build)4612_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.Build)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Counter)2774_storage)": {
+ "label": "mapping(uint256 => struct Counters.Counter)",
+ "numberOfBytes": "32"
+ },
+ "t_string_storage": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(App)4607_storage": {
+ "label": "struct FleekERC721.App",
+ "members": [
+ {
+ "label": "name",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "description",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "externalURL",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "ENS",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "currentBuild",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "4"
+ },
+ {
+ "label": "builds",
+ "type": "t_mapping(t_uint256,t_struct(Build)4612_storage)",
+ "offset": 0,
+ "slot": "5"
+ }
+ ],
+ "numberOfBytes": "192"
+ },
+ "t_struct(Build)4612_storage": {
+ "label": "struct FleekERC721.Build",
+ "members": [
+ {
+ "label": "commitHash",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "gitRepository",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_struct(Counter)2774_storage": {
+ "label": "struct Counters.Counter",
+ "members": [
+ {
+ "label": "_value",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_struct(Role)3943_storage": {
+ "label": "struct FleekAccessControl.Role",
+ "members": [
+ {
+ "label": "indexes",
+ "type": "t_mapping(t_address,t_uint256)",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "members",
+ "type": "t_array(t_address)dyn_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_uint256": {
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "t_uint8": {
+ "label": "uint8",
+ "numberOfBytes": "1"
+ }
+ }
+ }
+ },
+ "4bed61d9fa23c7805ebcfd02babfbc6cc196437ecd0880277f13c81b0b9d1276": {
+ "address": "0xc1fee489D542B95ECcA7DFCFaF79f900D87e668e",
+ "txHash": "0xc1d2fd5a7980bffafcf2b7642591d20d6355a83e39f8fcc39e8a8c157163142e",
+ "layout": {
+ "solcVersion": "0.8.7",
+ "storage": [
+ {
+ "label": "_initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint8",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62",
+ "retypedFrom": "bool"
+ },
+ {
+ "label": "_initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ContextUpgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ERC165Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol:41"
+ },
+ {
+ "label": "_name",
+ "offset": 0,
+ "slot": "101",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:25"
+ },
+ {
+ "label": "_symbol",
+ "offset": 0,
+ "slot": "102",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:28"
+ },
+ {
+ "label": "_owners",
+ "offset": 0,
+ "slot": "103",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:31"
+ },
+ {
+ "label": "_balances",
+ "offset": 0,
+ "slot": "104",
+ "type": "t_mapping(t_address,t_uint256)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:34"
+ },
+ {
+ "label": "_tokenApprovals",
+ "offset": 0,
+ "slot": "105",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:37"
+ },
+ {
+ "label": "_operatorApprovals",
+ "offset": 0,
+ "slot": "106",
+ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:40"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "107",
+ "type": "t_array(t_uint256)44_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:514"
+ },
+ {
+ "label": "_collectionRolesVersion",
+ "offset": 0,
+ "slot": "151",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:26"
+ },
+ {
+ "label": "_collectionRoles",
+ "offset": 0,
+ "slot": "152",
+ "type": "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:28"
+ },
+ {
+ "label": "_tokenRolesVersion",
+ "offset": 0,
+ "slot": "153",
+ "type": "t_mapping(t_uint256,t_struct(Counter)2774_storage)",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:30"
+ },
+ {
+ "label": "_tokenRoles",
+ "offset": 0,
+ "slot": "154",
+ "type": "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:32"
+ },
+ {
+ "label": "_tokenIds",
+ "offset": 0,
+ "slot": "155",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:45"
+ },
+ {
+ "label": "_apps",
+ "offset": 0,
+ "slot": "156",
+ "type": "t_mapping(t_uint256,t_struct(App)4607_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:46"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)44_storage": {
+ "label": "uint256[44]",
+ "numberOfBytes": "1408"
+ },
+ "t_array(t_uint256)50_storage": {
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_enum(Roles)3895": {
+ "label": "enum FleekAccessControl.Roles",
+ "members": ["Owner", "Controller"],
+ "numberOfBytes": "1"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_mapping(t_address,t_bool))": {
+ "label": "mapping(address => mapping(address => bool))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)": {
+ "label": "mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_address)": {
+ "label": "mapping(uint256 => address)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))": {
+ "label": "mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))": {
+ "label": "mapping(uint256 => mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(App)4607_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.App)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Build)4612_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.Build)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Counter)2774_storage)": {
+ "label": "mapping(uint256 => struct Counters.Counter)",
+ "numberOfBytes": "32"
+ },
+ "t_string_storage": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(App)4607_storage": {
+ "label": "struct FleekERC721.App",
+ "members": [
+ {
+ "label": "name",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "description",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "externalURL",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "ENS",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "currentBuild",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "4"
+ },
+ {
+ "label": "builds",
+ "type": "t_mapping(t_uint256,t_struct(Build)4612_storage)",
+ "offset": 0,
+ "slot": "5"
+ }
+ ],
+ "numberOfBytes": "192"
+ },
+ "t_struct(Build)4612_storage": {
+ "label": "struct FleekERC721.Build",
+ "members": [
+ {
+ "label": "commitHash",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "gitRepository",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_struct(Counter)2774_storage": {
+ "label": "struct Counters.Counter",
+ "members": [
+ {
+ "label": "_value",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_struct(Role)3943_storage": {
+ "label": "struct FleekAccessControl.Role",
+ "members": [
+ {
+ "label": "indexes",
+ "type": "t_mapping(t_address,t_uint256)",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "members",
+ "type": "t_array(t_address)dyn_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_uint256": {
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "t_uint8": {
+ "label": "uint8",
+ "numberOfBytes": "1"
+ }
+ }
+ }
+ },
+ "9e390d39043fd80a705a897c5ae44963e1446bfc550c5dcee6ba60c0ec867571": {
+ "address": "0xC5Cf07be0e653B0bB898A6bbc04292Ec6ff45C84",
+ "txHash": "0xc30b226cdb5628e7772d44d372ec06debbd1967e20bd13de064a46886ad4990f",
+ "layout": {
+ "solcVersion": "0.8.7",
+ "storage": [
+ {
+ "label": "_initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint8",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62",
+ "retypedFrom": "bool"
+ },
+ {
+ "label": "_initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ContextUpgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ERC165Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol:41"
+ },
+ {
+ "label": "_name",
+ "offset": 0,
+ "slot": "101",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:25"
+ },
+ {
+ "label": "_symbol",
+ "offset": 0,
+ "slot": "102",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:28"
+ },
+ {
+ "label": "_owners",
+ "offset": 0,
+ "slot": "103",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:31"
+ },
+ {
+ "label": "_balances",
+ "offset": 0,
+ "slot": "104",
+ "type": "t_mapping(t_address,t_uint256)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:34"
+ },
+ {
+ "label": "_tokenApprovals",
+ "offset": 0,
+ "slot": "105",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:37"
+ },
+ {
+ "label": "_operatorApprovals",
+ "offset": 0,
+ "slot": "106",
+ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:40"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "107",
+ "type": "t_array(t_uint256)44_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:514"
+ },
+ {
+ "label": "_collectionRolesVersion",
+ "offset": 0,
+ "slot": "151",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:26"
+ },
+ {
+ "label": "_collectionRoles",
+ "offset": 0,
+ "slot": "152",
+ "type": "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:28"
+ },
+ {
+ "label": "_tokenRolesVersion",
+ "offset": 0,
+ "slot": "153",
+ "type": "t_mapping(t_uint256,t_struct(Counter)2774_storage)",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:30"
+ },
+ {
+ "label": "_tokenRoles",
+ "offset": 0,
+ "slot": "154",
+ "type": "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:32"
+ },
+ {
+ "label": "_tokenIds",
+ "offset": 0,
+ "slot": "155",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:45"
+ },
+ {
+ "label": "_apps",
+ "offset": 0,
+ "slot": "156",
+ "type": "t_mapping(t_uint256,t_struct(App)4607_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:46"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)44_storage": {
+ "label": "uint256[44]",
+ "numberOfBytes": "1408"
+ },
+ "t_array(t_uint256)50_storage": {
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_enum(Roles)3895": {
+ "label": "enum FleekAccessControl.Roles",
+ "members": ["Owner", "Controller"],
+ "numberOfBytes": "1"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_mapping(t_address,t_bool))": {
+ "label": "mapping(address => mapping(address => bool))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)": {
+ "label": "mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_address)": {
+ "label": "mapping(uint256 => address)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))": {
+ "label": "mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))": {
+ "label": "mapping(uint256 => mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(App)4607_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.App)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Build)4612_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.Build)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Counter)2774_storage)": {
+ "label": "mapping(uint256 => struct Counters.Counter)",
+ "numberOfBytes": "32"
+ },
+ "t_string_storage": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(App)4607_storage": {
+ "label": "struct FleekERC721.App",
+ "members": [
+ {
+ "label": "name",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "description",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "externalURL",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "ENS",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "currentBuild",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "4"
+ },
+ {
+ "label": "builds",
+ "type": "t_mapping(t_uint256,t_struct(Build)4612_storage)",
+ "offset": 0,
+ "slot": "5"
+ }
+ ],
+ "numberOfBytes": "192"
+ },
+ "t_struct(Build)4612_storage": {
+ "label": "struct FleekERC721.Build",
+ "members": [
+ {
+ "label": "commitHash",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "gitRepository",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_struct(Counter)2774_storage": {
+ "label": "struct Counters.Counter",
+ "members": [
+ {
+ "label": "_value",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_struct(Role)3943_storage": {
+ "label": "struct FleekAccessControl.Role",
+ "members": [
+ {
+ "label": "indexes",
+ "type": "t_mapping(t_address,t_uint256)",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "members",
+ "type": "t_array(t_address)dyn_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_uint256": {
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "t_uint8": {
+ "label": "uint8",
+ "numberOfBytes": "1"
+ }
+ }
+ }
+ },
+ "7b21ac082895579c68e5704066472101609fd94fdffb3a0e00a42df5f746b49c": {
+ "address": "0xdb5D7976D468E536780563B10972f7ffAF04Be26",
+ "txHash": "0xb4a00fcaa8ba6e41282416307c1ef0506c8e98d7e243fe103c05625f2222b4d3",
+ "layout": {
+ "solcVersion": "0.8.12",
+ "storage": [
+ {
+ "label": "_initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint8",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62",
+ "retypedFrom": "bool"
+ },
+ {
+ "label": "_initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ContextUpgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ERC165Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol:41"
+ },
+ {
+ "label": "_name",
+ "offset": 0,
+ "slot": "101",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:25"
+ },
+ {
+ "label": "_symbol",
+ "offset": 0,
+ "slot": "102",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:28"
+ },
+ {
+ "label": "_owners",
+ "offset": 0,
+ "slot": "103",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:31"
+ },
+ {
+ "label": "_balances",
+ "offset": 0,
+ "slot": "104",
+ "type": "t_mapping(t_address,t_uint256)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:34"
+ },
+ {
+ "label": "_tokenApprovals",
+ "offset": 0,
+ "slot": "105",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:37"
+ },
+ {
+ "label": "_operatorApprovals",
+ "offset": 0,
+ "slot": "106",
+ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:40"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "107",
+ "type": "t_array(t_uint256)44_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:514"
+ },
+ {
+ "label": "_collectionRolesVersion",
+ "offset": 0,
+ "slot": "151",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:26"
+ },
+ {
+ "label": "_collectionRoles",
+ "offset": 0,
+ "slot": "152",
+ "type": "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:28"
+ },
+ {
+ "label": "_tokenRolesVersion",
+ "offset": 0,
+ "slot": "153",
+ "type": "t_mapping(t_uint256,t_struct(Counter)2774_storage)",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:30"
+ },
+ {
+ "label": "_tokenRoles",
+ "offset": 0,
+ "slot": "154",
+ "type": "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:32"
+ },
+ {
+ "label": "_appIds",
+ "offset": 0,
+ "slot": "155",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:82"
+ },
+ {
+ "label": "_apps",
+ "offset": 0,
+ "slot": "156",
+ "type": "t_mapping(t_uint256,t_struct(App)4667_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:83"
+ },
+ {
+ "label": "_accessPoints",
+ "offset": 0,
+ "slot": "157",
+ "type": "t_mapping(t_string_memory_ptr,t_struct(AccessPoint)4685_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:84"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_string_storage)dyn_storage": {
+ "label": "string[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)44_storage": {
+ "label": "uint256[44]",
+ "numberOfBytes": "1408"
+ },
+ "t_array(t_uint256)50_storage": {
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_enum(Roles)3895": {
+ "label": "enum FleekAccessControl.Roles",
+ "members": ["Owner", "Controller"],
+ "numberOfBytes": "1"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_mapping(t_address,t_bool))": {
+ "label": "mapping(address => mapping(address => bool))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)": {
+ "label": "mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_string_memory_ptr,t_struct(AccessPoint)4685_storage)": {
+ "label": "mapping(string => struct FleekERC721.AccessPoint)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_address)": {
+ "label": "mapping(uint256 => address)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))": {
+ "label": "mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))": {
+ "label": "mapping(uint256 => mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(App)4667_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.App)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Build)4672_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.Build)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Counter)2774_storage)": {
+ "label": "mapping(uint256 => struct Counters.Counter)",
+ "numberOfBytes": "32"
+ },
+ "t_string_memory_ptr": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_string_storage": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(AccessPoint)4685_storage": {
+ "label": "struct FleekERC721.AccessPoint",
+ "members": [
+ {
+ "label": "tokenId",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "index",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "score",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "contentVerified",
+ "type": "t_bool",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "nameVerified",
+ "type": "t_bool",
+ "offset": 1,
+ "slot": "3"
+ },
+ {
+ "label": "owner",
+ "type": "t_address",
+ "offset": 2,
+ "slot": "3"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_struct(App)4667_storage": {
+ "label": "struct FleekERC721.App",
+ "members": [
+ {
+ "label": "name",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "description",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "externalURL",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "ENS",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "currentBuild",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "4"
+ },
+ {
+ "label": "builds",
+ "type": "t_mapping(t_uint256,t_struct(Build)4672_storage)",
+ "offset": 0,
+ "slot": "5"
+ },
+ {
+ "label": "accessPoints",
+ "type": "t_array(t_string_storage)dyn_storage",
+ "offset": 0,
+ "slot": "6"
+ }
+ ],
+ "numberOfBytes": "224"
+ },
+ "t_struct(Build)4672_storage": {
+ "label": "struct FleekERC721.Build",
+ "members": [
+ {
+ "label": "commitHash",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "gitRepository",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_struct(Counter)2774_storage": {
+ "label": "struct Counters.Counter",
+ "members": [
+ {
+ "label": "_value",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_struct(Role)3943_storage": {
+ "label": "struct FleekAccessControl.Role",
+ "members": [
+ {
+ "label": "indexes",
+ "type": "t_mapping(t_address,t_uint256)",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "members",
+ "type": "t_array(t_address)dyn_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_uint256": {
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "t_uint8": {
+ "label": "uint8",
+ "numberOfBytes": "1"
+ }
+ }
+ }
+ },
+ "a8bd26ddc16038579da72acbab40e8e0cdf4af53bca59313f53db56dffbdaa34": {
+ "address": "0xefF92C4127e69045f06948c565451b1Add487b72",
+ "txHash": "0x35c7aa0de04367d62080d8572b8b895a3dfe714d50d3d6c4f21374f99e117b50",
+ "layout": {
+ "solcVersion": "0.8.12",
+ "storage": [
+ {
+ "label": "_initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint8",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62",
+ "retypedFrom": "bool"
+ },
+ {
+ "label": "_initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ContextUpgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ERC165Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol:41"
+ },
+ {
+ "label": "_name",
+ "offset": 0,
+ "slot": "101",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:25"
+ },
+ {
+ "label": "_symbol",
+ "offset": 0,
+ "slot": "102",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:28"
+ },
+ {
+ "label": "_owners",
+ "offset": 0,
+ "slot": "103",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:31"
+ },
+ {
+ "label": "_balances",
+ "offset": 0,
+ "slot": "104",
+ "type": "t_mapping(t_address,t_uint256)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:34"
+ },
+ {
+ "label": "_tokenApprovals",
+ "offset": 0,
+ "slot": "105",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:37"
+ },
+ {
+ "label": "_operatorApprovals",
+ "offset": 0,
+ "slot": "106",
+ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:40"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "107",
+ "type": "t_array(t_uint256)44_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:514"
+ },
+ {
+ "label": "_collectionRolesVersion",
+ "offset": 0,
+ "slot": "151",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:26"
+ },
+ {
+ "label": "_collectionRoles",
+ "offset": 0,
+ "slot": "152",
+ "type": "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:28"
+ },
+ {
+ "label": "_tokenRolesVersion",
+ "offset": 0,
+ "slot": "153",
+ "type": "t_mapping(t_uint256,t_struct(Counter)2774_storage)",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:30"
+ },
+ {
+ "label": "_tokenRoles",
+ "offset": 0,
+ "slot": "154",
+ "type": "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:32"
+ },
+ {
+ "label": "_appIds",
+ "offset": 0,
+ "slot": "155",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:82"
+ },
+ {
+ "label": "_apps",
+ "offset": 0,
+ "slot": "156",
+ "type": "t_mapping(t_uint256,t_struct(App)4667_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:83"
+ },
+ {
+ "label": "_accessPoints",
+ "offset": 0,
+ "slot": "157",
+ "type": "t_mapping(t_string_memory_ptr,t_struct(AccessPoint)4685_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:84"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_string_storage)dyn_storage": {
+ "label": "string[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)44_storage": {
+ "label": "uint256[44]",
+ "numberOfBytes": "1408"
+ },
+ "t_array(t_uint256)50_storage": {
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_enum(Roles)3895": {
+ "label": "enum FleekAccessControl.Roles",
+ "members": ["Owner", "Controller"],
+ "numberOfBytes": "1"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_mapping(t_address,t_bool))": {
+ "label": "mapping(address => mapping(address => bool))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)": {
+ "label": "mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_string_memory_ptr,t_struct(AccessPoint)4685_storage)": {
+ "label": "mapping(string => struct FleekERC721.AccessPoint)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_address)": {
+ "label": "mapping(uint256 => address)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))": {
+ "label": "mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))": {
+ "label": "mapping(uint256 => mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(App)4667_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.App)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Build)4672_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.Build)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Counter)2774_storage)": {
+ "label": "mapping(uint256 => struct Counters.Counter)",
+ "numberOfBytes": "32"
+ },
+ "t_string_memory_ptr": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_string_storage": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(AccessPoint)4685_storage": {
+ "label": "struct FleekERC721.AccessPoint",
+ "members": [
+ {
+ "label": "tokenId",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "index",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "score",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "contentVerified",
+ "type": "t_bool",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "nameVerified",
+ "type": "t_bool",
+ "offset": 1,
+ "slot": "3"
+ },
+ {
+ "label": "owner",
+ "type": "t_address",
+ "offset": 2,
+ "slot": "3"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_struct(App)4667_storage": {
+ "label": "struct FleekERC721.App",
+ "members": [
+ {
+ "label": "name",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "description",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "externalURL",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "ENS",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "currentBuild",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "4"
+ },
+ {
+ "label": "builds",
+ "type": "t_mapping(t_uint256,t_struct(Build)4672_storage)",
+ "offset": 0,
+ "slot": "5"
+ },
+ {
+ "label": "accessPoints",
+ "type": "t_array(t_string_storage)dyn_storage",
+ "offset": 0,
+ "slot": "6"
+ }
+ ],
+ "numberOfBytes": "224"
+ },
+ "t_struct(Build)4672_storage": {
+ "label": "struct FleekERC721.Build",
+ "members": [
+ {
+ "label": "commitHash",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "gitRepository",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_struct(Counter)2774_storage": {
+ "label": "struct Counters.Counter",
+ "members": [
+ {
+ "label": "_value",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_struct(Role)3943_storage": {
+ "label": "struct FleekAccessControl.Role",
+ "members": [
+ {
+ "label": "indexes",
+ "type": "t_mapping(t_address,t_uint256)",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "members",
+ "type": "t_array(t_address)dyn_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_uint256": {
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "t_uint8": {
+ "label": "uint8",
+ "numberOfBytes": "1"
+ }
+ }
+ }
+ },
+ "c3264ad5d0a420580d037432727f9de71963ee9e56969a9ec9ee1cc199cb29f6": {
+ "address": "0x05e1232d2ab4eaFa65cBCD112f655a221B374F37",
+ "txHash": "0xe7fe8463d18fe71ea88d781597c1d283eaa75735cc825119da90a8a5a1420e27",
+ "layout": {
+ "solcVersion": "0.8.12",
+ "storage": [
+ {
+ "label": "_initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint8",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62",
+ "retypedFrom": "bool"
+ },
+ {
+ "label": "_initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ContextUpgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ERC165Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol:41"
+ },
+ {
+ "label": "_name",
+ "offset": 0,
+ "slot": "101",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:25"
+ },
+ {
+ "label": "_symbol",
+ "offset": 0,
+ "slot": "102",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:28"
+ },
+ {
+ "label": "_owners",
+ "offset": 0,
+ "slot": "103",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:31"
+ },
+ {
+ "label": "_balances",
+ "offset": 0,
+ "slot": "104",
+ "type": "t_mapping(t_address,t_uint256)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:34"
+ },
+ {
+ "label": "_tokenApprovals",
+ "offset": 0,
+ "slot": "105",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:37"
+ },
+ {
+ "label": "_operatorApprovals",
+ "offset": 0,
+ "slot": "106",
+ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:40"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "107",
+ "type": "t_array(t_uint256)44_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:514"
+ },
+ {
+ "label": "_collectionRolesVersion",
+ "offset": 0,
+ "slot": "151",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:26"
+ },
+ {
+ "label": "_collectionRoles",
+ "offset": 0,
+ "slot": "152",
+ "type": "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:28"
+ },
+ {
+ "label": "_tokenRolesVersion",
+ "offset": 0,
+ "slot": "153",
+ "type": "t_mapping(t_uint256,t_struct(Counter)2774_storage)",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:30"
+ },
+ {
+ "label": "_tokenRoles",
+ "offset": 0,
+ "slot": "154",
+ "type": "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:32"
+ },
+ {
+ "label": "_appIds",
+ "offset": 0,
+ "slot": "155",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:84"
+ },
+ {
+ "label": "_apps",
+ "offset": 0,
+ "slot": "156",
+ "type": "t_mapping(t_uint256,t_struct(App)4671_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:85"
+ },
+ {
+ "label": "_accessPoints",
+ "offset": 0,
+ "slot": "157",
+ "type": "t_mapping(t_string_memory_ptr,t_struct(AccessPoint)4689_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:86"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_string_storage)dyn_storage": {
+ "label": "string[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)44_storage": {
+ "label": "uint256[44]",
+ "numberOfBytes": "1408"
+ },
+ "t_array(t_uint256)50_storage": {
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes3": {
+ "label": "bytes3",
+ "numberOfBytes": "3"
+ },
+ "t_enum(Roles)3895": {
+ "label": "enum FleekAccessControl.Roles",
+ "members": ["Owner", "Controller"],
+ "numberOfBytes": "1"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_mapping(t_address,t_bool))": {
+ "label": "mapping(address => mapping(address => bool))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)": {
+ "label": "mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_string_memory_ptr,t_struct(AccessPoint)4689_storage)": {
+ "label": "mapping(string => struct FleekERC721.AccessPoint)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_address)": {
+ "label": "mapping(uint256 => address)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))": {
+ "label": "mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))": {
+ "label": "mapping(uint256 => mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(App)4671_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.App)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Build)4676_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.Build)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Counter)2774_storage)": {
+ "label": "mapping(uint256 => struct Counters.Counter)",
+ "numberOfBytes": "32"
+ },
+ "t_string_memory_ptr": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_string_storage": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(AccessPoint)4689_storage": {
+ "label": "struct FleekERC721.AccessPoint",
+ "members": [
+ {
+ "label": "tokenId",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "index",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "score",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "contentVerified",
+ "type": "t_bool",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "nameVerified",
+ "type": "t_bool",
+ "offset": 1,
+ "slot": "3"
+ },
+ {
+ "label": "owner",
+ "type": "t_address",
+ "offset": 2,
+ "slot": "3"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_struct(App)4671_storage": {
+ "label": "struct FleekERC721.App",
+ "members": [
+ {
+ "label": "name",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "description",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "externalURL",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "ENS",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "currentBuild",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "4"
+ },
+ {
+ "label": "builds",
+ "type": "t_mapping(t_uint256,t_struct(Build)4676_storage)",
+ "offset": 0,
+ "slot": "5"
+ },
+ {
+ "label": "accessPoints",
+ "type": "t_array(t_string_storage)dyn_storage",
+ "offset": 0,
+ "slot": "6"
+ },
+ {
+ "label": "logo",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "7"
+ },
+ {
+ "label": "color",
+ "type": "t_bytes3",
+ "offset": 0,
+ "slot": "8"
+ }
+ ],
+ "numberOfBytes": "288"
+ },
+ "t_struct(Build)4676_storage": {
+ "label": "struct FleekERC721.Build",
+ "members": [
+ {
+ "label": "commitHash",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "gitRepository",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_struct(Counter)2774_storage": {
+ "label": "struct Counters.Counter",
+ "members": [
+ {
+ "label": "_value",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_struct(Role)3943_storage": {
+ "label": "struct FleekAccessControl.Role",
+ "members": [
+ {
+ "label": "indexes",
+ "type": "t_mapping(t_address,t_uint256)",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "members",
+ "type": "t_array(t_address)dyn_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_uint256": {
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "t_uint8": {
+ "label": "uint8",
+ "numberOfBytes": "1"
+ }
+ }
+ }
+ },
+ "36d3ea4a327b9d085d3bd524867ceac510402a2bf161e3df8f4dc3103354db60": {
+ "address": "0xdc61e08701566a4e7828cf8d4509d29F8311700F",
+ "txHash": "0x73b9d8aa7014ac353919cb59f7a73efb955a9ff50e7fb7937d6d8ae197808ca9",
+ "layout": {
+ "solcVersion": "0.8.12",
+ "storage": [
+ {
+ "label": "_initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint8",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62",
+ "retypedFrom": "bool"
+ },
+ {
+ "label": "_initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ContextUpgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ERC165Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol:41"
+ },
+ {
+ "label": "_name",
+ "offset": 0,
+ "slot": "101",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:25"
+ },
+ {
+ "label": "_symbol",
+ "offset": 0,
+ "slot": "102",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:28"
+ },
+ {
+ "label": "_owners",
+ "offset": 0,
+ "slot": "103",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:31"
+ },
+ {
+ "label": "_balances",
+ "offset": 0,
+ "slot": "104",
+ "type": "t_mapping(t_address,t_uint256)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:34"
+ },
+ {
+ "label": "_tokenApprovals",
+ "offset": 0,
+ "slot": "105",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:37"
+ },
+ {
+ "label": "_operatorApprovals",
+ "offset": 0,
+ "slot": "106",
+ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:40"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "107",
+ "type": "t_array(t_uint256)44_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:514"
+ },
+ {
+ "label": "_collectionRolesVersion",
+ "offset": 0,
+ "slot": "151",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:26"
+ },
+ {
+ "label": "_collectionRoles",
+ "offset": 0,
+ "slot": "152",
+ "type": "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:28"
+ },
+ {
+ "label": "_tokenRolesVersion",
+ "offset": 0,
+ "slot": "153",
+ "type": "t_mapping(t_uint256,t_struct(Counter)2774_storage)",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:30"
+ },
+ {
+ "label": "_tokenRoles",
+ "offset": 0,
+ "slot": "154",
+ "type": "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:32"
+ },
+ {
+ "label": "_appIds",
+ "offset": 0,
+ "slot": "155",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:84"
+ },
+ {
+ "label": "_apps",
+ "offset": 0,
+ "slot": "156",
+ "type": "t_mapping(t_uint256,t_struct(App)4671_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:85"
+ },
+ {
+ "label": "_accessPoints",
+ "offset": 0,
+ "slot": "157",
+ "type": "t_mapping(t_string_memory_ptr,t_struct(AccessPoint)4689_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:86"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_string_storage)dyn_storage": {
+ "label": "string[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)44_storage": {
+ "label": "uint256[44]",
+ "numberOfBytes": "1408"
+ },
+ "t_array(t_uint256)50_storage": {
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_bytes3": {
+ "label": "bytes3",
+ "numberOfBytes": "3"
+ },
+ "t_enum(Roles)3895": {
+ "label": "enum FleekAccessControl.Roles",
+ "members": ["Owner", "Controller"],
+ "numberOfBytes": "1"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_mapping(t_address,t_bool))": {
+ "label": "mapping(address => mapping(address => bool))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)": {
+ "label": "mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_string_memory_ptr,t_struct(AccessPoint)4689_storage)": {
+ "label": "mapping(string => struct FleekERC721.AccessPoint)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_address)": {
+ "label": "mapping(uint256 => address)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))": {
+ "label": "mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))": {
+ "label": "mapping(uint256 => mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(App)4671_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.App)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Build)4676_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.Build)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Counter)2774_storage)": {
+ "label": "mapping(uint256 => struct Counters.Counter)",
+ "numberOfBytes": "32"
+ },
+ "t_string_memory_ptr": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_string_storage": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(AccessPoint)4689_storage": {
+ "label": "struct FleekERC721.AccessPoint",
+ "members": [
+ {
+ "label": "tokenId",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "index",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "score",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "contentVerified",
+ "type": "t_bool",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "nameVerified",
+ "type": "t_bool",
+ "offset": 1,
+ "slot": "3"
+ },
+ {
+ "label": "owner",
+ "type": "t_address",
+ "offset": 2,
+ "slot": "3"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_struct(App)4671_storage": {
+ "label": "struct FleekERC721.App",
+ "members": [
+ {
+ "label": "name",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "description",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "externalURL",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "ENS",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "currentBuild",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "4"
+ },
+ {
+ "label": "builds",
+ "type": "t_mapping(t_uint256,t_struct(Build)4676_storage)",
+ "offset": 0,
+ "slot": "5"
+ },
+ {
+ "label": "accessPoints",
+ "type": "t_array(t_string_storage)dyn_storage",
+ "offset": 0,
+ "slot": "6"
+ },
+ {
+ "label": "logo",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "7"
+ },
+ {
+ "label": "color",
+ "type": "t_bytes3",
+ "offset": 0,
+ "slot": "8"
+ }
+ ],
+ "numberOfBytes": "288"
+ },
+ "t_struct(Build)4676_storage": {
+ "label": "struct FleekERC721.Build",
+ "members": [
+ {
+ "label": "commitHash",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "gitRepository",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_struct(Counter)2774_storage": {
+ "label": "struct Counters.Counter",
+ "members": [
+ {
+ "label": "_value",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_struct(Role)3943_storage": {
+ "label": "struct FleekAccessControl.Role",
+ "members": [
+ {
+ "label": "indexes",
+ "type": "t_mapping(t_address,t_uint256)",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "members",
+ "type": "t_array(t_address)dyn_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_uint256": {
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "t_uint8": {
+ "label": "uint8",
+ "numberOfBytes": "1"
+ }
+ }
+ }
+ },
+ "dbe12327cdac3a3af8139d6c0e2920058fcb4907430f3012a6b4eaacc2f967fe": {
+ "address": "0x8b5FaEdE1dd15085923C255Ac91A21c75f6A20e1",
+ "txHash": "0x77fe621458f449cca242a3b154462b30072a1d8e2d5bd6f815d57cb872585078",
+ "layout": {
+ "solcVersion": "0.8.12",
+ "storage": [
+ {
+ "label": "_initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint8",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62",
+ "retypedFrom": "bool"
+ },
+ {
+ "label": "_initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ContextUpgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ERC165Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol:41"
+ },
+ {
+ "label": "_name",
+ "offset": 0,
+ "slot": "101",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:25"
+ },
+ {
+ "label": "_symbol",
+ "offset": 0,
+ "slot": "102",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:28"
+ },
+ {
+ "label": "_owners",
+ "offset": 0,
+ "slot": "103",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:31"
+ },
+ {
+ "label": "_balances",
+ "offset": 0,
+ "slot": "104",
+ "type": "t_mapping(t_address,t_uint256)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:34"
+ },
+ {
+ "label": "_tokenApprovals",
+ "offset": 0,
+ "slot": "105",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:37"
+ },
+ {
+ "label": "_operatorApprovals",
+ "offset": 0,
+ "slot": "106",
+ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:40"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "107",
+ "type": "t_array(t_uint256)44_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:514"
+ },
+ {
+ "label": "_collectionRolesVersion",
+ "offset": 0,
+ "slot": "151",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:26"
+ },
+ {
+ "label": "_collectionRoles",
+ "offset": 0,
+ "slot": "152",
+ "type": "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:28"
+ },
+ {
+ "label": "_tokenRolesVersion",
+ "offset": 0,
+ "slot": "153",
+ "type": "t_mapping(t_uint256,t_struct(Counter)2774_storage)",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:30"
+ },
+ {
+ "label": "_tokenRoles",
+ "offset": 0,
+ "slot": "154",
+ "type": "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:32"
+ },
+ {
+ "label": "_appIds",
+ "offset": 0,
+ "slot": "155",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:84"
+ },
+ {
+ "label": "_apps",
+ "offset": 0,
+ "slot": "156",
+ "type": "t_mapping(t_uint256,t_struct(App)4671_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:85"
+ },
+ {
+ "label": "_accessPoints",
+ "offset": 0,
+ "slot": "157",
+ "type": "t_mapping(t_string_memory_ptr,t_struct(AccessPoint)4689_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:86"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_string_storage)dyn_storage": {
+ "label": "string[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)44_storage": {
+ "label": "uint256[44]",
+ "numberOfBytes": "1408"
+ },
+ "t_array(t_uint256)50_storage": {
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_enum(Roles)3895": {
+ "label": "enum FleekAccessControl.Roles",
+ "members": ["Owner", "Controller"],
+ "numberOfBytes": "1"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_mapping(t_address,t_bool))": {
+ "label": "mapping(address => mapping(address => bool))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)": {
+ "label": "mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_string_memory_ptr,t_struct(AccessPoint)4689_storage)": {
+ "label": "mapping(string => struct FleekERC721.AccessPoint)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_address)": {
+ "label": "mapping(uint256 => address)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))": {
+ "label": "mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))": {
+ "label": "mapping(uint256 => mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(App)4671_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.App)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Build)4676_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.Build)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Counter)2774_storage)": {
+ "label": "mapping(uint256 => struct Counters.Counter)",
+ "numberOfBytes": "32"
+ },
+ "t_string_memory_ptr": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_string_storage": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(AccessPoint)4689_storage": {
+ "label": "struct FleekERC721.AccessPoint",
+ "members": [
+ {
+ "label": "tokenId",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "index",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "score",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "contentVerified",
+ "type": "t_bool",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "nameVerified",
+ "type": "t_bool",
+ "offset": 1,
+ "slot": "3"
+ },
+ {
+ "label": "owner",
+ "type": "t_address",
+ "offset": 2,
+ "slot": "3"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_struct(App)4671_storage": {
+ "label": "struct FleekERC721.App",
+ "members": [
+ {
+ "label": "name",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "description",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "externalURL",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "ENS",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "currentBuild",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "4"
+ },
+ {
+ "label": "builds",
+ "type": "t_mapping(t_uint256,t_struct(Build)4676_storage)",
+ "offset": 0,
+ "slot": "5"
+ },
+ {
+ "label": "accessPoints",
+ "type": "t_array(t_string_storage)dyn_storage",
+ "offset": 0,
+ "slot": "6"
+ },
+ {
+ "label": "logo",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "7"
+ },
+ {
+ "label": "color",
+ "type": "t_uint24",
+ "offset": 0,
+ "slot": "8"
+ }
+ ],
+ "numberOfBytes": "288"
+ },
+ "t_struct(Build)4676_storage": {
+ "label": "struct FleekERC721.Build",
+ "members": [
+ {
+ "label": "commitHash",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "gitRepository",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_struct(Counter)2774_storage": {
+ "label": "struct Counters.Counter",
+ "members": [
+ {
+ "label": "_value",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_struct(Role)3943_storage": {
+ "label": "struct FleekAccessControl.Role",
+ "members": [
+ {
+ "label": "indexes",
+ "type": "t_mapping(t_address,t_uint256)",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "members",
+ "type": "t_array(t_address)dyn_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_uint24": {
+ "label": "uint24",
+ "numberOfBytes": "3"
+ },
+ "t_uint256": {
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "t_uint8": {
+ "label": "uint8",
+ "numberOfBytes": "1"
+ }
+ }
+ }
+ },
+ "a6d2704c34f0315546349135b554b70be22fd11e10a77d5ce6f07be5f808804a": {
+ "address": "0xFf91E2b2eC2676Db8d15Bd19CF41200dcf45B0bc",
+ "txHash": "0x969ca7c0d8fba1d6b140cd51e2b1c164c6a12efdf3729b522c3be46c2b175f38",
+ "layout": {
+ "solcVersion": "0.8.12",
+ "storage": [
+ {
+ "label": "_initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint8",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62",
+ "retypedFrom": "bool"
+ },
+ {
+ "label": "_initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ContextUpgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ERC165Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol:41"
+ },
+ {
+ "label": "_name",
+ "offset": 0,
+ "slot": "101",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:25"
+ },
+ {
+ "label": "_symbol",
+ "offset": 0,
+ "slot": "102",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:28"
+ },
+ {
+ "label": "_owners",
+ "offset": 0,
+ "slot": "103",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:31"
+ },
+ {
+ "label": "_balances",
+ "offset": 0,
+ "slot": "104",
+ "type": "t_mapping(t_address,t_uint256)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:34"
+ },
+ {
+ "label": "_tokenApprovals",
+ "offset": 0,
+ "slot": "105",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:37"
+ },
+ {
+ "label": "_operatorApprovals",
+ "offset": 0,
+ "slot": "106",
+ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:40"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "107",
+ "type": "t_array(t_uint256)44_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:514"
+ },
+ {
+ "label": "_collectionRolesVersion",
+ "offset": 0,
+ "slot": "151",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:26"
+ },
+ {
+ "label": "_collectionRoles",
+ "offset": 0,
+ "slot": "152",
+ "type": "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:28"
+ },
+ {
+ "label": "_tokenRolesVersion",
+ "offset": 0,
+ "slot": "153",
+ "type": "t_mapping(t_uint256,t_struct(Counter)2774_storage)",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:30"
+ },
+ {
+ "label": "_tokenRoles",
+ "offset": 0,
+ "slot": "154",
+ "type": "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:32"
+ },
+ {
+ "label": "_appIds",
+ "offset": 0,
+ "slot": "155",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:84"
+ },
+ {
+ "label": "_apps",
+ "offset": 0,
+ "slot": "156",
+ "type": "t_mapping(t_uint256,t_struct(App)4671_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:85"
+ },
+ {
+ "label": "_accessPoints",
+ "offset": 0,
+ "slot": "157",
+ "type": "t_mapping(t_string_memory_ptr,t_struct(AccessPoint)4689_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:86"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_string_storage)dyn_storage": {
+ "label": "string[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)44_storage": {
+ "label": "uint256[44]",
+ "numberOfBytes": "1408"
+ },
+ "t_array(t_uint256)50_storage": {
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_enum(Roles)3895": {
+ "label": "enum FleekAccessControl.Roles",
+ "members": ["Owner", "Controller"],
+ "numberOfBytes": "1"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_mapping(t_address,t_bool))": {
+ "label": "mapping(address => mapping(address => bool))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)": {
+ "label": "mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_string_memory_ptr,t_struct(AccessPoint)4689_storage)": {
+ "label": "mapping(string => struct FleekERC721.AccessPoint)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_address)": {
+ "label": "mapping(uint256 => address)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))": {
+ "label": "mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))": {
+ "label": "mapping(uint256 => mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(App)4671_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.App)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Build)4676_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.Build)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Counter)2774_storage)": {
+ "label": "mapping(uint256 => struct Counters.Counter)",
+ "numberOfBytes": "32"
+ },
+ "t_string_memory_ptr": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_string_storage": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(AccessPoint)4689_storage": {
+ "label": "struct FleekERC721.AccessPoint",
+ "members": [
+ {
+ "label": "tokenId",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "index",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "score",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "contentVerified",
+ "type": "t_bool",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "nameVerified",
+ "type": "t_bool",
+ "offset": 1,
+ "slot": "3"
+ },
+ {
+ "label": "owner",
+ "type": "t_address",
+ "offset": 2,
+ "slot": "3"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_struct(App)4671_storage": {
+ "label": "struct FleekERC721.App",
+ "members": [
+ {
+ "label": "name",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "description",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "externalURL",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "ENS",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "currentBuild",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "4"
+ },
+ {
+ "label": "builds",
+ "type": "t_mapping(t_uint256,t_struct(Build)4676_storage)",
+ "offset": 0,
+ "slot": "5"
+ },
+ {
+ "label": "accessPoints",
+ "type": "t_array(t_string_storage)dyn_storage",
+ "offset": 0,
+ "slot": "6"
+ },
+ {
+ "label": "logo",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "7"
+ },
+ {
+ "label": "color",
+ "type": "t_uint24",
+ "offset": 0,
+ "slot": "8"
+ }
+ ],
+ "numberOfBytes": "288"
+ },
+ "t_struct(Build)4676_storage": {
+ "label": "struct FleekERC721.Build",
+ "members": [
+ {
+ "label": "commitHash",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "gitRepository",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_struct(Counter)2774_storage": {
+ "label": "struct Counters.Counter",
+ "members": [
+ {
+ "label": "_value",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_struct(Role)3943_storage": {
+ "label": "struct FleekAccessControl.Role",
+ "members": [
+ {
+ "label": "indexes",
+ "type": "t_mapping(t_address,t_uint256)",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "members",
+ "type": "t_array(t_address)dyn_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_uint24": {
+ "label": "uint24",
+ "numberOfBytes": "3"
+ },
+ "t_uint256": {
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "t_uint8": {
+ "label": "uint8",
+ "numberOfBytes": "1"
+ }
+ }
+ }
+ },
+ "c40ee05a331881850c5f2a1b8f8a22ca36f33862afab696f8770380092fc84f6": {
+ "address": "0x6D18455DD1669DAbDD7Cf6c19D014E6cD689F28e",
+ "txHash": "0x8ed45df2eb4628754ea5fba2cf3ec3cc7aa62789551ac3f446b4f802626ad97a",
+ "layout": {
+ "solcVersion": "0.8.12",
+ "storage": [
+ {
+ "label": "_initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint8",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62",
+ "retypedFrom": "bool"
+ },
+ {
+ "label": "_initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ContextUpgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ERC165Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol:41"
+ },
+ {
+ "label": "_name",
+ "offset": 0,
+ "slot": "101",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:25"
+ },
+ {
+ "label": "_symbol",
+ "offset": 0,
+ "slot": "102",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:28"
+ },
+ {
+ "label": "_owners",
+ "offset": 0,
+ "slot": "103",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:31"
+ },
+ {
+ "label": "_balances",
+ "offset": 0,
+ "slot": "104",
+ "type": "t_mapping(t_address,t_uint256)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:34"
+ },
+ {
+ "label": "_tokenApprovals",
+ "offset": 0,
+ "slot": "105",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:37"
+ },
+ {
+ "label": "_operatorApprovals",
+ "offset": 0,
+ "slot": "106",
+ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:40"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "107",
+ "type": "t_array(t_uint256)44_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:514"
+ },
+ {
+ "label": "_collectionRolesVersion",
+ "offset": 0,
+ "slot": "151",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:26"
+ },
+ {
+ "label": "_collectionRoles",
+ "offset": 0,
+ "slot": "152",
+ "type": "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:28"
+ },
+ {
+ "label": "_tokenRolesVersion",
+ "offset": 0,
+ "slot": "153",
+ "type": "t_mapping(t_uint256,t_struct(Counter)2774_storage)",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:30"
+ },
+ {
+ "label": "_tokenRoles",
+ "offset": 0,
+ "slot": "154",
+ "type": "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:32"
+ },
+ {
+ "label": "_appIds",
+ "offset": 0,
+ "slot": "155",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:84"
+ },
+ {
+ "label": "_apps",
+ "offset": 0,
+ "slot": "156",
+ "type": "t_mapping(t_uint256,t_struct(App)4671_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:85"
+ },
+ {
+ "label": "_accessPoints",
+ "offset": 0,
+ "slot": "157",
+ "type": "t_mapping(t_string_memory_ptr,t_struct(AccessPoint)4689_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:86"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_string_storage)dyn_storage": {
+ "label": "string[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)44_storage": {
+ "label": "uint256[44]",
+ "numberOfBytes": "1408"
+ },
+ "t_array(t_uint256)50_storage": {
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_enum(Roles)3895": {
+ "label": "enum FleekAccessControl.Roles",
+ "members": ["Owner", "Controller"],
+ "numberOfBytes": "1"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_mapping(t_address,t_bool))": {
+ "label": "mapping(address => mapping(address => bool))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)": {
+ "label": "mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_string_memory_ptr,t_struct(AccessPoint)4689_storage)": {
+ "label": "mapping(string => struct FleekERC721.AccessPoint)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_address)": {
+ "label": "mapping(uint256 => address)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))": {
+ "label": "mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))": {
+ "label": "mapping(uint256 => mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(App)4671_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.App)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Build)4676_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.Build)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Counter)2774_storage)": {
+ "label": "mapping(uint256 => struct Counters.Counter)",
+ "numberOfBytes": "32"
+ },
+ "t_string_memory_ptr": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_string_storage": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(AccessPoint)4689_storage": {
+ "label": "struct FleekERC721.AccessPoint",
+ "members": [
+ {
+ "label": "tokenId",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "index",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "score",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "contentVerified",
+ "type": "t_bool",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "nameVerified",
+ "type": "t_bool",
+ "offset": 1,
+ "slot": "3"
+ },
+ {
+ "label": "owner",
+ "type": "t_address",
+ "offset": 2,
+ "slot": "3"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_struct(App)4671_storage": {
+ "label": "struct FleekERC721.App",
+ "members": [
+ {
+ "label": "name",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "description",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "externalURL",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "ENS",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "currentBuild",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "4"
+ },
+ {
+ "label": "builds",
+ "type": "t_mapping(t_uint256,t_struct(Build)4676_storage)",
+ "offset": 0,
+ "slot": "5"
+ },
+ {
+ "label": "accessPoints",
+ "type": "t_array(t_string_storage)dyn_storage",
+ "offset": 0,
+ "slot": "6"
+ },
+ {
+ "label": "logo",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "7"
+ },
+ {
+ "label": "color",
+ "type": "t_uint24",
+ "offset": 0,
+ "slot": "8"
+ }
+ ],
+ "numberOfBytes": "288"
+ },
+ "t_struct(Build)4676_storage": {
+ "label": "struct FleekERC721.Build",
+ "members": [
+ {
+ "label": "commitHash",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "gitRepository",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_struct(Counter)2774_storage": {
+ "label": "struct Counters.Counter",
+ "members": [
+ {
+ "label": "_value",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_struct(Role)3943_storage": {
+ "label": "struct FleekAccessControl.Role",
+ "members": [
+ {
+ "label": "indexes",
+ "type": "t_mapping(t_address,t_uint256)",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "members",
+ "type": "t_array(t_address)dyn_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_uint24": {
+ "label": "uint24",
+ "numberOfBytes": "3"
+ },
+ "t_uint256": {
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "t_uint8": {
+ "label": "uint8",
+ "numberOfBytes": "1"
+ }
+ }
+ }
+ },
+ "0acc4dd933529c87ed9cc86d7534462d537654b9c8d5a447396c8da43f977ef3": {
+ "address": "0x24E40AE36F16fda632a62DAB923e5bc4a6186e41",
+ "txHash": "0xd061a8f2d2f66aba6ba57dd4a78bbd04d4565f3550b7a93d0c08f5f57385d7d5",
+ "layout": {
+ "solcVersion": "0.8.12",
+ "storage": [
+ {
+ "label": "_initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint8",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62",
+ "retypedFrom": "bool"
+ },
+ {
+ "label": "_initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ContextUpgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ERC165Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol:41"
+ },
+ {
+ "label": "_name",
+ "offset": 0,
+ "slot": "101",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:25"
+ },
+ {
+ "label": "_symbol",
+ "offset": 0,
+ "slot": "102",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:28"
+ },
+ {
+ "label": "_owners",
+ "offset": 0,
+ "slot": "103",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:31"
+ },
+ {
+ "label": "_balances",
+ "offset": 0,
+ "slot": "104",
+ "type": "t_mapping(t_address,t_uint256)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:34"
+ },
+ {
+ "label": "_tokenApprovals",
+ "offset": 0,
+ "slot": "105",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:37"
+ },
+ {
+ "label": "_operatorApprovals",
+ "offset": 0,
+ "slot": "106",
+ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:40"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "107",
+ "type": "t_array(t_uint256)44_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:514"
+ },
+ {
+ "label": "_collectionRolesVersion",
+ "offset": 0,
+ "slot": "151",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:26"
+ },
+ {
+ "label": "_collectionRoles",
+ "offset": 0,
+ "slot": "152",
+ "type": "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:28"
+ },
+ {
+ "label": "_tokenRolesVersion",
+ "offset": 0,
+ "slot": "153",
+ "type": "t_mapping(t_uint256,t_struct(Counter)2774_storage)",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:30"
+ },
+ {
+ "label": "_tokenRoles",
+ "offset": 0,
+ "slot": "154",
+ "type": "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:32"
+ },
+ {
+ "label": "_appIds",
+ "offset": 0,
+ "slot": "155",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:84"
+ },
+ {
+ "label": "_apps",
+ "offset": 0,
+ "slot": "156",
+ "type": "t_mapping(t_uint256,t_struct(App)4671_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:85"
+ },
+ {
+ "label": "_accessPoints",
+ "offset": 0,
+ "slot": "157",
+ "type": "t_mapping(t_string_memory_ptr,t_struct(AccessPoint)4689_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:86"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_string_storage)dyn_storage": {
+ "label": "string[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)44_storage": {
+ "label": "uint256[44]",
+ "numberOfBytes": "1408"
+ },
+ "t_array(t_uint256)50_storage": {
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_enum(Roles)3895": {
+ "label": "enum FleekAccessControl.Roles",
+ "members": ["Owner", "Controller"],
+ "numberOfBytes": "1"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_mapping(t_address,t_bool))": {
+ "label": "mapping(address => mapping(address => bool))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)": {
+ "label": "mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_string_memory_ptr,t_struct(AccessPoint)4689_storage)": {
+ "label": "mapping(string => struct FleekERC721.AccessPoint)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_address)": {
+ "label": "mapping(uint256 => address)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))": {
+ "label": "mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))": {
+ "label": "mapping(uint256 => mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(App)4671_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.App)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Build)4676_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.Build)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Counter)2774_storage)": {
+ "label": "mapping(uint256 => struct Counters.Counter)",
+ "numberOfBytes": "32"
+ },
+ "t_string_memory_ptr": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_string_storage": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(AccessPoint)4689_storage": {
+ "label": "struct FleekERC721.AccessPoint",
+ "members": [
+ {
+ "label": "tokenId",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "index",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "score",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "contentVerified",
+ "type": "t_bool",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "nameVerified",
+ "type": "t_bool",
+ "offset": 1,
+ "slot": "3"
+ },
+ {
+ "label": "owner",
+ "type": "t_address",
+ "offset": 2,
+ "slot": "3"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_struct(App)4671_storage": {
+ "label": "struct FleekERC721.App",
+ "members": [
+ {
+ "label": "name",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "description",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "externalURL",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "ENS",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "currentBuild",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "4"
+ },
+ {
+ "label": "builds",
+ "type": "t_mapping(t_uint256,t_struct(Build)4676_storage)",
+ "offset": 0,
+ "slot": "5"
+ },
+ {
+ "label": "accessPoints",
+ "type": "t_array(t_string_storage)dyn_storage",
+ "offset": 0,
+ "slot": "6"
+ },
+ {
+ "label": "logo",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "7"
+ },
+ {
+ "label": "color",
+ "type": "t_uint24",
+ "offset": 0,
+ "slot": "8"
+ }
+ ],
+ "numberOfBytes": "288"
+ },
+ "t_struct(Build)4676_storage": {
+ "label": "struct FleekERC721.Build",
+ "members": [
+ {
+ "label": "commitHash",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "gitRepository",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_struct(Counter)2774_storage": {
+ "label": "struct Counters.Counter",
+ "members": [
+ {
+ "label": "_value",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_struct(Role)3943_storage": {
+ "label": "struct FleekAccessControl.Role",
+ "members": [
+ {
+ "label": "indexes",
+ "type": "t_mapping(t_address,t_uint256)",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "members",
+ "type": "t_array(t_address)dyn_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_uint24": {
+ "label": "uint24",
+ "numberOfBytes": "3"
+ },
+ "t_uint256": {
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "t_uint8": {
+ "label": "uint8",
+ "numberOfBytes": "1"
+ }
+ }
+ }
+ },
+ "2d9565583ce919a9deaff8380ba2cdd802ff2fcf64c6be9eeb15ba51f5429c9e": {
+ "address": "0x7e6314e553BD57B6Ed7275073c159860d41F1d16",
+ "txHash": "0xc7252872770c790e2b5e7782a490e84d80be3c98f7d15ccad2b50722fa80185e",
+ "layout": {
+ "solcVersion": "0.8.12",
+ "storage": [
+ {
+ "label": "_initialized",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint8",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62",
+ "retypedFrom": "bool"
+ },
+ {
+ "label": "_initializing",
+ "offset": 1,
+ "slot": "0",
+ "type": "t_bool",
+ "contract": "Initializable",
+ "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ContextUpgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "51",
+ "type": "t_array(t_uint256)50_storage",
+ "contract": "ERC165Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol:41"
+ },
+ {
+ "label": "_name",
+ "offset": 0,
+ "slot": "101",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:25"
+ },
+ {
+ "label": "_symbol",
+ "offset": 0,
+ "slot": "102",
+ "type": "t_string_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:28"
+ },
+ {
+ "label": "_owners",
+ "offset": 0,
+ "slot": "103",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:31"
+ },
+ {
+ "label": "_balances",
+ "offset": 0,
+ "slot": "104",
+ "type": "t_mapping(t_address,t_uint256)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:34"
+ },
+ {
+ "label": "_tokenApprovals",
+ "offset": 0,
+ "slot": "105",
+ "type": "t_mapping(t_uint256,t_address)",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:37"
+ },
+ {
+ "label": "_operatorApprovals",
+ "offset": 0,
+ "slot": "106",
+ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:40"
+ },
+ {
+ "label": "__gap",
+ "offset": 0,
+ "slot": "107",
+ "type": "t_array(t_uint256)44_storage",
+ "contract": "ERC721Upgradeable",
+ "src": "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol:514"
+ },
+ {
+ "label": "_collectionRolesVersion",
+ "offset": 0,
+ "slot": "151",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:26"
+ },
+ {
+ "label": "_collectionRoles",
+ "offset": 0,
+ "slot": "152",
+ "type": "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:28"
+ },
+ {
+ "label": "_tokenRolesVersion",
+ "offset": 0,
+ "slot": "153",
+ "type": "t_mapping(t_uint256,t_struct(Counter)2774_storage)",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:30"
+ },
+ {
+ "label": "_tokenRoles",
+ "offset": 0,
+ "slot": "154",
+ "type": "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))",
+ "contract": "FleekAccessControl",
+ "src": "contracts/FleekAccessControl.sol:32"
+ },
+ {
+ "label": "_appIds",
+ "offset": 0,
+ "slot": "155",
+ "type": "t_struct(Counter)2774_storage",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:84"
+ },
+ {
+ "label": "_apps",
+ "offset": 0,
+ "slot": "156",
+ "type": "t_mapping(t_uint256,t_struct(App)4671_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:85"
+ },
+ {
+ "label": "_accessPoints",
+ "offset": 0,
+ "slot": "157",
+ "type": "t_mapping(t_string_memory_ptr,t_struct(AccessPoint)4689_storage)",
+ "contract": "FleekERC721",
+ "src": "contracts/FleekERC721.sol:86"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_array(t_address)dyn_storage": {
+ "label": "address[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_string_storage)dyn_storage": {
+ "label": "string[]",
+ "numberOfBytes": "32"
+ },
+ "t_array(t_uint256)44_storage": {
+ "label": "uint256[44]",
+ "numberOfBytes": "1408"
+ },
+ "t_array(t_uint256)50_storage": {
+ "label": "uint256[50]",
+ "numberOfBytes": "1600"
+ },
+ "t_bool": {
+ "label": "bool",
+ "numberOfBytes": "1"
+ },
+ "t_enum(Roles)3895": {
+ "label": "enum FleekAccessControl.Roles",
+ "members": ["Owner", "Controller"],
+ "numberOfBytes": "1"
+ },
+ "t_mapping(t_address,t_bool)": {
+ "label": "mapping(address => bool)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_mapping(t_address,t_bool))": {
+ "label": "mapping(address => mapping(address => bool))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)": {
+ "label": "mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_string_memory_ptr,t_struct(AccessPoint)4689_storage)": {
+ "label": "mapping(string => struct FleekERC721.AccessPoint)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_address)": {
+ "label": "mapping(uint256 => address)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))": {
+ "label": "mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))": {
+ "label": "mapping(uint256 => mapping(uint256 => mapping(enum FleekAccessControl.Roles => struct FleekAccessControl.Role)))",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(App)4671_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.App)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Build)4676_storage)": {
+ "label": "mapping(uint256 => struct FleekERC721.Build)",
+ "numberOfBytes": "32"
+ },
+ "t_mapping(t_uint256,t_struct(Counter)2774_storage)": {
+ "label": "mapping(uint256 => struct Counters.Counter)",
+ "numberOfBytes": "32"
+ },
+ "t_string_memory_ptr": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_string_storage": {
+ "label": "string",
+ "numberOfBytes": "32"
+ },
+ "t_struct(AccessPoint)4689_storage": {
+ "label": "struct FleekERC721.AccessPoint",
+ "members": [
+ {
+ "label": "tokenId",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "index",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "score",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "contentVerified",
+ "type": "t_bool",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "nameVerified",
+ "type": "t_bool",
+ "offset": 1,
+ "slot": "3"
+ },
+ {
+ "label": "owner",
+ "type": "t_address",
+ "offset": 2,
+ "slot": "3"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_struct(App)4671_storage": {
+ "label": "struct FleekERC721.App",
+ "members": [
+ {
+ "label": "name",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "description",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ },
+ {
+ "label": "externalURL",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "2"
+ },
+ {
+ "label": "ENS",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "3"
+ },
+ {
+ "label": "currentBuild",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "4"
+ },
+ {
+ "label": "builds",
+ "type": "t_mapping(t_uint256,t_struct(Build)4676_storage)",
+ "offset": 0,
+ "slot": "5"
+ },
+ {
+ "label": "accessPoints",
+ "type": "t_array(t_string_storage)dyn_storage",
+ "offset": 0,
+ "slot": "6"
+ },
+ {
+ "label": "logo",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "7"
+ },
+ {
+ "label": "color",
+ "type": "t_uint24",
+ "offset": 0,
+ "slot": "8"
+ }
+ ],
+ "numberOfBytes": "288"
+ },
+ "t_struct(Build)4676_storage": {
+ "label": "struct FleekERC721.Build",
+ "members": [
+ {
+ "label": "commitHash",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "gitRepository",
+ "type": "t_string_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_struct(Counter)2774_storage": {
+ "label": "struct Counters.Counter",
+ "members": [
+ {
+ "label": "_value",
+ "type": "t_uint256",
+ "offset": 0,
+ "slot": "0"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_struct(Role)3943_storage": {
+ "label": "struct FleekAccessControl.Role",
+ "members": [
+ {
+ "label": "indexes",
+ "type": "t_mapping(t_address,t_uint256)",
+ "offset": 0,
+ "slot": "0"
+ },
+ {
+ "label": "members",
+ "type": "t_array(t_address)dyn_storage",
+ "offset": 0,
+ "slot": "1"
+ }
+ ],
+ "numberOfBytes": "64"
+ },
+ "t_uint24": {
+ "label": "uint24",
+ "numberOfBytes": "3"
+ },
+ "t_uint256": {
+ "label": "uint256",
+ "numberOfBytes": "32"
+ },
+ "t_uint8": {
+ "label": "uint8",
+ "numberOfBytes": "1"
+ }
+ }
+ }
}
}
}
diff --git a/assets/aave.svg b/assets/aave.svg
new file mode 100644
index 0000000..35f606e
--- /dev/null
+++ b/assets/aave.svg
@@ -0,0 +1,28 @@
+
+
+
\ No newline at end of file
diff --git a/assets/dydx.svg b/assets/dydx.svg
new file mode 100644
index 0000000..bfe1e10
--- /dev/null
+++ b/assets/dydx.svg
@@ -0,0 +1,23 @@
+
diff --git a/assets/fleek.svg b/assets/fleek.svg
new file mode 100644
index 0000000..598a174
--- /dev/null
+++ b/assets/fleek.svg
@@ -0,0 +1,64 @@
+
\ No newline at end of file
diff --git a/assets/html.svg b/assets/html.svg
new file mode 100644
index 0000000..c62fabb
--- /dev/null
+++ b/assets/html.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/model.svg b/assets/model.svg
new file mode 100644
index 0000000..d20e368
--- /dev/null
+++ b/assets/model.svg
@@ -0,0 +1,107 @@
+
\ No newline at end of file
diff --git a/assets/pancakeswap.svg b/assets/pancakeswap.svg
new file mode 100644
index 0000000..f4ab1ca
--- /dev/null
+++ b/assets/pancakeswap.svg
@@ -0,0 +1,14 @@
+
\ No newline at end of file
diff --git a/assets/psych.svg b/assets/psych.svg
new file mode 100644
index 0000000..fb1a48e
--- /dev/null
+++ b/assets/psych.svg
@@ -0,0 +1,619 @@
+
diff --git a/assets/uniswap.svg b/assets/uniswap.svg
new file mode 100644
index 0000000..68cfd75
--- /dev/null
+++ b/assets/uniswap.svg
@@ -0,0 +1,48 @@
+
+
+
\ No newline at end of file
diff --git a/assets/yearn.svg b/assets/yearn.svg
new file mode 100644
index 0000000..ae79fc3
--- /dev/null
+++ b/assets/yearn.svg
@@ -0,0 +1,23 @@
+
+
+
\ No newline at end of file
diff --git a/contracts/FleekERC721.sol b/contracts/FleekERC721.sol
index 20f81a1..ea0cce0 100644
--- a/contracts/FleekERC721.sol
+++ b/contracts/FleekERC721.sol
@@ -19,9 +19,10 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl {
event NewBuild(uint256 indexed token, string indexed commitHash, address indexed triggeredBy);
event NewTokenName(uint256 indexed token, string indexed name, address indexed triggeredBy);
event NewTokenDescription(uint256 indexed token, string indexed description, address indexed triggeredBy);
- event NewTokenImage(uint256 indexed token, string indexed image, address indexed triggeredBy);
+ event NewTokenLogo(uint256 indexed token, string indexed image, address indexed triggeredBy);
event NewTokenExternalURL(uint256 indexed token, string indexed externalURL, address indexed triggeredBy);
event NewTokenENS(uint256 indexed token, string indexed ENS, address indexed triggeredBy);
+ event NewTokenColor(uint256 indexed token, uint24 indexed color, address indexed triggeredBy);
event NewAccessPoint(string indexed apName, uint256 indexed tokenId, address indexed owner);
event RemoveAccessPoint(string indexed apName, uint256 indexed tokenId, address indexed owner);
@@ -57,6 +58,8 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl {
uint256 currentBuild; // The current build number (Increments by one with each change, starts at zero)
mapping(uint256 => Build) builds; // Mapping to build details for each build number
string[] accessPoints; // List of app AccessPoint
+ string logo;
+ uint24 color; // Color of the nft
}
/**
@@ -116,7 +119,9 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl {
string memory externalURL,
string memory ENS,
string memory commitHash,
- string memory gitRepository
+ string memory gitRepository,
+ string memory logo,
+ uint24 color
) public payable requireCollectionRole(Roles.Owner) returns (uint256) {
uint256 tokenId = _appIds.current();
_mint(to, tokenId);
@@ -127,6 +132,8 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl {
app.description = description;
app.externalURL = externalURL;
app.ENS = ENS;
+ app.logo = logo;
+ app.color = color;
// The mint interaction is considered to be the first build of the site. Updates from now on all increment the currentBuild by one and update the mapping.
app.currentBuild = 0;
@@ -271,6 +278,62 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl {
emit NewTokenDescription(tokenId, _tokenDescription, msg.sender);
}
+ /**
+ * @dev Updates the `logo` metadata field of a minted `tokenId`.
+ *
+ * May emit a {NewTokenLogo} event.
+ *
+ * Requirements:
+ *
+ * - the tokenId must be minted and valid.
+ * - the sender must have the `tokenController` role.
+ *
+ */
+ function setTokenLogo(
+ uint256 tokenId,
+ string memory _tokenLogo
+ ) public virtual requireTokenRole(tokenId, Roles.Controller) {
+ _requireMinted(tokenId);
+ _apps[tokenId].logo = _tokenLogo;
+ emit NewTokenLogo(tokenId, _tokenLogo, msg.sender);
+ }
+
+ /**
+ * @dev Updates the `color` metadata field of a minted `tokenId`.
+ *
+ * May emit a {NewTokenColor} event.
+ *
+ * Requirements:
+ *
+ * - the tokenId must be minted and valid.
+ * - the sender must have the `tokenController` role.
+ *
+ */
+ function setTokenColor(
+ uint256 tokenId,
+ uint24 _tokenColor
+ ) public virtual requireTokenRole(tokenId, Roles.Controller) {
+ _requireMinted(tokenId);
+ _apps[tokenId].color = _tokenColor;
+ emit NewTokenColor(tokenId, _tokenColor, msg.sender);
+ }
+
+ /**
+ * @dev Updates the `logo` and `color` metadata fields of a minted `tokenId`.
+ *
+ * May emit a {NewTokenLogo} and a {NewTokenColor} event.
+ *
+ * Requirements:
+ *
+ * - the tokenId must be minted and valid.
+ * - the sender must have the `tokenController` role.
+ *
+ */
+ function setTokenLogoAndColor(uint256 tokenId, string memory _tokenLogo, uint24 _tokenColor) public virtual {
+ setTokenLogo(tokenId, _tokenLogo);
+ setTokenColor(tokenId, _tokenColor);
+ }
+
/**
* @dev Add a new AccessPoint register for an app token.
* The AP name should be a DNS or ENS url and it should be unique.
diff --git a/contracts/util/FleekSVG.sol b/contracts/util/FleekSVG.sol
index 9cac338..b0c1d08 100644
--- a/contracts/util/FleekSVG.sol
+++ b/contracts/util/FleekSVG.sol
@@ -10,29 +10,69 @@ library FleekSVG {
/**
* @dev Generates a SVG image.
*/
- function generateBase64(string memory name, string memory ENS) internal pure returns (string memory) {
+ function generateBase64(
+ string memory name,
+ string memory ENS,
+ string memory logo,
+ string memory color
+ ) public pure returns (string memory) {
return (
string(
abi.encodePacked(
- "data:application/json;base64,",
+ "data:image/svg+xml;base64,",
Base64.encode(
abi.encodePacked(
- '"
)
)
diff --git a/contracts/util/FleekStrings.sol b/contracts/util/FleekStrings.sol
index b34bba5..1e5b909 100644
--- a/contracts/util/FleekStrings.sol
+++ b/contracts/util/FleekStrings.sol
@@ -11,6 +11,8 @@ library FleekStrings {
using Strings for uint256;
using Strings for uint160;
using FleekStrings for bool;
+ using FleekStrings for uint24;
+ using Strings for uint24;
/**
* @dev Converts a boolean value to a string.
@@ -38,12 +40,13 @@ library FleekStrings {
'"description":"', app.description, '",',
'"owner":"', uint160(owner).toHexString(20), '",',
'"external_url":"', app.externalURL, '",',
- '"image":"', FleekSVG.generateBase64(app.name, app.ENS), '",',
+ '"image":"', FleekSVG.generateBase64(app.name, app.ENS, app.logo, app.color.toColorString()), '",',
'"attributes": [',
'{"trait_type": "ENS", "value":"', app.ENS,'"},',
'{"trait_type": "Commit Hash", "value":"', app.builds[app.currentBuild].commitHash,'"},',
'{"trait_type": "Repository", "value":"', app.builds[app.currentBuild].gitRepository,'"},',
- '{"trait_type": "Version", "value":"', app.currentBuild.toString(),'"}',
+ '{"trait_type": "Version", "value":"', app.currentBuild.toString(),'"},',
+ '{"trait_type": "Color", "value":"', app.color.toColorString(),'"}',
']',
'}'
));
@@ -64,4 +67,17 @@ library FleekStrings {
"}"
));
}
+
+ /**
+ * @dev Converts bytes3 to a hex color string.
+ */
+ function toColorString(uint24 color) internal pure returns (string memory) {
+ bytes memory hexBytes = bytes(color.toHexString(3));
+ bytes memory hexColor = new bytes(7);
+ hexColor[0] = "#";
+ for (uint256 i = 1; i < 7; i++) {
+ hexColor[i] = hexBytes[i + 1];
+ }
+ return string(hexColor);
+ }
}
diff --git a/deployments/mumbai/FleekERC721.json b/deployments/mumbai/FleekERC721.json
index fdb727c..488735b 100644
--- a/deployments/mumbai/FleekERC721.json
+++ b/deployments/mumbai/FleekERC721.json
@@ -1,8 +1,8 @@
{
- "timestamp": "1/17/2023, 12:39:20 PM",
- "address": "0x21d7fBe220958A0F0f7cAE58780fe812EbcB3cd8",
- "transactionHash": "0x715976ee8931f6e220c1e8d03c4aea779e3393def1342c2ff99867fe47125961",
- "gasPrice": 1500000016,
+ "timestamp": "1/23/2023, 11:32:21 AM",
+ "address": "0x8679f8A4Fb3AaA1E851100D2C0444a729a3D946C",
+ "transactionHash": "0x04b40f658429aecbd674f98c0928396624f04ea95e8b7264580a089908332dd5",
+ "gasPrice": 2281682515,
"abi": [
{
"anonymous": false,
@@ -54,6 +54,99 @@
"name": "ApprovalForAll",
"type": "event"
},
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "string",
+ "name": "apName",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ },
+ {
+ "indexed": true,
+ "internalType": "bool",
+ "name": "verified",
+ "type": "bool"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "triggeredBy",
+ "type": "address"
+ }
+ ],
+ "name": "ChangeAccessPointContentVerify",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "string",
+ "name": "apName",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ },
+ {
+ "indexed": true,
+ "internalType": "bool",
+ "name": "verified",
+ "type": "bool"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "triggeredBy",
+ "type": "address"
+ }
+ ],
+ "name": "ChangeAccessPointNameVerify",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "string",
+ "name": "apName",
+ "type": "string"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "score",
+ "type": "uint256"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "triggeredBy",
+ "type": "address"
+ }
+ ],
+ "name": "ChangeAccessPointScore",
+ "type": "event"
+ },
{
"anonymous": false,
"inputs": [
@@ -117,6 +210,31 @@
"name": "Initialized",
"type": "event"
},
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "string",
+ "name": "apName",
+ "type": "string"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "NewAccessPoint",
+ "type": "event"
+ },
{
"anonymous": false,
"inputs": [
@@ -267,6 +385,31 @@
"name": "NewTokenName",
"type": "event"
},
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "string",
+ "name": "apName",
+ "type": "string"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "RemoveAccessPoint",
+ "type": "event"
+ },
{
"anonymous": false,
"inputs": [
@@ -354,6 +497,43 @@
"name": "Transfer",
"type": "event"
},
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "apName",
+ "type": "string"
+ }
+ ],
+ "name": "addAccessPoint",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "tokenId",
+ "type": "uint256"
+ }
+ ],
+ "name": "appAccessPoints",
+ "outputs": [
+ {
+ "internalType": "string[]",
+ "name": "",
+ "type": "string[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
{
"inputs": [
{
@@ -404,6 +584,38 @@
"stateMutability": "nonpayable",
"type": "function"
},
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "apName",
+ "type": "string"
+ }
+ ],
+ "name": "decreaseAccessPointScore",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "apName",
+ "type": "string"
+ }
+ ],
+ "name": "getAccessPointJSON",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
{
"inputs": [
{
@@ -560,6 +772,19 @@
"stateMutability": "view",
"type": "function"
},
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "apName",
+ "type": "string"
+ }
+ ],
+ "name": "increaseAccessPointScore",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
{
"inputs": [
{
@@ -578,6 +803,25 @@
"stateMutability": "nonpayable",
"type": "function"
},
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "apName",
+ "type": "string"
+ }
+ ],
+ "name": "isAccessPointNameVerified",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
{
"inputs": [
{
@@ -638,6 +882,16 @@
"internalType": "string",
"name": "gitRepository",
"type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "logo",
+ "type": "string"
+ },
+ {
+ "internalType": "uint24",
+ "name": "color",
+ "type": "uint24"
}
],
"name": "mint",
@@ -683,6 +937,19 @@
"stateMutability": "view",
"type": "function"
},
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "apName",
+ "type": "string"
+ }
+ ],
+ "name": "removeAccessPoint",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
{
"inputs": [
{
@@ -775,6 +1042,42 @@
"stateMutability": "nonpayable",
"type": "function"
},
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "apName",
+ "type": "string"
+ },
+ {
+ "internalType": "bool",
+ "name": "verified",
+ "type": "bool"
+ }
+ ],
+ "name": "setAccessPointContentVerify",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "apName",
+ "type": "string"
+ },
+ {
+ "internalType": "bool",
+ "name": "verified",
+ "type": "bool"
+ }
+ ],
+ "name": "setAccessPointNameVerify",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
{
"inputs": [
{
@@ -963,8 +1266,8 @@
"type": "function"
}
],
- "bytecode": "0x608060405234801561001057600080fd5b506141ea806100206000396000f3fe6080604052600436106101c25760003560e01c80636352211e116100f7578063aba8112511610095578063cdb0e89e11610064578063cdb0e89e14610510578063e944725014610530578063e985e9c514610550578063f93151771461059957600080fd5b8063aba811251461049d578063b42dbe38146104b0578063b88d4fde146104d0578063c87b56dd146104f057600080fd5b80638c3c0a44116100d15780638c3c0a441461042857806395d89b4114610448578063a22cb4651461045d578063a27d0b271461047d57600080fd5b80636352211e146103bb57806370a08231146103db57806378278cca1461040857600080fd5b80632d957aad116101645780633806f1521161013e5780633806f1521461033b57806342842e0e1461035b57806342966c681461037b5780634cd88b761461039b57600080fd5b80632d957aad146102ce5780632f1e8f0a146102ee578063353b07a41461031b57600080fd5b8063081812fc116101a0578063081812fc14610241578063095ea7b31461026e57806323b872dd1461028e578063246a908b146102ae57600080fd5b806301468deb146101c757806301ffc9a7146101e957806306fdde031461021f575b600080fd5b3480156101d357600080fd5b506101e76101e2366004612aa9565b6105b9565b005b3480156101f557600080fd5b5061020961020436600461296a565b610610565b6040516102169190613de4565b60405180910390f35b34801561022b57600080fd5b50610234610621565b6040516102169190613e00565b34801561024d57600080fd5b5061026161025c366004612a55565b6106b3565b6040516102169190613d81565b34801561027a57600080fd5b506101e7610289366004612937565b6106da565b34801561029a57600080fd5b506101e76102a93660046126fb565b610760565b3480156102ba57600080fd5b506101e76102c9366004612aef565b610791565b3480156102da57600080fd5b506101e76102e93660046129cd565b610844565b3480156102fa57600080fd5b5061030e610309366004612a76565b610887565b6040516102169190613dd3565b34801561032757600080fd5b5061030e6103363660046129ac565b610941565b34801561034757600080fd5b506101e7610356366004612b11565b6109f4565b34801561036757600080fd5b506101e76103763660046126fb565b610b03565b34801561038757600080fd5b506101e7610396366004612a55565b610b1e565b3480156103a757600080fd5b506101e76103b63660046129ef565b610bd8565b3480156103c757600080fd5b506102616103d6366004612a55565b610cb2565b3480156103e757600080fd5b506103fb6103f636600461269d565b610ce7565b6040516102169190613f11565b34801561041457600080fd5b506101e7610423366004612aef565b610d2b565b34801561043457600080fd5b506101e76104433660046129cd565b610dde565b34801561045457600080fd5b50610234610e21565b34801561046957600080fd5b506101e76104783660046127c9565b610e30565b34801561048957600080fd5b506101e7610498366004612aa9565b610e3f565b6103fb6104ab3660046127fc565b610e86565b3480156104bc57600080fd5b506102096104cb366004612aa9565b610fb5565b3480156104dc57600080fd5b506101e76104eb36600461274b565b61102d565b3480156104fc57600080fd5b5061023461050b366004612a55565b611065565b34801561051c57600080fd5b506101e761052b366004612aef565b61127d565b34801561053c57600080fd5b5061020961054b3660046129cd565b61132a565b34801561055c57600080fd5b5061020961056b3660046126be565b6001600160a01b039182166000908152606a6020908152604080832093909416825291909152205460ff1690565b3480156105a557600080fd5b506101e76105b4366004612aef565b61139c565b8260006105c7828233610fb5565b806105d957506105d982600033610fb5565b6105fe5760405162461bcd60e51b81526004016105f590613f01565b60405180910390fd5b61060985858561144f565b5050505050565b600061061b82611508565b92915050565b60606065805461063090614032565b80601f016020809104026020016040519081016040528092919081815260200182805461065c90614032565b80156106a95780601f1061067e576101008083540402835291602001916106a9565b820191906000526020600020905b81548152906001019060200180831161068c57829003601f168201915b5050505050905090565b60006106be82611558565b506000908152606960205260409020546001600160a01b031690565b60006106e582610cb2565b9050806001600160a01b0316836001600160a01b031614156107195760405162461bcd60e51b81526004016105f590613ed1565b336001600160a01b03821614806107355750610735813361056b565b6107515760405162461bcd60e51b81526004016105f590613ee1565b61075b838361158f565b505050565b61076a33826115fd565b6107865760405162461bcd60e51b81526004016105f590613e21565b61075b83838361167c565b81600161079f828233610fb5565b806107b157506107b182600033610fb5565b6107cd5760405162461bcd60e51b81526004016105f590613f01565b6107d684611558565b6000848152609c6020908152604090912084516107fb9260019092019186019061252f565b50604051339061080c908590613282565b6040519081900381209086907fd771eaa1c1382b0a9867125fcd921fdeddd211538b5381353a877abfbe3b50a490600090a450505050565b6000610850813361132a565b80610861575061086160003361132a565b61087d5760405162461bcd60e51b81526004016105f590613e61565b61075b83836117b1565b600082815260996020908152604080832054609a835281842081855290925282206060928460018111156108bd576108bd6140c7565b60018111156108ce576108ce6140c7565b815260200190815260200160002060010180548060200260200160405190810160405280929190818152602001828054801561093357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610915575b505050505091505092915050565b6060600061094e60975490565b6000818152609860205260408120919250846001811115610971576109716140c7565b6001811115610982576109826140c7565b81526020019081526020016000206001018054806020026020016040519081016040528092919081815260200182805480156109e757602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116109c9575b5050505050915050919050565b826001610a02828233610fb5565b80610a145750610a1482600033610fb5565b610a305760405162461bcd60e51b81526004016105f590613f01565b610a3985611558565b60408051808201825285815260208082018690526000888152609c90915291822060048101805492936005909201928290610a739061408b565b91829055508152602080820192909252604001600020825180519192610a9e9284929091019061252f565b506020828101518051610ab7926001850192019061252f565b5050604051339150610aca908690613282565b6040519081900381209087907f73b929bf4db6be678cdbc6d41a5fe0a2cbb84ca95572062c4a978d8bd80a41b190600090a45050505050565b61075b8383836040518060200160405280600081525061102d565b806000610b2c828233610fb5565b80610b3e5750610b3e82600033610fb5565b610b5a5760405162461bcd60e51b81526004016105f590613f01565b610b6383611861565b6000838152609c602052604090206002018054610b7f90614032565b15905061075b576000838152609c6020526040812090610b9f82826125b3565b610bad6001830160006125b3565b610bbb6002830160006125b3565b610bc96003830160006125b3565b60048201600090555050505050565b600054610100900460ff1615808015610bf85750600054600160ff909116105b80610c125750303b158015610c12575060005460ff166001145b610c2e5760405162461bcd60e51b81526004016105f590613ea1565b6000805460ff191660011790558015610c51576000805461ff0019166101001790555b610c5b8383611904565b610c63611935565b801561075b576000805461ff00191690556040517f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890610ca590600190613df2565b60405180910390a1505050565b6000818152606760205260408120546001600160a01b03168061061b5760405162461bcd60e51b81526004016105f590613ec1565b60006001600160a01b038216610d0f5760405162461bcd60e51b81526004016105f590613e91565b506001600160a01b031660009081526068602052604090205490565b816001610d39828233610fb5565b80610d4b5750610d4b82600033610fb5565b610d675760405162461bcd60e51b81526004016105f590613f01565b610d7084611558565b6000848152609c602090815260409091208451610d959260039092019186019061252f565b506040513390610da6908590613282565b6040519081900381209086907f91ce7fcd4462481791c3fe849f7049373c5b43ef44aed48e7f1ecce781586e1590600090a450505050565b6000610dea813361132a565b80610dfb5750610dfb60003361132a565b610e175760405162461bcd60e51b81526004016105f590613e61565b61075b8383611969565b60606066805461063090614032565b610e3b3383836119e7565b5050565b826000610e4d828233610fb5565b80610e5f5750610e5f82600033610fb5565b610e7b5760405162461bcd60e51b81526004016105f590613f01565b610609858585611a7d565b600080610e93813361132a565b80610ea45750610ea460003361132a565b610ec05760405162461bcd60e51b81526004016105f590613e61565b6000610ecb609b5490565b9050610ed78a82611b03565b610ee5609b80546001019055565b6000818152609c602090815260409091208a519091610f089183918d019061252f565b508851610f1e90600183019060208c019061252f565b508751610f3490600283019060208b019061252f565b508651610f4a90600383019060208a019061252f565b50600060048201819055604080518082018252888152602080820189905283805260058501815291909220825180519192610f8a9284929091019061252f565b506020828101518051610fa3926001850192019061252f565b50929c9b505050505050505050505050565b600083815260996020908152604080832054609a8352818420818552909252822082856001811115610fe957610fe96140c7565b6001811115610ffa57610ffa6140c7565b8152602080820192909252604090810160009081206001600160a01b038716825290925290205415159150509392505050565b61103733836115fd565b6110535760405162461bcd60e51b81526004016105f590613e21565b61105f84848484611c0c565b50505050565b606061107082611558565b600061107b83610cb2565b6000848152609c6020526040812091925081600181016110a56001600160a01b0386166014611c3f565b846002016111cb8660000180546110bb90614032565b80601f01602080910402602001604051908101604052809291908181526020018280546110e790614032565b80156111345780601f1061110957610100808354040283529160200191611134565b820191906000526020600020905b81548152906001019060200180831161111757829003601f168201915b505050505087600301805461114890614032565b80601f016020809104026020016040519081016040528092919081815260200182805461117490614032565b80156111c15780601f10611196576101008083540402835291602001916111c1565b820191906000526020600020905b8154815290600101906020018083116111a457829003601f168201915b5050505050611db1565b600487015460008181526005890160205260409020600389019160018201906111f390611e3f565b60405160200161120b99989796959493929190613b66565b60408051601f19818403018152828201909152601d82527f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000006020830152915061125382611edb565b60405160200161126492919061328e565b6040516020818303038152906040529350505050919050565b81600161128b828233610fb5565b8061129d575061129d82600033610fb5565b6112b95760405162461bcd60e51b81526004016105f590613f01565b6112c284611558565b6000848152609c6020908152604090912084516112e19286019061252f565b5060405133906112f2908590613282565b6040519081900381209086907ffbbfca16a2770c7ca6e7063ab1a7eea5fe441ffef818325db51752066a6b128a90600090a450505050565b60008061133660975490565b6000818152609860205260408120919250856001811115611359576113596140c7565b600181111561136a5761136a6140c7565b8152602080820192909252604090810160009081206001600160a01b0387168252909252902054151591505092915050565b8160016113aa828233610fb5565b806113bc57506113bc82600033610fb5565b6113d85760405162461bcd60e51b81526004016105f590613f01565b6113e184611558565b6000848152609c6020908152604090912084516114069260029092019186019061252f565b506040513390611417908590613282565b6040519081900381209086907fedbf1209b3baa7c1b5c43052ce5c511e243b3241d9f67733141d14f1da88cba190600090a450505050565b600083815260996020908152604080832054609a8352818420818552909252822090916114ae9190856001811115611489576114896140c7565b600181111561149a5761149a6140c7565b81526020019081526020016000208361202e565b816001600160a01b03168360018111156114ca576114ca6140c7565b857fe52d746e4c78c98c6bfa291b273406905c3e8550b7d911a6bea686368c2dc79d336040516114fa9190613d81565b60405180910390a450505050565b60006001600160e01b031982166380ac58cd60e01b148061153957506001600160e01b03198216635b5e139f60e01b145b8061061b57506301ffc9a760e01b6001600160e01b031983161461061b565b6000818152606760205260409020546001600160a01b031661158c5760405162461bcd60e51b81526004016105f590613ec1565b50565b600081815260696020526040902080546001600160a01b0319166001600160a01b03841690811790915581906115c482610cb2565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061160983610cb2565b9050806001600160a01b0316846001600160a01b0316148061165057506001600160a01b038082166000908152606a602090815260408083209388168352929052205460ff165b806116745750836001600160a01b0316611669846106b3565b6001600160a01b0316145b949350505050565b826001600160a01b031661168f82610cb2565b6001600160a01b0316146116b55760405162461bcd60e51b81526004016105f590613e41565b6001600160a01b0382166116db5760405162461bcd60e51b81526004016105f590613e71565b6116e88383836001612172565b826001600160a01b03166116fb82610cb2565b6001600160a01b0316146117215760405162461bcd60e51b81526004016105f590613e41565b600081815260696020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260688552838620805460001901905590871680865283862080546001019055868652606790945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60006117bc60975490565b600081815260986020526040812091925061180991908560018111156117e4576117e46140c7565b60018111156117f5576117f56140c7565b8152602001908152602001600020836121f0565b816001600160a01b0316836001811115611825576118256140c7565b7fcf081ed2b728e3115904be00eb8927b2375ff3401839b37f7accfa1bb2bee15c336040516118549190613d81565b60405180910390a3505050565b600061186c82610cb2565b905061187c816000846001612172565b61188582610cb2565b600083815260696020908152604080832080546001600160a01b03199081169091556001600160a01b0385168085526068845282852080546000190190558785526067909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b600054610100900460ff1661192b5760405162461bcd60e51b81526004016105f590613ef1565b610e3b8282612253565b600054610100900460ff1661195c5760405162461bcd60e51b81526004016105f590613ef1565b6119676000336117b1565b565b600061197460975490565b600081815260986020526040812091925061199c9190856001811115611489576114896140c7565b816001600160a01b03168360018111156119b8576119b86140c7565b7faeff57f0f5e4d3d10a37d4a70fde8ed67a95e67b251d5c512c0ea98c380d2f95336040516118549190613d81565b816001600160a01b0316836001600160a01b03161415611a195760405162461bcd60e51b81526004016105f590613e81565b6001600160a01b038381166000818152606a602090815260408083209487168084529490915290819020805460ff1916851515179055517f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3190611854908590613de4565b600083815260996020908152604080832054609a835281842081855290925282209091611ab791908560018111156117e4576117e46140c7565b816001600160a01b0316836001811115611ad357611ad36140c7565b857f0bf5a13b362503fcc74b8b9b1598aba2f3a9af85d05ba7978f7e9f447f22c239336040516114fa9190613d81565b6001600160a01b038216611b295760405162461bcd60e51b81526004016105f590613eb1565b6000818152606760205260409020546001600160a01b031615611b5e5760405162461bcd60e51b81526004016105f590613e51565b611b6c600083836001612172565b6000818152606760205260409020546001600160a01b031615611ba15760405162461bcd60e51b81526004016105f590613e51565b6001600160a01b038216600081815260686020908152604080832080546001019055848352606790915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b611c1784848461167c565b611c23848484846122a1565b61105f5760405162461bcd60e51b81526004016105f590613e31565b60606000611c4e836002613f91565b611c59906002613f65565b6001600160401b03811115611c7057611c7061411f565b6040519080825280601f01601f191660200182016040528015611c9a576020820181803683370190505b509050600360fc1b81600081518110611cb557611cb5614109565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110611ce457611ce4614109565b60200101906001600160f81b031916908160001a9053506000611d08846002613f91565b611d13906001613f65565b90505b6001811115611d8b576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110611d4757611d47614109565b1a60f81b828281518110611d5d57611d5d614109565b60200101906001600160f81b031916908160001a90535060049490941c93611d848161401b565b9050611d16565b508315611daa5760405162461bcd60e51b81526004016105f590613e11565b9392505050565b6060611ded60408051808201909152601d81527f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000602082015290565b611e178484604051602001611e039291906132a6565b604051602081830303815290604052611edb565b604051602001611e2892919061328e565b604051602081830303815290604052905092915050565b60606000611e4c836123ae565b60010190506000816001600160401b03811115611e6b57611e6b61411f565b6040519080825280601f01601f191660200182016040528015611e95576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084611ece57611ed3565b611e9f565b509392505050565b6060815160001415611efb57505060408051602081019091526000815290565b60006040518060600160405280604081526020016141756040913990506000600384516002611f2a9190613f65565b611f349190613f7d565b611f3f906004613f91565b6001600160401b03811115611f5657611f5661411f565b6040519080825280601f01601f191660200182016040528015611f80576020820181803683370190505b509050600182016020820185865187015b80821015611fec576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845360018401935050611f91565b5050600386510660018114612008576002811461201b57612023565b603d6001830353603d6002830353612023565b603d60018303535b509195945050505050565b6001600160a01b03811660009081526020839052604090205415610e3b576001600160a01b03811660009081526020839052604081205461207190600190613fb0565b6001848101549192506000916120879190613fb0565b905060008460010182815481106120a0576120a0614109565b6000918252602090912001546001860180546001600160a01b0390921692508291859081106120d1576120d1614109565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055612105836001613f65565b6001600160a01b03821660009081526020879052604090205560018501805480612131576121316140f3565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b038616825286905260408120555050505050565b6001600160a01b0384161580159061219257506001600160a01b03831615155b156121a6576121a18284612486565b6121e4565b6001600160a01b0384166121c0576121a182600085611a7d565b6001600160a01b0383166121e4576000828152609960205260409020805460010190555b61105f848484846124a7565b6001600160a01b038116600090815260208390526040902054610e3b576001828101805491820181556000818152602080822090930180546001600160a01b0319166001600160a01b039590951694851790559054928152929052604090912055565b600054610100900460ff1661227a5760405162461bcd60e51b81526004016105f590613ef1565b815161228d90606590602085019061252f565b50805161075b90606690602084019061252f565b60006001600160a01b0384163b156123a357604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906122e5903390899088908890600401613d8f565b602060405180830381600087803b1580156122ff57600080fd5b505af192505050801561232f575060408051601f3d908101601f1916820190925261232c9181019061298b565b60015b612389573d80801561235d576040519150601f19603f3d011682016040523d82523d6000602084013e612362565b606091505b5080516123815760405162461bcd60e51b81526004016105f590613e31565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611674565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106123ed5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310612419576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061243757662386f26fc10000830492506010015b6305f5e100831061244f576305f5e100830492506008015b612710831061246357612710830492506004015b60648310612475576064830492506002015b600a831061061b5760010192915050565b600082815260996020526040902080546001019055610e3b82600083611a7d565b600181111561105f576001600160a01b038416156124ed576001600160a01b038416600090815260686020526040812080548392906124e7908490613fb0565b90915550505b6001600160a01b0383161561105f576001600160a01b03831660009081526068602052604081208054839290612524908490613f65565b909155505050505050565b82805461253b90614032565b90600052602060002090601f01602090048101928261255d57600085556125a3565b82601f1061257657805160ff19168380011785556125a3565b828001600101855582156125a3579182015b828111156125a3578251825591602001919060010190612588565b506125af9291506125e9565b5090565b5080546125bf90614032565b6000825580601f106125cf575050565b601f01602090049060005260206000209081019061158c91905b5b808211156125af57600081556001016125ea565b600061261161260c84613f3b565b613f1f565b90508281526020810184848401111561262c5761262c600080fd5b611ed3848285613fe3565b803561061b81614135565b803561061b81614149565b803561061b81614151565b805161061b81614151565b600082601f83011261267757612677600080fd5b81356116748482602086016125fe565b803561061b81614161565b803561061b8161416e565b6000602082840312156126b2576126b2600080fd5b60006116748484612637565b600080604083850312156126d4576126d4600080fd5b60006126e08585612637565b92505060206126f185828601612637565b9150509250929050565b60008060006060848603121561271357612713600080fd5b600061271f8686612637565b935050602061273086828701612637565b925050604061274186828701612692565b9150509250925092565b6000806000806080858703121561276457612764600080fd5b60006127708787612637565b945050602061278187828801612637565b935050604061279287828801612692565b92505060608501356001600160401b038111156127b1576127b1600080fd5b6127bd87828801612663565b91505092959194509250565b600080604083850312156127df576127df600080fd5b60006127eb8585612637565b92505060206126f185828601612642565b600080600080600080600060e0888a03121561281a5761281a600080fd5b60006128268a8a612637565b97505060208801356001600160401b0381111561284557612845600080fd5b6128518a828b01612663565b96505060408801356001600160401b0381111561287057612870600080fd5b61287c8a828b01612663565b95505060608801356001600160401b0381111561289b5761289b600080fd5b6128a78a828b01612663565b94505060808801356001600160401b038111156128c6576128c6600080fd5b6128d28a828b01612663565b93505060a08801356001600160401b038111156128f1576128f1600080fd5b6128fd8a828b01612663565b92505060c08801356001600160401b0381111561291c5761291c600080fd5b6129288a828b01612663565b91505092959891949750929550565b6000806040838503121561294d5761294d600080fd5b60006129598585612637565b92505060206126f185828601612692565b60006020828403121561297f5761297f600080fd5b6000611674848461264d565b6000602082840312156129a0576129a0600080fd5b60006116748484612658565b6000602082840312156129c1576129c1600080fd5b60006116748484612687565b600080604083850312156129e3576129e3600080fd5b60006126e08585612687565b60008060408385031215612a0557612a05600080fd5b82356001600160401b03811115612a1e57612a1e600080fd5b612a2a85828601612663565b92505060208301356001600160401b03811115612a4957612a49600080fd5b6126f185828601612663565b600060208284031215612a6a57612a6a600080fd5b60006116748484612692565b60008060408385031215612a8c57612a8c600080fd5b6000612a988585612692565b92505060206126f185828601612687565b600080600060608486031215612ac157612ac1600080fd5b6000612acd8686612692565b9350506020612ade86828701612687565b925050604061274186828701612637565b60008060408385031215612b0557612b05600080fd5b6000612a2a8585612692565b600080600060608486031215612b2957612b29600080fd5b6000612b358686612692565b93505060208401356001600160401b03811115612b5457612b54600080fd5b612b6086828701612663565b92505060408401356001600160401b03811115612b7f57612b7f600080fd5b61274186828701612663565b6000612b978383612b9f565b505060200190565b612ba881613fc7565b82525050565b6000612bb8825190565b80845260209384019383018060005b83811015612bec578151612bdb8882612b8b565b975060208301925050600101612bc7565b509495945050505050565b801515612ba8565b6000612c09825190565b808452602084019350612c20818560208601613fef565b601f01601f19169290920192915050565b612ba881613fd8565b6000612c44825190565b612c52818560208601613fef565b9290920192915050565b60008154612c6981614032565b600182168015612c805760018114612c9157612cc1565b60ff19831686528186019350612cc1565b60008581526020902060005b83811015612cb957815488820152600190910190602001612c9d565b838801955050505b50505092915050565b60208082527f537472696e67733a20686578206c656e67746820696e73756666696369656e74910190815260005b5060200190565b602d81526000602082017f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6581526c1c881bdc88185c1c1c9bdd9959609a1b602082015291505b5060400190565b6e1e17ba39b830b71f1e17ba32bc3a1f60891b815260005b50600f0190565b603281526000602082017f4552433732313a207472616e7366657220746f206e6f6e20455243373231526581527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60208201529150612d45565b6e113232b9b1b934b83a34b7b7111d1160891b81526000612d64565b61088b60f21b815260005b5060020190565b602581526000602082017f4552433732313a207472616e736665722066726f6d20696e636f72726563742081526437bbb732b960d91b60208201529150612d45565b601c81526000602082017f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000081529150612cf8565b602d81526000602082017f466c65656b416363657373436f6e74726f6c3a206d757374206861766520636f81526c6c6c656374696f6e20726f6c6560981b60208201529150612d45565b602481526000602082017f4552433732313a207472616e7366657220746f20746865207a65726f206164648152637265737360e01b60208201529150612d45565b601981526000602082017f4552433732313a20617070726f766520746f2063616c6c65720000000000000081529150612cf8565b602981526000602082017f4552433732313a2061646472657373207a65726f206973206e6f7420612076618152683634b21037bbb732b960b91b60208201529150612d45565b602e81526000602082017f496e697469616c697a61626c653a20636f6e747261637420697320616c72656181526d191e481a5b9a5d1a585b1a5e995960921b60208201529150612d45565b681134b6b0b3b2911d1160b91b815260005b5060090190565b61227d60f01b81526000612de1565b60208082527f4552433732313a206d696e7420746f20746865207a65726f206164647265737391019081526000612cf8565b607d60f81b815260005b5060010190565b607b60f81b81526000613012565b6e2261747472696275746573223a205b60881b81526000612d64565b681137bbb732b9111d1160b91b81526000612fc0565b601881526000602082017f4552433732313a20696e76616c696420746f6b656e204944000000000000000081529150612cf8565b605d60f81b81526000613012565b602181526000602082017f4552433732313a20617070726f76616c20746f2063757272656e74206f776e658152603960f91b60208201529150612d45565b7f3c67207472616e73666f726d3d226d617472697828312030203020312033303281527410191b18971a1b94911039ba3cb6329e911110101f60591b602082015260005b5060350190565b603d81526000602082017f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f81527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c00000060208201529150612d45565b651e3232b3399f60d11b815260005b5060060190565b7f3c67207472616e73666f726d3d226d617472697828332e34322030203020332e8152741a1910199818171c9c10191a99171c9c149110101f60591b6020820152600061311d565b602b81526000602082017f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206981526a6e697469616c697a696e6760a81b60208201529150612d45565b602881526000602082017f466c65656b416363657373436f6e74726f6c3a206d757374206861766520746f8152676b656e20726f6c6560c01b60208201529150612d45565b651e17b9bb339f60d11b8152600061318d565b80612ba8565b6000611daa8284612c3a565b600061329a8285612c3a565b91506116748284612c3a565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323081527f30302f7376672220786d6c6e733a786c696e6b3d22687474703a2f2f7777772e60208201527f77332e6f72672f313939392f786c696e6b222076657273696f6e3d22312e312260408201527f2077696474683d2236343022206865696768743d22343830222076696577426f60608201527f783d2230203020363430203438302220786d6c3a73706163653d227072657365608082015264393b32911f60d91b60a082015260a501600061337d8261317e565b661e17b232b3399f60c91b8152600701915061339882613194565b7f3c706f6c79676f6e207374796c653d227374726f6b653a2072676228302c302c81527f30293b207374726f6b652d77696474683a20383b207374726f6b652d6461736860208201527f61727261793a206e6f6e653b207374726f6b652d6c696e656361703a2062757460408201527f743b207374726f6b652d646173686f66667365743a20303b207374726f6b652d60608201527f6c696e656a6f696e3a206d697465723b207374726f6b652d6d697465726c696d60808201527f69743a20343b2066696c6c3a20726762283135322c3135322c313833293b206660a08201527f696c6c2d72756c653a206e6f6e7a65726f3b206f7061636974793a20313b222060c08201527f766563746f722d6566666563743d226e6f6e2d7363616c696e672d7374726f6b60e08201527f65222020706f696e74733d222d35302c2d3530202d35302c35302035302c35306101008201526b101a9816169a98101110179f60a11b610120820152631e17b39f60e11b61012c82018190527f3c67207472616e73666f726d3d226d61747269782831203020302031203330336101308301527f2e35203131352e36372922207374796c653d222220203e0000000000000000006101508301527f3c7465787420786d6c3a73706163653d2270726573657276652220666f6e742d6101678301527f66616d696c793d224f70656e2053616e732220666f6e742d73697a653d2232346101878301527f2220666f6e742d7374796c653d226e6f726d616c2220666f6e742d77656967686101a78301527f743d226e6f726d616c22207374796c653d227374726f6b653a206e6f6e653b206101c78301527f7374726f6b652d77696474683a20313b207374726f6b652d64617368617272616101e78301527f793a206e6f6e653b207374726f6b652d6c696e656361703a20627574743b20736102078301527f74726f6b652d646173686f66667365743a20303b207374726f6b652d6c696e656102278301527f6a6f696e3a206d697465723b207374726f6b652d6d697465726c696d69743a206102478301527f343b2066696c6c3a2072676228302c302c30293b2066696c6c2d72756c653a206102678301527f6e6f6e7a65726f3b206f7061636974793a20313b2077686974652d73706163656102878301527f3a207072653b22203e3c747370616e20783d222d34352e372220793d22352e366102a78301527f3522207374796c653d227374726f6b652d77696474683a20313b20666f6e742d6102c78301527f66616d696c793a20224f70656e2053616e73222c2073616e732d73657269663b6102e78301527f20666f6e742d73697a653a20313870783b20666f6e742d7374796c653a206e6f6103078301527f726d616c3b20666f6e742d7765696768743a206e6f726d616c3b2066696c6c3a6103278301527f2072676228302c302c30293b20223e466c65656b204e4641733c2f747370616e610347830152671f1e17ba32bc3a1f60c11b61036783015261036f8201526103730191506137f7826130d9565b7f3c7465787420786d6c3a73706163653d2270726573657276652220666f6e742d81527f66616d696c793d224f70656e2053616e732220666f6e742d73697a653d22323860208201527f2220666f6e742d7374796c653d226e6f726d616c2220666f6e742d776569676860408201527f743d226e6f726d616c22207374796c653d227374726f6b653a206e6f6e653b2060608201527f7374726f6b652d77696474683a20313b207374726f6b652d646173686172726160808201527f793a206e6f6e653b207374726f6b652d6c696e656361703a20627574743b207360a08201527f74726f6b652d646173686f66667365743a20303b207374726f6b652d6c696e6560c08201527f6a6f696e3a206d697465723b207374726f6b652d6d697465726c696d69743a2060e08201527f343b2066696c6c3a2072676228302c302c30293b2066696c6c2d72756c653a206101008201527f6e6f6e7a65726f3b206f7061636974793a20313b2077686974652d73706163656101208201527f3a207072653b22203e3c747370616e20783d222d34342e32362220793d222d366101408201527f2e313422207374796c653d227374726f6b652d77696474683a20313b20666f6e6101608201527f742d66616d696c793a20224f70656e2053616e73222c2073616e732d736572696101808201527f663b20666f6e742d73697a653a20313870783b20666f6e742d7374796c653a206101a08201527f6e6f726d616c3b20666f6e742d7765696768743a206e6f726d616c3b2066696c6101c082015270361d103933b1141816181618149d90111f60791b6101e08201526101f1019150613a608285612c3a565b7f3c2f747370616e3e3c747370616e20783d222d33372e31342220793d2231372e81527f343522207374796c653d227374726f6b652d77696474683a20313b20666f6e7460208201527f2d66616d696c793a20224f70656e2053616e73222c2073616e732d736572696660408201527f3b20666f6e742d73697a653a20313870783b20666f6e742d7374796c653a206e60608201527f6f726d616c3b20666f6e742d7765696768743a206e6f726d616c3b2066696c6c60808201526f1d103933b1141816181618149d90111f60811b60a082015260b0019150613b438284612c3a565b9150613b4e82612d4c565b631e17b39f60e11b8152600401915061167482613269565b6000613b7182613019565b67113730b6b2911d1160c11b81526008019150613b8e828c612c5c565b9150613b9982612dd6565b9150613ba482612dba565b9150613bb0828b612c5c565b9150613bbb82612dd6565b9150613bc682613043565b9150613bd2828a612c3a565b9150613bdd82612dd6565b6f1132bc3a32b93730b62fbab936111d1160811b81526010019150613c028289612c5c565b9150613c0d82612dd6565b9150613c1882612fae565b9150613c248288612c3a565b9150613c2f82612dd6565b9150613c3a82613027565b7f7b2274726169745f74797065223a2022454e53222c202276616c7565223a22008152601f019150613c6c8287612c5c565b62089f4b60ea1b81527f7b2274726169745f74797065223a2022436f6d6d69742048617368222c20227660038201526630b63ab2911d1160c91b6023820152602a019150613cba8286612c5c565b62089f4b60ea1b81527f7b2274726169745f74797065223a20225265706f7369746f7279222c20227661600382015265363ab2911d1160d11b60238201526029019150613d078285612c5c565b62089f4b60ea1b81527f7b2274726169745f74797065223a202256657273696f6e222c202276616c7565600382015262111d1160e91b60238201526026019150613d518284612c3a565b9150613d5c82612fc7565b9150613d678261308d565b9150613d7282613008565b9b9a5050505050505050505050565b6020810161061b8284612b9f565b60808101613d9d8287612b9f565b613daa6020830186612b9f565b613db7604083018561327c565b8181036060830152613dc98184612bff565b9695505050505050565b60208082528101611daa8184612bae565b6020810161061b8284612bf7565b6020810161061b8284612c31565b60208082528101611daa8184612bff565b6020808252810161061b81612cca565b6020808252810161061b81612cff565b6020808252810161061b81612d6b565b6020808252810161061b81612de8565b6020808252810161061b81612e2a565b6020808252810161061b81612e5e565b6020808252810161061b81612ea8565b6020808252810161061b81612ee9565b6020808252810161061b81612f1d565b6020808252810161061b81612f63565b6020808252810161061b81612fd6565b6020808252810161061b81613059565b6020808252810161061b8161309b565b6020808252810161061b81613124565b6020808252810161061b816131dc565b6020808252810161061b81613224565b6020810161061b828461327c565b6000613f2a60405190565b9050613f36828261405f565b919050565b60006001600160401b03821115613f5457613f5461411f565b601f19601f83011660200192915050565b60008219821115613f7857613f7861409b565b500190565b600082613f8c57613f8c6140b1565b500490565b6000816000190483118215151615613fab57613fab61409b565b500290565b600082821015613fc257613fc261409b565b500390565b60006001600160a01b03821661061b565b600060ff821661061b565b82818337506000910152565b60005b8381101561400a578181015183820152602001613ff2565b8381111561105f5750506000910152565b60008161402a5761402a61409b565b506000190190565b60028104600182168061404657607f821691505b60208210811415614059576140596140dd565b50919050565b601f19601f83011681018181106001600160401b03821117156140845761408461411f565b6040525050565b6000600019821415613012576130125b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b61413e81613fc7565b811461158c57600080fd5b80151561413e565b6001600160e01b0319811661413e565b6002811061158c57600080fd5b8061413e56fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220b134b709d6db06d03e23b6b163ce704738e195c692f6b8aaf48a6a6471fc951164736f6c63430008070033",
- "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"toAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"byAddress\",\"type\":\"address\"}],\"name\":\"CollectionRoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"toAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"byAddress\",\"type\":\"address\"}],\"name\":\"CollectionRoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"token\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"string\",\"name\":\"commitHash\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"triggeredBy\",\"type\":\"address\"}],\"name\":\"NewBuild\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"token\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"triggeredBy\",\"type\":\"address\"}],\"name\":\"NewTokenDescription\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"token\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"string\",\"name\":\"ENS\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"triggeredBy\",\"type\":\"address\"}],\"name\":\"NewTokenENS\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"token\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"string\",\"name\":\"externalURL\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"triggeredBy\",\"type\":\"address\"}],\"name\":\"NewTokenExternalURL\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"token\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"string\",\"name\":\"image\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"triggeredBy\",\"type\":\"address\"}],\"name\":\"NewTokenImage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"token\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"triggeredBy\",\"type\":\"address\"}],\"name\":\"NewTokenName\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"toAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"byAddress\",\"type\":\"address\"}],\"name\":\"TokenRoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"toAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"byAddress\",\"type\":\"address\"}],\"name\":\"TokenRoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"}],\"name\":\"getCollectionRoleMembers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"}],\"name\":\"getTokenRoleMembers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantCollectionRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantTokenRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasCollectionRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasTokenRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"externalURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"ENS\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"commitHash\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"gitRepository\",\"type\":\"string\"}],\"name\":\"mint\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeCollectionRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeTokenRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_commitHash\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_gitRepository\",\"type\":\"string\"}],\"name\":\"setTokenBuild\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_tokenDescription\",\"type\":\"string\"}],\"name\":\"setTokenDescription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_tokenENS\",\"type\":\"string\"}],\"name\":\"setTokenENS\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_tokenExternalURL\",\"type\":\"string\"}],\"name\":\"setTokenExternalURL\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_tokenName\",\"type\":\"string\"}],\"name\":\"setTokenName\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"details\":\"See {IERC721-approve}.\"},\"balanceOf(address)\":{\"details\":\"See {IERC721-balanceOf}.\"},\"burn(uint256)\":{\"details\":\"Burns a previously minted `tokenId`. May emit a {Transfer} event. Requirements: - the tokenId must be minted and valid. - the sender must have the `tokenOwner` role.\"},\"getApproved(uint256)\":{\"details\":\"See {IERC721-getApproved}.\"},\"getCollectionRoleMembers(uint8)\":{\"details\":\"Returns an array of addresses that all have the collection role.\"},\"getTokenRoleMembers(uint256,uint8)\":{\"details\":\"Returns an array of addresses that all have the same token role for a certain tokenId.\"},\"grantCollectionRole(uint8,address)\":{\"details\":\"Grants the collection role to an address. Requirements: - the caller should have the collection role.\"},\"grantTokenRole(uint256,uint8,address)\":{\"details\":\"Grants the token role to an address. Requirements: - the caller should have the token role.\"},\"hasCollectionRole(uint8,address)\":{\"details\":\"Returns `True` if a certain address has the collection role.\"},\"hasTokenRole(uint256,uint8,address)\":{\"details\":\"Returns `True` if a certain address has the token role.\"},\"initialize(string,string)\":{\"details\":\"Initializes the contract by setting a `name` and a `symbol` to the token collection.\"},\"isApprovedForAll(address,address)\":{\"details\":\"See {IERC721-isApprovedForAll}.\"},\"mint(address,string,string,string,string,string,string)\":{\"details\":\"Mints a token and returns a tokenId. If the `tokenId` has not been minted before, and the `to` address is not zero, emits a {Transfer} event. Requirements: - the caller must have ``collectionOwner``'s admin role.\"},\"name()\":{\"details\":\"See {IERC721Metadata-name}.\"},\"ownerOf(uint256)\":{\"details\":\"See {IERC721-ownerOf}.\"},\"revokeCollectionRole(uint8,address)\":{\"details\":\"Revokes the collection role of an address. Requirements: - the caller should have the collection role.\"},\"revokeTokenRole(uint256,uint8,address)\":{\"details\":\"Revokes the token role of an address. Requirements: - the caller should have the token role.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"See {IERC721-setApprovalForAll}.\"},\"setTokenBuild(uint256,string,string)\":{\"details\":\"Adds a new build to a minted `tokenId`'s builds mapping. May emit a {NewBuild} event. Requirements: - the tokenId must be minted and valid. - the sender must have the `tokenController` role.\"},\"setTokenDescription(uint256,string)\":{\"details\":\"Updates the `description` metadata field of a minted `tokenId`. May emit a {NewTokenDescription} event. Requirements: - the tokenId must be minted and valid. - the sender must have the `tokenController` role.\"},\"setTokenENS(uint256,string)\":{\"details\":\"Updates the `ENS` metadata field of a minted `tokenId`. May emit a {NewTokenENS} event. Requirements: - the tokenId must be minted and valid. - the sender must have the `tokenController` role.\"},\"setTokenExternalURL(uint256,string)\":{\"details\":\"Updates the `externalURL` metadata field of a minted `tokenId`. May emit a {NewTokenExternalURL} event. Requirements: - the tokenId must be minted and valid. - the sender must have the `tokenController` role.\"},\"setTokenName(uint256,string)\":{\"details\":\"Updates the `name` metadata field of a minted `tokenId`. May emit a {NewTokenName} event. Requirements: - the tokenId must be minted and valid. - the sender must have the `tokenController` role.\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"symbol()\":{\"details\":\"See {IERC721Metadata-symbol}.\"},\"tokenURI(uint256)\":{\"details\":\"Returns the token metadata associated with the `tokenId`. Returns a based64 encoded string value of the URI. Requirements: - the tokenId must be minted and valid.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-transferFrom}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/FleekERC721.sol\":\"FleekERC721\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"details\":{\"constantOptimizer\":true,\"cse\":true,\"deduplicate\":true,\"inliner\":true,\"jumpdestRemover\":true,\"orderLiterals\":true,\"peephole\":true,\"yul\":false},\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"keccak256\":\"0xe798cadb41e2da274913e4b3183a80f50fb057a42238fe8467e077268100ec27\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://899f850f7df5a270bccfb765d70069959ca1c20d3a7381c1c3bda8a3ffee1935\",\"dweb:/ipfs/QmVdnAqwyX2L3nX2HDA5WKGtVBFyH1nKE9A1k7fZnPBkhP\"]},\"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\":{\"keccak256\":\"0x2a6a0b9fd2d316dcb4141159a9d13be92654066d6c0ae92757ed908ecdfecff0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c05d9be7ee043009eb9f2089b452efc0961345531fc63354a249d7337c69f3bb\",\"dweb:/ipfs/QmTXhzgaYrh6og76BP85i6exNFAv5NYw64uVWyworNogyG\"]},\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\":{\"keccak256\":\"0xbb2ed8106d94aeae6858e2551a1e7174df73994b77b13ebd120ccaaef80155f5\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8bc3c6a456dba727d8dd9fd33420febede490abb49a07469f61d2a3ace66a95a\",\"dweb:/ipfs/QmVAWtEVj7K5AbvgJa9Dz22KiDq9eoptCjnVZqsTMtKXyd\"]},\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\":{\"keccak256\":\"0x2c0b89cef83f353c6f9488c013d8a5968587ffdd6dfc26aad53774214b97e229\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4a68e662c2a82412308b1feb24f3d61a44b3b8772f44cbd440446237313c3195\",\"dweb:/ipfs/QmfBuWUE2TQef9hghDzzuVkDskw3UGAyPgLmPifTNV7K6g\"]},\"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\":{\"keccak256\":\"0x95a471796eb5f030fdc438660bebec121ad5d063763e64d92376ffb4b5ce8b70\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4ffbd627e6958983d288801acdedbf3491ee0ebf1a430338bce47c96481ce9e3\",\"dweb:/ipfs/QmUM1vpmNgBV34sYf946SthDJNGhwwqjoRggmj4TUUQmdB\"]},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x2edcb41c121abc510932e8d83ff8b82cf9cdde35e7c297622f5c29ef0af25183\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://72460c66cd1c3b1c11b863e0d8df0a1c56f37743019e468dc312c754f43e3b06\",\"dweb:/ipfs/QmPExYKiNb9PUsgktQBupPaM33kzDHxaYoVeJdLhv8s879\"]},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d6520943ea55fdf5f0bafb39ed909f64de17051bc954ff3e88c9e5621412c79c\",\"dweb:/ipfs/QmWZ4rAKTQbNG2HxGs46AcTXShsVytKeLs7CUCdCSv5N7a\"]},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"keccak256\":\"0x6b9a5d35b744b25529a2856a8093e7c03fb35a34b1c4fb5499e560f8ade140da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://187b5c3a1c9e77678732a2cc5284237f9cfca6bc28ee8bc0a0f4f951d7b3a2f8\",\"dweb:/ipfs/Qmb2KFr7WuQu7btdCiftQG64vTzrG4UyzVmo53EYHcnHYA\"]},\"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\":{\"keccak256\":\"0x9a3b990bd56d139df3e454a9edf1c64668530b5a77fc32eb063bc206f958274a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0895399d170daab2d69b4c43a0202e5a07f2e67a93b26e3354dcbedb062232f7\",\"dweb:/ipfs/QmUM1VH3XDk559Dsgh4QPvupr3YVKjz87HrSyYzzVFZbxw\"]},\"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\":{\"keccak256\":\"0xc6cef87559d0aeffdf0a99803de655938a7779ec0a3cd5d4383483ad85565a09\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://92ad7e572cf44e6b4b37631b44b62f9eb9fb1cf14d9ce51c1504d5dc7ccaf758\",\"dweb:/ipfs/QmcnbqX85tsWnUXPmtuPLE4SczME2sJaTfmqEFkuAJvWhy\"]},\"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol\":{\"keccak256\":\"0xc1bd5b53319c68f84e3becd75694d941e8f4be94049903232cd8bc7c535aaa5a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://056027a78e6f4b78a39be530983551651ee5a052e786ca2c1c6a3bb1222b03b4\",\"dweb:/ipfs/QmXRUpywAqNwAfXS89vrtiE2THRM9dX9pQ4QxAkV1Wx9kt\"]},\"@openzeppelin/contracts/utils/Base64.sol\":{\"keccak256\":\"0x5f3461639fe20794cfb4db4a6d8477388a15b2e70a018043084b7c4bedfa8136\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://77e5309e2cc4cdc3395214edb0ff43ff5a5f7373f5a425383e540f6fab530f96\",\"dweb:/ipfs/QmTV8DZ9knJDa3b5NPBFQqjvTzodyZVjRUg5mx5A99JPLJ\"]},\"@openzeppelin/contracts/utils/Counters.sol\":{\"keccak256\":\"0xf0018c2440fbe238dd3a8732fa8e17a0f9dce84d31451dc8a32f6d62b349c9f1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://59e1c62884d55b70f3ae5432b44bb3166ad71ae3acd19c57ab6ddc3c87c325ee\",\"dweb:/ipfs/QmezuXg5GK5oeA4F91EZhozBFekhq5TD966bHPH18cCqhu\"]},\"@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xa4d1d62251f8574deb032a35fc948386a9b4de74b812d4f545a1ac120486b48a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8c969013129ba9e651a20735ef659fef6d8a1139ea3607bd4b26ddea2d645634\",\"dweb:/ipfs/QmVhVa6LGuzAcB8qgDtVHRkucn4ihj5UZr8xBLcJkP6ucb\"]},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xa1e8e83cd0087785df04ac79fb395d9f3684caeaf973d9e2c71caef723a3a5d6\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://33bbf48cc069be677705037ba7520c22b1b622c23b33e1a71495f2d36549d40b\",\"dweb:/ipfs/Qmct36zWXv3j7LZB83uwbg7TXwnZSN1fqHNDZ93GG98bGz\"]},\"contracts/FleekAccessControl.sol\":{\"keccak256\":\"0x99b148a767f42ff1bfcee7ff68d8b11ece6aa78a96a5637c9b5e1ddc1cca7b34\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ff6dd367c0f3894c2c3fcd28cd02ccce384bea6dc23baa7b03041be237cc64ae\",\"dweb:/ipfs/QmWGtcukpo1ApXiVxkAfMJ3u8Be9quLXBzExcXr6KJ4gmL\"]},\"contracts/FleekERC721.sol\":{\"keccak256\":\"0x34e2da162e73cedb56c5fedc413604a79446535c2a16c2212b562c78a911241c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3d184d08e7803189d6f8091135d3550d1d528cadad0c6f52c973cc45a0260bc0\",\"dweb:/ipfs/Qma3FAvNVf6EQUqV1fdEZ126ZUQRttSSMEX3m9o4jqfHVW\"]}},\"version\":1}",
+ "bytecode": "0x6080806040523461001657614564908161001d8239f35b50600080fdfe6040608081526004361015610015575b50600080fd5b600090813560e01c806301468deb1461066557806301ffc9a71461064957806306fdde031461062d578063081812fc14610611578063095ea7b3146105f957806323b872dd146105e1578063246a908b146105c957806327dc5cec146105ad5780632d957aad146105955780632f1e8f0a14610531578063353b07a41461050a5780633806f152146104f257806342842e0e146104da57806342966c68146104c357806342e44bbf146104ab5780634cd88b76146104935780636352211e1461045e57806370a08231146104425780637469a03b1461042b57806378278cca146104135780638c3c0a44146103fb5780638deb2c32146103cb57806394ec65c5146103b457806395d89b4114610398578063a22cb46514610380578063a27d0b2714610368578063a397c83014610351578063b20b94f114610339578063b30437a014610326578063b42dbe3814610309578063b88d4fde146102ee578063c87b56dd146102c7578063cdb0e89e146102af578063d7a75be114610293578063e944725014610276578063e985e9c51461020d578063f6be6b78146101e25763f9315177146101c4575061000f565b346101de576101db6101d536610926565b90612fbd565b51f35b5080fd5b50346101de5761020991506101fe6101f936610787565b613ac5565b905191829182610d0a565b0390f35b50346101de57610209915061026561025e61024761022a36610cd7565b6001600160a01b039091166000908152606a602052604090209091565b9060018060a01b0316600052602052604060002090565b5460ff1690565b905190151581529081906020820190565b50346101de57610209915061026561028d3661097f565b90611bb8565b50346101de5761020991506102656102aa36610955565b6137fd565b50346101de576101db6102c136610926565b9061311d565b50346101de5761020991506102e36102de36610787565b612ad4565b905191829182610776565b50346101de576101db61030036610c67565b92919091611386565b50346101de5761020991506102656103203661069b565b91611c54565b506101db61033336610926565b90613333565b50346101de576101db61034b36610a73565b9061398c565b50346101de576101db61036336610955565b6138b1565b50346101de576101db61037a3661069b565b9161197d565b50346101de576101db61039236610c36565b906111f0565b50346101de5761020991506103ac3661070e565b6102e3610fd8565b50346101de576101db6103c636610955565b613825565b5061020991506103ec6103dd36610b28565b979690969591959492946126f7565b90519081529081906020820190565b50346101de576101db61040d3661097f565b90611a38565b50346101de576101db61042536610926565b9061307d565b50346101de576101db61043d36610955565b6134b2565b50346101de5761020991506103ec61045936610af1565b610d6c565b50346101de57610209915061047a61047536610787565b610e32565b90516001600160a01b0390911681529081906020820190565b50346101de576101db6104a536610aae565b9061213b565b50346101de576101db6104bd36610a73565b90613a3e565b50346101de576101db6104d536610787565b613c65565b50346101de576101db6104ec366107c0565b9161134c565b50346101de576101db61050436610a2d565b91613b79565b50346101de57610209915061052661052136610a12565b611cde565b9051918291826109ce565b50346101de576102099150610526600161058f61058a610550366109af565b919061057b610569826000526099602052604060002090565b5491600052609a602052604060002090565b90600052602052604060002090565b611b6c565b01611c86565b50346101de576101db6105a73661097f565b90611874565b50346101de5761020991506102e36105c436610955565b613688565b50346101de576101db6105db36610926565b906131ba565b50346101de576101db6105f3366107c0565b9161131c565b50346101de576101db61060b36610799565b9061108c565b50346101de57610209915061047a61062836610787565b6111b2565b50346101de5761020991506106413661070e565b6102e3610f21565b50346101de576102099150610265610660366106f3565b612efe565b50346101de576101db6106773661069b565b91611aca565b600435906001600160a01b03821682141561069457565b5050600080fd5b606090600319011261000f576004359060243560028110156106d857906044356001600160a01b0381168114156106cf5790565b50505050600080fd5b505050600080fd5b6001600160e01b03198116141561000f57565b602090600319011261000f5760043561070b816106e0565b90565b600090600319011261000f57565b918091926000905b82821061073c575011610735575050565b6000910152565b91508060209183015181860152018291610724565b9060209161076a8151809281855285808601910161071c565b601f01601f1916010190565b90602061070b928181520190610751565b602090600319011261000f5760043590565b604090600319011261000f576004356001600160a01b038116811415610694579060243590565b606090600319011261000f576001600160a01b03906004358281168114156106d857916024359081168114156106d8579060443590565b50634e487b7160e01b600052604160045260246000fd5b604081019081106001600160401b0382111761082957604052565b6108316107f7565b604052565b602081019081106001600160401b0382111761082957604052565b90601f801991011681019081106001600160401b0382111761082957604052565b6040519061087f8261080e565b565b6040519060c082018281106001600160401b0382111761082957604052565b6020906001600160401b0381116108bd575b601f01601f19160190565b6108c56107f7565b6108b2565b9291926108d6826108a0565b916108e46040519384610851565b829481845281830111610901578281602093846000960137010152565b5050505050600080fd5b9080601f830112156106d85781602061070b933591016108ca565b9060406003198301126106945760043591602435906001600160401b0382116106cf5761070b9160040161090b565b602060031982011261069457600435906001600160401b0382116106d85761070b9160040161090b565b604090600319011261000f57600435600281101561069457906024356001600160a01b0381168114156106d85790565b604090600319011261000f576004359060243560028110156106d85790565b6020908160408183019282815285518094520193019160005b8281106109f5575050505090565b83516001600160a01b0316855293810193928101926001016109e7565b602090600319011261000f5760043560028110156106945790565b606060031982011261069457600435916001600160401b036024358181116109015783610a5c9160040161090b565b926044359182116109015761070b9160040161090b565b604060031982011261069457600435906001600160401b0382116106d857610a9d9160040161090b565b906024358015158114156106d85790565b906040600319830112610694576001600160401b036004358181116106cf5783610ada9160040161090b565b926024359182116106cf5761070b9160040161090b565b602090600319011261000f576004356001600160a01b0381168114156106945790565b610104359062ffffff821682141561069457565b61012060031982011261069457610b3d61067d565b916001600160401b039060243582811161090157610b5f84600492830161090b565b93604435848111610c2a5781610b7691840161090b565b93606435818111610c1d5782610b8d91850161090b565b93608435828111610c0f5783610ba491860161090b565b9360a435838111610c005784610bbb91830161090b565b9360c435848111610bf05781610bd291840161090b565b9360e435908111610bf057610be7920161090b565b9061070b610b14565b5050505050505050505050600080fd5b50505050505050505050600080fd5b505050505050505050600080fd5b5050505050505050600080fd5b50505050505050600080fd5b604090600319011261000f576004356001600160a01b03811681141561069457906024358015158114156106d85790565b906080600319830112610694576001600160a01b03916004358381168114156106cf57926024359081168114156106cf579160443591606435906001600160401b038211610ccc5780602383011215610ccc5781602461070b936004013591016108ca565b505050505050600080fd5b604090600319011261000f576001600160a01b03906004358281168114156106d857916024359081168114156106d85790565b602080820190808352835180925260408301928160408460051b8301019501936000915b848310610d3e5750505050505090565b9091929394958480610d5c600193603f198682030187528a51610751565b9801930193019194939290610d2e565b6001600160a01b03168015610d8c57600052606860205260406000205490565b505060405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608490fd5b15610dec57565b5060405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606490fd5b6000908152606760205260409020546001600160a01b031661070b811515610de5565b90600182811c92168015610e87575b6020831014610e6f57565b5050634e487b7160e01b600052602260045260246000fd5b91607f1691610e64565b9060009291805491610ea283610e55565b918282526001938481169081600014610f045750600114610ec4575b50505050565b90919394506000526020928360002092846000945b838610610ef0575050505001019038808080610ebe565b805485870183015294019385908201610ed9565b60ff19166020840152505060400193503891508190508080610ebe565b6040519060008260655491610f3583610e55565b80835292600190818116908115610fbb5750600114610f5c575b5061087f92500383610851565b6065600090815291507f8ff97419363ffd7000167f130ef7168fbea05faf9251824ca5043f113cc6a7c75b848310610fa0575061087f935050810160200138610f4f565b81935090816020925483858a01015201910190918592610f87565b94505050505060ff1916602083015261087f826040810138610f4f565b6040519060008260665491610fec83610e55565b80835292600190818116908115610fbb5750600114611012575061087f92500383610851565b6066600090815291507f46501879b8ca8525e8c2fd519e2fbfcfa2ebea26501294aa02cbfcfb12e943545b848310611056575061087f935050810160200138610f4f565b81935090816020925483858a0101520191019091859261103d565b9061087f6110859260405193848092610e91565b0383610851565b9061109681610e32565b6001600160a01b03818116908416811461115f573314908115611131575b50156110c35761087f91611670565b505060405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000606482015260849150fd5b6001600160a01b03166000908152606a6020526040902060ff9150611157903390610247565b5416386110b4565b5050505050608460405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152fd5b6000818152606760205260409020546111d5906001600160a01b03161515610de5565b6000908152606960205260409020546001600160a01b031690565b6001600160a01b038116919033831461127157816112306112419233600052606a60205260406000209060018060a01b0316600052602052604060002090565b9060ff801983541691151516179055565b60405190151581527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a3565b50505050606460405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152fd5b156112c057565b5060405162461bcd60e51b815260206004820152602d60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201526c1c881bdc88185c1c1c9bdd9959609a1b6064820152608490fd5b9061087f929161133461132f8433611422565b6112b9565b6114f5565b6040519061134682610836565b60008252565b909161087f9260405192602084018481106001600160401b03821117611379575b60405260008452611386565b6113816107f7565b61136d565b906113aa93929161139a61132f8433611422565b6113a58383836114f5565b611759565b156113b157565b5060405162461bcd60e51b8152806113cb600482016113cf565b0390fd5b60809060208152603260208201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60608201520190565b6001600160a01b038061143484610e32565b16928183169284841494851561146a575b50508315611454575b50505090565b611460919293506111b2565b161438808061144e565b6000908152606a602090815260408083206001600160a01b03949094168352929052205460ff1693503880611445565b156114a157565b5060405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608490fd5b6115199061150284610e32565b6001600160a01b038281169390918216841461149a565b831692831561161a576115978261153487846115f196612f42565b611556856115506115448a610e32565b6001600160a01b031690565b1461149a565b61157d61156d886000526069602052604060002090565b80546001600160a01b0319169055565b6001600160a01b0316600090815260686020526040902090565b80546000190190556001600160a01b0381166000908152606860205260409020600181540190556115d2856000526067602052604060002090565b80546001600160a01b0319166001600160a01b03909216919091179055565b7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6000604051a4565b505050505050608460405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152fd5b600082815260696020526040902080546001600160a01b0319166001600160a01b0383161790556001600160a01b03806116a984610e32565b169116907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9256000604051a4565b90816020910312610694575161070b816106e0565b6001600160a01b03918216815291166020820152604081019190915260806060820181905261070b92910190610751565b506040513d6000823e3d90fd5b3d15611754573d9061173a826108a0565b916117486040519384610851565b82523d6000602084013e565b606090565b92909190823b156118085761178c926020926000604051809681958294630a85bd0160e11b9a8b855233600486016116eb565b03926001600160a01b03165af1600091816117e8575b506117da575050506117b2611729565b805190816117d557505060405162461bcd60e51b8152806113cb600482016113cf565b602001fd5b6001600160e01b0319161490565b6118019192506117f83d82610851565b3d8101906116d6565b90386117a2565b50505050600190565b1561181857565b5060405162461bcd60e51b815260206004820152602d60248201527f466c65656b416363657373436f6e74726f6c3a206d757374206861766520636f60448201526c6c6c656374696f6e20726f6c6560981b6064820152608490fd5b61187d33611b84565b801561190b575b61188d90611811565b60975460005260986020526118af826118aa836040600020611b6c565b611f13565b60028110156118f2576040513381526001600160a01b03909216917fcf081ed2b728e3115904be00eb8927b2375ff3401839b37f7accfa1bb2bee15c90602090a3565b505050634e487b7160e01b600052602160045260246000fd5b5061188d61191833611b84565b9050611884565b1561192657565b5060405162461bcd60e51b815260206004820152602860248201527f466c65656b416363657373436f6e74726f6c3a206d757374206861766520746f6044820152676b656e20726f6c6560c01b6064820152608490fd5b6119873382611bd5565b8015611a23575b6119979061191f565b600081815260996020526040812054609a602052604082209082526020526119c6846118aa8560408520611b6c565b6002831015611a0a57506040513381526001600160a01b03909316927f0bf5a13b362503fcc74b8b9b1598aba2f3a9af85d05ba7978f7e9f447f22c23990602090a4565b634e487b7160e01b815260216004526024945092505050fd5b50611997611a313383611bd5565b905061198e565b611a4133611b84565b8015611ab6575b611a5190611811565b6097546000526098602052611a7382611a6e836040600020611b6c565b612016565b60028110156118f2576040513381526001600160a01b03909216917faeff57f0f5e4d3d10a37d4a70fde8ed67a95e67b251d5c512c0ea98c380d2f9590602090a3565b50611a51611ac333611b84565b9050611a48565b611ad43382611bd5565b8015611b57575b611ae49061191f565b600081815260996020526040812054609a60205260408220908252602052611b1384611a6e8560408520611b6c565b6002831015611a0a57506040513381526001600160a01b03909316927fe52d746e4c78c98c6bfa291b273406905c3e8550b7d911a6bea686368c2dc79d90602090a4565b50611ae4611b653383611bd5565b9050611adb565b9060028110156118f257600052602052604060002090565b609754600090815260986020908152604080832083805282528083206001600160a01b039094168352929052205b54151590565b90610247611bb29260975460005260986020526040600020611b6c565b600090815260996020908152604080832054609a8352818420908452825280832083805282528083206001600160a01b03909416835292905220611bb2565b600090815260996020908152604080832054609a835281842090845282528083206001845282528083206001600160a01b03909416835292905220611bb2565b611bb29291610247916000526099602052604060002054609a6020526040600020906000526020526040600020611b6c565b9060405191828154918282526020928383019160005283600020936000905b828210611cbb5750505061087f92500383610851565b85546001600160a01b031684526001958601958895509381019390910190611ca5565b611cfe906097546000526020906098825260019283916040600020611b6c565b01604051918293849382845491828152019360005282600020926000905b828210611d345750505050509061070b910382610851565b84546001600160a01b03168652879650948501949383019390830190611d1c565b6097546000908152609860205260408120818052602052611d798260408320611f13565b6040513381526001600160a01b03909216917fcf081ed2b728e3115904be00eb8927b2375ff3401839b37f7accfa1bb2bee15c90602090a3565b600081819282527f0bf5a13b362503fcc74b8b9b1598aba2f3a9af85d05ba7978f7e9f447f22c239602060998152604080852054609a8352818620908652825280852085805282528085208083528186205415611e13575b5051338152a4565b60018101611e358154600160401b811015611e59575b60018101835582611eed565b81549060018060a01b039060031b1b19169055549086805283528186205538611e0b565b611e616107f7565b611e29565b60009080825260996020526040822054609a6020526040832090835260205260408220828052602052611e9c8360408420611f13565b6040513381526001600160a01b03909316927f0bf5a13b362503fcc74b8b9b1598aba2f3a9af85d05ba7978f7e9f447f22c23990602090a4565b50634e487b7160e01b600052603260045260246000fd5b8054821015611f06575b60005260206000200190600090565b611f0e611ed6565b611ef7565b6001600160a01b03821660009081526020829052604090209091905415611f38575050565b611f9f9060018301611f8682611f628354600160401b811015611fa2575b60018101855584611eed565b90919082549060031b9160018060a01b039283811b93849216901b16911916179055565b54929060018060a01b0316600052602052604060002090565b55565b611faa6107f7565b611f56565b50634e487b7160e01b600052601160045260246000fd5b60018110611fd6575b6000190190565b611fde611faf565b611fcf565b6002906002198111611ff3570190565b611ffb611faf565b0190565b50634e487b7160e01b600052603160045260246000fd5b6001600160a01b038216600090815260208290526040902054612037575050565b6001600160a01b03821660009081526020829052604081209092611f9f929091546001811061212e575b8419908181019160018401916120cc61208683855460018110612121575b0185611eed565b90546001600160a01b039660039290921b1c8616906120a982611f628389611eed565b60011910612114575b6001600160a01b0316600090815260208790526040902090565b5581548015612107575b01916120e28383611eed565b909182549160031b1b19169055559060018060a01b0316600052602052604060002090565b61210f611fff565b6120d6565b61211c611faf565b6120b2565b612129611faf565b61207f565b612136611faf565b612061565b6000549160ff8360081c16158093819461225a575b811561223a575b50156121db5761217d9183612174600160ff196000541617600055565b6121c257612268565b61218357565b61219361ff001960005416600055565b604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602090a1565b6121d661010061ff00196000541617600055565b612268565b50505050608460405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152fd5b303b1591508161224c575b5038612157565b6001915060ff161438612245565b600160ff8216109150612150565b9061228360ff60005460081c1661227e816123a4565b6123a4565b81516001600160401b038111612397575b6122a8816122a3606554610e55565b612433565b602080601f8311600114612304575081906122df946000926122f9575b50508160011b916000199060031b1c191617606555612524565b6122f060ff60005460081c166123a4565b61087f33611d55565b0151905038806122c5565b919293601f19841661233860656000527f8ff97419363ffd7000167f130ef7168fbea05faf9251824ca5043f113cc6a7c790565b936000905b82821061237f5750509160019391856122df97969410612366575b505050811b01606555612524565b015160001960f88460031b161c19169055388080612358565b8060018697829497870151815501960194019061233d565b61239f6107f7565b612294565b156123ab57565b5060405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608490fd5b50634e487b7160e01b600052600060045260246000fd5b818110612427575050565b6000815560010161241c565b90601f8211612440575050565b61087f9160656000527f8ff97419363ffd7000167f130ef7168fbea05faf9251824ca5043f113cc6a7c7906020601f840160051c8301931061248a575b601f0160051c019061241c565b909150819061247d565b90601f82116124a1575050565b61087f9160666000527f46501879b8ca8525e8c2fd519e2fbfcfa2ebea26501294aa02cbfcfb12e94354906020601f840160051c8301931061248a57601f0160051c019061241c565b9190601f81116124f957505050565b61087f926000526020600020906020601f840160051c8301931061248a57601f0160051c019061241c565b9081516001600160401b03811161260e575b61254a81612545606654610e55565b612494565b602080601f8311600114612586575081929360009261257b575b50508160011b916000199060031b1c191617606655565b015190503880612564565b90601f198316946125b960666000527f46501879b8ca8525e8c2fd519e2fbfcfa2ebea26501294aa02cbfcfb12e9435490565b926000905b8782106125f65750508360019596106125dd575b505050811b01606655565b015160001960f88460031b161c191690553880806125d2565b806001859682949686015181550195019301906125be565b6126166107f7565b612536565b91909182516001600160401b0381116126ea575b6126438161263d8454610e55565b846124ea565b602080601f831160011461267f575081929394600092612674575b50508160011b916000199060031b1c1916179055565b01519050388061265e565b90601f1983169561269585600052602060002090565b926000905b8882106126d2575050836001959697106126b9575b505050811b019055565b015160001960f88460031b161c191690553880806126af565b8060018596829496860151815501950193019061269a565b6126f26107f7565b61262f565b9793919692909695949561270a33611b84565b8015612911575b61271a90611811565b609b54986001600160a01b03811680156128c15760008b8152606760205260409020548b9290612753906001600160a01b031615612a74565b61275d8184611e66565b60008381526067602052604090205461277f906001600160a01b031615612a74565b6001600160a01b0381166000908152606860205260409020805460010190556127b2836000526067602052604060002090565b80546001600160a01b0319166001600160a01b039092169190911790556040517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60008092a46128066001609b5401609b55565b61281a89600052609c602052604060002090565b97612825908961261b565b612832906001890161261b565b61283f906002880161261b565b61284c906003870161261b565b612859906007860161261b565b6008840190612875919062ffffff1662ffffff19825416179055565b60006004840155612884610872565b9182526020820152600582016128a39060008052602052604060002090565b906128ad91612925565b6128b5612941565b61070b916006016129e0565b505050505050505050505050606460405162461bcd60e51b815260206004820152602060248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152fd5b5061271a61291e33611b84565b9050612711565b6001602061087f9361293881518561261b565b0151910161261b565b60405161294d81610836565b6000815290565b6001600160fe1b03811160011661296c575b60021b90565b612974611faf565b612966565b6129838154610e55565b908161298d575050565b81601f6000931160011461299f575055565b818352602083206129bb91601f0160051c81019060010161241c565b8160208120915555565b61087f92916129d35761261b565b6129db612405565b61261b565b815191600160401b8311612a67575b8154838355808410612a38575b50602080910191600052806000206000925b848410612a1c575050505050565b60018382612a2c8394518661261b565b01920193019290612a0e565b8260005283602060002091820191015b818110612a5557506129fc565b80612a61600192612979565b01612a48565b612a6f6107f7565b6129ef565b15612a7b57565b5060405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606490fd5b90611ffb6020928281519485920161071c565b600081815260676020526040902054612af7906001600160a01b03161515610de5565b612b0081610e32565b90600052609c6020526040600020612b5660405192612b1e8461080e565b601d84527f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000060208501526001600160a01b031661431f565b612b996003830160088401906000612b79612b74845462ffffff1690565b61441a565b6040518095819263891c235f60e01b835260078a01868b6004860161406c565b038173__$ecf603b2c2aa531f37c90ec146d2a3e91a$__5af4928315612ef1575b600093612ece575b506005850160048601549181612be384809490600052602052604060002090565b92612bf79190600052602052604060002090565b60010192612c0490614130565b935462ffffff16612c149061441a565b604051607b60f81b602082015267113730b6b2911d1160c11b6021820152978897919691612c4560298a01836140b4565b61088b60f21b81526002016e113232b9b1b934b83a34b7b7111d1160891b8152600f01612c7590600184016140b4565b61088b60f21b8152600201681137bbb732b9111d1160b91b8152600901612c9b91612ac1565b61088b60f21b81526002016f1132bc3a32b93730b62fbab936111d1160811b8152601001612ccb916002016140b4565b61088b60f21b8152600201681134b6b0b3b2911d1160b91b8152600901612cf191612ac1565b61088b60f21b81526002016e2261747472696275746573223a205b60881b8152600f017f7b2274726169745f74797065223a2022454e53222c202276616c7565223a22008152601f01612d43916140b4565b62089f4b60ea1b81526003017f7b2274726169745f74797065223a2022436f6d6d69742048617368222c20227681526630b63ab2911d1160c91b6020820152602701612d8e916140b4565b62089f4b60ea1b81526003017f7b2274726169745f74797065223a20225265706f7369746f7279222c20227661815265363ab2911d1160d11b6020820152602601612dd8916140b4565b62089f4b60ea1b81526003017f7b2274726169745f74797065223a202256657273696f6e222c202276616c7565815262111d1160e91b6020820152602301612e1f91612ac1565b62089f4b60ea1b81526003017f7b2274726169745f74797065223a2022436f6c6f72222c202276616c7565223a8152601160f91b6020820152602101612e6491612ac1565b61227d60f01b8152600201605d60f81b8152600101607d60f81b81526001010390601f19918281018252612e989082610851565b612ea190613f33565b9160405192839160208301612eb591612ac1565b612ebe91612ac1565b03908101825261070b9082610851565b612eea91933d90823e612ee13d82610851565b3d81019061400e565b9138612bc2565b612ef961171c565b612bba565b63ffffffff60e01b166380ac58cd60e01b8114908115612f31575b8115612f23575090565b6301ffc9a760e01b14919050565b635b5e139f60e01b81149150612f19565b6001600160a01b0390811615801580612fb2575b15612f8057505081612f7b61087f936000526099602052604060002060018154019055565b611e66565b15612f8f575061087f91611e66565b1615612f985750565b61087f906000526099602052604060002060018154019055565b508183161515612f56565b612fc73382611c14565b8015613048575b612fd79061191f565b600081815260676020526040902054612ffa906001600160a01b03161515610de5565b80600052609c60205261301482600260406000200161261b565b61301e339261305d565b907fedbf1209b3baa7c1b5c43052ce5c511e243b3241d9f67733141d14f1da88cba16000604051a4565b50612fd76130563383611bd5565b9050612fce565b6130759060206040519282848094519384920161071c565b810103902090565b6130873382611c14565b8015613108575b6130979061191f565b6000818152606760205260409020546130ba906001600160a01b03161515610de5565b80600052609c6020526130d482600360406000200161261b565b6130de339261305d565b907f91ce7fcd4462481791c3fe849f7049373c5b43ef44aed48e7f1ecce781586e156000604051a4565b506130976131163383611bd5565b905061308e565b6131273382611c14565b80156131a5575b6131379061191f565b60008181526067602052604090205461315a906001600160a01b03161515610de5565b80600052609c60205261317182604060002061261b565b61317b339261305d565b907ffbbfca16a2770c7ca6e7063ab1a7eea5fe441ffef818325db51752066a6b128a6000604051a4565b506131376131b33383611bd5565b905061312e565b6131c43382611c14565b8015613245575b6131d49061191f565b6000818152606760205260409020546131f7906001600160a01b03161515610de5565b80600052609c60205261321182600160406000200161261b565b61321b339261305d565b907fd771eaa1c1382b0a9867125fcd921fdeddd211538b5381353a877abfbe3b50a46000604051a4565b506131d46132533383611bd5565b90506131cb565b602061327391816040519382858094519384920161071c565b8101609d81520301902090565b600360a09183518155602084015160018201556040840151600282015501916132bb60608201511515849060ff801983541691151516179055565b6080810151835461ff00191690151560081b61ff00161783550151815462010000600160b01b03191660109190911b62010000600160b01b0316179055565b9061331d61087f92805490600160401b821015613326575b600182018155611eed565b6129d35761261b565b61332e6107f7565b613312565b600081815260676020526040902054613356906001600160a01b03161515610de5565b6001600160a01b0360036133698461325a565b015460101c1661341d576133ca600661338c83600052609c602052604060002090565b0154613396610881565b83815260208101919091526000604082018190526060820181905260808201523360a08201526133c58461325a565b613280565b6133ea8260066133e484600052609c602052604060002090565b016132fa565b6133f4339261305d565b7f8140554c907b4ba66a04ea1f43b882cba992d3db4cd5c49298a56402d7b36ca26000604051a4565b505060405162461bcd60e51b815260206004820152601e60248201527f466c65656b4552433732313a20415020616c7265616479206578697374730000604482015260649150fd5b1561346c57565b5060405162461bcd60e51b815260206004820152601760248201527f466c65656b4552433732313a20696e76616c69642041500000000000000000006044820152606490fd5b6001600160a01b036134d68160036134c98561325a565b015460101c161515613465565b60036134e18361325a565b015460101c163314156135bb5761358f6134fa8261325a565b549161356661351384600052609c602052604060002090565b600660016135208561325a565b0154910190600161355f61354661354061353a8654611fc6565b86611eed565b50611071565b61355a816135548688611eed565b906129c5565b61325a565b0155613602565b61358a6135728261325a565b60036000918281558260018201558260028201550155565b61305d565b9033917fef2f6bed86b96d79b41799f5285f73b31274bb303ebe5d55a3cb48c567ab2db06000604051a4565b505060405162461bcd60e51b815260206004820152601d60248201527f466c65656b4552433732313a206d757374206265204150206f776e65720000006044820152606490fd5b8054801561367b575b600019019061361a8282611eed565b61366e575b6136298154610e55565b908161363457505055565b81601f6000931160011461364757505555565b8183526020832061366391601f0160051c81019060010161241c565b816020812091555555565b613676612405565b61361f565b613683611fff565b61360b565b6001600160a01b03908161369b8261325a565b6003015460101c1615156136ae90613465565b6136b79061325a565b9081546136c390614130565b9060028301546136d290614130565b92600301548060081c60ff166136e7906143d4565b916136f460ff83166143d4565b9160101c166137029061431f565b604051607b60f81b60208201529485949193916021860169113a37b5b2b724b2111d60b11b8152600a0161373591612ac1565b600b60fa1b8152600101671139b1b7b932911d60c11b815260080161375991612ac1565b600b60fa1b81526001016e113730b6b2ab32b934b334b2b2111d60891b8152600f0161378491612ac1565b600b60fa1b8152600101711131b7b73a32b73a2b32b934b334b2b2111d60711b81526012016137b291612ac1565b600b60fa1b8152600101681137bbb732b9111d1160b91b81526009016137d791612ac1565b601160f91b8152600101607d60f81b815260010103601f198101825261070b9082610851565b60ff9060039061381c9061355a6001600160a01b03846134c98461325a565b015460081c1690565b61383b6001600160a01b0360036134c98461325a565b60026138468261325a565b0161385181546138a1565b905561385c8161325a565b54613873600261386b8461325a565b01549261305d565b6040519283527f3ea1c0fcf71b86fca8f96ccac3cf26fba8983d3bbbe7bd720f1865d67fbaee4360203394a4565b6001906000198114611ff3570190565b6138c76001600160a01b0360036134c98461325a565b60026138d28261325a565b0154156139395760026138e48261325a565b016138ef815461397f565b90556138fa8161325a565b54613909600261386b8461325a565b60405192835233927f3ea1c0fcf71b86fca8f96ccac3cf26fba8983d3bbbe7bd720f1865d67fbaee4390602090a4565b5050606460405162461bcd60e51b815260206004820152602060248201527f466c65656b4552433732313a2073636f72652063616e74206265206c6f7765726044820152fd5b8015611fd6576000190190565b6139a26001600160a01b0360036134c98461325a565b6139c76139ae8261325a565b546139b93382611c14565b908115613a2c575b5061191f565b6139e88260036139d68461325a565b019060ff801983541691151516179055565b6139fb6139f48261325a565b549161305d565b6040519182527fe2e598f7ff2dfd4bc3bd989635401b4c56846b7893cb7eace51d099f21e69bff60203394151593a4565b613a3891503390611bd5565b386139c1565b613a546001600160a01b0360036134c98461325a565b613a606139ae8261325a565b613a88826003613a6f8461325a565b019061ff00825491151560081b169061ff001916179055565b613a946139f48261325a565b6040519182527f17bd9b465aa0cdc6b308874903e9c38b13f561ecb1f2edaa8bf3969fe603d11c60203394151593a4565b600081815260676020526040902054613ae8906001600160a01b03161515610de5565b6000526020609c815260409060068260002001918254916001600160401b038311613b6c575b8193915193613b22828560051b0186610851565b8385526000928352818320908286015b858510613b425750505050505090565b60018481928451613b5e81613b57818a610e91565b0382610851565b815201930194019391613b32565b613b746107f7565b613b0e565b919091613b863382611c14565b8015613c50575b613b969061191f565b600081815260676020526040902054613bb9906001600160a01b03161515610de5565b7f73b929bf4db6be678cdbc6d41a5fe0a2cbb84ca95572062c4a978d8bd80a41b16040928351908482018281106001600160401b03821117613c43575b85528582526020820152613c34600091848352609c602052600586842001600487852001613c2481546138a1565b8091558452602052858320612925565b613c3e339561305d565b9351a4565b613c4b6107f7565b613bf6565b50613b96613c5e3383611bd5565b9050613b8d565b613c6f3382611bd5565b8015613dc3575b613c7f9061191f565b806001600160a01b0380613c9283610e32565b1615801580613dbb575b15613d8e5750613cbc826000526099602052604060002060018154019055565b613cc582611db3565b613cce82610e32565b600083815260696020526040812080546001600160a01b0319169055911680825260686020526040822060001981540190558282526067602052613d26604083206bffffffffffffffffffffffff60a01b8154169055565b7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef82604051a4613d6b6002613d6583600052609c602052604060002090565b01613dd8565b613d725750565b613d8961087f91600052609c602052604060002090565b613de2565b15613da157613d9c82611db3565b613cc5565b613d9c826000526099602052604060002060018154019055565b506000613c9c565b50613c7f613dd13383611bd5565b9050613c76565b61070b9054610e55565b613deb81612979565b6001613df8818301612979565b613e0460028301612979565b613e1060038301612979565b60006004830155600682018054906000815581613e40575b505050600881613e3c600760009401612979565b0155565b6000526020600020908101905b818110613e5957613e28565b80613e648492612979565b01613e4d565b60405190606082018281106001600160401b03821117613eda575b604052604082527f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f6040837f4142434445464748494a4b4c4d4e4f505152535455565758595a61626364656660208201520152565b613ee26107f7565b613e85565b60405190613ef48261080e565b6008825260203681840137565b90613f0b826108a0565b613f186040519182610851565b8281528092613f29601f19916108a0565b0190602036910137565b80511561400557613f42613e6a565b613f66613f61613f5c613f558551611fe3565b6003900490565b612954565b613f01565b9160208301918182518301915b828210613fb357505050600390510680600114613fa057600214613f95575090565b603d90600019015390565b50603d9081600019820153600119015390565b9091936004906003809401938451600190603f9082828260121c16880101518553828282600c1c16880101518386015382828260061c1688010151600286015316850101519082015301939190613f73565b5061070b611339565b6020818303126106d8578051906001600160401b0382116106cf570181601f820112156106d8578051614040816108a0565b9261404e6040519485610851565b818452602082840101116106cf5761070b916020808501910161071c565b9261409861070b959361408a6140a694608088526080880190610e91565b908682036020880152610e91565b908482036040860152610e91565b916060818403910152610751565b6000929181546140c381610e55565b9260019180831690811561411b57506001146140df5750505050565b90919293945060005260209081600020906000915b85831061410a5750505050019038808080610ebe565b8054858401529183019181016140f4565b60ff1916845250505001915038808080610ebe565b806000917a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000080821015614265575b506d04ee2d6d415b85acef810000000080831015614256575b50662386f26fc1000080831015614247575b506305f5e10080831015614238575b5061271080831015614229575b506064821015614219575b600a8092101561420f575b6001908160216141c7828701613f01565b95860101905b6141d9575b5050505090565b600019019083906f181899199a1a9b1b9c1cb0b131b232b360811b8282061a83530491821561420a579190826141cd565b6141d2565b91600101916141b6565b91906064600291049101916141ab565b600491939204910191386141a0565b60089193920491019138614193565b60109193920491019138614184565b60209193920491019138614172565b604093508104915038614159565b604051906142808261080e565b6007825260203681840137565b60209080511561429b570190565b611ffb611ed6565b60219080516001101561429b570190565b9060209180518210156142c657010190565b6142ce611ed6565b010190565b156142da57565b50606460405162461bcd60e51b815260206004820152602060248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b60405190606082018281106001600160401b038211176143c7575b604052602a8252604036602084013760306143548361428d565b536078614360836142a3565b536029905b600182116143785761070b9150156142d3565b80600f6143b4921660108110156143ba575b6f181899199a1a9b1b9c1cb0b131b232b360811b901a6143aa84866142b4565b5360041c9161397f565b90614365565b6143c2611ed6565b61438a565b6143cf6107f7565b61433a565b156143f9576040516143e58161080e565b60048152637472756560e01b602082015290565b6040516144058161080e565b600581526466616c736560d81b602082015290565b62ffffff16614427613ee7565b9060306144338361428d565b53607861443f836142a3565b5360079081905b600182116144db576144599150156142d3565b614461614273565b918251156144ce575b60236020840153600190815b838110614484575050505090565b6144bc9060011981116144c1575b6001600160f81b03196144a7828601856142b4565b511660001a6144b682886142b4565b536138a1565b614476565b6144c9611faf565b614492565b6144d6611ed6565b61446a565b80600f61450d92166010811015614513575b6f181899199a1a9b1b9c1cb0b131b232b360811b901a6143aa84876142b4565b90614446565b61451b611ed6565b6144ed56fea3646970667358221220c840b64c3d4c06cf9c4f24b98d406ed858dd15c39d335eb8f11de6a6094e74c76c6578706572696d656e74616cf564736f6c634300080c0041",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"apName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"verified\",\"type\":\"bool\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"triggeredBy\",\"type\":\"address\"}],\"name\":\"ChangeAccessPointContentVerify\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"apName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"verified\",\"type\":\"bool\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"triggeredBy\",\"type\":\"address\"}],\"name\":\"ChangeAccessPointNameVerify\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"apName\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"score\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"triggeredBy\",\"type\":\"address\"}],\"name\":\"ChangeAccessPointScore\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"toAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"byAddress\",\"type\":\"address\"}],\"name\":\"CollectionRoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"toAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"byAddress\",\"type\":\"address\"}],\"name\":\"CollectionRoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"apName\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"NewAccessPoint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"token\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"string\",\"name\":\"commitHash\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"triggeredBy\",\"type\":\"address\"}],\"name\":\"NewBuild\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"token\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"triggeredBy\",\"type\":\"address\"}],\"name\":\"NewTokenDescription\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"token\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"string\",\"name\":\"ENS\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"triggeredBy\",\"type\":\"address\"}],\"name\":\"NewTokenENS\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"token\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"string\",\"name\":\"externalURL\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"triggeredBy\",\"type\":\"address\"}],\"name\":\"NewTokenExternalURL\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"token\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"string\",\"name\":\"image\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"triggeredBy\",\"type\":\"address\"}],\"name\":\"NewTokenImage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"token\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"triggeredBy\",\"type\":\"address\"}],\"name\":\"NewTokenName\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"apName\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"RemoveAccessPoint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"toAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"byAddress\",\"type\":\"address\"}],\"name\":\"TokenRoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"toAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"byAddress\",\"type\":\"address\"}],\"name\":\"TokenRoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"apName\",\"type\":\"string\"}],\"name\":\"addAccessPoint\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"appAccessPoints\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"apName\",\"type\":\"string\"}],\"name\":\"decreaseAccessPointScore\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"apName\",\"type\":\"string\"}],\"name\":\"getAccessPointJSON\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"}],\"name\":\"getCollectionRoleMembers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"}],\"name\":\"getTokenRoleMembers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantCollectionRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantTokenRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasCollectionRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasTokenRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"apName\",\"type\":\"string\"}],\"name\":\"increaseAccessPointScore\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"apName\",\"type\":\"string\"}],\"name\":\"isAccessPointNameVerified\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"externalURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"ENS\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"commitHash\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"gitRepository\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"logo\",\"type\":\"string\"},{\"internalType\":\"uint24\",\"name\":\"color\",\"type\":\"uint24\"}],\"name\":\"mint\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"apName\",\"type\":\"string\"}],\"name\":\"removeAccessPoint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeCollectionRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"enum FleekAccessControl.Roles\",\"name\":\"role\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeTokenRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"apName\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"verified\",\"type\":\"bool\"}],\"name\":\"setAccessPointContentVerify\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"apName\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"verified\",\"type\":\"bool\"}],\"name\":\"setAccessPointNameVerify\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_commitHash\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_gitRepository\",\"type\":\"string\"}],\"name\":\"setTokenBuild\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_tokenDescription\",\"type\":\"string\"}],\"name\":\"setTokenDescription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_tokenENS\",\"type\":\"string\"}],\"name\":\"setTokenENS\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_tokenExternalURL\",\"type\":\"string\"}],\"name\":\"setTokenExternalURL\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_tokenName\",\"type\":\"string\"}],\"name\":\"setTokenName\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"addAccessPoint(uint256,string)\":{\"details\":\"Add a new AccessPoint register for an app token. The AP name should be a DNS or ENS url and it should be unique. Anyone can add an AP but it should requires a payment. May emit a {NewAccessPoint} event. Requirements: - the tokenId must be minted and valid. IMPORTANT: The payment is not set yet\"},\"appAccessPoints(uint256)\":{\"details\":\"A view function to gether the list of mirrros for a given app. Requirements: - the tokenId must be minted and valid.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC721-approve}.\"},\"balanceOf(address)\":{\"details\":\"See {IERC721-balanceOf}.\"},\"burn(uint256)\":{\"details\":\"Burns a previously minted `tokenId`. May emit a {Transfer} event. Requirements: - the tokenId must be minted and valid. - the sender must have the `tokenOwner` role.\"},\"decreaseAccessPointScore(string)\":{\"details\":\"Decreases the score of a AccessPoint registry if is greater than 0. May emit a {ChangeAccessPointScore} event. Requirements: - the AP must exist.\"},\"getAccessPointJSON(string)\":{\"details\":\"A view function to gether information about an AccessPoint. It returns a JSON string representing the AccessPoint information. Requirements: - the AP must exist.\"},\"getApproved(uint256)\":{\"details\":\"See {IERC721-getApproved}.\"},\"getCollectionRoleMembers(uint8)\":{\"details\":\"Returns an array of addresses that all have the collection role.\"},\"getTokenRoleMembers(uint256,uint8)\":{\"details\":\"Returns an array of addresses that all have the same token role for a certain tokenId.\"},\"grantCollectionRole(uint8,address)\":{\"details\":\"Grants the collection role to an address. Requirements: - the caller should have the collection role.\"},\"grantTokenRole(uint256,uint8,address)\":{\"details\":\"Grants the token role to an address. Requirements: - the caller should have the token role.\"},\"hasCollectionRole(uint8,address)\":{\"details\":\"Returns `True` if a certain address has the collection role.\"},\"hasTokenRole(uint256,uint8,address)\":{\"details\":\"Returns `True` if a certain address has the token role.\"},\"increaseAccessPointScore(string)\":{\"details\":\"Increases the score of a AccessPoint registry. May emit a {ChangeAccessPointScore} event. Requirements: - the AP must exist.\"},\"initialize(string,string)\":{\"details\":\"Initializes the contract by setting a `name` and a `symbol` to the token collection.\"},\"isAccessPointNameVerified(string)\":{\"details\":\"A view function to check if a AccessPoint is verified. Requirements: - the AP must exist.\"},\"isApprovedForAll(address,address)\":{\"details\":\"See {IERC721-isApprovedForAll}.\"},\"mint(address,string,string,string,string,string,string,string,uint24)\":{\"details\":\"Mints a token and returns a tokenId. If the `tokenId` has not been minted before, and the `to` address is not zero, emits a {Transfer} event. Requirements: - the caller must have ``collectionOwner``'s admin role.\"},\"name()\":{\"details\":\"See {IERC721Metadata-name}.\"},\"ownerOf(uint256)\":{\"details\":\"See {IERC721-ownerOf}.\"},\"removeAccessPoint(string)\":{\"details\":\"Remove an AccessPoint registry for an app token. It will also remove the AP from the app token APs list. May emit a {RemoveAccessPoint} event. Requirements: - the AP must exist. - must be called by the AP owner.\"},\"revokeCollectionRole(uint8,address)\":{\"details\":\"Revokes the collection role of an address. Requirements: - the caller should have the collection role.\"},\"revokeTokenRole(uint256,uint8,address)\":{\"details\":\"Revokes the token role of an address. Requirements: - the caller should have the token role.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"setAccessPointContentVerify(string,bool)\":{\"details\":\"Set the content verification of a AccessPoint registry. May emit a {ChangeAccessPointContentVerify} event. Requirements: - the AP must exist. - the sender must have the token controller role.\"},\"setAccessPointNameVerify(string,bool)\":{\"details\":\"Set the name verification of a AccessPoint registry. May emit a {ChangeAccessPointNameVerify} event. Requirements: - the AP must exist. - the sender must have the token controller role.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"See {IERC721-setApprovalForAll}.\"},\"setTokenBuild(uint256,string,string)\":{\"details\":\"Adds a new build to a minted `tokenId`'s builds mapping. May emit a {NewBuild} event. Requirements: - the tokenId must be minted and valid. - the sender must have the `tokenController` role.\"},\"setTokenDescription(uint256,string)\":{\"details\":\"Updates the `description` metadata field of a minted `tokenId`. May emit a {NewTokenDescription} event. Requirements: - the tokenId must be minted and valid. - the sender must have the `tokenController` role.\"},\"setTokenENS(uint256,string)\":{\"details\":\"Updates the `ENS` metadata field of a minted `tokenId`. May emit a {NewTokenENS} event. Requirements: - the tokenId must be minted and valid. - the sender must have the `tokenController` role.\"},\"setTokenExternalURL(uint256,string)\":{\"details\":\"Updates the `externalURL` metadata field of a minted `tokenId`. May emit a {NewTokenExternalURL} event. Requirements: - the tokenId must be minted and valid. - the sender must have the `tokenController` role.\"},\"setTokenName(uint256,string)\":{\"details\":\"Updates the `name` metadata field of a minted `tokenId`. May emit a {NewTokenName} event. Requirements: - the tokenId must be minted and valid. - the sender must have the `tokenController` role.\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"symbol()\":{\"details\":\"See {IERC721Metadata-symbol}.\"},\"tokenURI(uint256)\":{\"details\":\"Returns the token metadata associated with the `tokenId`. Returns a based64 encoded string value of the URI. Requirements: - the tokenId must be minted and valid.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-transferFrom}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/FleekERC721.sol\":\"FleekERC721\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[],\"viaIR\":true},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"keccak256\":\"0xe798cadb41e2da274913e4b3183a80f50fb057a42238fe8467e077268100ec27\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://899f850f7df5a270bccfb765d70069959ca1c20d3a7381c1c3bda8a3ffee1935\",\"dweb:/ipfs/QmVdnAqwyX2L3nX2HDA5WKGtVBFyH1nKE9A1k7fZnPBkhP\"]},\"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\":{\"keccak256\":\"0x2a6a0b9fd2d316dcb4141159a9d13be92654066d6c0ae92757ed908ecdfecff0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c05d9be7ee043009eb9f2089b452efc0961345531fc63354a249d7337c69f3bb\",\"dweb:/ipfs/QmTXhzgaYrh6og76BP85i6exNFAv5NYw64uVWyworNogyG\"]},\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\":{\"keccak256\":\"0xbb2ed8106d94aeae6858e2551a1e7174df73994b77b13ebd120ccaaef80155f5\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8bc3c6a456dba727d8dd9fd33420febede490abb49a07469f61d2a3ace66a95a\",\"dweb:/ipfs/QmVAWtEVj7K5AbvgJa9Dz22KiDq9eoptCjnVZqsTMtKXyd\"]},\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\":{\"keccak256\":\"0x2c0b89cef83f353c6f9488c013d8a5968587ffdd6dfc26aad53774214b97e229\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4a68e662c2a82412308b1feb24f3d61a44b3b8772f44cbd440446237313c3195\",\"dweb:/ipfs/QmfBuWUE2TQef9hghDzzuVkDskw3UGAyPgLmPifTNV7K6g\"]},\"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\":{\"keccak256\":\"0x95a471796eb5f030fdc438660bebec121ad5d063763e64d92376ffb4b5ce8b70\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4ffbd627e6958983d288801acdedbf3491ee0ebf1a430338bce47c96481ce9e3\",\"dweb:/ipfs/QmUM1vpmNgBV34sYf946SthDJNGhwwqjoRggmj4TUUQmdB\"]},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x2edcb41c121abc510932e8d83ff8b82cf9cdde35e7c297622f5c29ef0af25183\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://72460c66cd1c3b1c11b863e0d8df0a1c56f37743019e468dc312c754f43e3b06\",\"dweb:/ipfs/QmPExYKiNb9PUsgktQBupPaM33kzDHxaYoVeJdLhv8s879\"]},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d6520943ea55fdf5f0bafb39ed909f64de17051bc954ff3e88c9e5621412c79c\",\"dweb:/ipfs/QmWZ4rAKTQbNG2HxGs46AcTXShsVytKeLs7CUCdCSv5N7a\"]},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"keccak256\":\"0x6b9a5d35b744b25529a2856a8093e7c03fb35a34b1c4fb5499e560f8ade140da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://187b5c3a1c9e77678732a2cc5284237f9cfca6bc28ee8bc0a0f4f951d7b3a2f8\",\"dweb:/ipfs/Qmb2KFr7WuQu7btdCiftQG64vTzrG4UyzVmo53EYHcnHYA\"]},\"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\":{\"keccak256\":\"0x9a3b990bd56d139df3e454a9edf1c64668530b5a77fc32eb063bc206f958274a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0895399d170daab2d69b4c43a0202e5a07f2e67a93b26e3354dcbedb062232f7\",\"dweb:/ipfs/QmUM1VH3XDk559Dsgh4QPvupr3YVKjz87HrSyYzzVFZbxw\"]},\"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\":{\"keccak256\":\"0xc6cef87559d0aeffdf0a99803de655938a7779ec0a3cd5d4383483ad85565a09\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://92ad7e572cf44e6b4b37631b44b62f9eb9fb1cf14d9ce51c1504d5dc7ccaf758\",\"dweb:/ipfs/QmcnbqX85tsWnUXPmtuPLE4SczME2sJaTfmqEFkuAJvWhy\"]},\"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol\":{\"keccak256\":\"0xc1bd5b53319c68f84e3becd75694d941e8f4be94049903232cd8bc7c535aaa5a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://056027a78e6f4b78a39be530983551651ee5a052e786ca2c1c6a3bb1222b03b4\",\"dweb:/ipfs/QmXRUpywAqNwAfXS89vrtiE2THRM9dX9pQ4QxAkV1Wx9kt\"]},\"@openzeppelin/contracts/utils/Base64.sol\":{\"keccak256\":\"0x5f3461639fe20794cfb4db4a6d8477388a15b2e70a018043084b7c4bedfa8136\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://77e5309e2cc4cdc3395214edb0ff43ff5a5f7373f5a425383e540f6fab530f96\",\"dweb:/ipfs/QmTV8DZ9knJDa3b5NPBFQqjvTzodyZVjRUg5mx5A99JPLJ\"]},\"@openzeppelin/contracts/utils/Counters.sol\":{\"keccak256\":\"0xf0018c2440fbe238dd3a8732fa8e17a0f9dce84d31451dc8a32f6d62b349c9f1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://59e1c62884d55b70f3ae5432b44bb3166ad71ae3acd19c57ab6ddc3c87c325ee\",\"dweb:/ipfs/QmezuXg5GK5oeA4F91EZhozBFekhq5TD966bHPH18cCqhu\"]},\"@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xa4d1d62251f8574deb032a35fc948386a9b4de74b812d4f545a1ac120486b48a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8c969013129ba9e651a20735ef659fef6d8a1139ea3607bd4b26ddea2d645634\",\"dweb:/ipfs/QmVhVa6LGuzAcB8qgDtVHRkucn4ihj5UZr8xBLcJkP6ucb\"]},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xa1e8e83cd0087785df04ac79fb395d9f3684caeaf973d9e2c71caef723a3a5d6\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://33bbf48cc069be677705037ba7520c22b1b622c23b33e1a71495f2d36549d40b\",\"dweb:/ipfs/Qmct36zWXv3j7LZB83uwbg7TXwnZSN1fqHNDZ93GG98bGz\"]},\"contracts/FleekAccessControl.sol\":{\"keccak256\":\"0x99b148a767f42ff1bfcee7ff68d8b11ece6aa78a96a5637c9b5e1ddc1cca7b34\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ff6dd367c0f3894c2c3fcd28cd02ccce384bea6dc23baa7b03041be237cc64ae\",\"dweb:/ipfs/QmWGtcukpo1ApXiVxkAfMJ3u8Be9quLXBzExcXr6KJ4gmL\"]},\"contracts/FleekERC721.sol\":{\"keccak256\":\"0x17cb71d846831897ea6ced6e3a2fc36b830e6f31a91b2dc769066e8af44c0951\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1f3c29cc623a6751e8bacbf32eeb6200574904adfdd5fbb65e7bfce2e2ef313c\",\"dweb:/ipfs/QmaiC2fsTWamdfBAwKQmsjXrKkLvpYpWSrGcEk8LFqQBjS\"]},\"contracts/util/FleekSVG.sol\":{\"keccak256\":\"0x825f901fea144b1994171e060f996301a261a55a9c8482e5fdd31e21adab0e26\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d2f7572678c540100ba8a08ec771e991493a4f6fd626765747e588fd7844892b\",\"dweb:/ipfs/QmWATHHJm8b7BvT8vprdJ9hUbFLsvLqkPe1jZh8qudoDc7\"]},\"contracts/util/FleekStrings.sol\":{\"keccak256\":\"0xa3494dbe8df7abb25c60401cc7a23c720d912e9713784931abdc616cdb600eca\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://53873b5e4d672a6adfbe18863a4bcb9e26e7e4b801dfebed68a2dde44a06da2f\",\"dweb:/ipfs/Qmdpe9JjDhMcNQUzJUiSXQi6bPkDXR2ryWV9hLAXsNkKXY\"]}},\"version\":1}",
"storageLayout": {
"storage": [
{
@@ -1088,20 +1391,28 @@
"type": "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage)))"
},
{
- "astId": 4614,
+ "astId": 4692,
"contract": "contracts/FleekERC721.sol:FleekERC721",
- "label": "_tokenIds",
+ "label": "_appIds",
"offset": 0,
"slot": "155",
"type": "t_struct(Counter)2774_storage"
},
{
- "astId": 4619,
+ "astId": 4697,
"contract": "contracts/FleekERC721.sol:FleekERC721",
"label": "_apps",
"offset": 0,
"slot": "156",
- "type": "t_mapping(t_uint256,t_struct(App)4606_storage)"
+ "type": "t_mapping(t_uint256,t_struct(App)4671_storage)"
+ },
+ {
+ "astId": 4702,
+ "contract": "contracts/FleekERC721.sol:FleekERC721",
+ "label": "_accessPoints",
+ "offset": 0,
+ "slot": "157",
+ "type": "t_mapping(t_string_memory_ptr,t_struct(AccessPoint)4689_storage)"
}
],
"types": {
@@ -1116,6 +1427,12 @@
"label": "address[]",
"numberOfBytes": "32"
},
+ "t_array(t_string_storage)dyn_storage": {
+ "base": "t_string_storage",
+ "encoding": "dynamic_array",
+ "label": "string[]",
+ "numberOfBytes": "32"
+ },
"t_array(t_uint256)44_storage": {
"base": "t_uint256",
"encoding": "inplace",
@@ -1166,6 +1483,13 @@
"numberOfBytes": "32",
"value": "t_struct(Role)3943_storage"
},
+ "t_mapping(t_string_memory_ptr,t_struct(AccessPoint)4689_storage)": {
+ "encoding": "mapping",
+ "key": "t_string_memory_ptr",
+ "label": "mapping(string => struct FleekERC721.AccessPoint)",
+ "numberOfBytes": "32",
+ "value": "t_struct(AccessPoint)4689_storage"
+ },
"t_mapping(t_uint256,t_address)": {
"encoding": "mapping",
"key": "t_uint256",
@@ -1187,19 +1511,19 @@
"numberOfBytes": "32",
"value": "t_mapping(t_uint256,t_mapping(t_enum(Roles)3895,t_struct(Role)3943_storage))"
},
- "t_mapping(t_uint256,t_struct(App)4606_storage)": {
+ "t_mapping(t_uint256,t_struct(App)4671_storage)": {
"encoding": "mapping",
"key": "t_uint256",
"label": "mapping(uint256 => struct FleekERC721.App)",
"numberOfBytes": "32",
- "value": "t_struct(App)4606_storage"
+ "value": "t_struct(App)4671_storage"
},
- "t_mapping(t_uint256,t_struct(Build)4611_storage)": {
+ "t_mapping(t_uint256,t_struct(Build)4676_storage)": {
"encoding": "mapping",
"key": "t_uint256",
"label": "mapping(uint256 => struct FleekERC721.Build)",
"numberOfBytes": "32",
- "value": "t_struct(Build)4611_storage"
+ "value": "t_struct(Build)4676_storage"
},
"t_mapping(t_uint256,t_struct(Counter)2774_storage)": {
"encoding": "mapping",
@@ -1208,17 +1532,77 @@
"numberOfBytes": "32",
"value": "t_struct(Counter)2774_storage"
},
+ "t_string_memory_ptr": {
+ "encoding": "bytes",
+ "label": "string",
+ "numberOfBytes": "32"
+ },
"t_string_storage": {
"encoding": "bytes",
"label": "string",
"numberOfBytes": "32"
},
- "t_struct(App)4606_storage": {
+ "t_struct(AccessPoint)4689_storage": {
+ "encoding": "inplace",
+ "label": "struct FleekERC721.AccessPoint",
+ "members": [
+ {
+ "astId": 4678,
+ "contract": "contracts/FleekERC721.sol:FleekERC721",
+ "label": "tokenId",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 4680,
+ "contract": "contracts/FleekERC721.sol:FleekERC721",
+ "label": "index",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 4682,
+ "contract": "contracts/FleekERC721.sol:FleekERC721",
+ "label": "score",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint256"
+ },
+ {
+ "astId": 4684,
+ "contract": "contracts/FleekERC721.sol:FleekERC721",
+ "label": "contentVerified",
+ "offset": 0,
+ "slot": "3",
+ "type": "t_bool"
+ },
+ {
+ "astId": 4686,
+ "contract": "contracts/FleekERC721.sol:FleekERC721",
+ "label": "nameVerified",
+ "offset": 1,
+ "slot": "3",
+ "type": "t_bool"
+ },
+ {
+ "astId": 4688,
+ "contract": "contracts/FleekERC721.sol:FleekERC721",
+ "label": "owner",
+ "offset": 2,
+ "slot": "3",
+ "type": "t_address"
+ }
+ ],
+ "numberOfBytes": "128"
+ },
+ "t_struct(App)4671_storage": {
"encoding": "inplace",
"label": "struct FleekERC721.App",
"members": [
{
- "astId": 4592,
+ "astId": 4650,
"contract": "contracts/FleekERC721.sol:FleekERC721",
"label": "name",
"offset": 0,
@@ -1226,7 +1610,7 @@
"type": "t_string_storage"
},
{
- "astId": 4594,
+ "astId": 4652,
"contract": "contracts/FleekERC721.sol:FleekERC721",
"label": "description",
"offset": 0,
@@ -1234,7 +1618,7 @@
"type": "t_string_storage"
},
{
- "astId": 4596,
+ "astId": 4654,
"contract": "contracts/FleekERC721.sol:FleekERC721",
"label": "externalURL",
"offset": 0,
@@ -1242,7 +1626,7 @@
"type": "t_string_storage"
},
{
- "astId": 4598,
+ "astId": 4656,
"contract": "contracts/FleekERC721.sol:FleekERC721",
"label": "ENS",
"offset": 0,
@@ -1250,7 +1634,7 @@
"type": "t_string_storage"
},
{
- "astId": 4600,
+ "astId": 4658,
"contract": "contracts/FleekERC721.sol:FleekERC721",
"label": "currentBuild",
"offset": 0,
@@ -1258,22 +1642,46 @@
"type": "t_uint256"
},
{
- "astId": 4605,
+ "astId": 4663,
"contract": "contracts/FleekERC721.sol:FleekERC721",
"label": "builds",
"offset": 0,
"slot": "5",
- "type": "t_mapping(t_uint256,t_struct(Build)4611_storage)"
+ "type": "t_mapping(t_uint256,t_struct(Build)4676_storage)"
+ },
+ {
+ "astId": 4666,
+ "contract": "contracts/FleekERC721.sol:FleekERC721",
+ "label": "accessPoints",
+ "offset": 0,
+ "slot": "6",
+ "type": "t_array(t_string_storage)dyn_storage"
+ },
+ {
+ "astId": 4668,
+ "contract": "contracts/FleekERC721.sol:FleekERC721",
+ "label": "logo",
+ "offset": 0,
+ "slot": "7",
+ "type": "t_string_storage"
+ },
+ {
+ "astId": 4670,
+ "contract": "contracts/FleekERC721.sol:FleekERC721",
+ "label": "color",
+ "offset": 0,
+ "slot": "8",
+ "type": "t_uint24"
}
],
- "numberOfBytes": "192"
+ "numberOfBytes": "288"
},
- "t_struct(Build)4611_storage": {
+ "t_struct(Build)4676_storage": {
"encoding": "inplace",
"label": "struct FleekERC721.Build",
"members": [
{
- "astId": 4608,
+ "astId": 4673,
"contract": "contracts/FleekERC721.sol:FleekERC721",
"label": "commitHash",
"offset": 0,
@@ -1281,7 +1689,7 @@
"type": "t_string_storage"
},
{
- "astId": 4610,
+ "astId": 4675,
"contract": "contracts/FleekERC721.sol:FleekERC721",
"label": "gitRepository",
"offset": 0,
@@ -1329,6 +1737,11 @@
],
"numberOfBytes": "64"
},
+ "t_uint24": {
+ "encoding": "inplace",
+ "label": "uint24",
+ "numberOfBytes": "3"
+ },
"t_uint256": {
"encoding": "inplace",
"label": "uint256",
diff --git a/deployments/mumbai/FleekSVG.json b/deployments/mumbai/FleekSVG.json
new file mode 100644
index 0000000..493bd9c
--- /dev/null
+++ b/deployments/mumbai/FleekSVG.json
@@ -0,0 +1,48 @@
+{
+ "timestamp": "1/23/2023, 11:32:10 AM",
+ "address": "0x197d55b17045145077DAeB23B9AdE0FF300f0498",
+ "transactionHash": "0x1f6257692a914e0c1a8a52bc02b27db459db6227b7975b854a11edb5d46b9260",
+ "gasPrice": 2281682515,
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "ENS",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "logo",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "color",
+ "type": "string"
+ }
+ ],
+ "name": "generateBase64",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "pure",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x6080806040523461001a57612ae99081610021823930815050f35b50600080fdfe6080604052600480361015610015575b50600080fd5b6000803560e01c63891c235f1461002c575061000f565b60803660031901126100e05767ffffffffffffffff82358181116100d9576100579036908501610156565b926024358281116100d15761006f9036908301610156565b916044358181116100c8576100879036908401610156565b936064359182116100bf5750916100a96100af94926100bb9694369101610156565b92610226565b604051918291826101e3565b0390f35b94505050505080fd5b50505050809150fd5b505050809150fd5b5050809150fd5b809150fd5b50634e487b7160e01b600052604160045260246000fd5b90601f8019910116810190811067ffffffffffffffff82111761011e57604052565b6101266100e5565b604052565b60209067ffffffffffffffff8111610149575b601f01601f19160190565b6101516100e5565b61013e565b81601f820112156101a65780359061016d8261012b565b9261017b60405194856100fc565b8284526020838301011161019d57816000926020809301838601378301015290565b50505050600080fd5b505050600080fd5b918091926000905b8282106101ce5750116101c7575050565b6000910152565b915080602091830151818601520182916101b6565b6040916020825261020381518092816020860152602086860191016101ae565b601f01601f1916010190565b90610222602092828151948592016101ae565b0190565b604080517f3c7376672077696474683d223130363522206865696768743d2231303635222060208201527f76696577426f783d2230203020313036352031303635222066696c6c3d226e6f918101919091527f6e652220786d6c6e733d22687474703a2f2f7777772e77332e6f72672f32303060608201527f302f7376672220786d6c6e733a786c696e6b3d22687474703a2f2f7777772e77608082015271199737b93397989c9c9c97bc3634b735911f60711b60a08201529384939092909160b285017f3c7374796c6520747970653d22746578742f637373223e40696d706f7274207581527f726c282268747470733a2f2f666f6e74732e676f6f676c65617069732e636f6d60208201527f2f637373323f66616d696c793d496e7465723a77676874403530303b36303022604082015269149d9e17b9ba3cb6329f60b11b6060820152606a017f3c726563742077696474683d223130363522206865696768743d22313036352281527f2066696c6c3d2275726c28236261636b67726f756e642922202f3e3c7265637460208201527f206f7061636974793d22302e32222077696474683d223130363522206865696760408201527f68743d2231303635222066696c6c3d2275726c28236261636b67726f756e642d60608201526a3930b234b0b6149110179f60a91b6080820152608b017f3c672066696c7465723d2275726c28236469736b657474652d736861646f772981527f223e3c7061746820643d224d3835372e323331203237392e3731324c3930322e60208201527f3234203238362e363735433931302e353437203238372e3936203931372e393160408201527f35203239322e373231203932322e35203239392e3736384c3933382e3839342060608201527f3332342e393634433934322e323439203333302e3132203934332e333131203360808201527f33362e343337203934312e383237203334322e3430364c3933372e373938203360a08201527f35382e3631354c3932342e303439203335362e36354c3931392e34313620333760c08201527f342e3038344c3933342e303638203337362e32344c3739312e3934372039323260e08201527f2e313532433738382e313039203933362e383936203737332e363934203934366101008201527f2e333038203735382e363531203934332e3839334c3137392e363336203835306101208201527f2e393238433136322e333138203834382e313437203135312e323135203833306101408201527f2e393837203135352e373736203831342e3035314c3136302e343738203739366101608201527f2e35394c3730342e333135203837392e3537344c3835372e323331203237392e6101808201527f3731325a222066696c6c3d222330353035303522202f3e3c2f673e00000000006101a08201526101bb017f3c7061746820643d224d3834302e323331203234302e3731324c3838352e323481527f203234372e363735433839332e353437203234382e393631203930302e39313560208201527f203235332e373232203930352e35203236302e3736384c3932312e383934203260408201527f38352e393635433932352e323439203239312e3132203932362e33313120323960608201527f372e343337203932342e383237203330332e3430364c3932302e37393820333160808201527f392e3631364c3930372e303439203331372e36354c3930322e3431362033333560a08201527f2e3038344c3931372e303638203333372e3234314c3737342e3934372038383360c08201527f2e313532433737312e313039203839372e383936203735362e3639342039303760e08201527f2e333038203734312e363531203930342e3839334c3136322e363336203831316101008201527f2e393238433134352e333138203830392e313437203133342e323135203739316101208201527f2e393837203133382e373736203737352e3035314c3134332e343738203735376101408201527f2e35394c3638372e333135203834302e3537344c3834302e323331203234302e6101608201527f3731325a222066696c6c3d2275726c28236d61696e2922202f3e00000000000061018082015261019a01600080516020612a8683398151915281527f756c653d226576656e6f64642220643d224d3331392e383437203136312e353060208201527f32433331302e333536203136302e303037203330302e363734203136362e333260408201527f36203239382e323231203137352e3631364c3133382e373234203737392e373560608201527f38433133362e323731203738392e303438203134312e393737203739372e373960808201527f203135312e343638203739392e3238354c3734302e303631203839312e39373360a08201527f433734392e353533203839332e343637203735392e323335203838372e31343860c08201527f203736312e363837203837372e3835384c3930322e343035203334342e38353460e08201527f4c3838392e313538203334322e3736384c3839382e383732203330352e3937326101008201527f4c3931322e313139203330382e3035394c3931332e373333203330312e3934366101208201527f433931342e383337203239372e373632203931342e333039203239332e3437366101408201527f203931322e323531203238392e3932374c3839332e343834203235372e3536396101608201527f433839312e313533203235332e353439203838372e303633203235302e3832336101808201527f203838322e323231203235302e3036314c3832382e323035203234312e3535346101a08201527f433832322e323234203234302e363133203831352e383639203234322e3738336101c08201527f203831312e343237203234372e3238344c3830352e363836203235332e3130336101e08201527f433830342e323035203235342e363033203830322e303837203235352e3332366102008201527f203830302e303933203235352e3031334c3738332e363131203235322e3431376102208201527f4c3733342e33203433392e313936433733312e343339203435302e30333520376102408201527f32302e313433203435372e343037203730392e3037203435352e3636334c33326102608201527f382e383437203339352e373838433331372e373734203339342e3034352033316102808201527f312e313137203338332e383435203331332e393738203337332e3030374c33366102a08201527f362e353238203137332e3936324c3336362e353333203137332e3934314333366102c08201527f372e323334203137312e3234203336352e353732203136382e373032203336326102e08201527f2e3831203136382e3236374c3331392e383437203136312e3530325a4d3336396103008201527f2e333932203137342e3431344c3336382e363532203137372e3231374c3331366103208201527f2e383433203337332e343538433331342e3339203338322e373438203332302e6103408201527f303936203339312e3439203332392e353837203339322e3938354c3730392e386103608201527f31203435322e3836433731392e333031203435342e333534203732382e3938336103808201527f203434382e303335203733312e343336203433382e3734354c3738302e3734376103a08201527f203235312e3936364c3738332e323435203234322e3530344c3738332e3938356103c08201527f203233392e3730314c3336392e333932203137342e3431345a222066696c6c3d6103e08201526b111198999899989b1110179f60a11b61040082015261040c01600080516020612a8683398151915281527f756c653d226576656e6f646422207374726f6b653d2275726c28236d61696e2960208201527f22207374726f6b652d77696474683d223422207374726f6b652d6c696e65636160408201527f703d22726f756e6422207374726f6b652d6c696e656a6f696e3d22726f756e6460608201527f2220643d224d3331392e383437203136312e353032433331302e33353620313660808201527f302e303037203330302e363734203136362e333236203239382e32323120313760a08201527f352e3631364c3133382e373234203737392e373538433133362e32373120373860c08201527f392e303438203134312e393737203739372e3739203135312e3436382037393960e08201527f2e3238354c3734302e303631203839312e393733433734392e353533203839336101008201527f2e343637203735392e323335203838372e313438203736312e363837203837376101208201527f2e3835384c3930322e343035203334342e3835344c3838392e313538203334326101408201527f2e3736384c3839382e383732203330352e3937324c3931322e313139203330386101608201527f2e3035394c3931332e373333203330312e393436433931342e383337203239376101808201527f2e373632203931342e333039203239332e343736203931322e323531203238396101a08201527f2e3932374c3839332e343834203235372e353639433839312e313533203235336101c08201527f2e353439203838372e303633203235302e383233203838322e323231203235306101e08201527f2e3036314c3832382e323035203234312e353534433832322e323234203234306102008201527f2e363133203831352e383639203234322e373833203831312e343237203234376102208201527f2e3238344c3830352e363836203235332e313033433830342e323035203235346102408201527f2e363033203830322e303837203235352e333236203830302e303933203235356102608201527f2e3031334c3738332e363131203235322e3431374c3733342e33203433392e316102808201527f3936433733312e343339203435302e303335203732302e313433203435372e346102a08201527f3037203730392e3037203435352e3636334c3332382e383437203339352e37386102c08201527f38433331372e373734203339342e303435203331312e313137203338332e38346102e08201527f35203331332e393738203337332e3030374c3336362e353238203137332e39366103008201527f324c3336362e353333203137332e393431433336372e323334203137312e32346103208201527f203336352e353732203136382e373032203336322e3831203136382e3236374c6103408201527f3331392e383437203136312e3530325a4d3336392e333932203137342e3431346103608201527f4c3336382e363532203137372e3231374c3331362e383433203337332e3435386103808201527f433331342e3339203338322e373438203332302e303936203339312e343920336103a08201527f32392e353837203339322e3938354c3730392e3831203435322e3836433731396103c08201527f2e333031203435342e333534203732382e393833203434382e303335203733316103e08201527f2e343336203433382e3734354c3738302e373437203235312e3936364c3738336104008201527f2e323435203234322e3530344c3738332e393835203233392e3730314c3336396104208201527f2e333932203137342e3431345a222066696c6c3d2275726c28236469736b65746104408201527f74652d6772616469656e7429222066696c6c2d6f7061636974793d22302e32226104608201526210179f60e91b610480820152610483017f3c7061746820643d224d3333352e3338203230382e313133433333352e39323281527f203230382e313938203333362e343137203230372e363836203333362e32383360208201527f203230372e3137394c3333302e3339203138342e373935433333302e3234392060408201527f3138342e323631203332392e353239203138342e313438203332392e3132392060608201527f3138342e3539374c3331322e333538203230332e343131433331312e3937382060808201527f3230332e383338203331322e313734203230342e343538203331322e3731362060a08201527f3230342e3534344c3331372e393632203230352e3337433331382e333537203260c08201527f30352e343332203331382e353935203230352e373936203331382e343933203260e08201527f30362e3138334c3331342e37203232302e353531433331342e353937203232306101008201527f2e393338203331342e383335203232312e333032203331352e323331203232316101208201527f2e3336344c3332342e353339203232322e3833433332342e393335203232322e6101408201527f383933203332352e333338203232322e363239203332352e3434203232322e326101608201527f34324c3332392e323333203230372e383735433332392e333336203230372e346101808201527f3838203332392e373339203230372e323234203333302e313335203230372e326101a08201527f38364c3333352e3338203230382e3131335a222066696c6c3d2275726c28236d6101c08201526730b4b7149110179f60c11b6101e08201526101e8017f3c7061746820643d224d3331392e323832203236392e303837433331392e383281527f34203236392e313733203332302e333139203236382e363631203332302e313860208201527f36203236382e3135344c3331342e323932203234352e3737433331342e31353160408201527f203234352e323336203331332e343331203234352e313233203331332e30333160608201527f203234352e3537324c3239362e323631203236342e333836433239352e38382060808201527f3236342e383132203239362e303736203236352e343333203239362e3631382060a08201527f3236352e3531384c3330312e383634203236362e333434433330322e3235392060c08201527f3236362e343037203330322e343937203236362e373731203330322e3339352060e08201527f3236372e3135384c3239382e363032203238312e353236433239382e352032386101008201527f312e393133203239382e373337203238322e323737203239392e3133332032386101208201527f322e3333394c3330382e343431203238332e383035433330382e3833372032386101408201527f332e383637203330392e3234203238332e363034203330392e333433203238336101608201527f2e3231374c3331332e313336203236382e383439433331332e323338203236386101808201527f2e343632203331332e363431203236382e313939203331342e303337203236386101a08201527f2e3236314c3331392e323832203236392e3038375a222066696c6c3d22626c616101c08201527f636b222066696c6c2d6f7061636974793d22302e3522202f3e000000000000006101e08201526101f9017f3c7061746820643d224d3330332e313834203333302e303632433330332e373281527f36203333302e313438203330342e323231203332392e363336203330342e303860208201527f38203332392e3132384c3239382e313934203330362e373435433239382e303560408201527f33203330362e323131203239372e333333203330362e303938203239362e393360608201527f33203330362e3534374c3238302e313633203332352e333631433237392e373860808201527f32203332352e373837203237392e393739203332362e343038203238302e353260a08201527f203332362e3439334c3238352e373636203332372e333139433238362e31363160c08201527f203332372e333832203238362e333939203332372e373436203238362e32393760e08201527f203332382e3133334c3238322e353034203334322e353031433238322e3430326101008201527f203334322e383838203238322e363339203334332e323532203238332e3033356101208201527f203334332e3331344c3239322e333434203334342e3738433239322e373339206101408201527f3334342e383432203239332e313432203334342e353739203239332e323435206101608201527f3334342e3139324c3239372e303338203332392e383234433239372e313420336101808201527f32392e343337203239372e353433203332392e313734203239372e39333920336101a08201527f32392e3233364c3330332e313834203333302e3036325a222066696c6c3d22626101c08201527f6c61636b222066696c6c2d6f7061636974793d22302e3522202f3e00000000006101e08201526101fb017f3c70617468207374726f6b653d2275726c28236d61696e2922207374726f6b6581527f2d77696474683d223622207374726f6b652d6c696e656361703d22726f756e6460208201527f22207374726f6b652d6c696e656a6f696e3d22726f756e642220643d224d323960408201527f302e313039203436332e343138433239322e333538203435342e39303220333060608201527f312e323333203434392e3131203330392e393333203435302e34384c3737312e60808201527f3037203532332e303936433737392e3737203532342e3436372037383520353360a08201527f322e3438203738322e373532203534302e3939364c3639322e3038362038383460c08201527f2e3431384c3139392e343433203830362e38344c3239302e313039203436332e60e08201527f3431385a222066696c6c3d22626c61636b222066696c6c2d6f7061636974793d61010082015268111817189a1110179f60b91b61012082015261012901600080516020612a8683398151915281527f756c653d226576656e6f646422207374726f6b653d2275726c28236d61696e2960208201527f22207374726f6b652d77696474683d223622207374726f6b652d6c696e65636160408201527f703d22726f756e6422207374726f6b652d6c696e656a6f696e3d22726f756e6460608201527f2220643d224d3738372e353839203233372e3334394c3436302e33353420313860808201527f352e3831384c3430362e333235203339302e343639433430332e38373220333960a08201527f392e373539203430392e353738203430382e353031203431392e30363920343060c08201527f392e3939364c3731312e393334203435362e313134433732312e34323520343560e08201527f372e363039203733312e313037203435312e3239203733332e3536203434324c6101008201527f3738372e353839203233372e3334395a4d3636302e323639203234352e3031436101208201527f3635352e353233203234342e323633203635302e363832203234372e343233206101408201527f3634392e343536203235322e3036384c3630372e333836203431312e343138436101608201527f3630362e3136203431362e303633203630392e303133203432302e34333420366101808201527f31332e373539203432312e3138314c3638322e343939203433322e30303643366101a08201527f38372e323435203433322e373533203639322e303836203432392e35393420366101c08201527f39332e333132203432342e3934394c3733352e333832203236352e35393943376101e08201527f33362e363038203236302e393534203733332e373535203235362e35383320376102008201527f32392e3031203235352e3833354c3636302e323639203234352e30315a2220666102208201527234b6361e913ab9361411b6b0b4b7149110179f60691b61024082015261025301600080516020612a8683398151915281527f756c653d226576656e6f64642220643d224d3836342e363433203238332e393360208201527f37433836352e313836203238332e363035203836352e373038203238342e323560408201527f37203836352e323339203238342e3638334c3834342e323638203330332e373160608201527f39433834332e393338203330342e303138203834342e303933203330342e353160808201527f37203834342e353236203330342e3534384c3835332e373236203330352e323060a08201527f37433835342e313834203330352e3234203835342e333231203330352e37383760c08201527f203835332e393432203330362e3037314c3833332e383834203332312e31313260e08201527f433833332e353036203332312e333936203833332e363433203332312e3934336101008201527f203833342e313031203332312e3937364c3834342e303037203332322e3638356101208201527f433834342e343931203332322e3732203834342e363035203332332e333139206101408201527f3834342e313737203332332e35384c3739372e373532203335312e39353443376101608201527f39372e323039203335322e323836203739362e363837203335312e36333420376101808201527f39372e313536203335312e3230394c3831382e343033203333312e39323243386101a08201527f31382e373333203333312e363232203831382e353737203333312e31323320386101c08201527f31382e313435203333312e3039324c3830382e373438203333302e34324338306101e08201527f382e323932203333302e333837203830382e313534203332392e3834332038306102008201527f382e353239203332392e3535384c3832382e303534203331342e3734344338326102208201527f382e3433203331342e343539203832382e323931203331332e393135203832376102408201527f2e383335203331332e3838324c3831382e333839203331332e323036433831376102608201527f2e393034203331332e313731203831372e3739203331322e353732203831382e6102808201527f323138203331322e3331314c3836342e363433203238332e3933375a222066696102a08201526c36361e913bb434ba329110179f60991b6102c08201526102cd017f3c67207472616e73666f726d3d226d617472697828302e39383738323720302e81527f313535353537202d302e32353532363120302e3936363837322032353020373360208201527f3529223e3c7465787420666f6e742d66616d696c793d22496e7465722c20736160408201527f6e732d73657269662220666f6e742d7765696768743d22626f6c642220666f6e60608201527f742d73697a653d223432222066696c6c3d2223453545374638223e00000000006080820152609b016121e99161020f565b7f3c2f746578743e3c7465787420666f6e742d66616d696c793d22496e7465722c81527f2073616e732d73657269662220666f6e742d7765696768743d226e6f726d616c60208201527f2220793d2234302220666f6e742d73697a653d223232222066696c6c3d222337604082015266231c189c99111f60c91b60608201526067016122749161020f565b6a1e17ba32bc3a1f1e17b39f60a91b8152600b017f3c696d6167652077696474683d2231363722206865696768743d22313637222081527f7472616e73666f726d3d226d617472697828302e39383738323720302e31353560208201527f353537202d302e32353532363120302e393636383732203434342e313137203560408201526d191a17189b949110343932b31e9160911b6060820152606e0161231a9161020f565b631110179f60e11b8152600401651e3232b3399f60d11b81526006017f3c66696c7465722069643d226469736b657474652d736861646f772220783d2281527f37302e373438392220793d223139352e373132222077696474683d223935352e60208201527f37333322206865696768743d223833322e353538222066696c746572556e697460408201527f733d227573657253706163654f6e5573652220636f6c6f722d696e746572706f60608201527f6c6174696f6e2d66696c746572733d2273524742223e3c6665466c6f6f64206660808201527f6c6f6f642d6f7061636974793d223022202f3e3c6665426c656e6420696e3d2260a08201527f536f757263654772617068696322202f3e3c6665476175737369616e426c757260c08201527f20737464446576696174696f6e3d22343222202f3e3c2f66696c7465723e000060e082015260fe017f3c6c696e6561724772616469656e742069643d226261636b67726f756e64222081527f78313d223533322e35222079313d2230222078323d223533322e35222079323d60208201527f223130363522206772616469656e74556e6974733d227573657253706163654f60408201527f6e557365223e3c73746f70202f3e3c73746f70206f66667365743d223122207360608201527f746f702d636f6c6f723d222331333133313322202f3e3c2f6c696e656172477260808201526630b234b2b73a1f60c91b60a082015260a7017f3c72616469616c4772616469656e742069643d226261636b67726f756e642d7281527f616469616c222063783d2230222063793d22302220723d22312220677261646960208201527f656e74556e6974733d227573657253706163654f6e557365222067726164696560408201527f6e745472616e73666f726d3d227472616e736c617465283533322e352035333260608201527f2e352920726f746174652838392e39363129207363616c652837333529223e3c60808201527039ba37b81039ba37b816b1b7b637b91e9160791b60a082015260b101612616908261020f565b7f22202f3e3c73746f70206f66667365743d2231222073746f702d636f6c6f723d8152601160f91b6020820152602101612650908261020f565b7f222073746f702d6f7061636974793d223022202f3e3c2f72616469616c4772618152653234b2b73a1f60d11b60208201526026017f3c6c696e6561724772616469656e742069643d226469736b657474652d67726181527f6469656e74222078313d223932352e363236222079313d223235362e3839362260208201527f2078323d223133362e373739222079323d223830302e3230332220677261646960408201527f656e74556e6974733d227573657253706163654f6e557365223e3c73746f702060608201526b39ba37b816b1b7b637b91e9160a11b6080820152608c0161273c908261020f565b7f22202f3e3c73746f70206f66667365743d2231222073746f702d636f6c6f723d81527f222332433331334622202f3e3c2f6c696e6561724772616469656e743e0000006020820152603d017f3c6c696e6561724772616469656e742069643d226d61696e223e3c73746f702081526b39ba37b816b1b7b637b91e9160a11b6020820152602c016127cc9161020f565b741110179f1e17b634b732b0b923b930b234b2b73a1f60591b8152601501661e17b232b3399f60c91b8152600701651e17b9bb339f60d11b81526006010390601f1991828101825261281e90826100fc565b612827906129aa565b6040517f646174613a696d6167652f7376672b786d6c3b6261736536342c000000000000602082015291908290603a82016128619161020f565b03908101825261287190826100fc565b90565b604051906020820182811067ffffffffffffffff821117612899575b60405260008252565b6128a16100e5565b612890565b604051906060820182811067ffffffffffffffff821117612917575b604052604082527f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f6040837f4142434445464748494a4b4c4d4e4f505152535455565758595a61626364656660208201520152565b61291f6100e5565b6128c2565b50634e487b7160e01b600052601160045260246000fd5b600290600219811161294b570190565b610222612924565b6001600160fe1b03811160011661296b575b60021b90565b612973612924565b612965565b906129828261012b565b61298f60405191826100fc565b82815280926129a0601f199161012b565b0190602036910137565b805115612a7c576129b96128a6565b6129dd6129d86129d36129cc855161293b565b6003900490565b612953565b612978565b9160208301918182518301915b828210612a2a57505050600390510680600114612a1757600214612a0c575090565b603d90600019015390565b50603d9081600019820153600119015390565b9091936004906003809401938451600190603f9082828260121c16880101518553828282600c1c16880101518386015382828260061c16880101516002860153168501015190820153019391906129ea565b5061287161287456fe3c706174682066696c6c2d72756c653d226576656e6f64642220636c69702d72a36469706673582212208fd612fddcc34b313120008ebd7346aa8b4b29cf7f1ad48096c343f09d1b5b806c6578706572696d656e74616cf564736f6c634300080c0041",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"ENS\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"logo\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"color\",\"type\":\"string\"}],\"name\":\"generateBase64\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"generateBase64(string,string,string,string)\":{\"details\":\"Generates a SVG image.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/util/FleekSVG.sol\":\"FleekSVG\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[],\"viaIR\":true},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"keccak256\":\"0xe798cadb41e2da274913e4b3183a80f50fb057a42238fe8467e077268100ec27\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://899f850f7df5a270bccfb765d70069959ca1c20d3a7381c1c3bda8a3ffee1935\",\"dweb:/ipfs/QmVdnAqwyX2L3nX2HDA5WKGtVBFyH1nKE9A1k7fZnPBkhP\"]},\"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\":{\"keccak256\":\"0x2a6a0b9fd2d316dcb4141159a9d13be92654066d6c0ae92757ed908ecdfecff0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c05d9be7ee043009eb9f2089b452efc0961345531fc63354a249d7337c69f3bb\",\"dweb:/ipfs/QmTXhzgaYrh6og76BP85i6exNFAv5NYw64uVWyworNogyG\"]},\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\":{\"keccak256\":\"0xbb2ed8106d94aeae6858e2551a1e7174df73994b77b13ebd120ccaaef80155f5\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8bc3c6a456dba727d8dd9fd33420febede490abb49a07469f61d2a3ace66a95a\",\"dweb:/ipfs/QmVAWtEVj7K5AbvgJa9Dz22KiDq9eoptCjnVZqsTMtKXyd\"]},\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\":{\"keccak256\":\"0x2c0b89cef83f353c6f9488c013d8a5968587ffdd6dfc26aad53774214b97e229\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4a68e662c2a82412308b1feb24f3d61a44b3b8772f44cbd440446237313c3195\",\"dweb:/ipfs/QmfBuWUE2TQef9hghDzzuVkDskw3UGAyPgLmPifTNV7K6g\"]},\"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\":{\"keccak256\":\"0x95a471796eb5f030fdc438660bebec121ad5d063763e64d92376ffb4b5ce8b70\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4ffbd627e6958983d288801acdedbf3491ee0ebf1a430338bce47c96481ce9e3\",\"dweb:/ipfs/QmUM1vpmNgBV34sYf946SthDJNGhwwqjoRggmj4TUUQmdB\"]},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x2edcb41c121abc510932e8d83ff8b82cf9cdde35e7c297622f5c29ef0af25183\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://72460c66cd1c3b1c11b863e0d8df0a1c56f37743019e468dc312c754f43e3b06\",\"dweb:/ipfs/QmPExYKiNb9PUsgktQBupPaM33kzDHxaYoVeJdLhv8s879\"]},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d6520943ea55fdf5f0bafb39ed909f64de17051bc954ff3e88c9e5621412c79c\",\"dweb:/ipfs/QmWZ4rAKTQbNG2HxGs46AcTXShsVytKeLs7CUCdCSv5N7a\"]},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"keccak256\":\"0x6b9a5d35b744b25529a2856a8093e7c03fb35a34b1c4fb5499e560f8ade140da\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://187b5c3a1c9e77678732a2cc5284237f9cfca6bc28ee8bc0a0f4f951d7b3a2f8\",\"dweb:/ipfs/Qmb2KFr7WuQu7btdCiftQG64vTzrG4UyzVmo53EYHcnHYA\"]},\"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\":{\"keccak256\":\"0x9a3b990bd56d139df3e454a9edf1c64668530b5a77fc32eb063bc206f958274a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0895399d170daab2d69b4c43a0202e5a07f2e67a93b26e3354dcbedb062232f7\",\"dweb:/ipfs/QmUM1VH3XDk559Dsgh4QPvupr3YVKjz87HrSyYzzVFZbxw\"]},\"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\":{\"keccak256\":\"0xc6cef87559d0aeffdf0a99803de655938a7779ec0a3cd5d4383483ad85565a09\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://92ad7e572cf44e6b4b37631b44b62f9eb9fb1cf14d9ce51c1504d5dc7ccaf758\",\"dweb:/ipfs/QmcnbqX85tsWnUXPmtuPLE4SczME2sJaTfmqEFkuAJvWhy\"]},\"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol\":{\"keccak256\":\"0xc1bd5b53319c68f84e3becd75694d941e8f4be94049903232cd8bc7c535aaa5a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://056027a78e6f4b78a39be530983551651ee5a052e786ca2c1c6a3bb1222b03b4\",\"dweb:/ipfs/QmXRUpywAqNwAfXS89vrtiE2THRM9dX9pQ4QxAkV1Wx9kt\"]},\"@openzeppelin/contracts/utils/Base64.sol\":{\"keccak256\":\"0x5f3461639fe20794cfb4db4a6d8477388a15b2e70a018043084b7c4bedfa8136\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://77e5309e2cc4cdc3395214edb0ff43ff5a5f7373f5a425383e540f6fab530f96\",\"dweb:/ipfs/QmTV8DZ9knJDa3b5NPBFQqjvTzodyZVjRUg5mx5A99JPLJ\"]},\"@openzeppelin/contracts/utils/Counters.sol\":{\"keccak256\":\"0xf0018c2440fbe238dd3a8732fa8e17a0f9dce84d31451dc8a32f6d62b349c9f1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://59e1c62884d55b70f3ae5432b44bb3166ad71ae3acd19c57ab6ddc3c87c325ee\",\"dweb:/ipfs/QmezuXg5GK5oeA4F91EZhozBFekhq5TD966bHPH18cCqhu\"]},\"@openzeppelin/contracts/utils/Strings.sol\":{\"keccak256\":\"0xa4d1d62251f8574deb032a35fc948386a9b4de74b812d4f545a1ac120486b48a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8c969013129ba9e651a20735ef659fef6d8a1139ea3607bd4b26ddea2d645634\",\"dweb:/ipfs/QmVhVa6LGuzAcB8qgDtVHRkucn4ihj5UZr8xBLcJkP6ucb\"]},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xa1e8e83cd0087785df04ac79fb395d9f3684caeaf973d9e2c71caef723a3a5d6\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://33bbf48cc069be677705037ba7520c22b1b622c23b33e1a71495f2d36549d40b\",\"dweb:/ipfs/Qmct36zWXv3j7LZB83uwbg7TXwnZSN1fqHNDZ93GG98bGz\"]},\"contracts/FleekAccessControl.sol\":{\"keccak256\":\"0x99b148a767f42ff1bfcee7ff68d8b11ece6aa78a96a5637c9b5e1ddc1cca7b34\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ff6dd367c0f3894c2c3fcd28cd02ccce384bea6dc23baa7b03041be237cc64ae\",\"dweb:/ipfs/QmWGtcukpo1ApXiVxkAfMJ3u8Be9quLXBzExcXr6KJ4gmL\"]},\"contracts/FleekERC721.sol\":{\"keccak256\":\"0x17cb71d846831897ea6ced6e3a2fc36b830e6f31a91b2dc769066e8af44c0951\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1f3c29cc623a6751e8bacbf32eeb6200574904adfdd5fbb65e7bfce2e2ef313c\",\"dweb:/ipfs/QmaiC2fsTWamdfBAwKQmsjXrKkLvpYpWSrGcEk8LFqQBjS\"]},\"contracts/util/FleekSVG.sol\":{\"keccak256\":\"0x825f901fea144b1994171e060f996301a261a55a9c8482e5fdd31e21adab0e26\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d2f7572678c540100ba8a08ec771e991493a4f6fd626765747e588fd7844892b\",\"dweb:/ipfs/QmWATHHJm8b7BvT8vprdJ9hUbFLsvLqkPe1jZh8qudoDc7\"]},\"contracts/util/FleekStrings.sol\":{\"keccak256\":\"0xa3494dbe8df7abb25c60401cc7a23c720d912e9713784931abdc616cdb600eca\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://53873b5e4d672a6adfbe18863a4bcb9e26e7e4b801dfebed68a2dde44a06da2f\",\"dweb:/ipfs/Qmdpe9JjDhMcNQUzJUiSXQi6bPkDXR2ryWV9hLAXsNkKXY\"]}},\"version\":1}",
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
diff --git a/deployments/mumbai/proxy.json b/deployments/mumbai/proxy.json
index c59d28f..1dfc438 100644
--- a/deployments/mumbai/proxy.json
+++ b/deployments/mumbai/proxy.json
@@ -1,5 +1,13 @@
{
"FleekERC721": [
+ {
+ "address": "0x8679f8A4Fb3AaA1E851100D2C0444a729a3D946C",
+ "timestamp": "1/19/2023, 8:33:42 PM"
+ },
+ {
+ "address": "0x72b255A13ac5758971Ba365913e432eEd341656D",
+ "timestamp": "1/18/2023, 4:15:56 PM"
+ },
{
"address": "0x21d7fBe220958A0F0f7cAE58780fe812EbcB3cd8",
"timestamp": "1/16/2023, 8:51:51 AM"
diff --git a/deployments/mumbai/solcInputs/0eda7437ce4f580aad196968f5821802.json b/deployments/mumbai/solcInputs/0eda7437ce4f580aad196968f5821802.json
new file mode 100644
index 0000000..9ec30cb
--- /dev/null
+++ b/deployments/mumbai/solcInputs/0eda7437ce4f580aad196968f5821802.json
@@ -0,0 +1,85 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initialized`\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initializing`\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721Upgradeable.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256, /* firstTokenId */\n uint256 batchSize\n ) internal virtual {\n if (batchSize > 1) {\n if (from != address(0)) {\n _balances[from] -= batchSize;\n }\n if (to != address(0)) {\n _balances[to] += batchSize;\n }\n }\n }\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 firstTokenId,\n uint256 batchSize\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = MathUpgradeable.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, MathUpgradeable.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Base64.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n *\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n string memory result = new string(4 * ((data.length + 2) / 3));\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n\n // When data `bytes` is not exactly 3 bytes long\n // it is padded with `=` characters at the end\n switch mod(mload(data), 3)\n case 1 {\n mstore8(sub(resultPtr, 1), 0x3d)\n mstore8(sub(resultPtr, 2), 0x3d)\n }\n case 2 {\n mstore8(sub(resultPtr, 1), 0x3d)\n }\n }\n\n return result;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Counters.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/math/Math.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "contracts/FleekAccessControl.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\ncontract FleekAccessControl is Initializable {\n using Counters for Counters.Counter;\n\n enum Roles {\n Owner,\n Controller\n }\n\n event TokenRoleGranted(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event TokenRoleRevoked(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleGranted(Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleRevoked(Roles indexed role, address indexed toAddress, address byAddress);\n\n struct Role {\n mapping(address => uint256) indexes;\n address[] members;\n }\n\n Counters.Counter private _collectionRolesVersion;\n // _collectionRoles[version][role]\n mapping(uint256 => mapping(Roles => Role)) private _collectionRoles;\n\n mapping(uint256 => Counters.Counter) private _tokenRolesVersion;\n // _tokenRoles[tokenId][version][role]\n mapping(uint256 => mapping(uint256 => mapping(Roles => Role))) private _tokenRoles;\n\n /**\n * @dev Initializes the contract by granting the `Owner` role to the deployer.\n */\n function __FleekAccessControl_init() internal onlyInitializing {\n _grantCollectionRole(Roles.Owner, msg.sender);\n }\n\n /**\n * @dev Checks if the `msg.sender` has a certain role.\n */\n modifier requireCollectionRole(Roles role) {\n require(\n hasCollectionRole(role, msg.sender) || hasCollectionRole(Roles.Owner, msg.sender),\n \"FleekAccessControl: must have collection role\"\n );\n _;\n }\n\n /**\n * @dev Checks if the `msg.sender` has the `Token` role for a certain `tokenId`.\n */\n modifier requireTokenRole(uint256 tokenId, Roles role) {\n require(\n hasTokenRole(tokenId, role, msg.sender) || hasTokenRole(tokenId, Roles.Owner, msg.sender),\n \"FleekAccessControl: must have token role\"\n );\n _;\n }\n\n /**\n * @dev Grants the collection role to an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function grantCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _grantCollectionRole(role, account);\n }\n\n /**\n * @dev Grants the token role to an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function grantTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _grantTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function revokeCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _revokeCollectionRole(role, account);\n }\n\n /**\n * @dev Revokes the token role of an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function revokeTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _revokeTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Returns `True` if a certain address has the collection role.\n */\n function hasCollectionRole(Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _collectionRolesVersion.current();\n\n return _collectionRoles[currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns `True` if a certain address has the token role.\n */\n function hasTokenRole(uint256 tokenId, Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns an array of addresses that all have the collection role.\n */\n function getCollectionRoleMembers(Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _collectionRolesVersion.current();\n return _collectionRoles[currentVersion][role].members;\n }\n\n /**\n * @dev Returns an array of addresses that all have the same token role for a certain tokenId.\n */\n function getTokenRoleMembers(uint256 tokenId, Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].members;\n }\n\n /**\n * @dev Grants the collection role to an address.\n */\n function _grantCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _grantRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleGranted(role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n */\n function _revokeCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _revokeRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleRevoked(role, account, msg.sender);\n }\n\n /**\n * @dev Grants the token role to an address.\n */\n function _grantTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _grantRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleGranted(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the token role of an address.\n */\n function _revokeTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _revokeRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleRevoked(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Grants a certain role to a certain address.\n */\n function _grantRole(Role storage role, address account) internal {\n if (role.indexes[account] == 0) {\n role.members.push(account);\n role.indexes[account] = role.members.length;\n }\n }\n\n /**\n * @dev Revokes a certain role from a certain address.\n */\n function _revokeRole(Role storage role, address account) internal {\n if (role.indexes[account] != 0) {\n uint256 index = role.indexes[account] - 1;\n uint256 lastIndex = role.members.length - 1;\n address lastAccount = role.members[lastIndex];\n\n role.members[index] = lastAccount;\n role.indexes[lastAccount] = index + 1;\n\n role.members.pop();\n delete role.indexes[account];\n }\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId.\n * Should only be used for burning tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId) internal {\n _tokenRolesVersion[tokenId].increment();\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId and grants the owner role to a new address.\n * Should only be used for transferring tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId, address newOwner) internal {\n _clearAllTokenRoles(tokenId);\n _grantTokenRole(tokenId, Roles.Owner, newOwner);\n }\n}\n"
+ },
+ "contracts/FleekERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"./FleekAccessControl.sol\";\nimport \"./util/FleekStrings.sol\";\n\ncontract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl {\n using Strings for uint256;\n using Counters for Counters.Counter;\n using FleekStrings for FleekERC721.App;\n using FleekStrings for FleekERC721.AccessPoint;\n using FleekStrings for string;\n\n event NewBuild(uint256 indexed token, string indexed commitHash, address indexed triggeredBy);\n event NewTokenName(uint256 indexed token, string indexed name, address indexed triggeredBy);\n event NewTokenDescription(uint256 indexed token, string indexed description, address indexed triggeredBy);\n event NewTokenImage(uint256 indexed token, string indexed image, address indexed triggeredBy);\n event NewTokenExternalURL(uint256 indexed token, string indexed externalURL, address indexed triggeredBy);\n event NewTokenENS(uint256 indexed token, string indexed ENS, address indexed triggeredBy);\n\n event NewAccessPoint(string indexed apName, uint256 indexed tokenId, address indexed owner);\n event RemoveAccessPoint(string indexed apName, uint256 indexed tokenId, address indexed owner);\n event ChangeAccessPointScore(\n string indexed apName,\n uint256 indexed tokenId,\n uint256 score,\n address indexed triggeredBy\n );\n event ChangeAccessPointNameVerify(\n string indexed apName,\n uint256 tokenId,\n bool indexed verified,\n address indexed triggeredBy\n );\n event ChangeAccessPointContentVerify(\n string indexed apName,\n uint256 tokenId,\n bool indexed verified,\n address indexed triggeredBy\n );\n\n /**\n * The properties are stored as string to keep consistency with\n * other token contracts, we might consider changing for bytes32\n * in the future due to gas optimization.\n */\n struct App {\n string name; // Name of the site\n string description; // Description about the site\n string externalURL; // Site URL\n string ENS; // ENS ID\n uint256 currentBuild; // The current build number (Increments by one with each change, starts at zero)\n mapping(uint256 => Build) builds; // Mapping to build details for each build number\n string[] accessPoints; // List of app AccessPoint\n string logo;\n uint24 color; // Color of the nft\n }\n\n /**\n * The metadata that is stored for each build.\n */\n struct Build {\n string commitHash;\n string gitRepository;\n }\n\n /**\n * The stored data for each AccessPoint.\n */\n struct AccessPoint {\n uint256 tokenId;\n uint256 index;\n uint256 score;\n bool contentVerified;\n bool nameVerified;\n address owner;\n }\n\n Counters.Counter private _appIds;\n mapping(uint256 => App) private _apps;\n mapping(string => AccessPoint) private _accessPoints;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function initialize(string memory _name, string memory _symbol) public initializer {\n __ERC721_init(_name, _symbol);\n __FleekAccessControl_init();\n }\n\n /**\n * @dev Checks if the AccessPoint exists.\n */\n modifier requireAP(string memory apName) {\n require(_accessPoints[apName].owner != address(0), \"FleekERC721: invalid AP\");\n _;\n }\n\n /**\n * @dev Mints a token and returns a tokenId.\n *\n * If the `tokenId` has not been minted before, and the `to` address is not zero, emits a {Transfer} event.\n *\n * Requirements:\n *\n * - the caller must have ``collectionOwner``'s admin role.\n *\n */\n function mint(\n address to,\n string memory name,\n string memory description,\n string memory externalURL,\n string memory ENS,\n string memory commitHash,\n string memory gitRepository,\n string memory logo,\n uint24 color\n ) public payable requireCollectionRole(Roles.Owner) returns (uint256) {\n uint256 tokenId = _appIds.current();\n _mint(to, tokenId);\n _appIds.increment();\n\n App storage app = _apps[tokenId];\n app.name = name;\n app.description = description;\n app.externalURL = externalURL;\n app.ENS = ENS;\n app.logo = logo;\n app.color = color;\n\n // The mint interaction is considered to be the first build of the site. Updates from now on all increment the currentBuild by one and update the mapping.\n app.currentBuild = 0;\n app.builds[0] = Build(commitHash, gitRepository);\n app.accessPoints = new string[](0);\n\n return tokenId;\n }\n\n /**\n * @dev Returns the token metadata associated with the `tokenId`.\n *\n * Returns a based64 encoded string value of the URI.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n address owner = ownerOf(tokenId);\n App storage app = _apps[tokenId];\n\n return string(abi.encodePacked(_baseURI(), app.toString(owner).toBase64()));\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Upgradeable) returns (bool) {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Override of _beforeTokenTransfer of ERC721.\n * Here it needs to update the token controller roles for mint, burn and transfer.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId,\n uint256 batchSize\n ) internal virtual override {\n if (from != address(0) && to != address(0)) {\n // Transfer\n _clearAllTokenRoles(tokenId, to);\n } else if (from == address(0)) {\n // Mint\n _grantTokenRole(tokenId, Roles.Owner, to);\n } else if (to == address(0)) {\n // Burn\n _clearAllTokenRoles(tokenId);\n }\n super._beforeTokenTransfer(from, to, tokenId, batchSize);\n }\n\n /**\n * @dev A baseURI internal function implementation to be called in the `tokenURI` function.\n */\n function _baseURI() internal view virtual override returns (string memory) {\n return \"data:application/json;base64,\";\n }\n\n /**\n * @dev Updates the `externalURL` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenExternalURL} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenExternalURL(\n uint256 tokenId,\n string memory _tokenExternalURL\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].externalURL = _tokenExternalURL;\n emit NewTokenExternalURL(tokenId, _tokenExternalURL, msg.sender);\n }\n\n /**\n * @dev Updates the `ENS` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenENS} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenENS(\n uint256 tokenId,\n string memory _tokenENS\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].ENS = _tokenENS;\n emit NewTokenENS(tokenId, _tokenENS, msg.sender);\n }\n\n /**\n * @dev Updates the `name` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenName} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenName(\n uint256 tokenId,\n string memory _tokenName\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].name = _tokenName;\n emit NewTokenName(tokenId, _tokenName, msg.sender);\n }\n\n /**\n * @dev Updates the `description` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenDescription} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenDescription(\n uint256 tokenId,\n string memory _tokenDescription\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].description = _tokenDescription;\n emit NewTokenDescription(tokenId, _tokenDescription, msg.sender);\n }\n\n /**\n * @dev Add a new AccessPoint register for an app token.\n * The AP name should be a DNS or ENS url and it should be unique.\n * Anyone can add an AP but it should requires a payment.\n *\n * May emit a {NewAccessPoint} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n * IMPORTANT: The payment is not set yet\n */\n function addAccessPoint(uint256 tokenId, string memory apName) public payable {\n // require(msg.value == 0.1 ether, \"You need to pay at least 0.1 ETH\"); // TODO: define a minimum price\n _requireMinted(tokenId);\n require(_accessPoints[apName].owner == address(0), \"FleekERC721: AP already exists\");\n\n _accessPoints[apName] = AccessPoint(tokenId, _apps[tokenId].accessPoints.length, 0, false, false, msg.sender);\n _apps[tokenId].accessPoints.push(apName);\n\n emit NewAccessPoint(apName, tokenId, msg.sender);\n }\n\n /**\n * @dev Remove an AccessPoint registry for an app token.\n * It will also remove the AP from the app token APs list.\n *\n * May emit a {RemoveAccessPoint} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - must be called by the AP owner.\n */\n function removeAccessPoint(string memory apName) public requireAP(apName) {\n require(msg.sender == _accessPoints[apName].owner, \"FleekERC721: must be AP owner\");\n uint256 tokenId = _accessPoints[apName].tokenId;\n App storage _app = _apps[tokenId];\n\n // the index of the AP to remove\n uint256 indexToRemove = _accessPoints[apName].index;\n\n // the last item is reposited in the index to remove\n string memory lastAP = _app.accessPoints[_app.accessPoints.length - 1];\n _app.accessPoints[indexToRemove] = lastAP;\n _accessPoints[lastAP].index = indexToRemove;\n\n // remove the last item\n _app.accessPoints.pop();\n\n delete _accessPoints[apName];\n emit RemoveAccessPoint(apName, tokenId, msg.sender);\n }\n\n /**\n * @dev A view function to gether information about an AccessPoint.\n * It returns a JSON string representing the AccessPoint information.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function getAccessPointJSON(string memory apName) public view requireAP(apName) returns (string memory) {\n AccessPoint storage _ap = _accessPoints[apName];\n return _ap.toString();\n }\n\n /**\n * @dev A view function to check if a AccessPoint is verified.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function isAccessPointNameVerified(string memory apName) public view requireAP(apName) returns (bool) {\n return _accessPoints[apName].nameVerified;\n }\n\n /**\n * @dev Increases the score of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointScore} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function increaseAccessPointScore(string memory apName) public requireAP(apName) {\n _accessPoints[apName].score++;\n emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);\n }\n\n /**\n * @dev Decreases the score of a AccessPoint registry if is greater than 0.\n *\n * May emit a {ChangeAccessPointScore} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function decreaseAccessPointScore(string memory apName) public requireAP(apName) {\n require(_accessPoints[apName].score > 0, \"FleekERC721: score cant be lower\");\n _accessPoints[apName].score--;\n emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);\n }\n\n /**\n * @dev Set the content verification of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointContentVerify} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - the sender must have the token controller role.\n *\n */\n function setAccessPointContentVerify(\n string memory apName,\n bool verified\n ) public requireAP(apName) requireTokenRole(_accessPoints[apName].tokenId, Roles.Controller) {\n _accessPoints[apName].contentVerified = verified;\n emit ChangeAccessPointContentVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);\n }\n\n /**\n * @dev Set the name verification of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointNameVerify} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - the sender must have the token controller role.\n *\n */\n function setAccessPointNameVerify(\n string memory apName,\n bool verified\n ) public requireAP(apName) requireTokenRole(_accessPoints[apName].tokenId, Roles.Controller) {\n _accessPoints[apName].nameVerified = verified;\n emit ChangeAccessPointNameVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);\n }\n\n /**\n * @dev A view function to gether the list of mirrros for a given app.\n *\n * Requirements:\n * - the tokenId must be minted and valid.\n *\n */\n function appAccessPoints(uint256 tokenId) public view returns (string[] memory) {\n _requireMinted(tokenId);\n return _apps[tokenId].accessPoints;\n }\n\n /**\n * @dev Adds a new build to a minted `tokenId`'s builds mapping.\n *\n * May emit a {NewBuild} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenBuild(\n uint256 tokenId,\n string memory _commitHash,\n string memory _gitRepository\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].builds[++_apps[tokenId].currentBuild] = Build(_commitHash, _gitRepository);\n emit NewBuild(tokenId, _commitHash, msg.sender);\n }\n\n /**\n * @dev Burns a previously minted `tokenId`.\n *\n * May emit a {Transfer} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenOwner` role.\n *\n */\n function burn(uint256 tokenId) public virtual requireTokenRole(tokenId, Roles.Owner) {\n super._burn(tokenId);\n\n if (bytes(_apps[tokenId].externalURL).length != 0) {\n delete _apps[tokenId];\n }\n }\n}\n"
+ },
+ "contracts/util/FleekStrings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"../FleekERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"./FleekSVG.sol\";\n\nlibrary FleekStrings {\n using Strings for uint256;\n using Strings for uint160;\n using FleekStrings for bool;\n using FleekStrings for uint24;\n using Strings for uint24;\n\n /**\n * @dev Converts a boolean value to a string.\n */\n function toString(bool _bool) internal pure returns (string memory) {\n return _bool ? \"true\" : \"false\";\n }\n\n /**\n * @dev Converts a string to a base64 string.\n */\n function toBase64(string memory str) internal pure returns (string memory) {\n return Base64.encode(bytes(str));\n }\n\n /**\n * @dev Converts FleekERC721.App to a JSON string.\n * It requires to receive owner address as a parameter.\n */\n function toString(FleekERC721.App storage app, address owner) internal view returns (string memory) {\n // prettier-ignore\n return string(abi.encodePacked(\n '{',\n '\"name\":\"', app.name, '\",',\n '\"description\":\"', app.description, '\",',\n '\"owner\":\"', uint160(owner).toHexString(20), '\",',\n '\"external_url\":\"', app.externalURL, '\",',\n '\"image\":\"', FleekSVG.generateBase64(app.name, app.ENS, app.logo, app.color.toColorString()), '\",',\n '\"attributes\": [',\n '{\"trait_type\": \"ENS\", \"value\":\"', app.ENS,'\"},',\n '{\"trait_type\": \"Commit Hash\", \"value\":\"', app.builds[app.currentBuild].commitHash,'\"},',\n '{\"trait_type\": \"Repository\", \"value\":\"', app.builds[app.currentBuild].gitRepository,'\"},',\n '{\"trait_type\": \"Version\", \"value\":\"', app.currentBuild.toString(),'\"},',\n '{\"trait_type\": \"Color\", \"value\":\"', app.color.toColorString(),'\"}',\n ']',\n '}'\n ));\n }\n\n /**\n * @dev Converts FleekERC721.AccessPoint to a JSON string.\n */\n function toString(FleekERC721.AccessPoint storage ap) internal view returns (string memory) {\n // prettier-ignore\n return string(abi.encodePacked(\n \"{\",\n '\"tokenId\":', ap.tokenId.toString(), \",\",\n '\"score\":', ap.score.toString(), \",\",\n '\"nameVerified\":', ap.nameVerified.toString(), \",\",\n '\"contentVerified\":', ap.contentVerified.toString(), \",\",\n '\"owner\":\"', uint160(ap.owner).toHexString(20), '\"',\n \"}\"\n ));\n }\n\n /**\n * @dev Converts bytes3 to a hex color string.\n */\n function toColorString(uint24 color) internal pure returns (string memory) {\n bytes memory hexBytes = bytes(color.toHexString(3));\n bytes memory hexColor = new bytes(7);\n hexColor[0] = \"#\";\n for (uint256 i = 1; i < 7; i++) {\n hexColor[i] = hexBytes[i + 1];\n }\n return string(hexColor);\n }\n}\n"
+ },
+ "contracts/util/FleekSVG.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"../FleekERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\n\nlibrary FleekSVG {\n /**\n * @dev Generates a SVG image.\n */\n function generateBase64(\n string memory name,\n string memory ENS,\n string memory logo,\n string memory color\n ) internal pure returns (string memory) {\n return (\n string(\n abi.encodePacked(\n \"data:image/svg+xml;base64,\",\n Base64.encode(\n abi.encodePacked(\n '',\n '',\n ''\n '',\n '',\n '',\n '',\n '',\n '',\n '',\n ''\n ''\n '',\n name,\n \"\"\n '',\n ENS,\n \"\"\n \"\"\n )\n )\n )\n )\n );\n }\n}\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 200,
+ "details": {
+ "yul": true
+ }
+ },
+ "viaIR": true,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "storageLayout"
+ ],
+ "": ["ast"]
+ }
+ }
+ }
+}
diff --git a/deployments/mumbai/solcInputs/28a1ab40f8a49a8fd2e522556761b58a.json b/deployments/mumbai/solcInputs/28a1ab40f8a49a8fd2e522556761b58a.json
new file mode 100644
index 0000000..fadb9c8
--- /dev/null
+++ b/deployments/mumbai/solcInputs/28a1ab40f8a49a8fd2e522556761b58a.json
@@ -0,0 +1,82 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initialized`\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initializing`\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721Upgradeable.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256, /* firstTokenId */\n uint256 batchSize\n ) internal virtual {\n if (batchSize > 1) {\n if (from != address(0)) {\n _balances[from] -= batchSize;\n }\n if (to != address(0)) {\n _balances[to] += batchSize;\n }\n }\n }\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 firstTokenId,\n uint256 batchSize\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = MathUpgradeable.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, MathUpgradeable.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Base64.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n *\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n string memory result = new string(4 * ((data.length + 2) / 3));\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n\n // When data `bytes` is not exactly 3 bytes long\n // it is padded with `=` characters at the end\n switch mod(mload(data), 3)\n case 1 {\n mstore8(sub(resultPtr, 1), 0x3d)\n mstore8(sub(resultPtr, 2), 0x3d)\n }\n case 2 {\n mstore8(sub(resultPtr, 1), 0x3d)\n }\n }\n\n return result;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Counters.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/math/Math.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "contracts/FleekAccessControl.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\ncontract FleekAccessControl is Initializable {\n using Counters for Counters.Counter;\n\n enum Roles {\n Owner,\n Controller\n }\n\n event TokenRoleGranted(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event TokenRoleRevoked(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleGranted(Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleRevoked(Roles indexed role, address indexed toAddress, address byAddress);\n\n struct Role {\n mapping(address => uint256) indexes;\n address[] members;\n }\n\n Counters.Counter private _collectionRolesVersion;\n // _collectionRoles[version][role]\n mapping(uint256 => mapping(Roles => Role)) private _collectionRoles;\n\n mapping(uint256 => Counters.Counter) private _tokenRolesVersion;\n // _tokenRoles[tokenId][version][role]\n mapping(uint256 => mapping(uint256 => mapping(Roles => Role))) private _tokenRoles;\n\n /**\n * @dev Initializes the contract by granting the `Owner` role to the deployer.\n */\n function __FleekAccessControl_init() internal onlyInitializing {\n _grantCollectionRole(Roles.Owner, msg.sender);\n }\n\n /**\n * @dev Checks if the `msg.sender` has a certain role.\n */\n modifier requireCollectionRole(Roles role) {\n require(\n hasCollectionRole(role, msg.sender) || hasCollectionRole(Roles.Owner, msg.sender),\n \"FleekAccessControl: must have collection role\"\n );\n _;\n }\n\n /**\n * @dev Checks if the `msg.sender` has the `Token` role for a certain `tokenId`.\n */\n modifier requireTokenRole(uint256 tokenId, Roles role) {\n require(\n hasTokenRole(tokenId, role, msg.sender) || hasTokenRole(tokenId, Roles.Owner, msg.sender),\n \"FleekAccessControl: must have token role\"\n );\n _;\n }\n\n /**\n * @dev Grants the collection role to an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function grantCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _grantCollectionRole(role, account);\n }\n\n /**\n * @dev Grants the token role to an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function grantTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _grantTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function revokeCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _revokeCollectionRole(role, account);\n }\n\n /**\n * @dev Revokes the token role of an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function revokeTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _revokeTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Returns `True` if a certain address has the collection role.\n */\n function hasCollectionRole(Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _collectionRolesVersion.current();\n\n return _collectionRoles[currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns `True` if a certain address has the token role.\n */\n function hasTokenRole(uint256 tokenId, Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns an array of addresses that all have the collection role.\n */\n function getCollectionRoleMembers(Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _collectionRolesVersion.current();\n return _collectionRoles[currentVersion][role].members;\n }\n\n /**\n * @dev Returns an array of addresses that all have the same token role for a certain tokenId.\n */\n function getTokenRoleMembers(uint256 tokenId, Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].members;\n }\n\n /**\n * @dev Grants the collection role to an address.\n */\n function _grantCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _grantRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleGranted(role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n */\n function _revokeCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _revokeRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleRevoked(role, account, msg.sender);\n }\n\n /**\n * @dev Grants the token role to an address.\n */\n function _grantTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _grantRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleGranted(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the token role of an address.\n */\n function _revokeTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _revokeRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleRevoked(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Grants a certain role to a certain address.\n */\n function _grantRole(Role storage role, address account) internal {\n if (role.indexes[account] == 0) {\n role.members.push(account);\n role.indexes[account] = role.members.length;\n }\n }\n\n /**\n * @dev Revokes a certain role from a certain address.\n */\n function _revokeRole(Role storage role, address account) internal {\n if (role.indexes[account] != 0) {\n uint256 index = role.indexes[account] - 1;\n uint256 lastIndex = role.members.length - 1;\n address lastAccount = role.members[lastIndex];\n\n role.members[index] = lastAccount;\n role.indexes[lastAccount] = index + 1;\n\n role.members.pop();\n delete role.indexes[account];\n }\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId.\n * Should only be used for burning tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId) internal {\n _tokenRolesVersion[tokenId].increment();\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId and grants the owner role to a new address.\n * Should only be used for transferring tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId, address newOwner) internal {\n _clearAllTokenRoles(tokenId);\n _grantTokenRole(tokenId, Roles.Owner, newOwner);\n }\n}\n"
+ },
+ "contracts/FleekERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"./FleekAccessControl.sol\";\nimport \"./SVGLibrary.sol\";\n\ncontract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl {\n using Strings for uint256;\n using Counters for Counters.Counter;\n\n event NewBuild(uint256 indexed token, string indexed commitHash, address indexed triggeredBy);\n event NewTokenName(uint256 indexed token, string indexed name, address indexed triggeredBy);\n event NewTokenDescription(uint256 indexed token, string indexed description, address indexed triggeredBy);\n event NewTokenImage(uint256 indexed token, string indexed image, address indexed triggeredBy);\n event NewTokenExternalURL(uint256 indexed token, string indexed externalURL, address indexed triggeredBy);\n event NewTokenENS(uint256 indexed token, string indexed ENS, address indexed triggeredBy);\n\n /**\n * The properties are stored as string to keep consistency with\n * other token contracts, we might consider changing for bytes32\n * in the future due to gas optimization.\n */\n struct App {\n string name; // Name of the site\n string description; // Description about the site\n string externalURL; // Site URL\n string ENS; // ENS ID\n uint256 currentBuild; // The current build number (Increments by one with each change, starts at zero)\n mapping(uint256 => Build) builds; // Mapping to build details for each build number\n }\n\n /**\n * The metadata that is stored for each build.\n */\n struct Build {\n string commitHash;\n string gitRepository;\n }\n\n Counters.Counter private _tokenIds;\n mapping(uint256 => App) private _apps;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function initialize(string memory _name, string memory _symbol) public initializer {\n __ERC721_init(_name, _symbol);\n __FleekAccessControl_init();\n }\n\n /**\n * @dev Checks if msg.sender has the role of tokenOwner for a certain tokenId.\n */\n modifier requireTokenOwner(uint256 tokenId) {\n require(msg.sender == ownerOf(tokenId), \"FleekERC721: must be token owner\");\n _;\n }\n\n /**\n * @dev Generates a SVG image.\n */\n function _generateSVG(string memory name, string memory ENS) internal pure returns (string memory) {\n return (string(abi.encodePacked(\"data:image/svg+xml;base64,\", Base64.encode(SVGLibrary.parseSVG(name, ENS)))));\n }\n\n /**\n * @dev Mints a token and returns a tokenId.\n *\n * If the `tokenId` has not been minted before, and the `to` address is not zero, emits a {Transfer} event.\n *\n * Requirements:\n *\n * - the caller must have ``collectionOwner``'s admin role.\n *\n */\n function mint(\n address to,\n string memory name,\n string memory description,\n string memory externalURL,\n string memory ENS,\n string memory commitHash,\n string memory gitRepository\n ) public payable requireCollectionRole(Roles.Owner) returns (uint256) {\n uint256 tokenId = _tokenIds.current();\n _mint(to, tokenId);\n _tokenIds.increment();\n\n App storage app = _apps[tokenId];\n app.name = name;\n app.description = description;\n app.externalURL = externalURL;\n app.ENS = ENS;\n\n // The mint interaction is considered to be the first build of the site. Updates from now on all increment the currentBuild by one and update the mapping.\n app.currentBuild = 0;\n app.builds[0] = Build(commitHash, gitRepository);\n\n return tokenId;\n }\n\n /**\n * @dev Returns the token metadata associated with the `tokenId`.\n *\n * Returns a based64 encoded string value of the URI.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n address owner = ownerOf(tokenId);\n App storage app = _apps[tokenId];\n\n // prettier-ignore\n bytes memory dataURI = abi.encodePacked(\n '{',\n '\"name\":\"', app.name, '\",',\n '\"description\":\"', app.description, '\",',\n '\"owner\":\"', Strings.toHexString(uint160(owner), 20), '\",',\n '\"external_url\":\"', app.externalURL, '\",',\n '\"image\":\"', _generateSVG(app.name, app.ENS), '\",',\n '\"attributes\": [',\n '{\"trait_type\": \"ENS\", \"value\":\"', app.ENS,'\"},',\n '{\"trait_type\": \"Commit Hash\", \"value\":\"', app.builds[app.currentBuild].commitHash,'\"},',\n '{\"trait_type\": \"Repository\", \"value\":\"', app.builds[app.currentBuild].gitRepository,'\"},',\n '{\"trait_type\": \"Version\", \"value\":\"', Strings.toString(app.currentBuild),'\"}',\n ']',\n '}'\n );\n\n return string(abi.encodePacked(_baseURI(), Base64.encode((dataURI))));\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Upgradeable) returns (bool) {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Override of _beforeTokenTransfer of ERC721.\n * Here it needs to update the token controller roles for mint, burn and transfer.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId,\n uint256 batchSize\n ) internal virtual override {\n if (from != address(0) && to != address(0)) {\n // Transfer\n _clearAllTokenRoles(tokenId, to);\n } else if (from == address(0)) {\n // Mint\n _grantTokenRole(tokenId, Roles.Owner, to);\n } else if (to == address(0)) {\n // Burn\n _clearAllTokenRoles(tokenId);\n }\n super._beforeTokenTransfer(from, to, tokenId, batchSize);\n }\n\n /**\n * @dev A baseURI internal function implementation to be called in the `tokenURI` function.\n */\n function _baseURI() internal view virtual override returns (string memory) {\n return \"data:application/json;base64,\";\n }\n\n /**\n * @dev Updates the `externalURL` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenExternalURL} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenExternalURL(\n uint256 tokenId,\n string memory _tokenExternalURL\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].externalURL = _tokenExternalURL;\n emit NewTokenExternalURL(tokenId, _tokenExternalURL, msg.sender);\n }\n\n /**\n * @dev Updates the `ENS` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenENS} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenENS(\n uint256 tokenId,\n string memory _tokenENS\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].ENS = _tokenENS;\n emit NewTokenENS(tokenId, _tokenENS, msg.sender);\n }\n\n /**\n * @dev Updates the `name` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenName} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenName(\n uint256 tokenId,\n string memory _tokenName\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].name = _tokenName;\n emit NewTokenName(tokenId, _tokenName, msg.sender);\n }\n\n /**\n * @dev Updates the `description` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenDescription} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenDescription(\n uint256 tokenId,\n string memory _tokenDescription\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].description = _tokenDescription;\n emit NewTokenDescription(tokenId, _tokenDescription, msg.sender);\n }\n\n /**\n * @dev Adds a new build to a minted `tokenId`'s builds mapping.\n *\n * May emit a {NewBuild} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenBuild(\n uint256 tokenId,\n string memory _commitHash,\n string memory _gitRepository\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].builds[++_apps[tokenId].currentBuild] = Build(_commitHash, _gitRepository);\n emit NewBuild(tokenId, _commitHash, msg.sender);\n }\n\n /**\n * @dev Burns a previously minted `tokenId`.\n *\n * May emit a {Transfer} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenOwner` role.\n *\n */\n function burn(uint256 tokenId) public virtual requireTokenRole(tokenId, Roles.Owner) {\n super._burn(tokenId);\n\n if (bytes(_apps[tokenId].externalURL).length != 0) {\n delete _apps[tokenId];\n }\n }\n}\n"
+ },
+ "contracts/SVGLibrary.sol": {
+ "content": "library SVGLibrary {\r\n function parseSVG(string memory name, string memory version) internal pure returns (bytes memory) {\r\n return\r\n abi.encodePacked(\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n name,\r\n '',\r\n version,\r\n \"\"\r\n );\r\n }\r\n}\r\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 200,
+ "details": {
+ "yul": false
+ }
+ },
+ "viaIR": false,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "storageLayout"
+ ],
+ "": ["ast"]
+ }
+ }
+ }
+}
diff --git a/deployments/mumbai/solcInputs/3552ba8e8c74c7beab95d2faf58af779.json b/deployments/mumbai/solcInputs/3552ba8e8c74c7beab95d2faf58af779.json
new file mode 100644
index 0000000..62e815e
--- /dev/null
+++ b/deployments/mumbai/solcInputs/3552ba8e8c74c7beab95d2faf58af779.json
@@ -0,0 +1,85 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initialized`\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initializing`\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721Upgradeable.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256, /* firstTokenId */\n uint256 batchSize\n ) internal virtual {\n if (batchSize > 1) {\n if (from != address(0)) {\n _balances[from] -= batchSize;\n }\n if (to != address(0)) {\n _balances[to] += batchSize;\n }\n }\n }\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 firstTokenId,\n uint256 batchSize\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = MathUpgradeable.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, MathUpgradeable.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Base64.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n *\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n string memory result = new string(4 * ((data.length + 2) / 3));\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n\n // When data `bytes` is not exactly 3 bytes long\n // it is padded with `=` characters at the end\n switch mod(mload(data), 3)\n case 1 {\n mstore8(sub(resultPtr, 1), 0x3d)\n mstore8(sub(resultPtr, 2), 0x3d)\n }\n case 2 {\n mstore8(sub(resultPtr, 1), 0x3d)\n }\n }\n\n return result;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Counters.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/math/Math.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "contracts/FleekAccessControl.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\ncontract FleekAccessControl is Initializable {\n using Counters for Counters.Counter;\n\n enum Roles {\n Owner,\n Controller\n }\n\n event TokenRoleGranted(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event TokenRoleRevoked(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleGranted(Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleRevoked(Roles indexed role, address indexed toAddress, address byAddress);\n\n struct Role {\n mapping(address => uint256) indexes;\n address[] members;\n }\n\n Counters.Counter private _collectionRolesVersion;\n // _collectionRoles[version][role]\n mapping(uint256 => mapping(Roles => Role)) private _collectionRoles;\n\n mapping(uint256 => Counters.Counter) private _tokenRolesVersion;\n // _tokenRoles[tokenId][version][role]\n mapping(uint256 => mapping(uint256 => mapping(Roles => Role))) private _tokenRoles;\n\n /**\n * @dev Initializes the contract by granting the `Owner` role to the deployer.\n */\n function __FleekAccessControl_init() internal onlyInitializing {\n _grantCollectionRole(Roles.Owner, msg.sender);\n }\n\n /**\n * @dev Checks if the `msg.sender` has a certain role.\n */\n modifier requireCollectionRole(Roles role) {\n require(\n hasCollectionRole(role, msg.sender) || hasCollectionRole(Roles.Owner, msg.sender),\n \"FleekAccessControl: must have collection role\"\n );\n _;\n }\n\n /**\n * @dev Checks if the `msg.sender` has the `Token` role for a certain `tokenId`.\n */\n modifier requireTokenRole(uint256 tokenId, Roles role) {\n require(\n hasTokenRole(tokenId, role, msg.sender) || hasTokenRole(tokenId, Roles.Owner, msg.sender),\n \"FleekAccessControl: must have token role\"\n );\n _;\n }\n\n /**\n * @dev Grants the collection role to an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function grantCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _grantCollectionRole(role, account);\n }\n\n /**\n * @dev Grants the token role to an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function grantTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _grantTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function revokeCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _revokeCollectionRole(role, account);\n }\n\n /**\n * @dev Revokes the token role of an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function revokeTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _revokeTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Returns `True` if a certain address has the collection role.\n */\n function hasCollectionRole(Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _collectionRolesVersion.current();\n\n return _collectionRoles[currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns `True` if a certain address has the token role.\n */\n function hasTokenRole(uint256 tokenId, Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns an array of addresses that all have the collection role.\n */\n function getCollectionRoleMembers(Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _collectionRolesVersion.current();\n return _collectionRoles[currentVersion][role].members;\n }\n\n /**\n * @dev Returns an array of addresses that all have the same token role for a certain tokenId.\n */\n function getTokenRoleMembers(uint256 tokenId, Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].members;\n }\n\n /**\n * @dev Grants the collection role to an address.\n */\n function _grantCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _grantRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleGranted(role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n */\n function _revokeCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _revokeRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleRevoked(role, account, msg.sender);\n }\n\n /**\n * @dev Grants the token role to an address.\n */\n function _grantTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _grantRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleGranted(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the token role of an address.\n */\n function _revokeTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _revokeRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleRevoked(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Grants a certain role to a certain address.\n */\n function _grantRole(Role storage role, address account) internal {\n if (role.indexes[account] == 0) {\n role.members.push(account);\n role.indexes[account] = role.members.length;\n }\n }\n\n /**\n * @dev Revokes a certain role from a certain address.\n */\n function _revokeRole(Role storage role, address account) internal {\n if (role.indexes[account] != 0) {\n uint256 index = role.indexes[account] - 1;\n uint256 lastIndex = role.members.length - 1;\n address lastAccount = role.members[lastIndex];\n\n role.members[index] = lastAccount;\n role.indexes[lastAccount] = index + 1;\n\n role.members.pop();\n delete role.indexes[account];\n }\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId.\n * Should only be used for burning tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId) internal {\n _tokenRolesVersion[tokenId].increment();\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId and grants the owner role to a new address.\n * Should only be used for transferring tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId, address newOwner) internal {\n _clearAllTokenRoles(tokenId);\n _grantTokenRole(tokenId, Roles.Owner, newOwner);\n }\n}\n"
+ },
+ "contracts/FleekERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"./FleekAccessControl.sol\";\nimport \"./util/FleekStrings.sol\";\n\ncontract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl {\n using Strings for uint256;\n using Counters for Counters.Counter;\n using FleekStrings for FleekERC721.App;\n using FleekStrings for FleekERC721.AccessPoint;\n using FleekStrings for string;\n\n event NewBuild(uint256 indexed token, string indexed commitHash, address indexed triggeredBy);\n event NewTokenName(uint256 indexed token, string indexed name, address indexed triggeredBy);\n event NewTokenDescription(uint256 indexed token, string indexed description, address indexed triggeredBy);\n event NewTokenImage(uint256 indexed token, string indexed image, address indexed triggeredBy);\n event NewTokenExternalURL(uint256 indexed token, string indexed externalURL, address indexed triggeredBy);\n event NewTokenENS(uint256 indexed token, string indexed ENS, address indexed triggeredBy);\n\n event NewAccessPoint(string indexed apName, uint256 indexed tokenId, address indexed owner);\n event RemoveAccessPoint(string indexed apName, uint256 indexed tokenId, address indexed owner);\n event ChangeAccessPointScore(\n string indexed apName,\n uint256 indexed tokenId,\n uint256 score,\n address indexed triggeredBy\n );\n event ChangeAccessPointNameVerify(\n string indexed apName,\n uint256 tokenId,\n bool indexed verified,\n address indexed triggeredBy\n );\n event ChangeAccessPointContentVerify(\n string indexed apName,\n uint256 tokenId,\n bool indexed verified,\n address indexed triggeredBy\n );\n\n /**\n * The properties are stored as string to keep consistency with\n * other token contracts, we might consider changing for bytes32\n * in the future due to gas optimization.\n */\n struct App {\n string name; // Name of the site\n string description; // Description about the site\n string externalURL; // Site URL\n string ENS; // ENS ID\n uint256 currentBuild; // The current build number (Increments by one with each change, starts at zero)\n mapping(uint256 => Build) builds; // Mapping to build details for each build number\n string[] accessPoints; // List of app AccessPoint\n }\n\n /**\n * The metadata that is stored for each build.\n */\n struct Build {\n string commitHash;\n string gitRepository;\n }\n\n /**\n * The stored data for each AccessPoint.\n */\n struct AccessPoint {\n uint256 tokenId;\n uint256 index;\n uint256 score;\n bool contentVerified;\n bool nameVerified;\n address owner;\n }\n\n Counters.Counter private _appIds;\n mapping(uint256 => App) private _apps;\n mapping(string => AccessPoint) private _accessPoints;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function initialize(string memory _name, string memory _symbol) public initializer {\n __ERC721_init(_name, _symbol);\n __FleekAccessControl_init();\n }\n\n /**\n * @dev Checks if the AccessPoint exists.\n */\n modifier requireAP(string memory apName) {\n require(_accessPoints[apName].owner != address(0), \"FleekERC721: invalid AP\");\n _;\n }\n\n /**\n * @dev Mints a token and returns a tokenId.\n *\n * If the `tokenId` has not been minted before, and the `to` address is not zero, emits a {Transfer} event.\n *\n * Requirements:\n *\n * - the caller must have ``collectionOwner``'s admin role.\n *\n */\n function mint(\n address to,\n string memory name,\n string memory description,\n string memory externalURL,\n string memory ENS,\n string memory commitHash,\n string memory gitRepository\n ) public payable requireCollectionRole(Roles.Owner) returns (uint256) {\n uint256 tokenId = _appIds.current();\n _mint(to, tokenId);\n _appIds.increment();\n\n App storage app = _apps[tokenId];\n app.name = name;\n app.description = description;\n app.externalURL = externalURL;\n app.ENS = ENS;\n\n // The mint interaction is considered to be the first build of the site. Updates from now on all increment the currentBuild by one and update the mapping.\n app.currentBuild = 0;\n app.builds[0] = Build(commitHash, gitRepository);\n app.accessPoints = new string[](0);\n\n return tokenId;\n }\n\n /**\n * @dev Returns the token metadata associated with the `tokenId`.\n *\n * Returns a based64 encoded string value of the URI.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n address owner = ownerOf(tokenId);\n App storage app = _apps[tokenId];\n\n return string(abi.encodePacked(_baseURI(), app.toString(owner).toBase64()));\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Upgradeable) returns (bool) {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Override of _beforeTokenTransfer of ERC721.\n * Here it needs to update the token controller roles for mint, burn and transfer.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId,\n uint256 batchSize\n ) internal virtual override {\n if (from != address(0) && to != address(0)) {\n // Transfer\n _clearAllTokenRoles(tokenId, to);\n } else if (from == address(0)) {\n // Mint\n _grantTokenRole(tokenId, Roles.Owner, to);\n } else if (to == address(0)) {\n // Burn\n _clearAllTokenRoles(tokenId);\n }\n super._beforeTokenTransfer(from, to, tokenId, batchSize);\n }\n\n /**\n * @dev A baseURI internal function implementation to be called in the `tokenURI` function.\n */\n function _baseURI() internal view virtual override returns (string memory) {\n return \"data:application/json;base64,\";\n }\n\n /**\n * @dev Updates the `externalURL` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenExternalURL} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenExternalURL(\n uint256 tokenId,\n string memory _tokenExternalURL\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].externalURL = _tokenExternalURL;\n emit NewTokenExternalURL(tokenId, _tokenExternalURL, msg.sender);\n }\n\n /**\n * @dev Updates the `ENS` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenENS} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenENS(\n uint256 tokenId,\n string memory _tokenENS\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].ENS = _tokenENS;\n emit NewTokenENS(tokenId, _tokenENS, msg.sender);\n }\n\n /**\n * @dev Updates the `name` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenName} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenName(\n uint256 tokenId,\n string memory _tokenName\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].name = _tokenName;\n emit NewTokenName(tokenId, _tokenName, msg.sender);\n }\n\n /**\n * @dev Updates the `description` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenDescription} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenDescription(\n uint256 tokenId,\n string memory _tokenDescription\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].description = _tokenDescription;\n emit NewTokenDescription(tokenId, _tokenDescription, msg.sender);\n }\n\n /**\n * @dev Add a new AccessPoint register for an app token.\n * The AP name should be a DNS or ENS url and it should be unique.\n * Anyone can add an AP but it should requires a payment.\n *\n * May emit a {NewAccessPoint} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n * IMPORTANT: The payment is not set yet\n */\n function addAccessPoint(uint256 tokenId, string memory apName) public payable {\n // require(msg.value == 0.1 ether, \"You need to pay at least 0.1 ETH\"); // TODO: define a minimum price\n _requireMinted(tokenId);\n require(_accessPoints[apName].owner == address(0), \"FleekERC721: AP already exists\");\n\n _accessPoints[apName] = AccessPoint(tokenId, _apps[tokenId].accessPoints.length, 0, false, false, msg.sender);\n _apps[tokenId].accessPoints.push(apName);\n\n emit NewAccessPoint(apName, tokenId, msg.sender);\n }\n\n /**\n * @dev Remove an AccessPoint registry for an app token.\n * It will also remove the AP from the app token APs list.\n *\n * May emit a {RemoveAccessPoint} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - must be called by the AP owner.\n */\n function removeAccessPoint(string memory apName) public requireAP(apName) {\n require(msg.sender == _accessPoints[apName].owner, \"FleekERC721: must be AP owner\");\n uint256 tokenId = _accessPoints[apName].tokenId;\n App storage _app = _apps[tokenId];\n\n // the index of the AP to remove\n uint256 indexToRemove = _accessPoints[apName].index;\n\n // the last item is reposited in the index to remove\n string memory lastAP = _app.accessPoints[_app.accessPoints.length - 1];\n _app.accessPoints[indexToRemove] = lastAP;\n _accessPoints[lastAP].index = indexToRemove;\n\n // remove the last item\n _app.accessPoints.pop();\n\n delete _accessPoints[apName];\n emit RemoveAccessPoint(apName, tokenId, msg.sender);\n }\n\n /**\n * @dev A view function to gether information about an AccessPoint.\n * It returns a JSON string representing the AccessPoint information.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function getAccessPointJSON(string memory apName) public view requireAP(apName) returns (string memory) {\n AccessPoint storage _ap = _accessPoints[apName];\n return _ap.toString();\n }\n\n /**\n * @dev A view function to check if a AccessPoint is verified.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function isAccessPointNameVerified(string memory apName) public view requireAP(apName) returns (bool) {\n return _accessPoints[apName].nameVerified;\n }\n\n /**\n * @dev Increases the score of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointScore} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function increaseAccessPointScore(string memory apName) public requireAP(apName) {\n _accessPoints[apName].score++;\n emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);\n }\n\n /**\n * @dev Decreases the score of a AccessPoint registry if is greater than 0.\n *\n * May emit a {ChangeAccessPointScore} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function decreaseAccessPointScore(string memory apName) public requireAP(apName) {\n require(_accessPoints[apName].score > 0, \"FleekERC721: score cant be lower\");\n _accessPoints[apName].score--;\n emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);\n }\n\n /**\n * @dev Set the content verification of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointContentVerify} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - the sender must have the token controller role.\n *\n */\n function setAccessPointContentVerify(\n string memory apName,\n bool verified\n ) public requireAP(apName) requireTokenRole(_accessPoints[apName].tokenId, Roles.Controller) {\n _accessPoints[apName].contentVerified = verified;\n emit ChangeAccessPointContentVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);\n }\n\n /**\n * @dev Set the name verification of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointNameVerify} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - the sender must have the token controller role.\n *\n */\n function setAccessPointNameVerify(\n string memory apName,\n bool verified\n ) public requireAP(apName) requireTokenRole(_accessPoints[apName].tokenId, Roles.Controller) {\n _accessPoints[apName].nameVerified = verified;\n emit ChangeAccessPointNameVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);\n }\n\n /**\n * @dev A view function to gether the list of mirrros for a given app.\n *\n * Requirements:\n * - the tokenId must be minted and valid.\n *\n */\n function appAccessPoints(uint256 tokenId) public view returns (string[] memory) {\n _requireMinted(tokenId);\n return _apps[tokenId].accessPoints;\n }\n\n /**\n * @dev Adds a new build to a minted `tokenId`'s builds mapping.\n *\n * May emit a {NewBuild} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenBuild(\n uint256 tokenId,\n string memory _commitHash,\n string memory _gitRepository\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].builds[++_apps[tokenId].currentBuild] = Build(_commitHash, _gitRepository);\n emit NewBuild(tokenId, _commitHash, msg.sender);\n }\n\n /**\n * @dev Burns a previously minted `tokenId`.\n *\n * May emit a {Transfer} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenOwner` role.\n *\n */\n function burn(uint256 tokenId) public virtual requireTokenRole(tokenId, Roles.Owner) {\n super._burn(tokenId);\n\n if (bytes(_apps[tokenId].externalURL).length != 0) {\n delete _apps[tokenId];\n }\n }\n}\n"
+ },
+ "contracts/util/FleekStrings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"../FleekERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"./FleekSVG.sol\";\n\nlibrary FleekStrings {\n using Strings for uint256;\n using Strings for uint160;\n using FleekStrings for bool;\n\n /**\n * @dev Converts a boolean value to a string.\n */\n function toString(bool _bool) internal pure returns (string memory) {\n return _bool ? \"true\" : \"false\";\n }\n\n /**\n * @dev Converts a string to a base64 string.\n */\n function toBase64(string memory str) internal pure returns (string memory) {\n return Base64.encode(bytes(str));\n }\n\n /**\n * @dev Converts FleekERC721.App to a JSON string.\n * It requires to receive owner address as a parameter.\n */\n function toString(FleekERC721.App storage app, address owner) internal view returns (string memory) {\n // prettier-ignore\n return string(abi.encodePacked(\n '{',\n '\"name\":\"', app.name, '\",',\n '\"description\":\"', app.description, '\",',\n '\"owner\":\"', uint160(owner).toHexString(20), '\",',\n '\"external_url\":\"', app.externalURL, '\",',\n '\"image\":\"', FleekSVG.generateBase64(app.name, app.ENS), '\",',\n '\"attributes\": [',\n '{\"trait_type\": \"ENS\", \"value\":\"', app.ENS,'\"},',\n '{\"trait_type\": \"Commit Hash\", \"value\":\"', app.builds[app.currentBuild].commitHash,'\"},',\n '{\"trait_type\": \"Repository\", \"value\":\"', app.builds[app.currentBuild].gitRepository,'\"},',\n '{\"trait_type\": \"Version\", \"value\":\"', app.currentBuild.toString(),'\"}',\n ']',\n '}'\n ));\n }\n\n /**\n * @dev Converts FleekERC721.AccessPoint to a JSON string.\n */\n function toString(FleekERC721.AccessPoint storage ap) internal view returns (string memory) {\n // prettier-ignore\n return string(abi.encodePacked(\n \"{\",\n '\"tokenId\":', ap.tokenId.toString(), \",\",\n '\"score\":', ap.score.toString(), \",\",\n '\"nameVerified\":', ap.nameVerified.toString(), \",\",\n '\"contentVerified\":', ap.contentVerified.toString(), \",\",\n '\"owner\":\"', uint160(ap.owner).toHexString(20), '\"',\n \"}\"\n ));\n }\n}\n"
+ },
+ "contracts/util/FleekSVG.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"../FleekERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\n\nlibrary FleekSVG {\n /**\n * @dev Generates a SVG image.\n */\n function generateBase64(string memory name, string memory ENS) internal pure returns (string memory) {\n string memory color = \"#e34f26\";\n string\n memory logo = \"data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjI1MDAiIHdpZHRoPSIyMTgzIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjQgMTQxLjUzMTk5OTk5OTk5OTk4Ij48cGF0aCBkPSJNMTAuMzgzIDEyNi44OTRMMCAwbDEyNCAuMjU1LTEwLjk3OSAxMjYuNjM5LTUwLjU1MyAxNC42Mzh6IiBmaWxsPSIjZTM0ZjI2Ii8+PHBhdGggZD0iTTYyLjQ2OCAxMjkuMjc3VjEyLjA4NWw1MS4wNjQuMTctOS4xMDYgMTA0Ljg1MXoiIGZpbGw9IiNlZjY1MmEiLz48cGF0aCBkPSJNOTkuNDkgNDEuMzYybDEuNDQ2LTE1LjQ5SDIyLjM4M2w0LjM0IDQ3LjQ5aDU0LjIxM0w3OC44MSA5My42MTdsLTE3LjM2MiA0LjY4LTE3LjYxNy01LjEwNi0uOTM2LTEyLjA4NUgyNy4zMTlsMi4xMjggMjQuNjgxIDMyIDguOTM2IDMyLjI1NS04LjkzNiA0LjM0LTQ4LjE3SDQxLjEwN0wzOS40OSA0MS4zNjJ6IiBmaWxsPSIjZmZmIi8+PC9zdmc+\";\n\n return (\n string(\n abi.encodePacked(\n \"data:image/svg+xml;base64,\",\n Base64.encode(\n abi.encodePacked(\n '',\n '',\n ''\n '',\n '',\n '',\n '',\n '',\n '',\n '',\n ''\n ''\n '',\n name,\n \"\"\n '',\n ENS,\n \"\"\n \"\"\n )\n )\n )\n )\n );\n }\n}\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 200,
+ "details": {
+ "yul": true
+ }
+ },
+ "viaIR": true,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "storageLayout"
+ ],
+ "": ["ast"]
+ }
+ }
+ }
+}
diff --git a/deployments/mumbai/solcInputs/36fce6b2c84b45d410febd14169bdadd.json b/deployments/mumbai/solcInputs/36fce6b2c84b45d410febd14169bdadd.json
new file mode 100644
index 0000000..8e5f134
--- /dev/null
+++ b/deployments/mumbai/solcInputs/36fce6b2c84b45d410febd14169bdadd.json
@@ -0,0 +1,85 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initialized`\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initializing`\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721Upgradeable.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256, /* firstTokenId */\n uint256 batchSize\n ) internal virtual {\n if (batchSize > 1) {\n if (from != address(0)) {\n _balances[from] -= batchSize;\n }\n if (to != address(0)) {\n _balances[to] += batchSize;\n }\n }\n }\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 firstTokenId,\n uint256 batchSize\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = MathUpgradeable.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, MathUpgradeable.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Base64.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n *\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n string memory result = new string(4 * ((data.length + 2) / 3));\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n\n // When data `bytes` is not exactly 3 bytes long\n // it is padded with `=` characters at the end\n switch mod(mload(data), 3)\n case 1 {\n mstore8(sub(resultPtr, 1), 0x3d)\n mstore8(sub(resultPtr, 2), 0x3d)\n }\n case 2 {\n mstore8(sub(resultPtr, 1), 0x3d)\n }\n }\n\n return result;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Counters.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/math/Math.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "contracts/FleekAccessControl.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\ncontract FleekAccessControl is Initializable {\n using Counters for Counters.Counter;\n\n enum Roles {\n Owner,\n Controller\n }\n\n event TokenRoleGranted(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event TokenRoleRevoked(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleGranted(Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleRevoked(Roles indexed role, address indexed toAddress, address byAddress);\n\n struct Role {\n mapping(address => uint256) indexes;\n address[] members;\n }\n\n Counters.Counter private _collectionRolesVersion;\n // _collectionRoles[version][role]\n mapping(uint256 => mapping(Roles => Role)) private _collectionRoles;\n\n mapping(uint256 => Counters.Counter) private _tokenRolesVersion;\n // _tokenRoles[tokenId][version][role]\n mapping(uint256 => mapping(uint256 => mapping(Roles => Role))) private _tokenRoles;\n\n /**\n * @dev Initializes the contract by granting the `Owner` role to the deployer.\n */\n function __FleekAccessControl_init() internal onlyInitializing {\n _grantCollectionRole(Roles.Owner, msg.sender);\n }\n\n /**\n * @dev Checks if the `msg.sender` has a certain role.\n */\n modifier requireCollectionRole(Roles role) {\n require(\n hasCollectionRole(role, msg.sender) || hasCollectionRole(Roles.Owner, msg.sender),\n \"FleekAccessControl: must have collection role\"\n );\n _;\n }\n\n /**\n * @dev Checks if the `msg.sender` has the `Token` role for a certain `tokenId`.\n */\n modifier requireTokenRole(uint256 tokenId, Roles role) {\n require(\n hasTokenRole(tokenId, role, msg.sender) || hasTokenRole(tokenId, Roles.Owner, msg.sender),\n \"FleekAccessControl: must have token role\"\n );\n _;\n }\n\n /**\n * @dev Grants the collection role to an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function grantCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _grantCollectionRole(role, account);\n }\n\n /**\n * @dev Grants the token role to an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function grantTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _grantTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function revokeCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _revokeCollectionRole(role, account);\n }\n\n /**\n * @dev Revokes the token role of an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function revokeTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _revokeTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Returns `True` if a certain address has the collection role.\n */\n function hasCollectionRole(Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _collectionRolesVersion.current();\n\n return _collectionRoles[currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns `True` if a certain address has the token role.\n */\n function hasTokenRole(uint256 tokenId, Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns an array of addresses that all have the collection role.\n */\n function getCollectionRoleMembers(Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _collectionRolesVersion.current();\n return _collectionRoles[currentVersion][role].members;\n }\n\n /**\n * @dev Returns an array of addresses that all have the same token role for a certain tokenId.\n */\n function getTokenRoleMembers(uint256 tokenId, Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].members;\n }\n\n /**\n * @dev Grants the collection role to an address.\n */\n function _grantCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _grantRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleGranted(role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n */\n function _revokeCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _revokeRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleRevoked(role, account, msg.sender);\n }\n\n /**\n * @dev Grants the token role to an address.\n */\n function _grantTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _grantRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleGranted(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the token role of an address.\n */\n function _revokeTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _revokeRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleRevoked(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Grants a certain role to a certain address.\n */\n function _grantRole(Role storage role, address account) internal {\n if (role.indexes[account] == 0) {\n role.members.push(account);\n role.indexes[account] = role.members.length;\n }\n }\n\n /**\n * @dev Revokes a certain role from a certain address.\n */\n function _revokeRole(Role storage role, address account) internal {\n if (role.indexes[account] != 0) {\n uint256 index = role.indexes[account] - 1;\n uint256 lastIndex = role.members.length - 1;\n address lastAccount = role.members[lastIndex];\n\n role.members[index] = lastAccount;\n role.indexes[lastAccount] = index + 1;\n\n role.members.pop();\n delete role.indexes[account];\n }\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId.\n * Should only be used for burning tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId) internal {\n _tokenRolesVersion[tokenId].increment();\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId and grants the owner role to a new address.\n * Should only be used for transferring tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId, address newOwner) internal {\n _clearAllTokenRoles(tokenId);\n _grantTokenRole(tokenId, Roles.Owner, newOwner);\n }\n}\n"
+ },
+ "contracts/FleekERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"./FleekAccessControl.sol\";\nimport \"./util/FleekStrings.sol\";\n\ncontract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl {\n using Strings for uint256;\n using Counters for Counters.Counter;\n using FleekStrings for FleekERC721.App;\n using FleekStrings for FleekERC721.AccessPoint;\n using FleekStrings for string;\n\n event NewBuild(uint256 indexed token, string indexed commitHash, address indexed triggeredBy);\n event NewTokenName(uint256 indexed token, string indexed name, address indexed triggeredBy);\n event NewTokenDescription(uint256 indexed token, string indexed description, address indexed triggeredBy);\n event NewTokenImage(uint256 indexed token, string indexed image, address indexed triggeredBy);\n event NewTokenExternalURL(uint256 indexed token, string indexed externalURL, address indexed triggeredBy);\n event NewTokenENS(uint256 indexed token, string indexed ENS, address indexed triggeredBy);\n\n event NewAccessPoint(string indexed apName, uint256 indexed tokenId, address indexed owner);\n event RemoveAccessPoint(string indexed apName, uint256 indexed tokenId, address indexed owner);\n event ChangeAccessPointScore(\n string indexed apName,\n uint256 indexed tokenId,\n uint256 score,\n address indexed triggeredBy\n );\n event ChangeAccessPointNameVerify(\n string indexed apName,\n uint256 tokenId,\n bool indexed verified,\n address indexed triggeredBy\n );\n event ChangeAccessPointContentVerify(\n string indexed apName,\n uint256 tokenId,\n bool indexed verified,\n address indexed triggeredBy\n );\n\n /**\n * The properties are stored as string to keep consistency with\n * other token contracts, we might consider changing for bytes32\n * in the future due to gas optimization.\n */\n struct App {\n string name; // Name of the site\n string description; // Description about the site\n string externalURL; // Site URL\n string ENS; // ENS ID\n uint256 currentBuild; // The current build number (Increments by one with each change, starts at zero)\n mapping(uint256 => Build) builds; // Mapping to build details for each build number\n string[] accessPoints; // List of app AccessPoint\n string logo;\n uint24 color; // Color of the nft\n }\n\n /**\n * The metadata that is stored for each build.\n */\n struct Build {\n string commitHash;\n string gitRepository;\n }\n\n /**\n * The stored data for each AccessPoint.\n */\n struct AccessPoint {\n uint256 tokenId;\n uint256 index;\n uint256 score;\n bool contentVerified;\n bool nameVerified;\n address owner;\n }\n\n Counters.Counter private _appIds;\n mapping(uint256 => App) private _apps;\n mapping(string => AccessPoint) private _accessPoints;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function initialize(string memory _name, string memory _symbol) public initializer {\n __ERC721_init(_name, _symbol);\n __FleekAccessControl_init();\n }\n\n /**\n * @dev Checks if the AccessPoint exists.\n */\n modifier requireAP(string memory apName) {\n require(_accessPoints[apName].owner != address(0), \"FleekERC721: invalid AP\");\n _;\n }\n\n /**\n * @dev Mints a token and returns a tokenId.\n *\n * If the `tokenId` has not been minted before, and the `to` address is not zero, emits a {Transfer} event.\n *\n * Requirements:\n *\n * - the caller must have ``collectionOwner``'s admin role.\n *\n */\n function mint(\n address to,\n string memory name,\n string memory description,\n string memory externalURL,\n string memory ENS,\n string memory commitHash,\n string memory gitRepository,\n string memory logo,\n uint24 color\n ) public payable requireCollectionRole(Roles.Owner) returns (uint256) {\n uint256 tokenId = _appIds.current();\n _mint(to, tokenId);\n _appIds.increment();\n\n App storage app = _apps[tokenId];\n app.name = name;\n app.description = description;\n app.externalURL = externalURL;\n app.ENS = ENS;\n app.logo = logo;\n app.color = color;\n\n // The mint interaction is considered to be the first build of the site. Updates from now on all increment the currentBuild by one and update the mapping.\n app.currentBuild = 0;\n app.builds[0] = Build(commitHash, gitRepository);\n app.accessPoints = new string[](0);\n\n return tokenId;\n }\n\n /**\n * @dev Returns the token metadata associated with the `tokenId`.\n *\n * Returns a based64 encoded string value of the URI.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n address owner = ownerOf(tokenId);\n App storage app = _apps[tokenId];\n\n return string(abi.encodePacked(_baseURI(), app.toString(owner).toBase64()));\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Upgradeable) returns (bool) {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Override of _beforeTokenTransfer of ERC721.\n * Here it needs to update the token controller roles for mint, burn and transfer.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId,\n uint256 batchSize\n ) internal virtual override {\n if (from != address(0) && to != address(0)) {\n // Transfer\n _clearAllTokenRoles(tokenId, to);\n } else if (from == address(0)) {\n // Mint\n _grantTokenRole(tokenId, Roles.Owner, to);\n } else if (to == address(0)) {\n // Burn\n _clearAllTokenRoles(tokenId);\n }\n super._beforeTokenTransfer(from, to, tokenId, batchSize);\n }\n\n /**\n * @dev A baseURI internal function implementation to be called in the `tokenURI` function.\n */\n function _baseURI() internal view virtual override returns (string memory) {\n return \"data:application/json;base64,\";\n }\n\n /**\n * @dev Updates the `externalURL` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenExternalURL} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenExternalURL(\n uint256 tokenId,\n string memory _tokenExternalURL\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].externalURL = _tokenExternalURL;\n emit NewTokenExternalURL(tokenId, _tokenExternalURL, msg.sender);\n }\n\n /**\n * @dev Updates the `ENS` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenENS} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenENS(\n uint256 tokenId,\n string memory _tokenENS\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].ENS = _tokenENS;\n emit NewTokenENS(tokenId, _tokenENS, msg.sender);\n }\n\n /**\n * @dev Updates the `name` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenName} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenName(\n uint256 tokenId,\n string memory _tokenName\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].name = _tokenName;\n emit NewTokenName(tokenId, _tokenName, msg.sender);\n }\n\n /**\n * @dev Updates the `description` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenDescription} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenDescription(\n uint256 tokenId,\n string memory _tokenDescription\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].description = _tokenDescription;\n emit NewTokenDescription(tokenId, _tokenDescription, msg.sender);\n }\n\n /**\n * @dev Add a new AccessPoint register for an app token.\n * The AP name should be a DNS or ENS url and it should be unique.\n * Anyone can add an AP but it should requires a payment.\n *\n * May emit a {NewAccessPoint} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n * IMPORTANT: The payment is not set yet\n */\n function addAccessPoint(uint256 tokenId, string memory apName) public payable {\n // require(msg.value == 0.1 ether, \"You need to pay at least 0.1 ETH\"); // TODO: define a minimum price\n _requireMinted(tokenId);\n require(_accessPoints[apName].owner == address(0), \"FleekERC721: AP already exists\");\n\n _accessPoints[apName] = AccessPoint(tokenId, _apps[tokenId].accessPoints.length, 0, false, false, msg.sender);\n _apps[tokenId].accessPoints.push(apName);\n\n emit NewAccessPoint(apName, tokenId, msg.sender);\n }\n\n /**\n * @dev Remove an AccessPoint registry for an app token.\n * It will also remove the AP from the app token APs list.\n *\n * May emit a {RemoveAccessPoint} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - must be called by the AP owner.\n */\n function removeAccessPoint(string memory apName) public requireAP(apName) {\n require(msg.sender == _accessPoints[apName].owner, \"FleekERC721: must be AP owner\");\n uint256 tokenId = _accessPoints[apName].tokenId;\n App storage _app = _apps[tokenId];\n\n // the index of the AP to remove\n uint256 indexToRemove = _accessPoints[apName].index;\n\n // the last item is reposited in the index to remove\n string memory lastAP = _app.accessPoints[_app.accessPoints.length - 1];\n _app.accessPoints[indexToRemove] = lastAP;\n _accessPoints[lastAP].index = indexToRemove;\n\n // remove the last item\n _app.accessPoints.pop();\n\n delete _accessPoints[apName];\n emit RemoveAccessPoint(apName, tokenId, msg.sender);\n }\n\n /**\n * @dev A view function to gether information about an AccessPoint.\n * It returns a JSON string representing the AccessPoint information.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function getAccessPointJSON(string memory apName) public view requireAP(apName) returns (string memory) {\n AccessPoint storage _ap = _accessPoints[apName];\n return _ap.toString();\n }\n\n /**\n * @dev A view function to check if a AccessPoint is verified.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function isAccessPointNameVerified(string memory apName) public view requireAP(apName) returns (bool) {\n return _accessPoints[apName].nameVerified;\n }\n\n /**\n * @dev Increases the score of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointScore} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function increaseAccessPointScore(string memory apName) public requireAP(apName) {\n _accessPoints[apName].score++;\n emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);\n }\n\n /**\n * @dev Decreases the score of a AccessPoint registry if is greater than 0.\n *\n * May emit a {ChangeAccessPointScore} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function decreaseAccessPointScore(string memory apName) public requireAP(apName) {\n require(_accessPoints[apName].score > 0, \"FleekERC721: score cant be lower\");\n _accessPoints[apName].score--;\n emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);\n }\n\n /**\n * @dev Set the content verification of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointContentVerify} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - the sender must have the token controller role.\n *\n */\n function setAccessPointContentVerify(\n string memory apName,\n bool verified\n ) public requireAP(apName) requireTokenRole(_accessPoints[apName].tokenId, Roles.Controller) {\n _accessPoints[apName].contentVerified = verified;\n emit ChangeAccessPointContentVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);\n }\n\n /**\n * @dev Set the name verification of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointNameVerify} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - the sender must have the token controller role.\n *\n */\n function setAccessPointNameVerify(\n string memory apName,\n bool verified\n ) public requireAP(apName) requireTokenRole(_accessPoints[apName].tokenId, Roles.Controller) {\n _accessPoints[apName].nameVerified = verified;\n emit ChangeAccessPointNameVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);\n }\n\n /**\n * @dev A view function to gether the list of mirrros for a given app.\n *\n * Requirements:\n * - the tokenId must be minted and valid.\n *\n */\n function appAccessPoints(uint256 tokenId) public view returns (string[] memory) {\n _requireMinted(tokenId);\n return _apps[tokenId].accessPoints;\n }\n\n /**\n * @dev Adds a new build to a minted `tokenId`'s builds mapping.\n *\n * May emit a {NewBuild} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenBuild(\n uint256 tokenId,\n string memory _commitHash,\n string memory _gitRepository\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].builds[++_apps[tokenId].currentBuild] = Build(_commitHash, _gitRepository);\n emit NewBuild(tokenId, _commitHash, msg.sender);\n }\n\n /**\n * @dev Burns a previously minted `tokenId`.\n *\n * May emit a {Transfer} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenOwner` role.\n *\n */\n function burn(uint256 tokenId) public virtual requireTokenRole(tokenId, Roles.Owner) {\n super._burn(tokenId);\n\n if (bytes(_apps[tokenId].externalURL).length != 0) {\n delete _apps[tokenId];\n }\n }\n}\n"
+ },
+ "contracts/util/FleekStrings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"../FleekERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"./FleekSVG.sol\";\n\nlibrary FleekStrings {\n using Strings for uint256;\n using Strings for uint160;\n using FleekStrings for bool;\n using FleekStrings for uint24;\n using Strings for uint24;\n\n /**\n * @dev Converts a boolean value to a string.\n */\n function toString(bool _bool) internal pure returns (string memory) {\n return _bool ? \"true\" : \"false\";\n }\n\n /**\n * @dev Converts a string to a base64 string.\n */\n function toBase64(string memory str) internal pure returns (string memory) {\n return Base64.encode(bytes(str));\n }\n\n /**\n * @dev Converts FleekERC721.App to a JSON string.\n * It requires to receive owner address as a parameter.\n */\n function toString(FleekERC721.App storage app, address owner) internal view returns (string memory) {\n // prettier-ignore\n return string(abi.encodePacked(\n '{',\n '\"name\":\"', app.name, '\",',\n '\"description\":\"', app.description, '\",',\n '\"owner\":\"', uint160(owner).toHexString(20), '\",',\n '\"external_url\":\"', app.externalURL, '\",',\n '\"image\":\"', FleekSVG.generateBase64(app.name, app.ENS, app.logo, app.color.toColorString()), '\",',\n '\"attributes\": [',\n '{\"trait_type\": \"ENS\", \"value\":\"', app.ENS,'\"},',\n '{\"trait_type\": \"Commit Hash\", \"value\":\"', app.builds[app.currentBuild].commitHash,'\"},',\n '{\"trait_type\": \"Repository\", \"value\":\"', app.builds[app.currentBuild].gitRepository,'\"},',\n '{\"trait_type\": \"Version\", \"value\":\"', app.currentBuild.toString(),'\"},',\n '{\"trait_type\": \"Color\", \"value\":\"', app.color.toColorString(),'\"}',\n ']',\n '}'\n ));\n }\n\n /**\n * @dev Converts FleekERC721.AccessPoint to a JSON string.\n */\n function toString(FleekERC721.AccessPoint storage ap) internal view returns (string memory) {\n // prettier-ignore\n return string(abi.encodePacked(\n \"{\",\n '\"tokenId\":', ap.tokenId.toString(), \",\",\n '\"score\":', ap.score.toString(), \",\",\n '\"nameVerified\":', ap.nameVerified.toString(), \",\",\n '\"contentVerified\":', ap.contentVerified.toString(), \",\",\n '\"owner\":\"', uint160(ap.owner).toHexString(20), '\"',\n \"}\"\n ));\n }\n\n /**\n * @dev Converts bytes3 to a hex color string.\n */\n function toColorString(uint24 color) internal pure returns (string memory) {\n bytes memory hexBytes = bytes(color.toHexString(6));\n // remove 0x and add # from hexString\n bytes memory hexColor = new bytes(7);\n hexColor[0] = \"#\";\n for (uint256 i = 2; i < 8; i++) {\n hexColor[i - 2] = hexBytes[i];\n }\n return string(hexColor);\n }\n}\n"
+ },
+ "contracts/util/FleekSVG.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"../FleekERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\n\nlibrary FleekSVG {\n /**\n * @dev Generates a SVG image.\n */\n function generateBase64(\n string memory name,\n string memory ENS,\n string memory logo,\n string memory color\n ) internal pure returns (string memory) {\n return (\n string(\n abi.encodePacked(\n \"data:image/svg+xml;base64,\",\n Base64.encode(\n abi.encodePacked(\n '',\n '',\n ''\n '',\n '',\n '',\n '',\n '',\n '',\n '',\n ''\n ''\n '',\n name,\n \"\"\n '',\n ENS,\n \"\"\n \"\"\n )\n )\n )\n )\n );\n }\n}\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 200,
+ "details": {
+ "yul": true
+ }
+ },
+ "viaIR": true,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "storageLayout"
+ ],
+ "": ["ast"]
+ }
+ }
+ }
+}
diff --git a/deployments/mumbai/solcInputs/3e31d97b4e5be79f974bb2db691c518e.json b/deployments/mumbai/solcInputs/3e31d97b4e5be79f974bb2db691c518e.json
new file mode 100644
index 0000000..b6f2dbe
--- /dev/null
+++ b/deployments/mumbai/solcInputs/3e31d97b4e5be79f974bb2db691c518e.json
@@ -0,0 +1,85 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initialized`\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initializing`\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721Upgradeable.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256, /* firstTokenId */\n uint256 batchSize\n ) internal virtual {\n if (batchSize > 1) {\n if (from != address(0)) {\n _balances[from] -= batchSize;\n }\n if (to != address(0)) {\n _balances[to] += batchSize;\n }\n }\n }\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 firstTokenId,\n uint256 batchSize\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = MathUpgradeable.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, MathUpgradeable.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Base64.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n *\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n string memory result = new string(4 * ((data.length + 2) / 3));\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n\n // When data `bytes` is not exactly 3 bytes long\n // it is padded with `=` characters at the end\n switch mod(mload(data), 3)\n case 1 {\n mstore8(sub(resultPtr, 1), 0x3d)\n mstore8(sub(resultPtr, 2), 0x3d)\n }\n case 2 {\n mstore8(sub(resultPtr, 1), 0x3d)\n }\n }\n\n return result;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Counters.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/math/Math.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "contracts/FleekAccessControl.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\ncontract FleekAccessControl is Initializable {\n using Counters for Counters.Counter;\n\n enum Roles {\n Owner,\n Controller\n }\n\n event TokenRoleGranted(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event TokenRoleRevoked(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleGranted(Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleRevoked(Roles indexed role, address indexed toAddress, address byAddress);\n\n struct Role {\n mapping(address => uint256) indexes;\n address[] members;\n }\n\n Counters.Counter private _collectionRolesVersion;\n // _collectionRoles[version][role]\n mapping(uint256 => mapping(Roles => Role)) private _collectionRoles;\n\n mapping(uint256 => Counters.Counter) private _tokenRolesVersion;\n // _tokenRoles[tokenId][version][role]\n mapping(uint256 => mapping(uint256 => mapping(Roles => Role))) private _tokenRoles;\n\n /**\n * @dev Initializes the contract by granting the `Owner` role to the deployer.\n */\n function __FleekAccessControl_init() internal onlyInitializing {\n _grantCollectionRole(Roles.Owner, msg.sender);\n }\n\n /**\n * @dev Checks if the `msg.sender` has a certain role.\n */\n modifier requireCollectionRole(Roles role) {\n require(\n hasCollectionRole(role, msg.sender) || hasCollectionRole(Roles.Owner, msg.sender),\n \"FleekAccessControl: must have collection role\"\n );\n _;\n }\n\n /**\n * @dev Checks if the `msg.sender` has the `Token` role for a certain `tokenId`.\n */\n modifier requireTokenRole(uint256 tokenId, Roles role) {\n require(\n hasTokenRole(tokenId, role, msg.sender) || hasTokenRole(tokenId, Roles.Owner, msg.sender),\n \"FleekAccessControl: must have token role\"\n );\n _;\n }\n\n /**\n * @dev Grants the collection role to an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function grantCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _grantCollectionRole(role, account);\n }\n\n /**\n * @dev Grants the token role to an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function grantTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _grantTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function revokeCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _revokeCollectionRole(role, account);\n }\n\n /**\n * @dev Revokes the token role of an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function revokeTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _revokeTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Returns `True` if a certain address has the collection role.\n */\n function hasCollectionRole(Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _collectionRolesVersion.current();\n\n return _collectionRoles[currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns `True` if a certain address has the token role.\n */\n function hasTokenRole(uint256 tokenId, Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns an array of addresses that all have the collection role.\n */\n function getCollectionRoleMembers(Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _collectionRolesVersion.current();\n return _collectionRoles[currentVersion][role].members;\n }\n\n /**\n * @dev Returns an array of addresses that all have the same token role for a certain tokenId.\n */\n function getTokenRoleMembers(uint256 tokenId, Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].members;\n }\n\n /**\n * @dev Grants the collection role to an address.\n */\n function _grantCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _grantRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleGranted(role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n */\n function _revokeCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _revokeRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleRevoked(role, account, msg.sender);\n }\n\n /**\n * @dev Grants the token role to an address.\n */\n function _grantTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _grantRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleGranted(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the token role of an address.\n */\n function _revokeTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _revokeRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleRevoked(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Grants a certain role to a certain address.\n */\n function _grantRole(Role storage role, address account) internal {\n if (role.indexes[account] == 0) {\n role.members.push(account);\n role.indexes[account] = role.members.length;\n }\n }\n\n /**\n * @dev Revokes a certain role from a certain address.\n */\n function _revokeRole(Role storage role, address account) internal {\n if (role.indexes[account] != 0) {\n uint256 index = role.indexes[account] - 1;\n uint256 lastIndex = role.members.length - 1;\n address lastAccount = role.members[lastIndex];\n\n role.members[index] = lastAccount;\n role.indexes[lastAccount] = index + 1;\n\n role.members.pop();\n delete role.indexes[account];\n }\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId.\n * Should only be used for burning tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId) internal {\n _tokenRolesVersion[tokenId].increment();\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId and grants the owner role to a new address.\n * Should only be used for transferring tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId, address newOwner) internal {\n _clearAllTokenRoles(tokenId);\n _grantTokenRole(tokenId, Roles.Owner, newOwner);\n }\n}\n"
+ },
+ "contracts/FleekERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"./FleekAccessControl.sol\";\nimport \"./util/FleekStrings.sol\";\n\ncontract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl {\n using Strings for uint256;\n using Counters for Counters.Counter;\n using FleekStrings for FleekERC721.App;\n using FleekStrings for FleekERC721.AccessPoint;\n using FleekStrings for string;\n\n event NewBuild(uint256 indexed token, string indexed commitHash, address indexed triggeredBy);\n event NewTokenName(uint256 indexed token, string indexed name, address indexed triggeredBy);\n event NewTokenDescription(uint256 indexed token, string indexed description, address indexed triggeredBy);\n event NewTokenImage(uint256 indexed token, string indexed image, address indexed triggeredBy);\n event NewTokenExternalURL(uint256 indexed token, string indexed externalURL, address indexed triggeredBy);\n event NewTokenENS(uint256 indexed token, string indexed ENS, address indexed triggeredBy);\n\n event NewAccessPoint(string indexed apName, uint256 indexed tokenId, address indexed owner);\n event RemoveAccessPoint(string indexed apName, uint256 indexed tokenId, address indexed owner);\n event ChangeAccessPointScore(\n string indexed apName,\n uint256 indexed tokenId,\n uint256 score,\n address indexed triggeredBy\n );\n event ChangeAccessPointNameVerify(\n string indexed apName,\n uint256 tokenId,\n bool indexed verified,\n address indexed triggeredBy\n );\n event ChangeAccessPointContentVerify(\n string indexed apName,\n uint256 tokenId,\n bool indexed verified,\n address indexed triggeredBy\n );\n\n /**\n * The properties are stored as string to keep consistency with\n * other token contracts, we might consider changing for bytes32\n * in the future due to gas optimization.\n */\n struct App {\n string name; // Name of the site\n string description; // Description about the site\n string externalURL; // Site URL\n string ENS; // ENS ID\n uint256 currentBuild; // The current build number (Increments by one with each change, starts at zero)\n mapping(uint256 => Build) builds; // Mapping to build details for each build number\n string[] accessPoints; // List of app AccessPoint\n }\n\n /**\n * The metadata that is stored for each build.\n */\n struct Build {\n string commitHash;\n string gitRepository;\n }\n\n /**\n * The stored data for each AccessPoint.\n */\n struct AccessPoint {\n uint256 tokenId;\n uint256 index;\n uint256 score;\n bool contentVerified;\n bool nameVerified;\n address owner;\n }\n\n Counters.Counter private _appIds;\n mapping(uint256 => App) private _apps;\n mapping(string => AccessPoint) private _accessPoints;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function initialize(string memory _name, string memory _symbol) public initializer {\n __ERC721_init(_name, _symbol);\n __FleekAccessControl_init();\n }\n\n /**\n * @dev Checks if the AccessPoint exists.\n */\n modifier requireAP(string memory apName) {\n require(_accessPoints[apName].owner != address(0), \"FleekERC721: invalid AP\");\n _;\n }\n\n /**\n * @dev Mints a token and returns a tokenId.\n *\n * If the `tokenId` has not been minted before, and the `to` address is not zero, emits a {Transfer} event.\n *\n * Requirements:\n *\n * - the caller must have ``collectionOwner``'s admin role.\n *\n */\n function mint(\n address to,\n string memory name,\n string memory description,\n string memory externalURL,\n string memory ENS,\n string memory commitHash,\n string memory gitRepository\n ) public payable requireCollectionRole(Roles.Owner) returns (uint256) {\n uint256 tokenId = _appIds.current();\n _mint(to, tokenId);\n _appIds.increment();\n\n App storage app = _apps[tokenId];\n app.name = name;\n app.description = description;\n app.externalURL = externalURL;\n app.ENS = ENS;\n\n // The mint interaction is considered to be the first build of the site. Updates from now on all increment the currentBuild by one and update the mapping.\n app.currentBuild = 0;\n app.builds[0] = Build(commitHash, gitRepository);\n app.accessPoints = new string[](0);\n\n return tokenId;\n }\n\n /**\n * @dev Returns the token metadata associated with the `tokenId`.\n *\n * Returns a based64 encoded string value of the URI.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n address owner = ownerOf(tokenId);\n App storage app = _apps[tokenId];\n\n return string(abi.encodePacked(_baseURI(), app.toString(owner).toBase64()));\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Upgradeable) returns (bool) {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Override of _beforeTokenTransfer of ERC721.\n * Here it needs to update the token controller roles for mint, burn and transfer.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId,\n uint256 batchSize\n ) internal virtual override {\n if (from != address(0) && to != address(0)) {\n // Transfer\n _clearAllTokenRoles(tokenId, to);\n } else if (from == address(0)) {\n // Mint\n _grantTokenRole(tokenId, Roles.Owner, to);\n } else if (to == address(0)) {\n // Burn\n _clearAllTokenRoles(tokenId);\n }\n super._beforeTokenTransfer(from, to, tokenId, batchSize);\n }\n\n /**\n * @dev A baseURI internal function implementation to be called in the `tokenURI` function.\n */\n function _baseURI() internal view virtual override returns (string memory) {\n return \"data:application/json;base64,\";\n }\n\n /**\n * @dev Updates the `externalURL` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenExternalURL} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenExternalURL(\n uint256 tokenId,\n string memory _tokenExternalURL\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].externalURL = _tokenExternalURL;\n emit NewTokenExternalURL(tokenId, _tokenExternalURL, msg.sender);\n }\n\n /**\n * @dev Updates the `ENS` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenENS} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenENS(\n uint256 tokenId,\n string memory _tokenENS\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].ENS = _tokenENS;\n emit NewTokenENS(tokenId, _tokenENS, msg.sender);\n }\n\n /**\n * @dev Updates the `name` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenName} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenName(\n uint256 tokenId,\n string memory _tokenName\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].name = _tokenName;\n emit NewTokenName(tokenId, _tokenName, msg.sender);\n }\n\n /**\n * @dev Updates the `description` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenDescription} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenDescription(\n uint256 tokenId,\n string memory _tokenDescription\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].description = _tokenDescription;\n emit NewTokenDescription(tokenId, _tokenDescription, msg.sender);\n }\n\n /**\n * @dev Add a new AccessPoint register for an app token.\n * The AP name should be a DNS or ENS url and it should be unique.\n * Anyone can add an AP but it should requires a payment.\n *\n * May emit a {NewAccessPoint} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n * IMPORTANT: The payment is not set yet\n */\n function addAccessPoint(uint256 tokenId, string memory apName) public payable {\n // require(msg.value == 0.1 ether, \"You need to pay at least 0.1 ETH\"); // TODO: define a minimum price\n _requireMinted(tokenId);\n require(_accessPoints[apName].owner == address(0), \"FleekERC721: AP already exists\");\n\n _accessPoints[apName] = AccessPoint(tokenId, _apps[tokenId].accessPoints.length, 0, false, false, msg.sender);\n _apps[tokenId].accessPoints.push(apName);\n\n emit NewAccessPoint(apName, tokenId, msg.sender);\n }\n\n /**\n * @dev Remove an AccessPoint registry for an app token.\n * It will also remove the AP from the app token APs list.\n *\n * May emit a {RemoveAccessPoint} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - must be called by the AP owner.\n */\n function removeAccessPoint(string memory apName) public requireAP(apName) {\n require(msg.sender == _accessPoints[apName].owner, \"FleekERC721: must be AP owner\");\n uint256 tokenId = _accessPoints[apName].tokenId;\n App storage _app = _apps[tokenId];\n\n // the index of the AP to remove\n uint256 indexToRemove = _accessPoints[apName].index;\n\n // the last item is reposited in the index to remove\n string memory lastAP = _app.accessPoints[_app.accessPoints.length - 1];\n _app.accessPoints[indexToRemove] = lastAP;\n _accessPoints[lastAP].index = indexToRemove;\n\n // remove the last item\n _app.accessPoints.pop();\n\n delete _accessPoints[apName];\n emit RemoveAccessPoint(apName, tokenId, msg.sender);\n }\n\n /**\n * @dev A view function to gether information about an AccessPoint.\n * It returns a JSON string representing the AccessPoint information.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function getAccessPointJSON(string memory apName) public view requireAP(apName) returns (string memory) {\n AccessPoint storage _ap = _accessPoints[apName];\n return _ap.toString();\n }\n\n /**\n * @dev A view function to check if a AccessPoint is verified.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function isAccessPointNameVerified(string memory apName) public view requireAP(apName) returns (bool) {\n return _accessPoints[apName].nameVerified;\n }\n\n /**\n * @dev Increases the score of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointScore} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function increaseAccessPointScore(string memory apName) public requireAP(apName) {\n _accessPoints[apName].score++;\n emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);\n }\n\n /**\n * @dev Decreases the score of a AccessPoint registry if is greater than 0.\n *\n * May emit a {ChangeAccessPointScore} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function decreaseAccessPointScore(string memory apName) public requireAP(apName) {\n require(_accessPoints[apName].score > 0, \"FleekERC721: score cant be lower\");\n _accessPoints[apName].score--;\n emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);\n }\n\n /**\n * @dev Set the content verification of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointContentVerify} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - the sender must have the token controller role.\n *\n */\n function setAccessPointContentVerify(\n string memory apName,\n bool verified\n ) public requireAP(apName) requireTokenRole(_accessPoints[apName].tokenId, Roles.Controller) {\n _accessPoints[apName].contentVerified = verified;\n emit ChangeAccessPointContentVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);\n }\n\n /**\n * @dev Set the name verification of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointNameVerify} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - the sender must have the token controller role.\n *\n */\n function setAccessPointNameVerify(\n string memory apName,\n bool verified\n ) public requireAP(apName) requireTokenRole(_accessPoints[apName].tokenId, Roles.Controller) {\n _accessPoints[apName].nameVerified = verified;\n emit ChangeAccessPointNameVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);\n }\n\n /**\n * @dev A view function to gether the list of mirrros for a given app.\n *\n * Requirements:\n * - the tokenId must be minted and valid.\n *\n */\n function appAccessPoints(uint256 tokenId) public view returns (string[] memory) {\n _requireMinted(tokenId);\n return _apps[tokenId].accessPoints;\n }\n\n /**\n * @dev Adds a new build to a minted `tokenId`'s builds mapping.\n *\n * May emit a {NewBuild} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenBuild(\n uint256 tokenId,\n string memory _commitHash,\n string memory _gitRepository\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].builds[++_apps[tokenId].currentBuild] = Build(_commitHash, _gitRepository);\n emit NewBuild(tokenId, _commitHash, msg.sender);\n }\n\n /**\n * @dev Burns a previously minted `tokenId`.\n *\n * May emit a {Transfer} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenOwner` role.\n *\n */\n function burn(uint256 tokenId) public virtual requireTokenRole(tokenId, Roles.Owner) {\n super._burn(tokenId);\n\n if (bytes(_apps[tokenId].externalURL).length != 0) {\n delete _apps[tokenId];\n }\n }\n}\n"
+ },
+ "contracts/util/FleekStrings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"../FleekERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"./FleekSVG.sol\";\n\nlibrary FleekStrings {\n using Strings for uint256;\n using Strings for uint160;\n using FleekStrings for bool;\n\n /**\n * @dev Converts a boolean value to a string.\n */\n function toString(bool _bool) internal pure returns (string memory) {\n return _bool ? \"true\" : \"false\";\n }\n\n /**\n * @dev Converts a string to a base64 string.\n */\n function toBase64(string memory str) internal pure returns (string memory) {\n return Base64.encode(bytes(str));\n }\n\n /**\n * @dev Converts FleekERC721.App to a JSON string.\n * It requires to receive owner address as a parameter.\n */\n function toString(FleekERC721.App storage app, address owner) internal view returns (string memory) {\n // prettier-ignore\n return string(abi.encodePacked(\n '{',\n '\"name\":\"', app.name, '\",',\n '\"description\":\"', app.description, '\",',\n '\"owner\":\"', uint160(owner).toHexString(20), '\",',\n '\"external_url\":\"', app.externalURL, '\",',\n '\"image\":\"', FleekSVG.generateBase64(app.name, app.ENS), '\",',\n '\"attributes\": [',\n '{\"trait_type\": \"ENS\", \"value\":\"', app.ENS,'\"},',\n '{\"trait_type\": \"Commit Hash\", \"value\":\"', app.builds[app.currentBuild].commitHash,'\"},',\n '{\"trait_type\": \"Repository\", \"value\":\"', app.builds[app.currentBuild].gitRepository,'\"},',\n '{\"trait_type\": \"Version\", \"value\":\"', app.currentBuild.toString(),'\"}',\n ']',\n '}'\n ));\n }\n\n /**\n * @dev Converts FleekERC721.AccessPoint to a JSON string.\n */\n function toString(FleekERC721.AccessPoint storage ap) internal view returns (string memory) {\n // prettier-ignore\n return string(abi.encodePacked(\n \"{\",\n '\"tokenId\":', ap.tokenId.toString(), \",\",\n '\"score\":', ap.score.toString(), \",\",\n '\"nameVerified\":', ap.nameVerified.toString(), \",\",\n '\"contentVerified\":', ap.contentVerified.toString(), \",\",\n '\"owner\":\"', uint160(ap.owner).toHexString(20), '\"',\n \"}\"\n ));\n }\n}\n"
+ },
+ "contracts/util/FleekSVG.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"../FleekERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\n\nlibrary FleekSVG {\n /**\n * @dev Generates a SVG image.\n */\n function generateBase64(string memory name, string memory ENS) internal pure returns (string memory) {\n string memory color = \"#e34f26\";\n string memory logo = \"https://cdn.worldvectorlogo.com/logos/html-1.svg\";\n\n return (\n string(\n abi.encodePacked(\n \"data:application/json;base64,\",\n Base64.encode(\n abi.encodePacked(\n '',\n '',\n '',\n '',\n '',\n '',\n '',\n '',\n '',\n ''\n ''\n '',\n name,\n \"\"\n '',\n ENS,\n \"\"\n \"\"\n )\n )\n )\n )\n );\n }\n}\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 200,
+ "details": {
+ "yul": true
+ }
+ },
+ "viaIR": true,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "storageLayout"
+ ],
+ "": ["ast"]
+ }
+ }
+ }
+}
diff --git a/deployments/mumbai/solcInputs/503442bf66fe6b63b37bab0162882994.json b/deployments/mumbai/solcInputs/503442bf66fe6b63b37bab0162882994.json
new file mode 100644
index 0000000..4ad701a
--- /dev/null
+++ b/deployments/mumbai/solcInputs/503442bf66fe6b63b37bab0162882994.json
@@ -0,0 +1,85 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initialized`\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initializing`\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721Upgradeable.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256, /* firstTokenId */\n uint256 batchSize\n ) internal virtual {\n if (batchSize > 1) {\n if (from != address(0)) {\n _balances[from] -= batchSize;\n }\n if (to != address(0)) {\n _balances[to] += batchSize;\n }\n }\n }\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 firstTokenId,\n uint256 batchSize\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = MathUpgradeable.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, MathUpgradeable.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Base64.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n *\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n string memory result = new string(4 * ((data.length + 2) / 3));\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n\n // When data `bytes` is not exactly 3 bytes long\n // it is padded with `=` characters at the end\n switch mod(mload(data), 3)\n case 1 {\n mstore8(sub(resultPtr, 1), 0x3d)\n mstore8(sub(resultPtr, 2), 0x3d)\n }\n case 2 {\n mstore8(sub(resultPtr, 1), 0x3d)\n }\n }\n\n return result;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Counters.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/math/Math.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "contracts/FleekAccessControl.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\ncontract FleekAccessControl is Initializable {\n using Counters for Counters.Counter;\n\n enum Roles {\n Owner,\n Controller\n }\n\n event TokenRoleGranted(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event TokenRoleRevoked(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleGranted(Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleRevoked(Roles indexed role, address indexed toAddress, address byAddress);\n\n struct Role {\n mapping(address => uint256) indexes;\n address[] members;\n }\n\n Counters.Counter private _collectionRolesVersion;\n // _collectionRoles[version][role]\n mapping(uint256 => mapping(Roles => Role)) private _collectionRoles;\n\n mapping(uint256 => Counters.Counter) private _tokenRolesVersion;\n // _tokenRoles[tokenId][version][role]\n mapping(uint256 => mapping(uint256 => mapping(Roles => Role))) private _tokenRoles;\n\n /**\n * @dev Initializes the contract by granting the `Owner` role to the deployer.\n */\n function __FleekAccessControl_init() internal onlyInitializing {\n _grantCollectionRole(Roles.Owner, msg.sender);\n }\n\n /**\n * @dev Checks if the `msg.sender` has a certain role.\n */\n modifier requireCollectionRole(Roles role) {\n require(\n hasCollectionRole(role, msg.sender) || hasCollectionRole(Roles.Owner, msg.sender),\n \"FleekAccessControl: must have collection role\"\n );\n _;\n }\n\n /**\n * @dev Checks if the `msg.sender` has the `Token` role for a certain `tokenId`.\n */\n modifier requireTokenRole(uint256 tokenId, Roles role) {\n require(\n hasTokenRole(tokenId, role, msg.sender) || hasTokenRole(tokenId, Roles.Owner, msg.sender),\n \"FleekAccessControl: must have token role\"\n );\n _;\n }\n\n /**\n * @dev Grants the collection role to an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function grantCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _grantCollectionRole(role, account);\n }\n\n /**\n * @dev Grants the token role to an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function grantTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _grantTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function revokeCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _revokeCollectionRole(role, account);\n }\n\n /**\n * @dev Revokes the token role of an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function revokeTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _revokeTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Returns `True` if a certain address has the collection role.\n */\n function hasCollectionRole(Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _collectionRolesVersion.current();\n\n return _collectionRoles[currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns `True` if a certain address has the token role.\n */\n function hasTokenRole(uint256 tokenId, Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns an array of addresses that all have the collection role.\n */\n function getCollectionRoleMembers(Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _collectionRolesVersion.current();\n return _collectionRoles[currentVersion][role].members;\n }\n\n /**\n * @dev Returns an array of addresses that all have the same token role for a certain tokenId.\n */\n function getTokenRoleMembers(uint256 tokenId, Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].members;\n }\n\n /**\n * @dev Grants the collection role to an address.\n */\n function _grantCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _grantRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleGranted(role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n */\n function _revokeCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _revokeRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleRevoked(role, account, msg.sender);\n }\n\n /**\n * @dev Grants the token role to an address.\n */\n function _grantTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _grantRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleGranted(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the token role of an address.\n */\n function _revokeTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _revokeRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleRevoked(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Grants a certain role to a certain address.\n */\n function _grantRole(Role storage role, address account) internal {\n if (role.indexes[account] == 0) {\n role.members.push(account);\n role.indexes[account] = role.members.length;\n }\n }\n\n /**\n * @dev Revokes a certain role from a certain address.\n */\n function _revokeRole(Role storage role, address account) internal {\n if (role.indexes[account] != 0) {\n uint256 index = role.indexes[account] - 1;\n uint256 lastIndex = role.members.length - 1;\n address lastAccount = role.members[lastIndex];\n\n role.members[index] = lastAccount;\n role.indexes[lastAccount] = index + 1;\n\n role.members.pop();\n delete role.indexes[account];\n }\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId.\n * Should only be used for burning tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId) internal {\n _tokenRolesVersion[tokenId].increment();\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId and grants the owner role to a new address.\n * Should only be used for transferring tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId, address newOwner) internal {\n _clearAllTokenRoles(tokenId);\n _grantTokenRole(tokenId, Roles.Owner, newOwner);\n }\n}\n"
+ },
+ "contracts/FleekERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"./FleekAccessControl.sol\";\nimport \"./util/FleekStrings.sol\";\n\ncontract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl {\n using Strings for uint256;\n using Counters for Counters.Counter;\n using FleekStrings for FleekERC721.App;\n using FleekStrings for FleekERC721.AccessPoint;\n using FleekStrings for string;\n\n event NewBuild(uint256 indexed token, string indexed commitHash, address indexed triggeredBy);\n event NewTokenName(uint256 indexed token, string indexed name, address indexed triggeredBy);\n event NewTokenDescription(uint256 indexed token, string indexed description, address indexed triggeredBy);\n event NewTokenImage(uint256 indexed token, string indexed image, address indexed triggeredBy);\n event NewTokenExternalURL(uint256 indexed token, string indexed externalURL, address indexed triggeredBy);\n event NewTokenENS(uint256 indexed token, string indexed ENS, address indexed triggeredBy);\n\n event NewAccessPoint(string indexed apName, uint256 indexed tokenId, address indexed owner);\n event RemoveAccessPoint(string indexed apName, uint256 indexed tokenId, address indexed owner);\n event ChangeAccessPointScore(\n string indexed apName,\n uint256 indexed tokenId,\n uint256 score,\n address indexed triggeredBy\n );\n event ChangeAccessPointNameVerify(\n string indexed apName,\n uint256 tokenId,\n bool indexed verified,\n address indexed triggeredBy\n );\n event ChangeAccessPointContentVerify(\n string indexed apName,\n uint256 tokenId,\n bool indexed verified,\n address indexed triggeredBy\n );\n\n /**\n * The properties are stored as string to keep consistency with\n * other token contracts, we might consider changing for bytes32\n * in the future due to gas optimization.\n */\n struct App {\n string name; // Name of the site\n string description; // Description about the site\n string externalURL; // Site URL\n string ENS; // ENS ID\n uint256 currentBuild; // The current build number (Increments by one with each change, starts at zero)\n mapping(uint256 => Build) builds; // Mapping to build details for each build number\n string[] accessPoints; // List of app AccessPoint\n string logo;\n bytes3 color; // Color of the nft\n }\n\n /**\n * The metadata that is stored for each build.\n */\n struct Build {\n string commitHash;\n string gitRepository;\n }\n\n /**\n * The stored data for each AccessPoint.\n */\n struct AccessPoint {\n uint256 tokenId;\n uint256 index;\n uint256 score;\n bool contentVerified;\n bool nameVerified;\n address owner;\n }\n\n Counters.Counter private _appIds;\n mapping(uint256 => App) private _apps;\n mapping(string => AccessPoint) private _accessPoints;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function initialize(string memory _name, string memory _symbol) public initializer {\n __ERC721_init(_name, _symbol);\n __FleekAccessControl_init();\n }\n\n /**\n * @dev Checks if the AccessPoint exists.\n */\n modifier requireAP(string memory apName) {\n require(_accessPoints[apName].owner != address(0), \"FleekERC721: invalid AP\");\n _;\n }\n\n /**\n * @dev Mints a token and returns a tokenId.\n *\n * If the `tokenId` has not been minted before, and the `to` address is not zero, emits a {Transfer} event.\n *\n * Requirements:\n *\n * - the caller must have ``collectionOwner``'s admin role.\n *\n */\n function mint(\n address to,\n string memory name,\n string memory description,\n string memory externalURL,\n string memory ENS,\n string memory commitHash,\n string memory gitRepository,\n string memory logo,\n bytes3 color\n ) public payable requireCollectionRole(Roles.Owner) returns (uint256) {\n uint256 tokenId = _appIds.current();\n _mint(to, tokenId);\n _appIds.increment();\n\n App storage app = _apps[tokenId];\n app.name = name;\n app.description = description;\n app.externalURL = externalURL;\n app.ENS = ENS;\n app.logo = logo;\n app.color = color;\n\n // The mint interaction is considered to be the first build of the site. Updates from now on all increment the currentBuild by one and update the mapping.\n app.currentBuild = 0;\n app.builds[0] = Build(commitHash, gitRepository);\n app.accessPoints = new string[](0);\n\n return tokenId;\n }\n\n /**\n * @dev Returns the token metadata associated with the `tokenId`.\n *\n * Returns a based64 encoded string value of the URI.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n address owner = ownerOf(tokenId);\n App storage app = _apps[tokenId];\n\n return string(abi.encodePacked(_baseURI(), app.toString(owner).toBase64()));\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Upgradeable) returns (bool) {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Override of _beforeTokenTransfer of ERC721.\n * Here it needs to update the token controller roles for mint, burn and transfer.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId,\n uint256 batchSize\n ) internal virtual override {\n if (from != address(0) && to != address(0)) {\n // Transfer\n _clearAllTokenRoles(tokenId, to);\n } else if (from == address(0)) {\n // Mint\n _grantTokenRole(tokenId, Roles.Owner, to);\n } else if (to == address(0)) {\n // Burn\n _clearAllTokenRoles(tokenId);\n }\n super._beforeTokenTransfer(from, to, tokenId, batchSize);\n }\n\n /**\n * @dev A baseURI internal function implementation to be called in the `tokenURI` function.\n */\n function _baseURI() internal view virtual override returns (string memory) {\n return \"data:application/json;base64,\";\n }\n\n /**\n * @dev Updates the `externalURL` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenExternalURL} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenExternalURL(\n uint256 tokenId,\n string memory _tokenExternalURL\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].externalURL = _tokenExternalURL;\n emit NewTokenExternalURL(tokenId, _tokenExternalURL, msg.sender);\n }\n\n /**\n * @dev Updates the `ENS` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenENS} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenENS(\n uint256 tokenId,\n string memory _tokenENS\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].ENS = _tokenENS;\n emit NewTokenENS(tokenId, _tokenENS, msg.sender);\n }\n\n /**\n * @dev Updates the `name` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenName} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenName(\n uint256 tokenId,\n string memory _tokenName\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].name = _tokenName;\n emit NewTokenName(tokenId, _tokenName, msg.sender);\n }\n\n /**\n * @dev Updates the `description` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenDescription} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenDescription(\n uint256 tokenId,\n string memory _tokenDescription\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].description = _tokenDescription;\n emit NewTokenDescription(tokenId, _tokenDescription, msg.sender);\n }\n\n /**\n * @dev Add a new AccessPoint register for an app token.\n * The AP name should be a DNS or ENS url and it should be unique.\n * Anyone can add an AP but it should requires a payment.\n *\n * May emit a {NewAccessPoint} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n * IMPORTANT: The payment is not set yet\n */\n function addAccessPoint(uint256 tokenId, string memory apName) public payable {\n // require(msg.value == 0.1 ether, \"You need to pay at least 0.1 ETH\"); // TODO: define a minimum price\n _requireMinted(tokenId);\n require(_accessPoints[apName].owner == address(0), \"FleekERC721: AP already exists\");\n\n _accessPoints[apName] = AccessPoint(tokenId, _apps[tokenId].accessPoints.length, 0, false, false, msg.sender);\n _apps[tokenId].accessPoints.push(apName);\n\n emit NewAccessPoint(apName, tokenId, msg.sender);\n }\n\n /**\n * @dev Remove an AccessPoint registry for an app token.\n * It will also remove the AP from the app token APs list.\n *\n * May emit a {RemoveAccessPoint} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - must be called by the AP owner.\n */\n function removeAccessPoint(string memory apName) public requireAP(apName) {\n require(msg.sender == _accessPoints[apName].owner, \"FleekERC721: must be AP owner\");\n uint256 tokenId = _accessPoints[apName].tokenId;\n App storage _app = _apps[tokenId];\n\n // the index of the AP to remove\n uint256 indexToRemove = _accessPoints[apName].index;\n\n // the last item is reposited in the index to remove\n string memory lastAP = _app.accessPoints[_app.accessPoints.length - 1];\n _app.accessPoints[indexToRemove] = lastAP;\n _accessPoints[lastAP].index = indexToRemove;\n\n // remove the last item\n _app.accessPoints.pop();\n\n delete _accessPoints[apName];\n emit RemoveAccessPoint(apName, tokenId, msg.sender);\n }\n\n /**\n * @dev A view function to gether information about an AccessPoint.\n * It returns a JSON string representing the AccessPoint information.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function getAccessPointJSON(string memory apName) public view requireAP(apName) returns (string memory) {\n AccessPoint storage _ap = _accessPoints[apName];\n return _ap.toString();\n }\n\n /**\n * @dev A view function to check if a AccessPoint is verified.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function isAccessPointNameVerified(string memory apName) public view requireAP(apName) returns (bool) {\n return _accessPoints[apName].nameVerified;\n }\n\n /**\n * @dev Increases the score of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointScore} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function increaseAccessPointScore(string memory apName) public requireAP(apName) {\n _accessPoints[apName].score++;\n emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);\n }\n\n /**\n * @dev Decreases the score of a AccessPoint registry if is greater than 0.\n *\n * May emit a {ChangeAccessPointScore} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function decreaseAccessPointScore(string memory apName) public requireAP(apName) {\n require(_accessPoints[apName].score > 0, \"FleekERC721: score cant be lower\");\n _accessPoints[apName].score--;\n emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);\n }\n\n /**\n * @dev Set the content verification of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointContentVerify} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - the sender must have the token controller role.\n *\n */\n function setAccessPointContentVerify(\n string memory apName,\n bool verified\n ) public requireAP(apName) requireTokenRole(_accessPoints[apName].tokenId, Roles.Controller) {\n _accessPoints[apName].contentVerified = verified;\n emit ChangeAccessPointContentVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);\n }\n\n /**\n * @dev Set the name verification of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointNameVerify} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - the sender must have the token controller role.\n *\n */\n function setAccessPointNameVerify(\n string memory apName,\n bool verified\n ) public requireAP(apName) requireTokenRole(_accessPoints[apName].tokenId, Roles.Controller) {\n _accessPoints[apName].nameVerified = verified;\n emit ChangeAccessPointNameVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);\n }\n\n /**\n * @dev A view function to gether the list of mirrros for a given app.\n *\n * Requirements:\n * - the tokenId must be minted and valid.\n *\n */\n function appAccessPoints(uint256 tokenId) public view returns (string[] memory) {\n _requireMinted(tokenId);\n return _apps[tokenId].accessPoints;\n }\n\n /**\n * @dev Adds a new build to a minted `tokenId`'s builds mapping.\n *\n * May emit a {NewBuild} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenBuild(\n uint256 tokenId,\n string memory _commitHash,\n string memory _gitRepository\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].builds[++_apps[tokenId].currentBuild] = Build(_commitHash, _gitRepository);\n emit NewBuild(tokenId, _commitHash, msg.sender);\n }\n\n /**\n * @dev Burns a previously minted `tokenId`.\n *\n * May emit a {Transfer} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenOwner` role.\n *\n */\n function burn(uint256 tokenId) public virtual requireTokenRole(tokenId, Roles.Owner) {\n super._burn(tokenId);\n\n if (bytes(_apps[tokenId].externalURL).length != 0) {\n delete _apps[tokenId];\n }\n }\n}\n"
+ },
+ "contracts/util/FleekStrings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"../FleekERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"./FleekSVG.sol\";\n\nlibrary FleekStrings {\n using Strings for uint256;\n using Strings for uint160;\n using FleekStrings for bool;\n using FleekStrings for bytes3;\n\n /**\n * @dev Converts a boolean value to a string.\n */\n function toString(bool _bool) internal pure returns (string memory) {\n return _bool ? \"true\" : \"false\";\n }\n\n /**\n * @dev Converts a string to a base64 string.\n */\n function toBase64(string memory str) internal pure returns (string memory) {\n return Base64.encode(bytes(str));\n }\n\n /**\n * @dev Converts FleekERC721.App to a JSON string.\n * It requires to receive owner address as a parameter.\n */\n function toString(FleekERC721.App storage app, address owner) internal view returns (string memory) {\n // prettier-ignore\n return string(abi.encodePacked(\n '{',\n '\"name\":\"', app.name, '\",',\n '\"description\":\"', app.description, '\",',\n '\"owner\":\"', uint160(owner).toHexString(20), '\",',\n '\"external_url\":\"', app.externalURL, '\",',\n '\"image\":\"', FleekSVG.generateBase64(app.name, app.ENS, app.logo, app.color.toColorString()), '\",',\n '\"attributes\": [',\n '{\"trait_type\": \"ENS\", \"value\":\"', app.ENS,'\"},',\n '{\"trait_type\": \"Commit Hash\", \"value\":\"', app.builds[app.currentBuild].commitHash,'\"},',\n '{\"trait_type\": \"Repository\", \"value\":\"', app.builds[app.currentBuild].gitRepository,'\"},',\n '{\"trait_type\": \"Version\", \"value\":\"', app.currentBuild.toString(),'\"}',\n '{\"trait_type\": \"Color\", \"value\":\"', app.color.toColorString(),'\"}',\n ']',\n '}'\n ));\n }\n\n /**\n * @dev Converts FleekERC721.AccessPoint to a JSON string.\n */\n function toString(FleekERC721.AccessPoint storage ap) internal view returns (string memory) {\n // prettier-ignore\n return string(abi.encodePacked(\n \"{\",\n '\"tokenId\":', ap.tokenId.toString(), \",\",\n '\"score\":', ap.score.toString(), \",\",\n '\"nameVerified\":', ap.nameVerified.toString(), \",\",\n '\"contentVerified\":', ap.contentVerified.toString(), \",\",\n '\"owner\":\"', uint160(ap.owner).toHexString(20), '\"',\n \"}\"\n ));\n }\n\n /**\n * @dev Converts bytes3 to a hex color string.\n */\n function toColorString(bytes3 _bytes) internal pure returns (string memory) {\n return string(abi.encodePacked(\"#\", _bytes[0], _bytes[1], _bytes[2]));\n }\n}\n"
+ },
+ "contracts/util/FleekSVG.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"../FleekERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\n\nlibrary FleekSVG {\n /**\n * @dev Generates a SVG image.\n */\n function generateBase64(\n string memory name,\n string memory ENS,\n string memory logo,\n string memory color\n ) internal pure returns (string memory) {\n return (\n string(\n abi.encodePacked(\n \"data:image/svg+xml;base64,\",\n Base64.encode(\n abi.encodePacked(\n '',\n '',\n ''\n '',\n '',\n '',\n '',\n '',\n '',\n '',\n ''\n ''\n '',\n name,\n \"\"\n '',\n ENS,\n \"\"\n \"\"\n )\n )\n )\n )\n );\n }\n}\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 200,
+ "details": {
+ "yul": true
+ }
+ },
+ "viaIR": true,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "storageLayout"
+ ],
+ "": ["ast"]
+ }
+ }
+ }
+}
diff --git a/deployments/mumbai/solcInputs/505ec583d0c3578b33b03d3f73cbb55d.json b/deployments/mumbai/solcInputs/505ec583d0c3578b33b03d3f73cbb55d.json
new file mode 100644
index 0000000..8aeb566
--- /dev/null
+++ b/deployments/mumbai/solcInputs/505ec583d0c3578b33b03d3f73cbb55d.json
@@ -0,0 +1,85 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initialized`\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initializing`\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721Upgradeable.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256, /* firstTokenId */\n uint256 batchSize\n ) internal virtual {\n if (batchSize > 1) {\n if (from != address(0)) {\n _balances[from] -= batchSize;\n }\n if (to != address(0)) {\n _balances[to] += batchSize;\n }\n }\n }\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 firstTokenId,\n uint256 batchSize\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = MathUpgradeable.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, MathUpgradeable.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Base64.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n *\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n string memory result = new string(4 * ((data.length + 2) / 3));\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n\n // When data `bytes` is not exactly 3 bytes long\n // it is padded with `=` characters at the end\n switch mod(mload(data), 3)\n case 1 {\n mstore8(sub(resultPtr, 1), 0x3d)\n mstore8(sub(resultPtr, 2), 0x3d)\n }\n case 2 {\n mstore8(sub(resultPtr, 1), 0x3d)\n }\n }\n\n return result;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Counters.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/math/Math.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "contracts/FleekAccessControl.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\ncontract FleekAccessControl is Initializable {\n using Counters for Counters.Counter;\n\n enum Roles {\n Owner,\n Controller\n }\n\n event TokenRoleGranted(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event TokenRoleRevoked(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleGranted(Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleRevoked(Roles indexed role, address indexed toAddress, address byAddress);\n\n struct Role {\n mapping(address => uint256) indexes;\n address[] members;\n }\n\n Counters.Counter private _collectionRolesVersion;\n // _collectionRoles[version][role]\n mapping(uint256 => mapping(Roles => Role)) private _collectionRoles;\n\n mapping(uint256 => Counters.Counter) private _tokenRolesVersion;\n // _tokenRoles[tokenId][version][role]\n mapping(uint256 => mapping(uint256 => mapping(Roles => Role))) private _tokenRoles;\n\n /**\n * @dev Initializes the contract by granting the `Owner` role to the deployer.\n */\n function __FleekAccessControl_init() internal onlyInitializing {\n _grantCollectionRole(Roles.Owner, msg.sender);\n }\n\n /**\n * @dev Checks if the `msg.sender` has a certain role.\n */\n modifier requireCollectionRole(Roles role) {\n require(\n hasCollectionRole(role, msg.sender) || hasCollectionRole(Roles.Owner, msg.sender),\n \"FleekAccessControl: must have collection role\"\n );\n _;\n }\n\n /**\n * @dev Checks if the `msg.sender` has the `Token` role for a certain `tokenId`.\n */\n modifier requireTokenRole(uint256 tokenId, Roles role) {\n require(\n hasTokenRole(tokenId, role, msg.sender) || hasTokenRole(tokenId, Roles.Owner, msg.sender),\n \"FleekAccessControl: must have token role\"\n );\n _;\n }\n\n /**\n * @dev Grants the collection role to an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function grantCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _grantCollectionRole(role, account);\n }\n\n /**\n * @dev Grants the token role to an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function grantTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _grantTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function revokeCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _revokeCollectionRole(role, account);\n }\n\n /**\n * @dev Revokes the token role of an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function revokeTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _revokeTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Returns `True` if a certain address has the collection role.\n */\n function hasCollectionRole(Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _collectionRolesVersion.current();\n\n return _collectionRoles[currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns `True` if a certain address has the token role.\n */\n function hasTokenRole(uint256 tokenId, Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns an array of addresses that all have the collection role.\n */\n function getCollectionRoleMembers(Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _collectionRolesVersion.current();\n return _collectionRoles[currentVersion][role].members;\n }\n\n /**\n * @dev Returns an array of addresses that all have the same token role for a certain tokenId.\n */\n function getTokenRoleMembers(uint256 tokenId, Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].members;\n }\n\n /**\n * @dev Grants the collection role to an address.\n */\n function _grantCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _grantRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleGranted(role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n */\n function _revokeCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _revokeRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleRevoked(role, account, msg.sender);\n }\n\n /**\n * @dev Grants the token role to an address.\n */\n function _grantTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _grantRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleGranted(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the token role of an address.\n */\n function _revokeTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _revokeRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleRevoked(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Grants a certain role to a certain address.\n */\n function _grantRole(Role storage role, address account) internal {\n if (role.indexes[account] == 0) {\n role.members.push(account);\n role.indexes[account] = role.members.length;\n }\n }\n\n /**\n * @dev Revokes a certain role from a certain address.\n */\n function _revokeRole(Role storage role, address account) internal {\n if (role.indexes[account] != 0) {\n uint256 index = role.indexes[account] - 1;\n uint256 lastIndex = role.members.length - 1;\n address lastAccount = role.members[lastIndex];\n\n role.members[index] = lastAccount;\n role.indexes[lastAccount] = index + 1;\n\n role.members.pop();\n delete role.indexes[account];\n }\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId.\n * Should only be used for burning tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId) internal {\n _tokenRolesVersion[tokenId].increment();\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId and grants the owner role to a new address.\n * Should only be used for transferring tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId, address newOwner) internal {\n _clearAllTokenRoles(tokenId);\n _grantTokenRole(tokenId, Roles.Owner, newOwner);\n }\n}\n"
+ },
+ "contracts/FleekERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"./FleekAccessControl.sol\";\nimport \"./util/FleekStrings.sol\";\n\ncontract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl {\n using Strings for uint256;\n using Counters for Counters.Counter;\n using FleekStrings for FleekERC721.App;\n using FleekStrings for FleekERC721.AccessPoint;\n using FleekStrings for string;\n\n event NewBuild(uint256 indexed token, string indexed commitHash, address indexed triggeredBy);\n event NewTokenName(uint256 indexed token, string indexed name, address indexed triggeredBy);\n event NewTokenDescription(uint256 indexed token, string indexed description, address indexed triggeredBy);\n event NewTokenImage(uint256 indexed token, string indexed image, address indexed triggeredBy);\n event NewTokenExternalURL(uint256 indexed token, string indexed externalURL, address indexed triggeredBy);\n event NewTokenENS(uint256 indexed token, string indexed ENS, address indexed triggeredBy);\n\n event NewAccessPoint(string indexed apName, uint256 indexed tokenId, address indexed owner);\n event RemoveAccessPoint(string indexed apName, uint256 indexed tokenId, address indexed owner);\n event ChangeAccessPointScore(\n string indexed apName,\n uint256 indexed tokenId,\n uint256 score,\n address indexed triggeredBy\n );\n event ChangeAccessPointNameVerify(\n string indexed apName,\n uint256 tokenId,\n bool indexed verified,\n address indexed triggeredBy\n );\n event ChangeAccessPointContentVerify(\n string indexed apName,\n uint256 tokenId,\n bool indexed verified,\n address indexed triggeredBy\n );\n\n /**\n * The properties are stored as string to keep consistency with\n * other token contracts, we might consider changing for bytes32\n * in the future due to gas optimization.\n */\n struct App {\n string name; // Name of the site\n string description; // Description about the site\n string externalURL; // Site URL\n string ENS; // ENS ID\n uint256 currentBuild; // The current build number (Increments by one with each change, starts at zero)\n mapping(uint256 => Build) builds; // Mapping to build details for each build number\n string[] accessPoints; // List of app AccessPoint\n string logo;\n uint24 color; // Color of the nft\n }\n\n /**\n * The metadata that is stored for each build.\n */\n struct Build {\n string commitHash;\n string gitRepository;\n }\n\n /**\n * The stored data for each AccessPoint.\n */\n struct AccessPoint {\n uint256 tokenId;\n uint256 index;\n uint256 score;\n bool contentVerified;\n bool nameVerified;\n address owner;\n }\n\n Counters.Counter private _appIds;\n mapping(uint256 => App) private _apps;\n mapping(string => AccessPoint) private _accessPoints;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function initialize(string memory _name, string memory _symbol) public initializer {\n __ERC721_init(_name, _symbol);\n __FleekAccessControl_init();\n }\n\n /**\n * @dev Checks if the AccessPoint exists.\n */\n modifier requireAP(string memory apName) {\n require(_accessPoints[apName].owner != address(0), \"FleekERC721: invalid AP\");\n _;\n }\n\n /**\n * @dev Mints a token and returns a tokenId.\n *\n * If the `tokenId` has not been minted before, and the `to` address is not zero, emits a {Transfer} event.\n *\n * Requirements:\n *\n * - the caller must have ``collectionOwner``'s admin role.\n *\n */\n function mint(\n address to,\n string memory name,\n string memory description,\n string memory externalURL,\n string memory ENS,\n string memory commitHash,\n string memory gitRepository,\n string memory logo,\n uint24 color\n ) public payable requireCollectionRole(Roles.Owner) returns (uint256) {\n uint256 tokenId = _appIds.current();\n _mint(to, tokenId);\n _appIds.increment();\n\n App storage app = _apps[tokenId];\n app.name = name;\n app.description = description;\n app.externalURL = externalURL;\n app.ENS = ENS;\n app.logo = logo;\n app.color = color;\n\n // The mint interaction is considered to be the first build of the site. Updates from now on all increment the currentBuild by one and update the mapping.\n app.currentBuild = 0;\n app.builds[0] = Build(commitHash, gitRepository);\n app.accessPoints = new string[](0);\n\n return tokenId;\n }\n\n /**\n * @dev Returns the token metadata associated with the `tokenId`.\n *\n * Returns a based64 encoded string value of the URI.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n address owner = ownerOf(tokenId);\n App storage app = _apps[tokenId];\n\n return string(abi.encodePacked(_baseURI(), app.toString(owner).toBase64()));\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Upgradeable) returns (bool) {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Override of _beforeTokenTransfer of ERC721.\n * Here it needs to update the token controller roles for mint, burn and transfer.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId,\n uint256 batchSize\n ) internal virtual override {\n if (from != address(0) && to != address(0)) {\n // Transfer\n _clearAllTokenRoles(tokenId, to);\n } else if (from == address(0)) {\n // Mint\n _grantTokenRole(tokenId, Roles.Owner, to);\n } else if (to == address(0)) {\n // Burn\n _clearAllTokenRoles(tokenId);\n }\n super._beforeTokenTransfer(from, to, tokenId, batchSize);\n }\n\n /**\n * @dev A baseURI internal function implementation to be called in the `tokenURI` function.\n */\n function _baseURI() internal view virtual override returns (string memory) {\n return \"data:application/json;base64,\";\n }\n\n /**\n * @dev Updates the `externalURL` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenExternalURL} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenExternalURL(\n uint256 tokenId,\n string memory _tokenExternalURL\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].externalURL = _tokenExternalURL;\n emit NewTokenExternalURL(tokenId, _tokenExternalURL, msg.sender);\n }\n\n /**\n * @dev Updates the `ENS` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenENS} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenENS(\n uint256 tokenId,\n string memory _tokenENS\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].ENS = _tokenENS;\n emit NewTokenENS(tokenId, _tokenENS, msg.sender);\n }\n\n /**\n * @dev Updates the `name` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenName} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenName(\n uint256 tokenId,\n string memory _tokenName\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].name = _tokenName;\n emit NewTokenName(tokenId, _tokenName, msg.sender);\n }\n\n /**\n * @dev Updates the `description` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenDescription} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenDescription(\n uint256 tokenId,\n string memory _tokenDescription\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].description = _tokenDescription;\n emit NewTokenDescription(tokenId, _tokenDescription, msg.sender);\n }\n\n /**\n * @dev Add a new AccessPoint register for an app token.\n * The AP name should be a DNS or ENS url and it should be unique.\n * Anyone can add an AP but it should requires a payment.\n *\n * May emit a {NewAccessPoint} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n * IMPORTANT: The payment is not set yet\n */\n function addAccessPoint(uint256 tokenId, string memory apName) public payable {\n // require(msg.value == 0.1 ether, \"You need to pay at least 0.1 ETH\"); // TODO: define a minimum price\n _requireMinted(tokenId);\n require(_accessPoints[apName].owner == address(0), \"FleekERC721: AP already exists\");\n\n _accessPoints[apName] = AccessPoint(tokenId, _apps[tokenId].accessPoints.length, 0, false, false, msg.sender);\n _apps[tokenId].accessPoints.push(apName);\n\n emit NewAccessPoint(apName, tokenId, msg.sender);\n }\n\n /**\n * @dev Remove an AccessPoint registry for an app token.\n * It will also remove the AP from the app token APs list.\n *\n * May emit a {RemoveAccessPoint} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - must be called by the AP owner.\n */\n function removeAccessPoint(string memory apName) public requireAP(apName) {\n require(msg.sender == _accessPoints[apName].owner, \"FleekERC721: must be AP owner\");\n uint256 tokenId = _accessPoints[apName].tokenId;\n App storage _app = _apps[tokenId];\n\n // the index of the AP to remove\n uint256 indexToRemove = _accessPoints[apName].index;\n\n // the last item is reposited in the index to remove\n string memory lastAP = _app.accessPoints[_app.accessPoints.length - 1];\n _app.accessPoints[indexToRemove] = lastAP;\n _accessPoints[lastAP].index = indexToRemove;\n\n // remove the last item\n _app.accessPoints.pop();\n\n delete _accessPoints[apName];\n emit RemoveAccessPoint(apName, tokenId, msg.sender);\n }\n\n /**\n * @dev A view function to gether information about an AccessPoint.\n * It returns a JSON string representing the AccessPoint information.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function getAccessPointJSON(string memory apName) public view requireAP(apName) returns (string memory) {\n AccessPoint storage _ap = _accessPoints[apName];\n return _ap.toString();\n }\n\n /**\n * @dev A view function to check if a AccessPoint is verified.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function isAccessPointNameVerified(string memory apName) public view requireAP(apName) returns (bool) {\n return _accessPoints[apName].nameVerified;\n }\n\n /**\n * @dev Increases the score of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointScore} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function increaseAccessPointScore(string memory apName) public requireAP(apName) {\n _accessPoints[apName].score++;\n emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);\n }\n\n /**\n * @dev Decreases the score of a AccessPoint registry if is greater than 0.\n *\n * May emit a {ChangeAccessPointScore} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function decreaseAccessPointScore(string memory apName) public requireAP(apName) {\n require(_accessPoints[apName].score > 0, \"FleekERC721: score cant be lower\");\n _accessPoints[apName].score--;\n emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);\n }\n\n /**\n * @dev Set the content verification of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointContentVerify} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - the sender must have the token controller role.\n *\n */\n function setAccessPointContentVerify(\n string memory apName,\n bool verified\n ) public requireAP(apName) requireTokenRole(_accessPoints[apName].tokenId, Roles.Controller) {\n _accessPoints[apName].contentVerified = verified;\n emit ChangeAccessPointContentVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);\n }\n\n /**\n * @dev Set the name verification of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointNameVerify} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - the sender must have the token controller role.\n *\n */\n function setAccessPointNameVerify(\n string memory apName,\n bool verified\n ) public requireAP(apName) requireTokenRole(_accessPoints[apName].tokenId, Roles.Controller) {\n _accessPoints[apName].nameVerified = verified;\n emit ChangeAccessPointNameVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);\n }\n\n /**\n * @dev A view function to gether the list of mirrros for a given app.\n *\n * Requirements:\n * - the tokenId must be minted and valid.\n *\n */\n function appAccessPoints(uint256 tokenId) public view returns (string[] memory) {\n _requireMinted(tokenId);\n return _apps[tokenId].accessPoints;\n }\n\n /**\n * @dev Adds a new build to a minted `tokenId`'s builds mapping.\n *\n * May emit a {NewBuild} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenBuild(\n uint256 tokenId,\n string memory _commitHash,\n string memory _gitRepository\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].builds[++_apps[tokenId].currentBuild] = Build(_commitHash, _gitRepository);\n emit NewBuild(tokenId, _commitHash, msg.sender);\n }\n\n /**\n * @dev Burns a previously minted `tokenId`.\n *\n * May emit a {Transfer} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenOwner` role.\n *\n */\n function burn(uint256 tokenId) public virtual requireTokenRole(tokenId, Roles.Owner) {\n super._burn(tokenId);\n\n if (bytes(_apps[tokenId].externalURL).length != 0) {\n delete _apps[tokenId];\n }\n }\n}\n"
+ },
+ "contracts/util/FleekStrings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"../FleekERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"./FleekSVG.sol\";\n\nlibrary FleekStrings {\n using Strings for uint256;\n using Strings for uint160;\n using FleekStrings for bool;\n using FleekStrings for uint24;\n using Strings for uint24;\n\n /**\n * @dev Converts a boolean value to a string.\n */\n function toString(bool _bool) internal pure returns (string memory) {\n return _bool ? \"true\" : \"false\";\n }\n\n /**\n * @dev Converts a string to a base64 string.\n */\n function toBase64(string memory str) internal pure returns (string memory) {\n return Base64.encode(bytes(str));\n }\n\n /**\n * @dev Converts FleekERC721.App to a JSON string.\n * It requires to receive owner address as a parameter.\n */\n function toString(FleekERC721.App storage app, address owner) internal view returns (string memory) {\n // prettier-ignore\n return string(abi.encodePacked(\n '{',\n '\"name\":\"', app.name, '\",',\n '\"description\":\"', app.description, '\",',\n '\"owner\":\"', uint160(owner).toHexString(20), '\",',\n '\"external_url\":\"', app.externalURL, '\",',\n '\"image\":\"', FleekSVG.generateBase64(app.name, app.ENS, app.logo, app.color.toColorString()), '\",',\n '\"attributes\": [',\n '{\"trait_type\": \"ENS\", \"value\":\"', app.ENS,'\"},',\n '{\"trait_type\": \"Commit Hash\", \"value\":\"', app.builds[app.currentBuild].commitHash,'\"},',\n '{\"trait_type\": \"Repository\", \"value\":\"', app.builds[app.currentBuild].gitRepository,'\"},',\n '{\"trait_type\": \"Version\", \"value\":\"', app.currentBuild.toString(),'\"},',\n '{\"trait_type\": \"Color\", \"value\":\"', app.color.toColorString(),'\"}',\n ']',\n '}'\n ));\n }\n\n /**\n * @dev Converts FleekERC721.AccessPoint to a JSON string.\n */\n function toString(FleekERC721.AccessPoint storage ap) internal view returns (string memory) {\n // prettier-ignore\n return string(abi.encodePacked(\n \"{\",\n '\"tokenId\":', ap.tokenId.toString(), \",\",\n '\"score\":', ap.score.toString(), \",\",\n '\"nameVerified\":', ap.nameVerified.toString(), \",\",\n '\"contentVerified\":', ap.contentVerified.toString(), \",\",\n '\"owner\":\"', uint160(ap.owner).toHexString(20), '\"',\n \"}\"\n ));\n }\n\n /**\n * @dev Converts bytes3 to a hex color string.\n */\n function toColorString(uint24 color) internal pure returns (string memory) {\n bytes memory hexBytes = bytes(color.toHexString(3));\n bytes memory hexColor = new bytes(7);\n hexColor[0] = \"#\";\n for (uint256 i = 1; i < 7; i++) {\n hexColor[i] = hexBytes[i + 1];\n }\n return string(hexColor);\n }\n}\n"
+ },
+ "contracts/util/FleekSVG.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"../FleekERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\n\nlibrary FleekSVG {\n /**\n * @dev Generates a SVG image.\n */\n function generateBase64(\n string memory name,\n string memory ENS,\n string memory logo,\n string memory color\n ) public pure returns (string memory) {\n return (\n string(\n abi.encodePacked(\n \"data:image/svg+xml;base64,\",\n Base64.encode(\n abi.encodePacked(\n '',\n \n // background\n '',\n ''\n \n // shadows\n '',\n '',\n\n // diskette fill\n '',\n '',\n\n // arrows\n '',\n '',\n '',\n\n // body\n '',\n\n // slider\n ''\n\n // fleek logo\n '',\n\n // text\n '',name,'', ENS, '',\n\n // logo\n '',\n\n // defs\n '',\n\n // shadow\n '',\n\n // bg\n '',\n '',\n\n // fill gradient\n '',\n\n // color\n '',\n\n // end defs\n '',\n\n ''\n )\n )\n )\n )\n );\n }\n}\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 200,
+ "details": {
+ "yul": true
+ }
+ },
+ "viaIR": true,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "storageLayout"
+ ],
+ "": ["ast"]
+ }
+ }
+ }
+}
diff --git a/deployments/mumbai/solcInputs/b53070acef325f87a56b723eb4710b81.json b/deployments/mumbai/solcInputs/b53070acef325f87a56b723eb4710b81.json
new file mode 100644
index 0000000..dcc6913
--- /dev/null
+++ b/deployments/mumbai/solcInputs/b53070acef325f87a56b723eb4710b81.json
@@ -0,0 +1,82 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initialized`\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initializing`\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721Upgradeable.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256, /* firstTokenId */\n uint256 batchSize\n ) internal virtual {\n if (batchSize > 1) {\n if (from != address(0)) {\n _balances[from] -= batchSize;\n }\n if (to != address(0)) {\n _balances[to] += batchSize;\n }\n }\n }\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 firstTokenId,\n uint256 batchSize\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = MathUpgradeable.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, MathUpgradeable.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Base64.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n *\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n string memory result = new string(4 * ((data.length + 2) / 3));\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n\n // When data `bytes` is not exactly 3 bytes long\n // it is padded with `=` characters at the end\n switch mod(mload(data), 3)\n case 1 {\n mstore8(sub(resultPtr, 1), 0x3d)\n mstore8(sub(resultPtr, 2), 0x3d)\n }\n case 2 {\n mstore8(sub(resultPtr, 1), 0x3d)\n }\n }\n\n return result;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Counters.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/math/Math.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "contracts/FleekAccessControl.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\ncontract FleekAccessControl is Initializable {\n using Counters for Counters.Counter;\n\n enum Roles {\n Owner,\n Controller\n }\n\n event TokenRoleGranted(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event TokenRoleRevoked(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleGranted(Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleRevoked(Roles indexed role, address indexed toAddress, address byAddress);\n\n struct Role {\n mapping(address => uint256) indexes;\n address[] members;\n }\n\n Counters.Counter private _collectionRolesVersion;\n // _collectionRoles[version][role]\n mapping(uint256 => mapping(Roles => Role)) private _collectionRoles;\n\n mapping(uint256 => Counters.Counter) private _tokenRolesVersion;\n // _tokenRoles[tokenId][version][role]\n mapping(uint256 => mapping(uint256 => mapping(Roles => Role))) private _tokenRoles;\n\n /**\n * @dev Initializes the contract by granting the `Owner` role to the deployer.\n */\n function __FleekAccessControl_init() internal onlyInitializing {\n _grantCollectionRole(Roles.Owner, msg.sender);\n }\n\n /**\n * @dev Checks if the `msg.sender` has a certain role.\n */\n modifier requireCollectionRole(Roles role) {\n require(\n hasCollectionRole(role, msg.sender) || hasCollectionRole(Roles.Owner, msg.sender),\n \"FleekAccessControl: must have collection role\"\n );\n _;\n }\n\n /**\n * @dev Checks if the `msg.sender` has the `Token` role for a certain `tokenId`.\n */\n modifier requireTokenRole(uint256 tokenId, Roles role) {\n require(\n hasTokenRole(tokenId, role, msg.sender) || hasTokenRole(tokenId, Roles.Owner, msg.sender),\n \"FleekAccessControl: must have token role\"\n );\n _;\n }\n\n /**\n * @dev Grants the collection role to an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function grantCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _grantCollectionRole(role, account);\n }\n\n /**\n * @dev Grants the token role to an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function grantTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _grantTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function revokeCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _revokeCollectionRole(role, account);\n }\n\n /**\n * @dev Revokes the token role of an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function revokeTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _revokeTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Returns `True` if a certain address has the collection role.\n */\n function hasCollectionRole(Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _collectionRolesVersion.current();\n\n return _collectionRoles[currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns `True` if a certain address has the token role.\n */\n function hasTokenRole(uint256 tokenId, Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns an array of addresses that all have the collection role.\n */\n function getCollectionRoleMembers(Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _collectionRolesVersion.current();\n return _collectionRoles[currentVersion][role].members;\n }\n\n /**\n * @dev Returns an array of addresses that all have the same token role for a certain tokenId.\n */\n function getTokenRoleMembers(uint256 tokenId, Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].members;\n }\n\n /**\n * @dev Grants the collection role to an address.\n */\n function _grantCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _grantRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleGranted(role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n */\n function _revokeCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _revokeRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleRevoked(role, account, msg.sender);\n }\n\n /**\n * @dev Grants the token role to an address.\n */\n function _grantTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _grantRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleGranted(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the token role of an address.\n */\n function _revokeTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _revokeRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleRevoked(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Grants a certain role to a certain address.\n */\n function _grantRole(Role storage role, address account) internal {\n if (role.indexes[account] == 0) {\n role.members.push(account);\n role.indexes[account] = role.members.length;\n }\n }\n\n /**\n * @dev Revokes a certain role from a certain address.\n */\n function _revokeRole(Role storage role, address account) internal {\n if (role.indexes[account] != 0) {\n uint256 index = role.indexes[account] - 1;\n uint256 lastIndex = role.members.length - 1;\n address lastAccount = role.members[lastIndex];\n\n role.members[index] = lastAccount;\n role.indexes[lastAccount] = index + 1;\n\n role.members.pop();\n delete role.indexes[account];\n }\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId.\n * Should only be used for burning tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId) internal {\n _tokenRolesVersion[tokenId].increment();\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId and grants the owner role to a new address.\n * Should only be used for transferring tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId, address newOwner) internal {\n _clearAllTokenRoles(tokenId);\n _grantTokenRole(tokenId, Roles.Owner, newOwner);\n }\n}\n"
+ },
+ "contracts/FleekERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"./FleekAccessControl.sol\";\nimport \"./SVGLibrary.sol\";\n\ncontract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl {\n using Strings for uint256;\n using Counters for Counters.Counter;\n\n event NewBuild(uint256 indexed token, string indexed commitHash, address indexed triggeredBy);\n event NewTokenName(uint256 indexed token, string indexed name, address indexed triggeredBy);\n event NewTokenDescription(uint256 indexed token, string indexed description, address indexed triggeredBy);\n event NewTokenImage(uint256 indexed token, string indexed image, address indexed triggeredBy);\n event NewTokenExternalURL(uint256 indexed token, string indexed externalURL, address indexed triggeredBy);\n event NewTokenENS(uint256 indexed token, string indexed ENS, address indexed triggeredBy);\n\n /**\n * The properties are stored as string to keep consistency with\n * other token contracts, we might consider changing for bytes32\n * in the future due to gas optimization.\n */\n struct App {\n string name; // Name of the site\n string description; // Description about the site\n string externalURL; // Site URL\n string ENS; // ENS ID\n uint256 currentBuild; // The current build number (Increments by one with each change, starts at zero)\n mapping(uint256 => Build) builds; // Mapping to build details for each build number\n }\n\n /**\n * The metadata that is stored for each build.\n */\n struct Build {\n string commitHash;\n string gitRepository;\n }\n\n Counters.Counter private _tokenIds;\n mapping(uint256 => App) private _apps;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function initialize(string memory _name, string memory _symbol) public initializer {\n __ERC721_init(_name, _symbol);\n __FleekAccessControl_init();\n }\n\n /**\n * @dev Checks if msg.sender has the role of tokenOwner for a certain tokenId.\n */\n modifier requireTokenOwner(uint256 tokenId) {\n require(msg.sender == ownerOf(tokenId), \"FleekERC721: must be token owner\");\n _;\n }\n\n /**\n * @dev Generates a SVG image.\n */\n function _generateSVG(string memory name, string memory ENS) internal pure returns (string memory) {\n return (string(abi.encodePacked(\"data:image/svg+xml;base64\", Base64.encode(SVGLibrary.parseSVG(name, ENS)))));\n }\n\n /**\n * @dev Mints a token and returns a tokenId.\n *\n * If the `tokenId` has not been minted before, and the `to` address is not zero, emits a {Transfer} event.\n *\n * Requirements:\n *\n * - the caller must have ``collectionOwner``'s admin role.\n *\n */\n function mint(\n address to,\n string memory name,\n string memory description,\n string memory externalURL,\n string memory ENS,\n string memory commitHash,\n string memory gitRepository\n ) public payable requireCollectionRole(Roles.Owner) returns (uint256) {\n uint256 tokenId = _tokenIds.current();\n _mint(to, tokenId);\n _tokenIds.increment();\n\n App storage app = _apps[tokenId];\n app.name = name;\n app.description = description;\n app.externalURL = externalURL;\n app.ENS = ENS;\n\n // The mint interaction is considered to be the first build of the site. Updates from now on all increment the currentBuild by one and update the mapping.\n app.currentBuild = 0;\n app.builds[0] = Build(commitHash, gitRepository);\n\n return tokenId;\n }\n\n /**\n * @dev Returns the token metadata associated with the `tokenId`.\n *\n * Returns a based64 encoded string value of the URI.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n address owner = ownerOf(tokenId);\n App storage app = _apps[tokenId];\n\n // prettier-ignore\n bytes memory dataURI = abi.encodePacked(\n '{',\n '\"name\":\"', app.name, '\",',\n '\"description\":\"', app.description, '\",',\n '\"owner\":\"', Strings.toHexString(uint160(owner), 20), '\",',\n '\"external_url\":\"', app.externalURL, '\",',\n '\"image\":\"', _generateSVG(app.name, app.ENS), '\",',\n '\"attributes\": [',\n '{\"trait_type\": \"ENS\", \"value\":\"', app.ENS,'\"},',\n '{\"trait_type\": \"Commit Hash\", \"value\":\"', app.builds[app.currentBuild].commitHash,'\"},',\n '{\"trait_type\": \"Repository\", \"value\":\"', app.builds[app.currentBuild].gitRepository,'\"},',\n '{\"trait_type\": \"Version\", \"value\":\"', Strings.toString(app.currentBuild),'\"}',\n ']',\n '}'\n );\n\n return string(abi.encodePacked(_baseURI(), Base64.encode((dataURI))));\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Upgradeable) returns (bool) {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Override of _beforeTokenTransfer of ERC721.\n * Here it needs to update the token controller roles for mint, burn and transfer.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId,\n uint256 batchSize\n ) internal virtual override {\n if (from != address(0) && to != address(0)) {\n // Transfer\n _clearAllTokenRoles(tokenId, to);\n } else if (from == address(0)) {\n // Mint\n _grantTokenRole(tokenId, Roles.Owner, to);\n } else if (to == address(0)) {\n // Burn\n _clearAllTokenRoles(tokenId);\n }\n super._beforeTokenTransfer(from, to, tokenId, batchSize);\n }\n\n /**\n * @dev A baseURI internal function implementation to be called in the `tokenURI` function.\n */\n function _baseURI() internal view virtual override returns (string memory) {\n return \"data:application/json;base64,\";\n }\n\n /**\n * @dev Updates the `externalURL` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenExternalURL} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenExternalURL(\n uint256 tokenId,\n string memory _tokenExternalURL\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].externalURL = _tokenExternalURL;\n emit NewTokenExternalURL(tokenId, _tokenExternalURL, msg.sender);\n }\n\n /**\n * @dev Updates the `ENS` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenENS} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenENS(\n uint256 tokenId,\n string memory _tokenENS\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].ENS = _tokenENS;\n emit NewTokenENS(tokenId, _tokenENS, msg.sender);\n }\n\n /**\n * @dev Updates the `name` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenName} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenName(\n uint256 tokenId,\n string memory _tokenName\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].name = _tokenName;\n emit NewTokenName(tokenId, _tokenName, msg.sender);\n }\n\n /**\n * @dev Updates the `description` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenDescription} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenDescription(\n uint256 tokenId,\n string memory _tokenDescription\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].description = _tokenDescription;\n emit NewTokenDescription(tokenId, _tokenDescription, msg.sender);\n }\n\n /**\n * @dev Adds a new build to a minted `tokenId`'s builds mapping.\n *\n * May emit a {NewBuild} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenBuild(\n uint256 tokenId,\n string memory _commitHash,\n string memory _gitRepository\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].builds[++_apps[tokenId].currentBuild] = Build(_commitHash, _gitRepository);\n emit NewBuild(tokenId, _commitHash, msg.sender);\n }\n\n /**\n * @dev Burns a previously minted `tokenId`.\n *\n * May emit a {Transfer} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenOwner` role.\n *\n */\n function burn(uint256 tokenId) public virtual requireTokenRole(tokenId, Roles.Owner) {\n super._burn(tokenId);\n\n if (bytes(_apps[tokenId].externalURL).length != 0) {\n delete _apps[tokenId];\n }\n }\n}\n"
+ },
+ "contracts/SVGLibrary.sol": {
+ "content": "library SVGLibrary {\r\n function parseSVG(string memory name, string memory version) internal pure returns (bytes memory) {\r\n return\r\n abi.encodePacked(\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n name,\r\n '',\r\n version,\r\n \"\"\r\n );\r\n }\r\n}\r\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 200,
+ "details": {
+ "yul": false
+ }
+ },
+ "viaIR": false,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "storageLayout"
+ ],
+ "": ["ast"]
+ }
+ }
+ }
+}
diff --git a/deployments/mumbai/solcInputs/c40db91ea574f699252226adfb3fa85d.json b/deployments/mumbai/solcInputs/c40db91ea574f699252226adfb3fa85d.json
new file mode 100644
index 0000000..bbda01f
--- /dev/null
+++ b/deployments/mumbai/solcInputs/c40db91ea574f699252226adfb3fa85d.json
@@ -0,0 +1,85 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initialized`\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initializing`\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721Upgradeable.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256, /* firstTokenId */\n uint256 batchSize\n ) internal virtual {\n if (batchSize > 1) {\n if (from != address(0)) {\n _balances[from] -= batchSize;\n }\n if (to != address(0)) {\n _balances[to] += batchSize;\n }\n }\n }\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 firstTokenId,\n uint256 batchSize\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = MathUpgradeable.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, MathUpgradeable.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Base64.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n *\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n string memory result = new string(4 * ((data.length + 2) / 3));\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n\n // When data `bytes` is not exactly 3 bytes long\n // it is padded with `=` characters at the end\n switch mod(mload(data), 3)\n case 1 {\n mstore8(sub(resultPtr, 1), 0x3d)\n mstore8(sub(resultPtr, 2), 0x3d)\n }\n case 2 {\n mstore8(sub(resultPtr, 1), 0x3d)\n }\n }\n\n return result;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Counters.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/math/Math.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "contracts/FleekAccessControl.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\ncontract FleekAccessControl is Initializable {\n using Counters for Counters.Counter;\n\n enum Roles {\n Owner,\n Controller\n }\n\n event TokenRoleGranted(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event TokenRoleRevoked(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleGranted(Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleRevoked(Roles indexed role, address indexed toAddress, address byAddress);\n\n struct Role {\n mapping(address => uint256) indexes;\n address[] members;\n }\n\n Counters.Counter private _collectionRolesVersion;\n // _collectionRoles[version][role]\n mapping(uint256 => mapping(Roles => Role)) private _collectionRoles;\n\n mapping(uint256 => Counters.Counter) private _tokenRolesVersion;\n // _tokenRoles[tokenId][version][role]\n mapping(uint256 => mapping(uint256 => mapping(Roles => Role))) private _tokenRoles;\n\n /**\n * @dev Initializes the contract by granting the `Owner` role to the deployer.\n */\n function __FleekAccessControl_init() internal onlyInitializing {\n _grantCollectionRole(Roles.Owner, msg.sender);\n }\n\n /**\n * @dev Checks if the `msg.sender` has a certain role.\n */\n modifier requireCollectionRole(Roles role) {\n require(\n hasCollectionRole(role, msg.sender) || hasCollectionRole(Roles.Owner, msg.sender),\n \"FleekAccessControl: must have collection role\"\n );\n _;\n }\n\n /**\n * @dev Checks if the `msg.sender` has the `Token` role for a certain `tokenId`.\n */\n modifier requireTokenRole(uint256 tokenId, Roles role) {\n require(\n hasTokenRole(tokenId, role, msg.sender) || hasTokenRole(tokenId, Roles.Owner, msg.sender),\n \"FleekAccessControl: must have token role\"\n );\n _;\n }\n\n /**\n * @dev Grants the collection role to an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function grantCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _grantCollectionRole(role, account);\n }\n\n /**\n * @dev Grants the token role to an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function grantTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _grantTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function revokeCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _revokeCollectionRole(role, account);\n }\n\n /**\n * @dev Revokes the token role of an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function revokeTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _revokeTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Returns `True` if a certain address has the collection role.\n */\n function hasCollectionRole(Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _collectionRolesVersion.current();\n\n return _collectionRoles[currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns `True` if a certain address has the token role.\n */\n function hasTokenRole(uint256 tokenId, Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns an array of addresses that all have the collection role.\n */\n function getCollectionRoleMembers(Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _collectionRolesVersion.current();\n return _collectionRoles[currentVersion][role].members;\n }\n\n /**\n * @dev Returns an array of addresses that all have the same token role for a certain tokenId.\n */\n function getTokenRoleMembers(uint256 tokenId, Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].members;\n }\n\n /**\n * @dev Grants the collection role to an address.\n */\n function _grantCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _grantRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleGranted(role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n */\n function _revokeCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _revokeRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleRevoked(role, account, msg.sender);\n }\n\n /**\n * @dev Grants the token role to an address.\n */\n function _grantTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _grantRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleGranted(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the token role of an address.\n */\n function _revokeTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _revokeRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleRevoked(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Grants a certain role to a certain address.\n */\n function _grantRole(Role storage role, address account) internal {\n if (role.indexes[account] == 0) {\n role.members.push(account);\n role.indexes[account] = role.members.length;\n }\n }\n\n /**\n * @dev Revokes a certain role from a certain address.\n */\n function _revokeRole(Role storage role, address account) internal {\n if (role.indexes[account] != 0) {\n uint256 index = role.indexes[account] - 1;\n uint256 lastIndex = role.members.length - 1;\n address lastAccount = role.members[lastIndex];\n\n role.members[index] = lastAccount;\n role.indexes[lastAccount] = index + 1;\n\n role.members.pop();\n delete role.indexes[account];\n }\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId.\n * Should only be used for burning tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId) internal {\n _tokenRolesVersion[tokenId].increment();\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId and grants the owner role to a new address.\n * Should only be used for transferring tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId, address newOwner) internal {\n _clearAllTokenRoles(tokenId);\n _grantTokenRole(tokenId, Roles.Owner, newOwner);\n }\n}\n"
+ },
+ "contracts/FleekERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"./FleekAccessControl.sol\";\nimport \"./util/FleekStrings.sol\";\n\ncontract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl {\n using Strings for uint256;\n using Counters for Counters.Counter;\n using FleekStrings for FleekERC721.App;\n using FleekStrings for FleekERC721.AccessPoint;\n using FleekStrings for string;\n\n event NewBuild(uint256 indexed token, string indexed commitHash, address indexed triggeredBy);\n event NewTokenName(uint256 indexed token, string indexed name, address indexed triggeredBy);\n event NewTokenDescription(uint256 indexed token, string indexed description, address indexed triggeredBy);\n event NewTokenImage(uint256 indexed token, string indexed image, address indexed triggeredBy);\n event NewTokenExternalURL(uint256 indexed token, string indexed externalURL, address indexed triggeredBy);\n event NewTokenENS(uint256 indexed token, string indexed ENS, address indexed triggeredBy);\n\n event NewAccessPoint(string indexed apName, uint256 indexed tokenId, address indexed owner);\n event RemoveAccessPoint(string indexed apName, uint256 indexed tokenId, address indexed owner);\n event ChangeAccessPointScore(\n string indexed apName,\n uint256 indexed tokenId,\n uint256 score,\n address indexed triggeredBy\n );\n event ChangeAccessPointNameVerify(\n string indexed apName,\n uint256 tokenId,\n bool indexed verified,\n address indexed triggeredBy\n );\n event ChangeAccessPointContentVerify(\n string indexed apName,\n uint256 tokenId,\n bool indexed verified,\n address indexed triggeredBy\n );\n\n /**\n * The properties are stored as string to keep consistency with\n * other token contracts, we might consider changing for bytes32\n * in the future due to gas optimization.\n */\n struct App {\n string name; // Name of the site\n string description; // Description about the site\n string externalURL; // Site URL\n string ENS; // ENS ID\n uint256 currentBuild; // The current build number (Increments by one with each change, starts at zero)\n mapping(uint256 => Build) builds; // Mapping to build details for each build number\n string[] accessPoints; // List of app AccessPoint\n string logo;\n bytes3 color; // Color of the nft\n }\n\n /**\n * The metadata that is stored for each build.\n */\n struct Build {\n string commitHash;\n string gitRepository;\n }\n\n /**\n * The stored data for each AccessPoint.\n */\n struct AccessPoint {\n uint256 tokenId;\n uint256 index;\n uint256 score;\n bool contentVerified;\n bool nameVerified;\n address owner;\n }\n\n Counters.Counter private _appIds;\n mapping(uint256 => App) private _apps;\n mapping(string => AccessPoint) private _accessPoints;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function initialize(string memory _name, string memory _symbol) public initializer {\n __ERC721_init(_name, _symbol);\n __FleekAccessControl_init();\n }\n\n /**\n * @dev Checks if the AccessPoint exists.\n */\n modifier requireAP(string memory apName) {\n require(_accessPoints[apName].owner != address(0), \"FleekERC721: invalid AP\");\n _;\n }\n\n /**\n * @dev Mints a token and returns a tokenId.\n *\n * If the `tokenId` has not been minted before, and the `to` address is not zero, emits a {Transfer} event.\n *\n * Requirements:\n *\n * - the caller must have ``collectionOwner``'s admin role.\n *\n */\n function mint(\n address to,\n string memory name,\n string memory description,\n string memory externalURL,\n string memory ENS,\n string memory commitHash,\n string memory gitRepository,\n string memory logo,\n bytes3 color\n ) public payable requireCollectionRole(Roles.Owner) returns (uint256) {\n uint256 tokenId = _appIds.current();\n _mint(to, tokenId);\n _appIds.increment();\n\n App storage app = _apps[tokenId];\n app.name = name;\n app.description = description;\n app.externalURL = externalURL;\n app.ENS = ENS;\n app.logo = logo;\n app.color = color;\n\n // The mint interaction is considered to be the first build of the site. Updates from now on all increment the currentBuild by one and update the mapping.\n app.currentBuild = 0;\n app.builds[0] = Build(commitHash, gitRepository);\n app.accessPoints = new string[](0);\n\n return tokenId;\n }\n\n /**\n * @dev Returns the token metadata associated with the `tokenId`.\n *\n * Returns a based64 encoded string value of the URI.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n address owner = ownerOf(tokenId);\n App storage app = _apps[tokenId];\n\n return string(abi.encodePacked(_baseURI(), app.toString(owner).toBase64()));\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Upgradeable) returns (bool) {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Override of _beforeTokenTransfer of ERC721.\n * Here it needs to update the token controller roles for mint, burn and transfer.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId,\n uint256 batchSize\n ) internal virtual override {\n if (from != address(0) && to != address(0)) {\n // Transfer\n _clearAllTokenRoles(tokenId, to);\n } else if (from == address(0)) {\n // Mint\n _grantTokenRole(tokenId, Roles.Owner, to);\n } else if (to == address(0)) {\n // Burn\n _clearAllTokenRoles(tokenId);\n }\n super._beforeTokenTransfer(from, to, tokenId, batchSize);\n }\n\n /**\n * @dev A baseURI internal function implementation to be called in the `tokenURI` function.\n */\n function _baseURI() internal view virtual override returns (string memory) {\n return \"data:application/json;base64,\";\n }\n\n /**\n * @dev Updates the `externalURL` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenExternalURL} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenExternalURL(\n uint256 tokenId,\n string memory _tokenExternalURL\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].externalURL = _tokenExternalURL;\n emit NewTokenExternalURL(tokenId, _tokenExternalURL, msg.sender);\n }\n\n /**\n * @dev Updates the `ENS` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenENS} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenENS(\n uint256 tokenId,\n string memory _tokenENS\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].ENS = _tokenENS;\n emit NewTokenENS(tokenId, _tokenENS, msg.sender);\n }\n\n /**\n * @dev Updates the `name` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenName} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenName(\n uint256 tokenId,\n string memory _tokenName\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].name = _tokenName;\n emit NewTokenName(tokenId, _tokenName, msg.sender);\n }\n\n /**\n * @dev Updates the `description` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenDescription} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenDescription(\n uint256 tokenId,\n string memory _tokenDescription\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].description = _tokenDescription;\n emit NewTokenDescription(tokenId, _tokenDescription, msg.sender);\n }\n\n /**\n * @dev Add a new AccessPoint register for an app token.\n * The AP name should be a DNS or ENS url and it should be unique.\n * Anyone can add an AP but it should requires a payment.\n *\n * May emit a {NewAccessPoint} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n * IMPORTANT: The payment is not set yet\n */\n function addAccessPoint(uint256 tokenId, string memory apName) public payable {\n // require(msg.value == 0.1 ether, \"You need to pay at least 0.1 ETH\"); // TODO: define a minimum price\n _requireMinted(tokenId);\n require(_accessPoints[apName].owner == address(0), \"FleekERC721: AP already exists\");\n\n _accessPoints[apName] = AccessPoint(tokenId, _apps[tokenId].accessPoints.length, 0, false, false, msg.sender);\n _apps[tokenId].accessPoints.push(apName);\n\n emit NewAccessPoint(apName, tokenId, msg.sender);\n }\n\n /**\n * @dev Remove an AccessPoint registry for an app token.\n * It will also remove the AP from the app token APs list.\n *\n * May emit a {RemoveAccessPoint} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - must be called by the AP owner.\n */\n function removeAccessPoint(string memory apName) public requireAP(apName) {\n require(msg.sender == _accessPoints[apName].owner, \"FleekERC721: must be AP owner\");\n uint256 tokenId = _accessPoints[apName].tokenId;\n App storage _app = _apps[tokenId];\n\n // the index of the AP to remove\n uint256 indexToRemove = _accessPoints[apName].index;\n\n // the last item is reposited in the index to remove\n string memory lastAP = _app.accessPoints[_app.accessPoints.length - 1];\n _app.accessPoints[indexToRemove] = lastAP;\n _accessPoints[lastAP].index = indexToRemove;\n\n // remove the last item\n _app.accessPoints.pop();\n\n delete _accessPoints[apName];\n emit RemoveAccessPoint(apName, tokenId, msg.sender);\n }\n\n /**\n * @dev A view function to gether information about an AccessPoint.\n * It returns a JSON string representing the AccessPoint information.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function getAccessPointJSON(string memory apName) public view requireAP(apName) returns (string memory) {\n AccessPoint storage _ap = _accessPoints[apName];\n return _ap.toString();\n }\n\n /**\n * @dev A view function to check if a AccessPoint is verified.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function isAccessPointNameVerified(string memory apName) public view requireAP(apName) returns (bool) {\n return _accessPoints[apName].nameVerified;\n }\n\n /**\n * @dev Increases the score of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointScore} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function increaseAccessPointScore(string memory apName) public requireAP(apName) {\n _accessPoints[apName].score++;\n emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);\n }\n\n /**\n * @dev Decreases the score of a AccessPoint registry if is greater than 0.\n *\n * May emit a {ChangeAccessPointScore} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function decreaseAccessPointScore(string memory apName) public requireAP(apName) {\n require(_accessPoints[apName].score > 0, \"FleekERC721: score cant be lower\");\n _accessPoints[apName].score--;\n emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);\n }\n\n /**\n * @dev Set the content verification of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointContentVerify} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - the sender must have the token controller role.\n *\n */\n function setAccessPointContentVerify(\n string memory apName,\n bool verified\n ) public requireAP(apName) requireTokenRole(_accessPoints[apName].tokenId, Roles.Controller) {\n _accessPoints[apName].contentVerified = verified;\n emit ChangeAccessPointContentVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);\n }\n\n /**\n * @dev Set the name verification of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointNameVerify} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - the sender must have the token controller role.\n *\n */\n function setAccessPointNameVerify(\n string memory apName,\n bool verified\n ) public requireAP(apName) requireTokenRole(_accessPoints[apName].tokenId, Roles.Controller) {\n _accessPoints[apName].nameVerified = verified;\n emit ChangeAccessPointNameVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);\n }\n\n /**\n * @dev A view function to gether the list of mirrros for a given app.\n *\n * Requirements:\n * - the tokenId must be minted and valid.\n *\n */\n function appAccessPoints(uint256 tokenId) public view returns (string[] memory) {\n _requireMinted(tokenId);\n return _apps[tokenId].accessPoints;\n }\n\n /**\n * @dev Adds a new build to a minted `tokenId`'s builds mapping.\n *\n * May emit a {NewBuild} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenBuild(\n uint256 tokenId,\n string memory _commitHash,\n string memory _gitRepository\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].builds[++_apps[tokenId].currentBuild] = Build(_commitHash, _gitRepository);\n emit NewBuild(tokenId, _commitHash, msg.sender);\n }\n\n /**\n * @dev Burns a previously minted `tokenId`.\n *\n * May emit a {Transfer} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenOwner` role.\n *\n */\n function burn(uint256 tokenId) public virtual requireTokenRole(tokenId, Roles.Owner) {\n super._burn(tokenId);\n\n if (bytes(_apps[tokenId].externalURL).length != 0) {\n delete _apps[tokenId];\n }\n }\n}\n"
+ },
+ "contracts/util/FleekStrings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"../FleekERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"./FleekSVG.sol\";\n\nlibrary FleekStrings {\n using Strings for uint256;\n using Strings for uint160;\n using Strings for uint8;\n using FleekStrings for bool;\n using FleekStrings for bytes3;\n\n /**\n * @dev Converts a boolean value to a string.\n */\n function toString(bool _bool) internal pure returns (string memory) {\n return _bool ? \"true\" : \"false\";\n }\n\n /**\n * @dev Converts a string to a base64 string.\n */\n function toBase64(string memory str) internal pure returns (string memory) {\n return Base64.encode(bytes(str));\n }\n\n /**\n * @dev Converts FleekERC721.App to a JSON string.\n * It requires to receive owner address as a parameter.\n */\n function toString(FleekERC721.App storage app, address owner) internal view returns (string memory) {\n // prettier-ignore\n return string(abi.encodePacked(\n '{',\n '\"name\":\"', app.name, '\",',\n '\"description\":\"', app.description, '\",',\n '\"owner\":\"', uint160(owner).toHexString(20), '\",',\n '\"external_url\":\"', app.externalURL, '\",',\n '\"image\":\"', FleekSVG.generateBase64(app.name, app.ENS, app.logo, app.color.toColorString()), '\",',\n '\"attributes\": [',\n '{\"trait_type\": \"ENS\", \"value\":\"', app.ENS,'\"},',\n '{\"trait_type\": \"Commit Hash\", \"value\":\"', app.builds[app.currentBuild].commitHash,'\"},',\n '{\"trait_type\": \"Repository\", \"value\":\"', app.builds[app.currentBuild].gitRepository,'\"},',\n '{\"trait_type\": \"Version\", \"value\":\"', app.currentBuild.toString(),'\"}',\n '{\"trait_type\": \"Color\", \"value\":\"', app.color.toColorString(),'\"}',\n ']',\n '}'\n ));\n }\n\n /**\n * @dev Converts FleekERC721.AccessPoint to a JSON string.\n */\n function toString(FleekERC721.AccessPoint storage ap) internal view returns (string memory) {\n // prettier-ignore\n return string(abi.encodePacked(\n \"{\",\n '\"tokenId\":', ap.tokenId.toString(), \",\",\n '\"score\":', ap.score.toString(), \",\",\n '\"nameVerified\":', ap.nameVerified.toString(), \",\",\n '\"contentVerified\":', ap.contentVerified.toString(), \",\",\n '\"owner\":\"', uint160(ap.owner).toHexString(20), '\"',\n \"}\"\n ));\n }\n\n /**\n * @dev Converts bytes3 to a hex color string.\n */\n function toColorString(bytes3 _bytes) internal pure returns (string memory) {\n return\n string(\n abi.encodePacked(\n \"#\",\n uint8(_bytes[0]).toHexString(),\n uint8(_bytes[1]).toHexString(),\n uint8(_bytes[2]).toHexString()\n )\n );\n }\n}\n"
+ },
+ "contracts/util/FleekSVG.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"../FleekERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\n\nlibrary FleekSVG {\n /**\n * @dev Generates a SVG image.\n */\n function generateBase64(\n string memory name,\n string memory ENS,\n string memory logo,\n string memory color\n ) internal pure returns (string memory) {\n return (\n string(\n abi.encodePacked(\n \"data:image/svg+xml;base64,\",\n Base64.encode(\n abi.encodePacked(\n '',\n '',\n ''\n '',\n '',\n '',\n '',\n '',\n '',\n '',\n ''\n ''\n '',\n name,\n \"\"\n '',\n ENS,\n \"\"\n \"\"\n )\n )\n )\n )\n );\n }\n}\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 200,
+ "details": {
+ "yul": true
+ }
+ },
+ "viaIR": true,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "storageLayout"
+ ],
+ "": ["ast"]
+ }
+ }
+ }
+}
diff --git a/deployments/mumbai/solcInputs/ca4121c62597d5085f2b7de4230d5cd3.json b/deployments/mumbai/solcInputs/ca4121c62597d5085f2b7de4230d5cd3.json
new file mode 100644
index 0000000..0cc7b1c
--- /dev/null
+++ b/deployments/mumbai/solcInputs/ca4121c62597d5085f2b7de4230d5cd3.json
@@ -0,0 +1,82 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initialized`\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initializing`\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721Upgradeable.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256, /* firstTokenId */\n uint256 batchSize\n ) internal virtual {\n if (batchSize > 1) {\n if (from != address(0)) {\n _balances[from] -= batchSize;\n }\n if (to != address(0)) {\n _balances[to] += batchSize;\n }\n }\n }\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 firstTokenId,\n uint256 batchSize\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = MathUpgradeable.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, MathUpgradeable.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Base64.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n *\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n string memory result = new string(4 * ((data.length + 2) / 3));\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n\n // When data `bytes` is not exactly 3 bytes long\n // it is padded with `=` characters at the end\n switch mod(mload(data), 3)\n case 1 {\n mstore8(sub(resultPtr, 1), 0x3d)\n mstore8(sub(resultPtr, 2), 0x3d)\n }\n case 2 {\n mstore8(sub(resultPtr, 1), 0x3d)\n }\n }\n\n return result;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Counters.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/math/Math.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "contracts/FleekAccessControl.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\ncontract FleekAccessControl is Initializable {\n using Counters for Counters.Counter;\n\n enum Roles {\n Owner,\n Controller\n }\n\n event TokenRoleGranted(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event TokenRoleRevoked(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleGranted(Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleRevoked(Roles indexed role, address indexed toAddress, address byAddress);\n\n struct Role {\n mapping(address => uint256) indexes;\n address[] members;\n }\n\n Counters.Counter private _collectionRolesVersion;\n // _collectionRoles[version][role]\n mapping(uint256 => mapping(Roles => Role)) private _collectionRoles;\n\n mapping(uint256 => Counters.Counter) private _tokenRolesVersion;\n // _tokenRoles[tokenId][version][role]\n mapping(uint256 => mapping(uint256 => mapping(Roles => Role))) private _tokenRoles;\n\n /**\n * @dev Initializes the contract by granting the `Owner` role to the deployer.\n */\n function __FleekAccessControl_init() internal onlyInitializing {\n _grantCollectionRole(Roles.Owner, msg.sender);\n }\n\n /**\n * @dev Checks if the `msg.sender` has a certain role.\n */\n modifier requireCollectionRole(Roles role) {\n require(\n hasCollectionRole(role, msg.sender) || hasCollectionRole(Roles.Owner, msg.sender),\n \"FleekAccessControl: must have collection role\"\n );\n _;\n }\n\n /**\n * @dev Checks if the `msg.sender` has the `Token` role for a certain `tokenId`.\n */\n modifier requireTokenRole(uint256 tokenId, Roles role) {\n require(\n hasTokenRole(tokenId, role, msg.sender) || hasTokenRole(tokenId, Roles.Owner, msg.sender),\n \"FleekAccessControl: must have token role\"\n );\n _;\n }\n\n /**\n * @dev Grants the collection role to an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function grantCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _grantCollectionRole(role, account);\n }\n\n /**\n * @dev Grants the token role to an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function grantTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _grantTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function revokeCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _revokeCollectionRole(role, account);\n }\n\n /**\n * @dev Revokes the token role of an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function revokeTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _revokeTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Returns `True` if a certain address has the collection role.\n */\n function hasCollectionRole(Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _collectionRolesVersion.current();\n\n return _collectionRoles[currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns `True` if a certain address has the token role.\n */\n function hasTokenRole(uint256 tokenId, Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns an array of addresses that all have the collection role.\n */\n function getCollectionRoleMembers(Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _collectionRolesVersion.current();\n return _collectionRoles[currentVersion][role].members;\n }\n\n /**\n * @dev Returns an array of addresses that all have the same token role for a certain tokenId.\n */\n function getTokenRoleMembers(uint256 tokenId, Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].members;\n }\n\n /**\n * @dev Grants the collection role to an address.\n */\n function _grantCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _grantRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleGranted(role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n */\n function _revokeCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _revokeRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleRevoked(role, account, msg.sender);\n }\n\n /**\n * @dev Grants the token role to an address.\n */\n function _grantTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _grantRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleGranted(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the token role of an address.\n */\n function _revokeTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _revokeRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleRevoked(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Grants a certain role to a certain address.\n */\n function _grantRole(Role storage role, address account) internal {\n if (role.indexes[account] == 0) {\n role.members.push(account);\n role.indexes[account] = role.members.length;\n }\n }\n\n /**\n * @dev Revokes a certain role from a certain address.\n */\n function _revokeRole(Role storage role, address account) internal {\n if (role.indexes[account] != 0) {\n uint256 index = role.indexes[account] - 1;\n uint256 lastIndex = role.members.length - 1;\n address lastAccount = role.members[lastIndex];\n\n role.members[index] = lastAccount;\n role.indexes[lastAccount] = index + 1;\n\n role.members.pop();\n delete role.indexes[account];\n }\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId.\n * Should only be used for burning tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId) internal {\n _tokenRolesVersion[tokenId].increment();\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId and grants the owner role to a new address.\n * Should only be used for transferring tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId, address newOwner) internal {\n _clearAllTokenRoles(tokenId);\n _grantTokenRole(tokenId, Roles.Owner, newOwner);\n }\n}\n"
+ },
+ "contracts/FleekERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"./FleekAccessControl.sol\";\nimport \"./SVGLibrary.sol\";\n\ncontract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl {\n using Strings for uint256;\n using Counters for Counters.Counter;\n\n event NewBuild(uint256 indexed token, string indexed commitHash, address indexed triggeredBy);\n event NewTokenName(uint256 indexed token, string indexed name, address indexed triggeredBy);\n event NewTokenDescription(uint256 indexed token, string indexed description, address indexed triggeredBy);\n event NewTokenImage(uint256 indexed token, string indexed image, address indexed triggeredBy);\n event NewTokenExternalURL(uint256 indexed token, string indexed externalURL, address indexed triggeredBy);\n event NewTokenENS(uint256 indexed token, string indexed ENS, address indexed triggeredBy);\n\n /**\n * The properties are stored as string to keep consistency with\n * other token contracts, we might consider changing for bytes32\n * in the future due to gas optimization.\n */\n struct App {\n string name; // Name of the site\n string description; // Description about the site\n string externalURL; // Site URL\n string ENS; // ENS ID\n uint256 currentBuild; // The current build number (Increments by one with each change, starts at zero)\n mapping(uint256 => Build) builds; // Mapping to build details for each build number\n }\n\n /**\n * The metadata that is stored for each build.\n */\n struct Build {\n string commitHash;\n string gitRepository;\n }\n\n Counters.Counter private _tokenIds;\n mapping(uint256 => App) private _apps;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function initialize(string memory _name, string memory _symbol) public initializer {\n __ERC721_init(_name, _symbol);\n __FleekAccessControl_init();\n }\n\n /**\n * @dev Checks if msg.sender has the role of tokenOwner for a certain tokenId.\n */\n modifier requireTokenOwner(uint256 tokenId) {\n require(msg.sender == ownerOf(tokenId), \"FleekERC721: must be token owner\");\n _;\n }\n\n /**\n * @dev Generates a SVG image.\n */\n function _generateSVG(string memory name, string memory ENS) internal pure returns (string memory) {\n return (string(abi.encodePacked(\"data:image/svg+xml;base64,\", Base64.encode(SVGLibrary.parseSVG(name, ENS)))));\n }\n\n /**\n * @dev Mints a token and returns a tokenId.\n *\n * If the `tokenId` has not been minted before, and the `to` address is not zero, emits a {Transfer} event.\n *\n * Requirements:\n *\n * - the caller must have ``collectionOwner``'s admin role.\n *\n */\n function mint(\n address to,\n string memory name,\n string memory description,\n string memory externalURL,\n string memory ENS,\n string memory commitHash,\n string memory gitRepository\n ) public payable requireCollectionRole(Roles.Owner) returns (uint256) {\n uint256 tokenId = _tokenIds.current();\n _mint(to, tokenId);\n _tokenIds.increment();\n\n App storage app = _apps[tokenId];\n app.name = name;\n app.description = description;\n app.externalURL = externalURL;\n app.ENS = ENS;\n\n // The mint interaction is considered to be the first build of the site. Updates from now on all increment the currentBuild by one and update the mapping.\n app.currentBuild = 0;\n app.builds[0] = Build(commitHash, gitRepository);\n\n return tokenId;\n }\n\n /**\n * @dev Returns the token metadata associated with the `tokenId`.\n *\n * Returns a based64 encoded string value of the URI.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n address owner = ownerOf(tokenId);\n App storage app = _apps[tokenId];\n\n // prettier-ignore\n bytes memory dataURI = abi.encodePacked(\n '{',\n '\"name\":\"', app.name, '\",',\n '\"description\":\"', app.description, '\",',\n '\"owner\":\"', Strings.toHexString(uint160(owner), 20), '\",',\n '\"external_url\":\"', app.externalURL, '\",',\n '\"image\":\"', _generateSVG(app.name, app.ENS), '\",',\n '\"attributes\": [',\n '{\"trait_type\": \"ENS\", \"value\":\"', app.ENS,'\"},',\n '{\"trait_type\": \"Commit Hash\", \"value\":\"', app.builds[app.currentBuild].commitHash,'\"},',\n '{\"trait_type\": \"Repository\", \"value\":\"', app.builds[app.currentBuild].gitRepository,'\"},',\n '{\"trait_type\": \"Version\", \"value\":\"', Strings.toString(app.currentBuild),'\"}',\n ']',\n '}'\n );\n\n return string(abi.encodePacked(_baseURI(), Base64.encode((dataURI))));\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Upgradeable) returns (bool) {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Override of _beforeTokenTransfer of ERC721.\n * Here it needs to update the token controller roles for mint, burn and transfer.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId,\n uint256 batchSize\n ) internal virtual override {\n if (from != address(0) && to != address(0)) {\n // Transfer\n _clearAllTokenRoles(tokenId, to);\n } else if (from == address(0)) {\n // Mint\n _grantTokenRole(tokenId, Roles.Owner, to);\n } else if (to == address(0)) {\n // Burn\n _clearAllTokenRoles(tokenId);\n }\n super._beforeTokenTransfer(from, to, tokenId, batchSize);\n }\n\n /**\n * @dev A baseURI internal function implementation to be called in the `tokenURI` function.\n */\n function _baseURI() internal view virtual override returns (string memory) {\n return \"data:application/json;base64,\";\n }\n\n /**\n * @dev Updates the `externalURL` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenExternalURL} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenExternalURL(\n uint256 tokenId,\n string memory _tokenExternalURL\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].externalURL = _tokenExternalURL;\n emit NewTokenExternalURL(tokenId, _tokenExternalURL, msg.sender);\n }\n\n /**\n * @dev Updates the `ENS` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenENS} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenENS(\n uint256 tokenId,\n string memory _tokenENS\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].ENS = _tokenENS;\n emit NewTokenENS(tokenId, _tokenENS, msg.sender);\n }\n\n /**\n * @dev Updates the `name` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenName} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenName(\n uint256 tokenId,\n string memory _tokenName\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].name = _tokenName;\n emit NewTokenName(tokenId, _tokenName, msg.sender);\n }\n\n /**\n * @dev Updates the `description` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenDescription} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenDescription(\n uint256 tokenId,\n string memory _tokenDescription\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].description = _tokenDescription;\n emit NewTokenDescription(tokenId, _tokenDescription, msg.sender);\n }\n\n /**\n * @dev Adds a new build to a minted `tokenId`'s builds mapping.\n *\n * May emit a {NewBuild} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenBuild(\n uint256 tokenId,\n string memory _commitHash,\n string memory _gitRepository\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].builds[++_apps[tokenId].currentBuild] = Build(_commitHash, _gitRepository);\n emit NewBuild(tokenId, _commitHash, msg.sender);\n }\n\n /**\n * @dev Burns a previously minted `tokenId`.\n *\n * May emit a {Transfer} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenOwner` role.\n *\n */\n function burn(uint256 tokenId) public virtual requireTokenRole(tokenId, Roles.Owner) {\n super._burn(tokenId);\n\n if (bytes(_apps[tokenId].externalURL).length != 0) {\n delete _apps[tokenId];\n }\n }\n}\n"
+ },
+ "contracts/SVGLibrary.sol": {
+ "content": "library SVGLibrary {\r\n function parseSVG(string memory name, string memory version) internal pure returns (bytes memory) {\r\n return\r\n abi.encodePacked(\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n name,\r\n '',\r\n version,\r\n \"\"\r\n );\r\n }\r\n}\r\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 200,
+ "details": {
+ "yul": false
+ }
+ },
+ "viaIR": false,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "storageLayout"
+ ],
+ "": ["ast"]
+ }
+ }
+ }
+}
diff --git a/deployments/mumbai/solcInputs/eaf67d6e913a02593ac4fc53b3d49e45.json b/deployments/mumbai/solcInputs/eaf67d6e913a02593ac4fc53b3d49e45.json
new file mode 100644
index 0000000..8d88258
--- /dev/null
+++ b/deployments/mumbai/solcInputs/eaf67d6e913a02593ac4fc53b3d49e45.json
@@ -0,0 +1,85 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initialized`\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initializing`\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721Upgradeable.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256, /* firstTokenId */\n uint256 batchSize\n ) internal virtual {\n if (batchSize > 1) {\n if (from != address(0)) {\n _balances[from] -= batchSize;\n }\n if (to != address(0)) {\n _balances[to] += batchSize;\n }\n }\n }\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 firstTokenId,\n uint256 batchSize\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = MathUpgradeable.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, MathUpgradeable.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Base64.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n *\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n string memory result = new string(4 * ((data.length + 2) / 3));\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n\n // When data `bytes` is not exactly 3 bytes long\n // it is padded with `=` characters at the end\n switch mod(mload(data), 3)\n case 1 {\n mstore8(sub(resultPtr, 1), 0x3d)\n mstore8(sub(resultPtr, 2), 0x3d)\n }\n case 2 {\n mstore8(sub(resultPtr, 1), 0x3d)\n }\n }\n\n return result;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Counters.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/math/Math.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "contracts/FleekAccessControl.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\ncontract FleekAccessControl is Initializable {\n using Counters for Counters.Counter;\n\n enum Roles {\n Owner,\n Controller\n }\n\n event TokenRoleGranted(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event TokenRoleRevoked(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleGranted(Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleRevoked(Roles indexed role, address indexed toAddress, address byAddress);\n\n struct Role {\n mapping(address => uint256) indexes;\n address[] members;\n }\n\n Counters.Counter private _collectionRolesVersion;\n // _collectionRoles[version][role]\n mapping(uint256 => mapping(Roles => Role)) private _collectionRoles;\n\n mapping(uint256 => Counters.Counter) private _tokenRolesVersion;\n // _tokenRoles[tokenId][version][role]\n mapping(uint256 => mapping(uint256 => mapping(Roles => Role))) private _tokenRoles;\n\n /**\n * @dev Initializes the contract by granting the `Owner` role to the deployer.\n */\n function __FleekAccessControl_init() internal onlyInitializing {\n _grantCollectionRole(Roles.Owner, msg.sender);\n }\n\n /**\n * @dev Checks if the `msg.sender` has a certain role.\n */\n modifier requireCollectionRole(Roles role) {\n require(\n hasCollectionRole(role, msg.sender) || hasCollectionRole(Roles.Owner, msg.sender),\n \"FleekAccessControl: must have collection role\"\n );\n _;\n }\n\n /**\n * @dev Checks if the `msg.sender` has the `Token` role for a certain `tokenId`.\n */\n modifier requireTokenRole(uint256 tokenId, Roles role) {\n require(\n hasTokenRole(tokenId, role, msg.sender) || hasTokenRole(tokenId, Roles.Owner, msg.sender),\n \"FleekAccessControl: must have token role\"\n );\n _;\n }\n\n /**\n * @dev Grants the collection role to an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function grantCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _grantCollectionRole(role, account);\n }\n\n /**\n * @dev Grants the token role to an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function grantTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _grantTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function revokeCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _revokeCollectionRole(role, account);\n }\n\n /**\n * @dev Revokes the token role of an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function revokeTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _revokeTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Returns `True` if a certain address has the collection role.\n */\n function hasCollectionRole(Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _collectionRolesVersion.current();\n\n return _collectionRoles[currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns `True` if a certain address has the token role.\n */\n function hasTokenRole(uint256 tokenId, Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns an array of addresses that all have the collection role.\n */\n function getCollectionRoleMembers(Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _collectionRolesVersion.current();\n return _collectionRoles[currentVersion][role].members;\n }\n\n /**\n * @dev Returns an array of addresses that all have the same token role for a certain tokenId.\n */\n function getTokenRoleMembers(uint256 tokenId, Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].members;\n }\n\n /**\n * @dev Grants the collection role to an address.\n */\n function _grantCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _grantRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleGranted(role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n */\n function _revokeCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _revokeRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleRevoked(role, account, msg.sender);\n }\n\n /**\n * @dev Grants the token role to an address.\n */\n function _grantTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _grantRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleGranted(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the token role of an address.\n */\n function _revokeTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _revokeRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleRevoked(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Grants a certain role to a certain address.\n */\n function _grantRole(Role storage role, address account) internal {\n if (role.indexes[account] == 0) {\n role.members.push(account);\n role.indexes[account] = role.members.length;\n }\n }\n\n /**\n * @dev Revokes a certain role from a certain address.\n */\n function _revokeRole(Role storage role, address account) internal {\n if (role.indexes[account] != 0) {\n uint256 index = role.indexes[account] - 1;\n uint256 lastIndex = role.members.length - 1;\n address lastAccount = role.members[lastIndex];\n\n role.members[index] = lastAccount;\n role.indexes[lastAccount] = index + 1;\n\n role.members.pop();\n delete role.indexes[account];\n }\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId.\n * Should only be used for burning tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId) internal {\n _tokenRolesVersion[tokenId].increment();\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId and grants the owner role to a new address.\n * Should only be used for transferring tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId, address newOwner) internal {\n _clearAllTokenRoles(tokenId);\n _grantTokenRole(tokenId, Roles.Owner, newOwner);\n }\n}\n"
+ },
+ "contracts/FleekERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"./FleekAccessControl.sol\";\nimport \"./util/FleekStrings.sol\";\n\ncontract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl {\n using Strings for uint256;\n using Counters for Counters.Counter;\n using FleekStrings for FleekERC721.App;\n using FleekStrings for FleekERC721.AccessPoint;\n using FleekStrings for string;\n\n event NewBuild(uint256 indexed token, string indexed commitHash, address indexed triggeredBy);\n event NewTokenName(uint256 indexed token, string indexed name, address indexed triggeredBy);\n event NewTokenDescription(uint256 indexed token, string indexed description, address indexed triggeredBy);\n event NewTokenImage(uint256 indexed token, string indexed image, address indexed triggeredBy);\n event NewTokenExternalURL(uint256 indexed token, string indexed externalURL, address indexed triggeredBy);\n event NewTokenENS(uint256 indexed token, string indexed ENS, address indexed triggeredBy);\n\n event NewAccessPoint(string indexed apName, uint256 indexed tokenId, address indexed owner);\n event RemoveAccessPoint(string indexed apName, uint256 indexed tokenId, address indexed owner);\n event ChangeAccessPointScore(\n string indexed apName,\n uint256 indexed tokenId,\n uint256 score,\n address indexed triggeredBy\n );\n event ChangeAccessPointNameVerify(\n string indexed apName,\n uint256 tokenId,\n bool indexed verified,\n address indexed triggeredBy\n );\n event ChangeAccessPointContentVerify(\n string indexed apName,\n uint256 tokenId,\n bool indexed verified,\n address indexed triggeredBy\n );\n\n /**\n * The properties are stored as string to keep consistency with\n * other token contracts, we might consider changing for bytes32\n * in the future due to gas optimization.\n */\n struct App {\n string name; // Name of the site\n string description; // Description about the site\n string externalURL; // Site URL\n string ENS; // ENS ID\n uint256 currentBuild; // The current build number (Increments by one with each change, starts at zero)\n mapping(uint256 => Build) builds; // Mapping to build details for each build number\n string[] accessPoints; // List of app AccessPoint\n string logo;\n uint24 color; // Color of the nft\n }\n\n /**\n * The metadata that is stored for each build.\n */\n struct Build {\n string commitHash;\n string gitRepository;\n }\n\n /**\n * The stored data for each AccessPoint.\n */\n struct AccessPoint {\n uint256 tokenId;\n uint256 index;\n uint256 score;\n bool contentVerified;\n bool nameVerified;\n address owner;\n }\n\n Counters.Counter private _appIds;\n mapping(uint256 => App) private _apps;\n mapping(string => AccessPoint) private _accessPoints;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function initialize(string memory _name, string memory _symbol) public initializer {\n __ERC721_init(_name, _symbol);\n __FleekAccessControl_init();\n }\n\n /**\n * @dev Checks if the AccessPoint exists.\n */\n modifier requireAP(string memory apName) {\n require(_accessPoints[apName].owner != address(0), \"FleekERC721: invalid AP\");\n _;\n }\n\n /**\n * @dev Mints a token and returns a tokenId.\n *\n * If the `tokenId` has not been minted before, and the `to` address is not zero, emits a {Transfer} event.\n *\n * Requirements:\n *\n * - the caller must have ``collectionOwner``'s admin role.\n *\n */\n function mint(\n address to,\n string memory name,\n string memory description,\n string memory externalURL,\n string memory ENS,\n string memory commitHash,\n string memory gitRepository,\n string memory logo,\n uint24 color\n ) public payable requireCollectionRole(Roles.Owner) returns (uint256) {\n uint256 tokenId = _appIds.current();\n _mint(to, tokenId);\n _appIds.increment();\n\n App storage app = _apps[tokenId];\n app.name = name;\n app.description = description;\n app.externalURL = externalURL;\n app.ENS = ENS;\n app.logo = logo;\n app.color = color;\n\n // The mint interaction is considered to be the first build of the site. Updates from now on all increment the currentBuild by one and update the mapping.\n app.currentBuild = 0;\n app.builds[0] = Build(commitHash, gitRepository);\n app.accessPoints = new string[](0);\n\n return tokenId;\n }\n\n /**\n * @dev Returns the token metadata associated with the `tokenId`.\n *\n * Returns a based64 encoded string value of the URI.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n address owner = ownerOf(tokenId);\n App storage app = _apps[tokenId];\n\n return string(abi.encodePacked(_baseURI(), app.toString(owner).toBase64()));\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Upgradeable) returns (bool) {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Override of _beforeTokenTransfer of ERC721.\n * Here it needs to update the token controller roles for mint, burn and transfer.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId,\n uint256 batchSize\n ) internal virtual override {\n if (from != address(0) && to != address(0)) {\n // Transfer\n _clearAllTokenRoles(tokenId, to);\n } else if (from == address(0)) {\n // Mint\n _grantTokenRole(tokenId, Roles.Owner, to);\n } else if (to == address(0)) {\n // Burn\n _clearAllTokenRoles(tokenId);\n }\n super._beforeTokenTransfer(from, to, tokenId, batchSize);\n }\n\n /**\n * @dev A baseURI internal function implementation to be called in the `tokenURI` function.\n */\n function _baseURI() internal view virtual override returns (string memory) {\n return \"data:application/json;base64,\";\n }\n\n /**\n * @dev Updates the `externalURL` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenExternalURL} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenExternalURL(\n uint256 tokenId,\n string memory _tokenExternalURL\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].externalURL = _tokenExternalURL;\n emit NewTokenExternalURL(tokenId, _tokenExternalURL, msg.sender);\n }\n\n /**\n * @dev Updates the `ENS` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenENS} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenENS(\n uint256 tokenId,\n string memory _tokenENS\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].ENS = _tokenENS;\n emit NewTokenENS(tokenId, _tokenENS, msg.sender);\n }\n\n /**\n * @dev Updates the `name` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenName} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenName(\n uint256 tokenId,\n string memory _tokenName\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].name = _tokenName;\n emit NewTokenName(tokenId, _tokenName, msg.sender);\n }\n\n /**\n * @dev Updates the `description` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenDescription} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenDescription(\n uint256 tokenId,\n string memory _tokenDescription\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].description = _tokenDescription;\n emit NewTokenDescription(tokenId, _tokenDescription, msg.sender);\n }\n\n /**\n * @dev Add a new AccessPoint register for an app token.\n * The AP name should be a DNS or ENS url and it should be unique.\n * Anyone can add an AP but it should requires a payment.\n *\n * May emit a {NewAccessPoint} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n * IMPORTANT: The payment is not set yet\n */\n function addAccessPoint(uint256 tokenId, string memory apName) public payable {\n // require(msg.value == 0.1 ether, \"You need to pay at least 0.1 ETH\"); // TODO: define a minimum price\n _requireMinted(tokenId);\n require(_accessPoints[apName].owner == address(0), \"FleekERC721: AP already exists\");\n\n _accessPoints[apName] = AccessPoint(tokenId, _apps[tokenId].accessPoints.length, 0, false, false, msg.sender);\n _apps[tokenId].accessPoints.push(apName);\n\n emit NewAccessPoint(apName, tokenId, msg.sender);\n }\n\n /**\n * @dev Remove an AccessPoint registry for an app token.\n * It will also remove the AP from the app token APs list.\n *\n * May emit a {RemoveAccessPoint} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - must be called by the AP owner.\n */\n function removeAccessPoint(string memory apName) public requireAP(apName) {\n require(msg.sender == _accessPoints[apName].owner, \"FleekERC721: must be AP owner\");\n uint256 tokenId = _accessPoints[apName].tokenId;\n App storage _app = _apps[tokenId];\n\n // the index of the AP to remove\n uint256 indexToRemove = _accessPoints[apName].index;\n\n // the last item is reposited in the index to remove\n string memory lastAP = _app.accessPoints[_app.accessPoints.length - 1];\n _app.accessPoints[indexToRemove] = lastAP;\n _accessPoints[lastAP].index = indexToRemove;\n\n // remove the last item\n _app.accessPoints.pop();\n\n delete _accessPoints[apName];\n emit RemoveAccessPoint(apName, tokenId, msg.sender);\n }\n\n /**\n * @dev A view function to gether information about an AccessPoint.\n * It returns a JSON string representing the AccessPoint information.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function getAccessPointJSON(string memory apName) public view requireAP(apName) returns (string memory) {\n AccessPoint storage _ap = _accessPoints[apName];\n return _ap.toString();\n }\n\n /**\n * @dev A view function to check if a AccessPoint is verified.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function isAccessPointNameVerified(string memory apName) public view requireAP(apName) returns (bool) {\n return _accessPoints[apName].nameVerified;\n }\n\n /**\n * @dev Increases the score of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointScore} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function increaseAccessPointScore(string memory apName) public requireAP(apName) {\n _accessPoints[apName].score++;\n emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);\n }\n\n /**\n * @dev Decreases the score of a AccessPoint registry if is greater than 0.\n *\n * May emit a {ChangeAccessPointScore} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function decreaseAccessPointScore(string memory apName) public requireAP(apName) {\n require(_accessPoints[apName].score > 0, \"FleekERC721: score cant be lower\");\n _accessPoints[apName].score--;\n emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);\n }\n\n /**\n * @dev Set the content verification of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointContentVerify} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - the sender must have the token controller role.\n *\n */\n function setAccessPointContentVerify(\n string memory apName,\n bool verified\n ) public requireAP(apName) requireTokenRole(_accessPoints[apName].tokenId, Roles.Controller) {\n _accessPoints[apName].contentVerified = verified;\n emit ChangeAccessPointContentVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);\n }\n\n /**\n * @dev Set the name verification of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointNameVerify} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - the sender must have the token controller role.\n *\n */\n function setAccessPointNameVerify(\n string memory apName,\n bool verified\n ) public requireAP(apName) requireTokenRole(_accessPoints[apName].tokenId, Roles.Controller) {\n _accessPoints[apName].nameVerified = verified;\n emit ChangeAccessPointNameVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);\n }\n\n /**\n * @dev A view function to gether the list of mirrros for a given app.\n *\n * Requirements:\n * - the tokenId must be minted and valid.\n *\n */\n function appAccessPoints(uint256 tokenId) public view returns (string[] memory) {\n _requireMinted(tokenId);\n return _apps[tokenId].accessPoints;\n }\n\n /**\n * @dev Adds a new build to a minted `tokenId`'s builds mapping.\n *\n * May emit a {NewBuild} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenBuild(\n uint256 tokenId,\n string memory _commitHash,\n string memory _gitRepository\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].builds[++_apps[tokenId].currentBuild] = Build(_commitHash, _gitRepository);\n emit NewBuild(tokenId, _commitHash, msg.sender);\n }\n\n /**\n * @dev Burns a previously minted `tokenId`.\n *\n * May emit a {Transfer} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenOwner` role.\n *\n */\n function burn(uint256 tokenId) public virtual requireTokenRole(tokenId, Roles.Owner) {\n super._burn(tokenId);\n\n if (bytes(_apps[tokenId].externalURL).length != 0) {\n delete _apps[tokenId];\n }\n }\n}\n"
+ },
+ "contracts/util/FleekStrings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"../FleekERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"./FleekSVG.sol\";\n\nlibrary FleekStrings {\n using Strings for uint256;\n using Strings for uint160;\n using Strings for uint24;\n using FleekStrings for bool;\n using FleekStrings for bytes3;\n\n /**\n * @dev Converts a boolean value to a string.\n */\n function toString(bool _bool) internal pure returns (string memory) {\n return _bool ? \"true\" : \"false\";\n }\n\n /**\n * @dev Converts a string to a base64 string.\n */\n function toBase64(string memory str) internal pure returns (string memory) {\n return Base64.encode(bytes(str));\n }\n\n /**\n * @dev Converts FleekERC721.App to a JSON string.\n * It requires to receive owner address as a parameter.\n */\n function toString(FleekERC721.App storage app, address owner) internal view returns (string memory) {\n // prettier-ignore\n return string(abi.encodePacked(\n '{',\n '\"name\":\"', app.name, '\",',\n '\"description\":\"', app.description, '\",',\n '\"owner\":\"', uint160(owner).toHexString(20), '\",',\n '\"external_url\":\"', app.externalURL, '\",',\n '\"image\":\"', FleekSVG.generateBase64(app.name, app.ENS, app.logo, app.color.toHexString()), '\",',\n '\"attributes\": [',\n '{\"trait_type\": \"ENS\", \"value\":\"', app.ENS,'\"},',\n '{\"trait_type\": \"Commit Hash\", \"value\":\"', app.builds[app.currentBuild].commitHash,'\"},',\n '{\"trait_type\": \"Repository\", \"value\":\"', app.builds[app.currentBuild].gitRepository,'\"},',\n '{\"trait_type\": \"Version\", \"value\":\"', app.currentBuild.toString(),'\"},',\n '{\"trait_type\": \"Color\", \"value\":\"', app.color.toHexString(),'\"}',\n ']',\n '}'\n ));\n }\n\n /**\n * @dev Converts FleekERC721.AccessPoint to a JSON string.\n */\n function toString(FleekERC721.AccessPoint storage ap) internal view returns (string memory) {\n // prettier-ignore\n return string(abi.encodePacked(\n \"{\",\n '\"tokenId\":', ap.tokenId.toString(), \",\",\n '\"score\":', ap.score.toString(), \",\",\n '\"nameVerified\":', ap.nameVerified.toString(), \",\",\n '\"contentVerified\":', ap.contentVerified.toString(), \",\",\n '\"owner\":\"', uint160(ap.owner).toHexString(20), '\"',\n \"}\"\n ));\n }\n}\n"
+ },
+ "contracts/util/FleekSVG.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"../FleekERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\n\nlibrary FleekSVG {\n /**\n * @dev Generates a SVG image.\n */\n function generateBase64(\n string memory name,\n string memory ENS,\n string memory logo,\n string memory color\n ) internal pure returns (string memory) {\n return (\n string(\n abi.encodePacked(\n \"data:image/svg+xml;base64,\",\n Base64.encode(\n abi.encodePacked(\n '',\n '',\n ''\n '',\n '',\n '',\n '',\n '',\n '',\n '',\n ''\n ''\n '',\n name,\n \"\"\n '',\n ENS,\n \"\"\n \"\"\n )\n )\n )\n )\n );\n }\n}\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 200,
+ "details": {
+ "yul": true
+ }
+ },
+ "viaIR": true,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "storageLayout"
+ ],
+ "": ["ast"]
+ }
+ }
+ }
+}
diff --git a/deployments/mumbai/solcInputs/eafa2f45625b20e34f38411e5cd3ddab.json b/deployments/mumbai/solcInputs/eafa2f45625b20e34f38411e5cd3ddab.json
new file mode 100644
index 0000000..99f8b6d
--- /dev/null
+++ b/deployments/mumbai/solcInputs/eafa2f45625b20e34f38411e5cd3ddab.json
@@ -0,0 +1,85 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initialized`\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initializing`\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721Upgradeable.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256, /* firstTokenId */\n uint256 batchSize\n ) internal virtual {\n if (batchSize > 1) {\n if (from != address(0)) {\n _balances[from] -= batchSize;\n }\n if (to != address(0)) {\n _balances[to] += batchSize;\n }\n }\n }\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 firstTokenId,\n uint256 batchSize\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = MathUpgradeable.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, MathUpgradeable.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Base64.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n *\n * _Available since v4.5._\n */\nlibrary Base64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n string memory result = new string(4 * ((data.length + 2) / 3));\n\n /// @solidity memory-safe-assembly\n assembly {\n // Prepare the lookup table (skip the first \"length\" byte)\n let tablePtr := add(table, 1)\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n let dataPtr := data\n let endPtr := add(data, mload(data))\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (18 bits) chunk\n // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F which is the number of\n // the previous character in the ASCII table prior to the Base64 Table\n // The result is then added to the table to get the character to write,\n // and finally write it in the result pointer but with a left shift\n // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n\n // When data `bytes` is not exactly 3 bytes long\n // it is padded with `=` characters at the end\n switch mod(mload(data), 3)\n case 1 {\n mstore8(sub(resultPtr, 1), 0x3d)\n mstore8(sub(resultPtr, 2), 0x3d)\n }\n case 2 {\n mstore8(sub(resultPtr, 1), 0x3d)\n }\n }\n\n return result;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Counters.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/math/Math.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "contracts/FleekAccessControl.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\ncontract FleekAccessControl is Initializable {\n using Counters for Counters.Counter;\n\n enum Roles {\n Owner,\n Controller\n }\n\n event TokenRoleGranted(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event TokenRoleRevoked(uint256 indexed tokenId, Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleGranted(Roles indexed role, address indexed toAddress, address byAddress);\n event CollectionRoleRevoked(Roles indexed role, address indexed toAddress, address byAddress);\n\n struct Role {\n mapping(address => uint256) indexes;\n address[] members;\n }\n\n Counters.Counter private _collectionRolesVersion;\n // _collectionRoles[version][role]\n mapping(uint256 => mapping(Roles => Role)) private _collectionRoles;\n\n mapping(uint256 => Counters.Counter) private _tokenRolesVersion;\n // _tokenRoles[tokenId][version][role]\n mapping(uint256 => mapping(uint256 => mapping(Roles => Role))) private _tokenRoles;\n\n /**\n * @dev Initializes the contract by granting the `Owner` role to the deployer.\n */\n function __FleekAccessControl_init() internal onlyInitializing {\n _grantCollectionRole(Roles.Owner, msg.sender);\n }\n\n /**\n * @dev Checks if the `msg.sender` has a certain role.\n */\n modifier requireCollectionRole(Roles role) {\n require(\n hasCollectionRole(role, msg.sender) || hasCollectionRole(Roles.Owner, msg.sender),\n \"FleekAccessControl: must have collection role\"\n );\n _;\n }\n\n /**\n * @dev Checks if the `msg.sender` has the `Token` role for a certain `tokenId`.\n */\n modifier requireTokenRole(uint256 tokenId, Roles role) {\n require(\n hasTokenRole(tokenId, role, msg.sender) || hasTokenRole(tokenId, Roles.Owner, msg.sender),\n \"FleekAccessControl: must have token role\"\n );\n _;\n }\n\n /**\n * @dev Grants the collection role to an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function grantCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _grantCollectionRole(role, account);\n }\n\n /**\n * @dev Grants the token role to an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function grantTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _grantTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n *\n * Requirements:\n *\n * - the caller should have the collection role.\n *\n */\n function revokeCollectionRole(Roles role, address account) public requireCollectionRole(Roles.Owner) {\n _revokeCollectionRole(role, account);\n }\n\n /**\n * @dev Revokes the token role of an address.\n *\n * Requirements:\n *\n * - the caller should have the token role.\n *\n */\n function revokeTokenRole(\n uint256 tokenId,\n Roles role,\n address account\n ) public requireTokenRole(tokenId, Roles.Owner) {\n _revokeTokenRole(tokenId, role, account);\n }\n\n /**\n * @dev Returns `True` if a certain address has the collection role.\n */\n function hasCollectionRole(Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _collectionRolesVersion.current();\n\n return _collectionRoles[currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns `True` if a certain address has the token role.\n */\n function hasTokenRole(uint256 tokenId, Roles role, address account) public view returns (bool) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].indexes[account] != 0;\n }\n\n /**\n * @dev Returns an array of addresses that all have the collection role.\n */\n function getCollectionRoleMembers(Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _collectionRolesVersion.current();\n return _collectionRoles[currentVersion][role].members;\n }\n\n /**\n * @dev Returns an array of addresses that all have the same token role for a certain tokenId.\n */\n function getTokenRoleMembers(uint256 tokenId, Roles role) public view returns (address[] memory) {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n return _tokenRoles[tokenId][currentVersion][role].members;\n }\n\n /**\n * @dev Grants the collection role to an address.\n */\n function _grantCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _grantRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleGranted(role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the collection role of an address.\n */\n function _revokeCollectionRole(Roles role, address account) internal {\n uint256 currentVersion = _collectionRolesVersion.current();\n _revokeRole(_collectionRoles[currentVersion][role], account);\n emit CollectionRoleRevoked(role, account, msg.sender);\n }\n\n /**\n * @dev Grants the token role to an address.\n */\n function _grantTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _grantRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleGranted(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Revokes the token role of an address.\n */\n function _revokeTokenRole(uint256 tokenId, Roles role, address account) internal {\n uint256 currentVersion = _tokenRolesVersion[tokenId].current();\n _revokeRole(_tokenRoles[tokenId][currentVersion][role], account);\n emit TokenRoleRevoked(tokenId, role, account, msg.sender);\n }\n\n /**\n * @dev Grants a certain role to a certain address.\n */\n function _grantRole(Role storage role, address account) internal {\n if (role.indexes[account] == 0) {\n role.members.push(account);\n role.indexes[account] = role.members.length;\n }\n }\n\n /**\n * @dev Revokes a certain role from a certain address.\n */\n function _revokeRole(Role storage role, address account) internal {\n if (role.indexes[account] != 0) {\n uint256 index = role.indexes[account] - 1;\n uint256 lastIndex = role.members.length - 1;\n address lastAccount = role.members[lastIndex];\n\n role.members[index] = lastAccount;\n role.indexes[lastAccount] = index + 1;\n\n role.members.pop();\n delete role.indexes[account];\n }\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId.\n * Should only be used for burning tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId) internal {\n _tokenRolesVersion[tokenId].increment();\n }\n\n /**\n * @dev Clears all token roles for a certain tokenId and grants the owner role to a new address.\n * Should only be used for transferring tokens.\n */\n function _clearAllTokenRoles(uint256 tokenId, address newOwner) internal {\n _clearAllTokenRoles(tokenId);\n _grantTokenRole(tokenId, Roles.Owner, newOwner);\n }\n}\n"
+ },
+ "contracts/FleekERC721.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"./FleekAccessControl.sol\";\nimport \"./util/FleekStrings.sol\";\n\ncontract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl {\n using Strings for uint256;\n using Counters for Counters.Counter;\n using FleekStrings for FleekERC721.App;\n using FleekStrings for FleekERC721.AccessPoint;\n using FleekStrings for string;\n\n event NewBuild(uint256 indexed token, string indexed commitHash, address indexed triggeredBy);\n event NewTokenName(uint256 indexed token, string indexed name, address indexed triggeredBy);\n event NewTokenDescription(uint256 indexed token, string indexed description, address indexed triggeredBy);\n event NewTokenImage(uint256 indexed token, string indexed image, address indexed triggeredBy);\n event NewTokenExternalURL(uint256 indexed token, string indexed externalURL, address indexed triggeredBy);\n event NewTokenENS(uint256 indexed token, string indexed ENS, address indexed triggeredBy);\n\n event NewAccessPoint(string indexed apName, uint256 indexed tokenId, address indexed owner);\n event RemoveAccessPoint(string indexed apName, uint256 indexed tokenId, address indexed owner);\n event ChangeAccessPointScore(\n string indexed apName,\n uint256 indexed tokenId,\n uint256 score,\n address indexed triggeredBy\n );\n event ChangeAccessPointNameVerify(\n string indexed apName,\n uint256 tokenId,\n bool indexed verified,\n address indexed triggeredBy\n );\n event ChangeAccessPointContentVerify(\n string indexed apName,\n uint256 tokenId,\n bool indexed verified,\n address indexed triggeredBy\n );\n\n /**\n * The properties are stored as string to keep consistency with\n * other token contracts, we might consider changing for bytes32\n * in the future due to gas optimization.\n */\n struct App {\n string name; // Name of the site\n string description; // Description about the site\n string externalURL; // Site URL\n string ENS; // ENS ID\n uint256 currentBuild; // The current build number (Increments by one with each change, starts at zero)\n mapping(uint256 => Build) builds; // Mapping to build details for each build number\n string[] accessPoints; // List of app AccessPoint\n string logo;\n uint24 color; // Color of the nft\n }\n\n /**\n * The metadata that is stored for each build.\n */\n struct Build {\n string commitHash;\n string gitRepository;\n }\n\n /**\n * The stored data for each AccessPoint.\n */\n struct AccessPoint {\n uint256 tokenId;\n uint256 index;\n uint256 score;\n bool contentVerified;\n bool nameVerified;\n address owner;\n }\n\n Counters.Counter private _appIds;\n mapping(uint256 => App) private _apps;\n mapping(string => AccessPoint) private _accessPoints;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function initialize(string memory _name, string memory _symbol) public initializer {\n __ERC721_init(_name, _symbol);\n __FleekAccessControl_init();\n }\n\n /**\n * @dev Checks if the AccessPoint exists.\n */\n modifier requireAP(string memory apName) {\n require(_accessPoints[apName].owner != address(0), \"FleekERC721: invalid AP\");\n _;\n }\n\n /**\n * @dev Mints a token and returns a tokenId.\n *\n * If the `tokenId` has not been minted before, and the `to` address is not zero, emits a {Transfer} event.\n *\n * Requirements:\n *\n * - the caller must have ``collectionOwner``'s admin role.\n *\n */\n function mint(\n address to,\n string memory name,\n string memory description,\n string memory externalURL,\n string memory ENS,\n string memory commitHash,\n string memory gitRepository,\n string memory logo,\n uint24 color\n ) public payable requireCollectionRole(Roles.Owner) returns (uint256) {\n uint256 tokenId = _appIds.current();\n _mint(to, tokenId);\n _appIds.increment();\n\n App storage app = _apps[tokenId];\n app.name = name;\n app.description = description;\n app.externalURL = externalURL;\n app.ENS = ENS;\n app.logo = logo;\n app.color = color;\n\n // The mint interaction is considered to be the first build of the site. Updates from now on all increment the currentBuild by one and update the mapping.\n app.currentBuild = 0;\n app.builds[0] = Build(commitHash, gitRepository);\n app.accessPoints = new string[](0);\n\n return tokenId;\n }\n\n /**\n * @dev Returns the token metadata associated with the `tokenId`.\n *\n * Returns a based64 encoded string value of the URI.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n address owner = ownerOf(tokenId);\n App storage app = _apps[tokenId];\n\n return string(abi.encodePacked(_baseURI(), app.toString(owner).toBase64()));\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Upgradeable) returns (bool) {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Override of _beforeTokenTransfer of ERC721.\n * Here it needs to update the token controller roles for mint, burn and transfer.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId,\n uint256 batchSize\n ) internal virtual override {\n if (from != address(0) && to != address(0)) {\n // Transfer\n _clearAllTokenRoles(tokenId, to);\n } else if (from == address(0)) {\n // Mint\n _grantTokenRole(tokenId, Roles.Owner, to);\n } else if (to == address(0)) {\n // Burn\n _clearAllTokenRoles(tokenId);\n }\n super._beforeTokenTransfer(from, to, tokenId, batchSize);\n }\n\n /**\n * @dev A baseURI internal function implementation to be called in the `tokenURI` function.\n */\n function _baseURI() internal view virtual override returns (string memory) {\n return \"data:application/json;base64,\";\n }\n\n /**\n * @dev Updates the `externalURL` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenExternalURL} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenExternalURL(\n uint256 tokenId,\n string memory _tokenExternalURL\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].externalURL = _tokenExternalURL;\n emit NewTokenExternalURL(tokenId, _tokenExternalURL, msg.sender);\n }\n\n /**\n * @dev Updates the `ENS` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenENS} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenENS(\n uint256 tokenId,\n string memory _tokenENS\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].ENS = _tokenENS;\n emit NewTokenENS(tokenId, _tokenENS, msg.sender);\n }\n\n /**\n * @dev Updates the `name` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenName} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenName(\n uint256 tokenId,\n string memory _tokenName\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].name = _tokenName;\n emit NewTokenName(tokenId, _tokenName, msg.sender);\n }\n\n /**\n * @dev Updates the `description` metadata field of a minted `tokenId`.\n *\n * May emit a {NewTokenDescription} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenDescription(\n uint256 tokenId,\n string memory _tokenDescription\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].description = _tokenDescription;\n emit NewTokenDescription(tokenId, _tokenDescription, msg.sender);\n }\n\n /**\n * @dev Add a new AccessPoint register for an app token.\n * The AP name should be a DNS or ENS url and it should be unique.\n * Anyone can add an AP but it should requires a payment.\n *\n * May emit a {NewAccessPoint} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n *\n * IMPORTANT: The payment is not set yet\n */\n function addAccessPoint(uint256 tokenId, string memory apName) public payable {\n // require(msg.value == 0.1 ether, \"You need to pay at least 0.1 ETH\"); // TODO: define a minimum price\n _requireMinted(tokenId);\n require(_accessPoints[apName].owner == address(0), \"FleekERC721: AP already exists\");\n\n _accessPoints[apName] = AccessPoint(tokenId, _apps[tokenId].accessPoints.length, 0, false, false, msg.sender);\n _apps[tokenId].accessPoints.push(apName);\n\n emit NewAccessPoint(apName, tokenId, msg.sender);\n }\n\n /**\n * @dev Remove an AccessPoint registry for an app token.\n * It will also remove the AP from the app token APs list.\n *\n * May emit a {RemoveAccessPoint} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - must be called by the AP owner.\n */\n function removeAccessPoint(string memory apName) public requireAP(apName) {\n require(msg.sender == _accessPoints[apName].owner, \"FleekERC721: must be AP owner\");\n uint256 tokenId = _accessPoints[apName].tokenId;\n App storage _app = _apps[tokenId];\n\n // the index of the AP to remove\n uint256 indexToRemove = _accessPoints[apName].index;\n\n // the last item is reposited in the index to remove\n string memory lastAP = _app.accessPoints[_app.accessPoints.length - 1];\n _app.accessPoints[indexToRemove] = lastAP;\n _accessPoints[lastAP].index = indexToRemove;\n\n // remove the last item\n _app.accessPoints.pop();\n\n delete _accessPoints[apName];\n emit RemoveAccessPoint(apName, tokenId, msg.sender);\n }\n\n /**\n * @dev A view function to gether information about an AccessPoint.\n * It returns a JSON string representing the AccessPoint information.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function getAccessPointJSON(string memory apName) public view requireAP(apName) returns (string memory) {\n AccessPoint storage _ap = _accessPoints[apName];\n return _ap.toString();\n }\n\n /**\n * @dev A view function to check if a AccessPoint is verified.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function isAccessPointNameVerified(string memory apName) public view requireAP(apName) returns (bool) {\n return _accessPoints[apName].nameVerified;\n }\n\n /**\n * @dev Increases the score of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointScore} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function increaseAccessPointScore(string memory apName) public requireAP(apName) {\n _accessPoints[apName].score++;\n emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);\n }\n\n /**\n * @dev Decreases the score of a AccessPoint registry if is greater than 0.\n *\n * May emit a {ChangeAccessPointScore} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n *\n */\n function decreaseAccessPointScore(string memory apName) public requireAP(apName) {\n require(_accessPoints[apName].score > 0, \"FleekERC721: score cant be lower\");\n _accessPoints[apName].score--;\n emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);\n }\n\n /**\n * @dev Set the content verification of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointContentVerify} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - the sender must have the token controller role.\n *\n */\n function setAccessPointContentVerify(\n string memory apName,\n bool verified\n ) public requireAP(apName) requireTokenRole(_accessPoints[apName].tokenId, Roles.Controller) {\n _accessPoints[apName].contentVerified = verified;\n emit ChangeAccessPointContentVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);\n }\n\n /**\n * @dev Set the name verification of a AccessPoint registry.\n *\n * May emit a {ChangeAccessPointNameVerify} event.\n *\n * Requirements:\n *\n * - the AP must exist.\n * - the sender must have the token controller role.\n *\n */\n function setAccessPointNameVerify(\n string memory apName,\n bool verified\n ) public requireAP(apName) requireTokenRole(_accessPoints[apName].tokenId, Roles.Controller) {\n _accessPoints[apName].nameVerified = verified;\n emit ChangeAccessPointNameVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);\n }\n\n /**\n * @dev A view function to gether the list of mirrros for a given app.\n *\n * Requirements:\n * - the tokenId must be minted and valid.\n *\n */\n function appAccessPoints(uint256 tokenId) public view returns (string[] memory) {\n _requireMinted(tokenId);\n return _apps[tokenId].accessPoints;\n }\n\n /**\n * @dev Adds a new build to a minted `tokenId`'s builds mapping.\n *\n * May emit a {NewBuild} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenController` role.\n *\n */\n function setTokenBuild(\n uint256 tokenId,\n string memory _commitHash,\n string memory _gitRepository\n ) public virtual requireTokenRole(tokenId, Roles.Controller) {\n _requireMinted(tokenId);\n _apps[tokenId].builds[++_apps[tokenId].currentBuild] = Build(_commitHash, _gitRepository);\n emit NewBuild(tokenId, _commitHash, msg.sender);\n }\n\n /**\n * @dev Burns a previously minted `tokenId`.\n *\n * May emit a {Transfer} event.\n *\n * Requirements:\n *\n * - the tokenId must be minted and valid.\n * - the sender must have the `tokenOwner` role.\n *\n */\n function burn(uint256 tokenId) public virtual requireTokenRole(tokenId, Roles.Owner) {\n super._burn(tokenId);\n\n if (bytes(_apps[tokenId].externalURL).length != 0) {\n delete _apps[tokenId];\n }\n }\n}\n"
+ },
+ "contracts/util/FleekStrings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"../FleekERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\nimport \"./FleekSVG.sol\";\n\nlibrary FleekStrings {\n using Strings for uint256;\n using Strings for uint160;\n using FleekStrings for bool;\n using FleekStrings for uint24;\n using Strings for uint24;\n\n /**\n * @dev Converts a boolean value to a string.\n */\n function toString(bool _bool) internal pure returns (string memory) {\n return _bool ? \"true\" : \"false\";\n }\n\n /**\n * @dev Converts a string to a base64 string.\n */\n function toBase64(string memory str) internal pure returns (string memory) {\n return Base64.encode(bytes(str));\n }\n\n /**\n * @dev Converts FleekERC721.App to a JSON string.\n * It requires to receive owner address as a parameter.\n */\n function toString(FleekERC721.App storage app, address owner) internal view returns (string memory) {\n // prettier-ignore\n return string(abi.encodePacked(\n '{',\n '\"name\":\"', app.name, '\",',\n '\"description\":\"', app.description, '\",',\n '\"owner\":\"', uint160(owner).toHexString(20), '\",',\n '\"external_url\":\"', app.externalURL, '\",',\n '\"image\":\"', FleekSVG.generateBase64(app.name, app.ENS, app.logo, app.color.toColorString()), '\",',\n '\"attributes\": [',\n '{\"trait_type\": \"ENS\", \"value\":\"', app.ENS,'\"},',\n '{\"trait_type\": \"Commit Hash\", \"value\":\"', app.builds[app.currentBuild].commitHash,'\"},',\n '{\"trait_type\": \"Repository\", \"value\":\"', app.builds[app.currentBuild].gitRepository,'\"},',\n '{\"trait_type\": \"Version\", \"value\":\"', app.currentBuild.toString(),'\"},',\n '{\"trait_type\": \"Color\", \"value\":\"', app.color.toColorString(),'\"}',\n ']',\n '}'\n ));\n }\n\n /**\n * @dev Converts FleekERC721.AccessPoint to a JSON string.\n */\n function toString(FleekERC721.AccessPoint storage ap) internal view returns (string memory) {\n // prettier-ignore\n return string(abi.encodePacked(\n \"{\",\n '\"tokenId\":', ap.tokenId.toString(), \",\",\n '\"score\":', ap.score.toString(), \",\",\n '\"nameVerified\":', ap.nameVerified.toString(), \",\",\n '\"contentVerified\":', ap.contentVerified.toString(), \",\",\n '\"owner\":\"', uint160(ap.owner).toHexString(20), '\"',\n \"}\"\n ));\n }\n\n /**\n * @dev Converts bytes3 to a hex color string.\n */\n function toColorString(uint24 color) internal pure returns (string memory) {\n bytes memory hexBytes = bytes(color.toHexString(3));\n bytes memory hexColor = new bytes(7);\n hexColor[0] = \"#\";\n for (uint256 i = 1; i < 7; i++) {\n hexColor[i] = hexBytes[i + 1];\n }\n return string(hexColor);\n }\n}\n"
+ },
+ "contracts/util/FleekSVG.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.7;\n\nimport \"../FleekERC721.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"@openzeppelin/contracts/utils/Base64.sol\";\n\nlibrary FleekSVG {\n /**\n * @dev Generates a SVG image.\n */\n function generateBase64(\n string memory name,\n string memory ENS,\n string memory logo,\n string memory color\n ) public pure returns (string memory) {\n return (\n string(\n abi.encodePacked(\n \"data:image/svg+xml;base64,\",\n Base64.encode(\n abi.encodePacked(\n '',\n // background\n '',\n '',\n // shadows\n '',\n '',\n // diskette fill\n '',\n '',\n // arrows\n '',\n '',\n '',\n // body\n '',\n // slider\n '',\n // fleek logo\n '',\n // text\n '',\n name,\n '',\n ENS,\n \"\",\n // logo\n '',\n // defs\n \"\",\n // shadow\n '',\n // bg\n '',\n '',\n // fill gradient\n '',\n // color\n '',\n // end defs\n \"\",\n \"\"\n )\n )\n )\n )\n );\n }\n}\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 200,
+ "details": {
+ "yul": true
+ }
+ },
+ "viaIR": true,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "storageLayout"
+ ],
+ "": ["ast"]
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
index 732dffa..639ebea 100644
--- a/package.json
+++ b/package.json
@@ -40,6 +40,7 @@
"@openzeppelin/hardhat-upgrades": "^1.22.0",
"@types/mocha": "^10.0.1",
"chai": "^4.3.6",
+ "colorthief": "^2.3.2",
"dotenv": "^16.0.2",
"ethers": "^5.7.2",
"hardhat": "^2.11.2",
@@ -50,6 +51,7 @@
"pinst": "^3.0.0",
"prettier": "^2.7.1",
"prettier-plugin-solidity": "^1.0.0",
+ "sharp": "^0.31.3",
"solidity-coverage": "^0.8.2",
"ts-node": "^10.9.1",
"typescript": "^4.9.3",
diff --git a/scripts/deploy.js b/scripts/deploy.js
index 5ccb143..d03c834 100644
--- a/scripts/deploy.js
+++ b/scripts/deploy.js
@@ -1,15 +1,55 @@
-const { deployStore } = require('./utils/deploy-store');
+const {
+ deployStore,
+ getCurrentAddressIfSameBytecode,
+} = require('./utils/deploy-store');
const { getProxyAddress, proxyStore } = require('./utils/proxy-store');
-const CONTRACT_NAME = 'FleekERC721';
-const NETWORK = hre.network.name;
+// --- Inputs ---
const ARGUMENTS = [
'FleekNFAs', // Collection name
'FLKNFA', // Collection symbol
];
-const deploy = async () => {
- const Contract = await ethers.getContractFactory(CONTRACT_NAME);
+// --- Script Settings ---
+const CONTRACT_NAME = 'FleekERC721';
+const NETWORK = hre.network.name;
+const DEFAULT_PROXY_SETTINGS = {
+ unsafeAllow: ['external-library-linking'],
+};
+const LIBRARIES_TO_DEPLOY = ['FleekSVG'];
+
+const libraryDeployment = async () => {
+ console.log('Deploying Libraries...');
+ const libraries = {};
+
+ for (const lib of LIBRARIES_TO_DEPLOY) {
+ const libAddress = await getCurrentAddressIfSameBytecode(lib);
+ if (libAddress) {
+ console.log(`Library "${lib}" already deployed at ${libAddress}`);
+ libraries[lib] = libAddress;
+ continue;
+ }
+ const libContract = await hre.ethers.getContractFactory(lib);
+ const libInstance = await libContract.deploy();
+ await libInstance.deployed();
+ deployStore(NETWORK, lib, libInstance);
+ console.log(`Library "${lib}" deployed at ${libInstance.address}`);
+ libraries[lib] = libInstance.address;
+ }
+
+ return libraries;
+};
+
+const main = async () => {
+ console.log(':: Starting Deployment ::');
+ console.log('Network:', NETWORK);
+ console.log('Contract:', CONTRACT_NAME);
+
+ const libraries = await libraryDeployment();
+
+ const Contract = await ethers.getContractFactory(CONTRACT_NAME, {
+ libraries,
+ });
const proxyAddress = await getProxyAddress(CONTRACT_NAME, NETWORK);
let deployResult;
@@ -17,7 +57,11 @@ const deploy = async () => {
try {
if (!proxyAddress) throw new Error('No proxy address found');
console.log(`Trying to upgrade proxy contract at: "${proxyAddress}"`);
- deployResult = await upgrades.upgradeProxy(proxyAddress, Contract);
+ deployResult = await upgrades.upgradeProxy(
+ proxyAddress,
+ Contract,
+ DEFAULT_PROXY_SETTINGS
+ );
console.log(
`Contract ${CONTRACT_NAME} upgraded at "${deployResult.address}" by account "${deployResult.signer.address}"`
);
@@ -29,7 +73,11 @@ const deploy = async () => {
) {
console.log(`Failed to upgrade proxy contract: "${e.message?.trim()}"`);
console.log('Creating new proxy contract...');
- deployResult = await upgrades.deployProxy(Contract, ARGUMENTS);
+ deployResult = await upgrades.deployProxy(
+ Contract,
+ ARGUMENTS,
+ DEFAULT_PROXY_SETTINGS
+ );
await deployResult.deployed();
await proxyStore(CONTRACT_NAME, deployResult.address, hre.network.name);
console.log(
@@ -45,9 +93,8 @@ const deploy = async () => {
console.error('Could not write deploy files', e);
}
}
+
+ return deployResult;
};
-console.log(':: Starting Deployment ::');
-console.log('Network:', NETWORK);
-console.log('Contract:', CONTRACT_NAME);
-deploy();
+main();
diff --git a/scripts/mint.js b/scripts/mint.js
index 5b0c5c7..3669809 100644
--- a/scripts/mint.js
+++ b/scripts/mint.js
@@ -1,20 +1,96 @@
// npx hardhat run scripts/mint.js --network mumbai
const { getContract } = require('./util');
+const { getSVGBase64, getSVGColor } = require('./utils/read-svg');
+const path = require('path');
-// TODO: make this arguments
-const params = [
- '0x7ED735b7095C05d78dF169F991f2b7f1A1F1A049', // to
- 'Fleek App', // name
- 'Description', // description
- 'https://fleek.co/', // external url
- 'fleek.eth', // ens
- '6ea6ad16c46ae85faced7e50555ff7368422f57', // commit hash
- 'https://github.com/org/repo', // repo
-];
+const DEFAULT_MINTS = {
+ html5: [
+ 'HTML5 App', // name
+ 'Description for HTML5 app', // description
+ 'https://html.com/', // external url
+ 'html.eth', // ens
+ '6ea6ad16c46ae85faced7e50555ff7368422f57', // commit hash
+ 'https://github.com/org/repo', // repo
+ path.resolve(__dirname, '../assets/html.svg'), // svg
+ ],
+ psych: [
+ 'Psychedelic App', // name
+ 'A decentralized product studio building web3 products for an omni-chain world', // description
+ 'https://psychedelic.com/', // external url
+ 'psychedelic.eth', // ens
+ '6ea6ad16c46ae85faced7e50555ff7368422f57', // commit hash
+ 'https://github.com/org/repo', // repo
+ path.resolve(__dirname, '../assets/psych.svg'), // svg
+ ],
+ fleek: [
+ 'Fleek App', // name
+ 'The easiest way to build and deploy scalable web3 apps. Fleek is an open source, blockchain agnostic, extensible web3 development platform', // description
+ 'https://fleek.xyz/', // external url
+ 'fleek.eth', // ens
+ '6ea6ad16c46ae85faced7e50555ff7368422f57', // commit hash
+ 'https://github.com/org/repo', // repo
+ path.resolve(__dirname, '../assets/fleek.svg'), // svg
+ ],
+ dydx: [
+ 'dydx', // name
+ 'Trade Perpetual Contracts with no fees*, deep liquidity, and up to 20× more Buying Power. Deposit just $10 to', // description
+ 'https://dydx.exchange/', // external url
+ 'dydx.eth', // ens
+ '6ea6ad16c46ae85faced7e50555ff7368422f57', // commit hash
+ 'https://github.com/org/repo', // repo
+ path.resolve(__dirname, '../assets/dydx.svg'), // svg
+ ],
+ aave: [
+ 'aave', // name
+ 'Earn interest, borrow assets, and build applications', // description
+ 'https://aave.com/', // external url
+ 'aave.eth', // ens
+ '6ea6ad16c46ae85faced7e50555ff7368422f57', // commit hash
+ 'https://github.com/org/repo', // repo
+ path.resolve(__dirname, '../assets/aave.svg'), // svg
+ ],
+ uniswap: [
+ 'Uniswap', // name
+ 'Swap, earn, and build on the leading decentralized crypto trading protocol', // description
+ 'https://uniswap.org/', // external url
+ 'uniswap.eth', // ens
+ '6ea6ad16c46ae85faced7e50555ff7368422f57', // commit hash
+ 'https://github.com/org/repo', // repo
+ path.resolve(__dirname, '../assets/uniswap.svg'), // svg
+ ],
+ yearn: [
+ 'Yearn', // name
+ 'Yearn is a decentralized suite of products helping individuals, DAOs, and other protocols earn yield on their digital assets.', // description
+ 'https://yearn.finance/', // external url
+ 'yearn.eth', // ens
+ '6ea6ad16c46ae85faced7e50555ff7368422f57', // commit hash
+ 'https://github.com/org/repo', // repo
+ path.resolve(__dirname, '../assets/yearn.svg'), // svg
+ ],
+ pancake: [
+ 'PancakeSwap', // name
+ 'Trade, earn, and win crypto on the most popular decentralized platform in the galaxy.', // description
+ 'https://pancakeswap.finance/', // external url
+ 'pancake.eth', // ens
+ '6ea6ad16c46ae85faced7e50555ff7368422f57', // commit hash
+ 'https://github.com/org/repo', // repo
+ path.resolve(__dirname, '../assets/pancakeswap.svg'), // svg
+ ],
+};
+
+const params = DEFAULT_MINTS.fleek;
+const mintTo = '0x7ED735b7095C05d78dF169F991f2b7f1A1F1A049';
(async () => {
const contract = await getContract('FleekERC721');
+ params.unshift(mintTo);
+ const svgPath = params.pop();
+ console.log('SVG Path: ', svgPath);
+ params.push(await getSVGBase64(svgPath));
+ console.log('SVG length: ', params[params.length - 1].length);
+ params.push(await getSVGColor(svgPath));
+
const transaction = await contract.mint(...params);
console.log('Response: ', transaction);
diff --git a/scripts/utils/deploy-store.js b/scripts/utils/deploy-store.js
index 5d5009d..6b58ec9 100644
--- a/scripts/utils/deploy-store.js
+++ b/scripts/utils/deploy-store.js
@@ -1,4 +1,5 @@
const { writeFile } = require('./file');
+const { existsSync } = require('fs');
const path = require('path');
const getDeployFilePath = (network, contractName) => {
@@ -8,9 +9,7 @@ const getDeployFilePath = (network, contractName) => {
);
};
-module.exports.deployStore = async (network, contractName, contract) => {
- const filePath = getDeployFilePath(network, contractName);
-
+const getBuildData = async (contractName) => {
const buildArtifact = await hre.artifacts.readArtifact(contractName);
const {
id: buildId,
@@ -23,16 +22,32 @@ module.exports.deployStore = async (network, contractName, contract) => {
const contractOutput =
solcOutput.contracts[buildArtifact.sourceName][contractName];
+ return {
+ buildId,
+ abi: contractOutput.abi,
+ bytecode: buildArtifact.bytecode,
+ metadata: contractOutput.metadata,
+ storageLayout: contractOutput.storageLayout,
+ solcInput,
+ };
+};
+
+const deployStore = async (network, contractName, contract) => {
+ const filePath = getDeployFilePath(network, contractName);
+
+ const { buildId, solcInput, abi, bytecode, metadata, storageLayout } =
+ await getBuildData(contractName);
+
const data = {
timestamp: new Date().toLocaleString('en-US'),
address: contract.address,
transactionHash: contract.deployTransaction.hash,
args: contract.deployTransaction.args,
gasPrice: contract.deployTransaction.gasPrice.toNumber(),
- abi: contractOutput.abi,
- bytecode: buildArtifact.bytecode,
- metadata: contractOutput.metadata,
- storageLayout: contractOutput.storageLayout,
+ abi,
+ bytecode,
+ metadata,
+ storageLayout,
};
try {
@@ -47,3 +62,23 @@ module.exports.deployStore = async (network, contractName, contract) => {
throw `Could not write file: ${err}`;
}
};
+
+const getCurrentAddressIfSameBytecode = async (contractName) => {
+ const { bytecode } = await getBuildData(contractName);
+
+ if (existsSync(getDeployFilePath(hre.network.name, contractName))) {
+ const deployData = require(getDeployFilePath(
+ hre.network.name,
+ contractName
+ ));
+ return deployData.bytecode === bytecode ? deployData.address : null;
+ }
+
+ return null;
+};
+
+module.exports = {
+ getBuildData,
+ deployStore,
+ getCurrentAddressIfSameBytecode,
+};
diff --git a/scripts/utils/read-svg.js b/scripts/utils/read-svg.js
new file mode 100644
index 0000000..e4c624c
--- /dev/null
+++ b/scripts/utils/read-svg.js
@@ -0,0 +1,16 @@
+const { getColor } = require('colorthief');
+const sharp = require('sharp');
+const fs = require('fs').promises;
+
+module.exports.getSVGColor = async (path) => {
+ const png = (await sharp(path).png().toBuffer()).toString('base64');
+ const colorValues = await getColor(`data:image/png;base64,${png}`);
+ return colorValues;
+};
+
+module.exports.getSVGBase64 = async (path) => {
+ const svg = Buffer.from(
+ await fs.readFile(path, { encoding: 'utf-8' })
+ ).toString('base64');
+ return `data:image/svg+xml;base64,${svg}`;
+};
diff --git a/test/FleekERC721.ts b/test/FleekERC721.ts
index 5c2646f..fac69c5 100644
--- a/test/FleekERC721.ts
+++ b/test/FleekERC721.ts
@@ -11,11 +11,12 @@ describe('FleekERC721', () => {
const MINT_PARAMS = Object.freeze({
name: 'Fleek Test App',
description: 'Fleek Test App Description',
- image: 'https://fleek.co/image.png',
ens: 'fleek.eth',
externalUrl: 'https://fleek.co',
commitHash: 'b72e47171746b6a9e29b801af9cb655ecf4d665c',
gitRepository: 'https://github.com/fleekxyz/non-fungible-apps',
+ logo: 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjI1MDAiIHdpZHRoPSIyMTgzIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjQgMTQxLjUzMTk5OTk5OTk5OTk4Ij48cGF0aCBkPSJNMTAuMzgzIDEyNi44OTRMMCAwbDEyNCAuMjU1LTEwLjk3OSAxMjYuNjM5LTUwLjU1MyAxNC42Mzh6IiBmaWxsPSIjZTM0ZjI2Ii8+PHBhdGggZD0iTTYyLjQ2OCAxMjkuMjc3VjEyLjA4NWw1MS4wNjQuMTctOS4xMDYgMTA0Ljg1MXoiIGZpbGw9IiNlZjY1MmEiLz48cGF0aCBkPSJNOTkuNDkgNDEuMzYybDEuNDQ2LTE1LjQ5SDIyLjM4M2w0LjM0IDQ3LjQ5aDU0LjIxM0w3OC44MSA5My42MTdsLTE3LjM2MiA0LjY4LTE3LjYxNy01LjEwNi0uOTM2LTEyLjA4NUgyNy4zMTlsMi4xMjggMjQuNjgxIDMyIDguOTM2IDMyLjI1NS04LjkzNiA0LjM0LTQ4LjE3SDQxLjEwN0wzOS40OSA0MS4zNjJ6IiBmaWxsPSIjZmZmIi8+PC9zdmc+',
+ color: 0xe34f26,
});
const COLLECTION_PARAMS = Object.freeze({
@@ -27,11 +28,21 @@ describe('FleekERC721', () => {
// Contracts are deployed using the first signer/account by default
const [owner, otherAccount] = await ethers.getSigners();
- const Contract = await ethers.getContractFactory('FleekERC721');
- const contract = await upgrades.deployProxy(Contract, [
- COLLECTION_PARAMS.name,
- COLLECTION_PARAMS.symbol,
- ]);
+ const libraries = {
+ FleekSVG: (await (await ethers.getContractFactory('FleekSVG')).deploy())
+ .address,
+ };
+
+ const Contract = await ethers.getContractFactory('FleekERC721', {
+ libraries,
+ });
+ const contract = await upgrades.deployProxy(
+ Contract,
+ [COLLECTION_PARAMS.name, COLLECTION_PARAMS.symbol],
+ {
+ unsafeAllow: ['external-library-linking'],
+ }
+ );
return { owner, otherAccount, contract };
};
@@ -62,7 +73,9 @@ describe('FleekERC721', () => {
MINT_PARAMS.externalUrl,
MINT_PARAMS.ens,
MINT_PARAMS.commitHash,
- MINT_PARAMS.gitRepository
+ MINT_PARAMS.gitRepository,
+ MINT_PARAMS.logo,
+ MINT_PARAMS.color
);
expect(response.value).to.be.instanceOf(ethers.BigNumber);
@@ -82,7 +95,9 @@ describe('FleekERC721', () => {
MINT_PARAMS.externalUrl,
MINT_PARAMS.ens,
MINT_PARAMS.commitHash,
- MINT_PARAMS.gitRepository
+ MINT_PARAMS.gitRepository,
+ MINT_PARAMS.logo,
+ MINT_PARAMS.color
)
).to.be.revertedWith('FleekAccessControl: must have collection role');
});
@@ -99,7 +114,9 @@ describe('FleekERC721', () => {
MINT_PARAMS.externalUrl,
MINT_PARAMS.ens,
MINT_PARAMS.commitHash,
- MINT_PARAMS.gitRepository
+ MINT_PARAMS.gitRepository,
+ MINT_PARAMS.logo,
+ MINT_PARAMS.color
);
const tokenId = response.value.toNumber();
@@ -132,7 +149,9 @@ describe('FleekERC721', () => {
MINT_PARAMS.externalUrl,
MINT_PARAMS.ens,
MINT_PARAMS.commitHash,
- MINT_PARAMS.gitRepository
+ MINT_PARAMS.gitRepository,
+ MINT_PARAMS.logo,
+ MINT_PARAMS.color
);
tokenId = response.value.toNumber();
@@ -149,35 +168,12 @@ describe('FleekERC721', () => {
const parsedURI = JSON.parse(tokenURIDecoded);
- const imageDecoded = Buffer.from(
- parsedURI.image.replace('data:application/json;base64,', ''),
- 'base64'
- ).toString('ascii');
-
- parsedURI.image = imageDecoded;
-
expect(parsedURI).to.eql({
owner: fixture.owner.address.toLowerCase(),
name: MINT_PARAMS.name,
description: MINT_PARAMS.description,
image:
- '' +
- '' +
- '' +
- '' +
- '' +
- '' +
- '' +
- 'Fleek NFAs' +
- '' +
- '' +
- '' +
- MINT_PARAMS.name +
- '' +
- MINT_PARAMS.ens +
- '' +
- '' +
- '',
+ 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTA2NSIgaGVpZ2h0PSIxMDY1IiB2aWV3Qm94PSIwIDAgMTA2NSAxMDY1IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48c3R5bGUgdHlwZT0idGV4dC9jc3MiPkBpbXBvcnQgdXJsKCJodHRwczovL2ZvbnRzLmdvb2dsZWFwaXMuY29tL2NzczI/ZmFtaWx5PUludGVyOndnaHRANTAwOzYwMCIpOzwvc3R5bGU+PHJlY3Qgd2lkdGg9IjEwNjUiIGhlaWdodD0iMTA2NSIgZmlsbD0idXJsKCNiYWNrZ3JvdW5kKSIgLz48cmVjdCBvcGFjaXR5PSIwLjIiIHdpZHRoPSIxMDY1IiBoZWlnaHQ9IjEwNjUiIGZpbGw9InVybCgjYmFja2dyb3VuZC1yYWRpYWwpIiAvPjxnIGZpbHRlcj0idXJsKCNkaXNrZXR0ZS1zaGFkb3cpIj48cGF0aCBkPSJNODU3LjIzMSAyNzkuNzEyTDkwMi4yNCAyODYuNjc1QzkxMC41NDcgMjg3Ljk2IDkxNy45MTUgMjkyLjcyMSA5MjIuNSAyOTkuNzY4TDkzOC44OTQgMzI0Ljk2NEM5NDIuMjQ5IDMzMC4xMiA5NDMuMzExIDMzNi40MzcgOTQxLjgyNyAzNDIuNDA2TDkzNy43OTggMzU4LjYxNUw5MjQuMDQ5IDM1Ni42NUw5MTkuNDE2IDM3NC4wODRMOTM0LjA2OCAzNzYuMjRMNzkxLjk0NyA5MjIuMTUyQzc4OC4xMDkgOTM2Ljg5NiA3NzMuNjk0IDk0Ni4zMDggNzU4LjY1MSA5NDMuODkzTDE3OS42MzYgODUwLjkyOEMxNjIuMzE4IDg0OC4xNDcgMTUxLjIxNSA4MzAuOTg3IDE1NS43NzYgODE0LjA1MUwxNjAuNDc4IDc5Ni41OUw3MDQuMzE1IDg3OS41NzRMODU3LjIzMSAyNzkuNzEyWiIgZmlsbD0iIzA1MDUwNSIgLz48L2c+PHBhdGggZD0iTTg0MC4yMzEgMjQwLjcxMkw4ODUuMjQgMjQ3LjY3NUM4OTMuNTQ3IDI0OC45NjEgOTAwLjkxNSAyNTMuNzIyIDkwNS41IDI2MC43NjhMOTIxLjg5NCAyODUuOTY1QzkyNS4yNDkgMjkxLjEyIDkyNi4zMTEgMjk3LjQzNyA5MjQuODI3IDMwMy40MDZMOTIwLjc5OCAzMTkuNjE2TDkwNy4wNDkgMzE3LjY1TDkwMi40MTYgMzM1LjA4NEw5MTcuMDY4IDMzNy4yNDFMNzc0Ljk0NyA4ODMuMTUyQzc3MS4xMDkgODk3Ljg5NiA3NTYuNjk0IDkwNy4zMDggNzQxLjY1MSA5MDQuODkzTDE2Mi42MzYgODExLjkyOEMxNDUuMzE4IDgwOS4xNDcgMTM0LjIxNSA3OTEuOTg3IDEzOC43NzYgNzc1LjA1MUwxNDMuNDc4IDc1Ny41OUw2ODcuMzE1IDg0MC41NzRMODQwLjIzMSAyNDAuNzEyWiIgZmlsbD0idXJsKCNtYWluKSIgLz48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTMxOS44NDcgMTYxLjUwMkMzMTAuMzU2IDE2MC4wMDcgMzAwLjY3NCAxNjYuMzI2IDI5OC4yMjEgMTc1LjYxNkwxMzguNzI0IDc3OS43NThDMTM2LjI3MSA3ODkuMDQ4IDE0MS45NzcgNzk3Ljc5IDE1MS40NjggNzk5LjI4NUw3NDAuMDYxIDg5MS45NzNDNzQ5LjU1MyA4OTMuNDY3IDc1OS4yMzUgODg3LjE0OCA3NjEuNjg3IDg3Ny44NThMOTAyLjQwNSAzNDQuODU0TDg4OS4xNTggMzQyLjc2OEw4OTguODcyIDMwNS45NzJMOTEyLjExOSAzMDguMDU5TDkxMy43MzMgMzAxLjk0NkM5MTQuODM3IDI5Ny43NjIgOTE0LjMwOSAyOTMuNDc2IDkxMi4yNTEgMjg5LjkyN0w4OTMuNDg0IDI1Ny41NjlDODkxLjE1MyAyNTMuNTQ5IDg4Ny4wNjMgMjUwLjgyMyA4ODIuMjIxIDI1MC4wNjFMODI4LjIwNSAyNDEuNTU0QzgyMi4yMjQgMjQwLjYxMyA4MTUuODY5IDI0Mi43ODMgODExLjQyNyAyNDcuMjg0TDgwNS42ODYgMjUzLjEwM0M4MDQuMjA1IDI1NC42MDMgODAyLjA4NyAyNTUuMzI2IDgwMC4wOTMgMjU1LjAxM0w3ODMuNjExIDI1Mi40MTdMNzM0LjMgNDM5LjE5NkM3MzEuNDM5IDQ1MC4wMzUgNzIwLjE0MyA0NTcuNDA3IDcwOS4wNyA0NTUuNjYzTDMyOC44NDcgMzk1Ljc4OEMzMTcuNzc0IDM5NC4wNDUgMzExLjExNyAzODMuODQ1IDMxMy45NzggMzczLjAwN0wzNjYuNTI4IDE3My45NjJMMzY2LjUzMyAxNzMuOTQxQzM2Ny4yMzQgMTcxLjI0IDM2NS41NzIgMTY4LjcwMiAzNjIuODEgMTY4LjI2N0wzMTkuODQ3IDE2MS41MDJaTTM2OS4zOTIgMTc0LjQxNEwzNjguNjUyIDE3Ny4yMTdMMzE2Ljg0MyAzNzMuNDU4QzMxNC4zOSAzODIuNzQ4IDMyMC4wOTYgMzkxLjQ5IDMyOS41ODcgMzkyLjk4NUw3MDkuODEgNDUyLjg2QzcxOS4zMDEgNDU0LjM1NCA3MjguOTgzIDQ0OC4wMzUgNzMxLjQzNiA0MzguNzQ1TDc4MC43NDcgMjUxLjk2Nkw3ODMuMjQ1IDI0Mi41MDRMNzgzLjk4NSAyMzkuNzAxTDM2OS4zOTIgMTc0LjQxNFoiIGZpbGw9IiMxMzEzMTYiIC8+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0idXJsKCNtYWluKSIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGQ9Ik0zMTkuODQ3IDE2MS41MDJDMzEwLjM1NiAxNjAuMDA3IDMwMC42NzQgMTY2LjMyNiAyOTguMjIxIDE3NS42MTZMMTM4LjcyNCA3NzkuNzU4QzEzNi4yNzEgNzg5LjA0OCAxNDEuOTc3IDc5Ny43OSAxNTEuNDY4IDc5OS4yODVMNzQwLjA2MSA4OTEuOTczQzc0OS41NTMgODkzLjQ2NyA3NTkuMjM1IDg4Ny4xNDggNzYxLjY4NyA4NzcuODU4TDkwMi40MDUgMzQ0Ljg1NEw4ODkuMTU4IDM0Mi43NjhMODk4Ljg3MiAzMDUuOTcyTDkxMi4xMTkgMzA4LjA1OUw5MTMuNzMzIDMwMS45NDZDOTE0LjgzNyAyOTcuNzYyIDkxNC4zMDkgMjkzLjQ3NiA5MTIuMjUxIDI4OS45MjdMODkzLjQ4NCAyNTcuNTY5Qzg5MS4xNTMgMjUzLjU0OSA4ODcuMDYzIDI1MC44MjMgODgyLjIyMSAyNTAuMDYxTDgyOC4yMDUgMjQxLjU1NEM4MjIuMjI0IDI0MC42MTMgODE1Ljg2OSAyNDIuNzgzIDgxMS40MjcgMjQ3LjI4NEw4MDUuNjg2IDI1My4xMDNDODA0LjIwNSAyNTQuNjAzIDgwMi4wODcgMjU1LjMyNiA4MDAuMDkzIDI1NS4wMTNMNzgzLjYxMSAyNTIuNDE3TDczNC4zIDQzOS4xOTZDNzMxLjQzOSA0NTAuMDM1IDcyMC4xNDMgNDU3LjQwNyA3MDkuMDcgNDU1LjY2M0wzMjguODQ3IDM5NS43ODhDMzE3Ljc3NCAzOTQuMDQ1IDMxMS4xMTcgMzgzLjg0NSAzMTMuOTc4IDM3My4wMDdMMzY2LjUyOCAxNzMuOTYyTDM2Ni41MzMgMTczLjk0MUMzNjcuMjM0IDE3MS4yNCAzNjUuNTcyIDE2OC43MDIgMzYyLjgxIDE2OC4yNjdMMzE5Ljg0NyAxNjEuNTAyWk0zNjkuMzkyIDE3NC40MTRMMzY4LjY1MiAxNzcuMjE3TDMxNi44NDMgMzczLjQ1OEMzMTQuMzkgMzgyLjc0OCAzMjAuMDk2IDM5MS40OSAzMjkuNTg3IDM5Mi45ODVMNzA5LjgxIDQ1Mi44NkM3MTkuMzAxIDQ1NC4zNTQgNzI4Ljk4MyA0NDguMDM1IDczMS40MzYgNDM4Ljc0NUw3ODAuNzQ3IDI1MS45NjZMNzgzLjI0NSAyNDIuNTA0TDc4My45ODUgMjM5LjcwMUwzNjkuMzkyIDE3NC40MTRaIiBmaWxsPSJ1cmwoI2Rpc2tldHRlLWdyYWRpZW50KSIgZmlsbC1vcGFjaXR5PSIwLjIiIC8+PHBhdGggZD0iTTMzNS4zOCAyMDguMTEzQzMzNS45MjIgMjA4LjE5OCAzMzYuNDE3IDIwNy42ODYgMzM2LjI4MyAyMDcuMTc5TDMzMC4zOSAxODQuNzk1QzMzMC4yNDkgMTg0LjI2MSAzMjkuNTI5IDE4NC4xNDggMzI5LjEyOSAxODQuNTk3TDMxMi4zNTggMjAzLjQxMUMzMTEuOTc4IDIwMy44MzggMzEyLjE3NCAyMDQuNDU4IDMxMi43MTYgMjA0LjU0NEwzMTcuOTYyIDIwNS4zN0MzMTguMzU3IDIwNS40MzIgMzE4LjU5NSAyMDUuNzk2IDMxOC40OTMgMjA2LjE4M0wzMTQuNyAyMjAuNTUxQzMxNC41OTcgMjIwLjkzOCAzMTQuODM1IDIyMS4zMDIgMzE1LjIzMSAyMjEuMzY0TDMyNC41MzkgMjIyLjgzQzMyNC45MzUgMjIyLjg5MyAzMjUuMzM4IDIyMi42MjkgMzI1LjQ0IDIyMi4yNDJMMzI5LjIzMyAyMDcuODc1QzMyOS4zMzYgMjA3LjQ4OCAzMjkuNzM5IDIwNy4yMjQgMzMwLjEzNSAyMDcuMjg2TDMzNS4zOCAyMDguMTEzWiIgZmlsbD0idXJsKCNtYWluKSIgLz48cGF0aCBkPSJNMzE5LjI4MiAyNjkuMDg3QzMxOS44MjQgMjY5LjE3MyAzMjAuMzE5IDI2OC42NjEgMzIwLjE4NiAyNjguMTU0TDMxNC4yOTIgMjQ1Ljc3QzMxNC4xNTEgMjQ1LjIzNiAzMTMuNDMxIDI0NS4xMjMgMzEzLjAzMSAyNDUuNTcyTDI5Ni4yNjEgMjY0LjM4NkMyOTUuODggMjY0LjgxMiAyOTYuMDc2IDI2NS40MzMgMjk2LjYxOCAyNjUuNTE4TDMwMS44NjQgMjY2LjM0NEMzMDIuMjU5IDI2Ni40MDcgMzAyLjQ5NyAyNjYuNzcxIDMwMi4zOTUgMjY3LjE1OEwyOTguNjAyIDI4MS41MjZDMjk4LjUgMjgxLjkxMyAyOTguNzM3IDI4Mi4yNzcgMjk5LjEzMyAyODIuMzM5TDMwOC40NDEgMjgzLjgwNUMzMDguODM3IDI4My44NjcgMzA5LjI0IDI4My42MDQgMzA5LjM0MyAyODMuMjE3TDMxMy4xMzYgMjY4Ljg0OUMzMTMuMjM4IDI2OC40NjIgMzEzLjY0MSAyNjguMTk5IDMxNC4wMzcgMjY4LjI2MUwzMTkuMjgyIDI2OS4wODdaIiBmaWxsPSJibGFjayIgZmlsbC1vcGFjaXR5PSIwLjUiIC8+PHBhdGggZD0iTTMwMy4xODQgMzMwLjA2MkMzMDMuNzI2IDMzMC4xNDggMzA0LjIyMSAzMjkuNjM2IDMwNC4wODggMzI5LjEyOEwyOTguMTk0IDMwNi43NDVDMjk4LjA1MyAzMDYuMjExIDI5Ny4zMzMgMzA2LjA5OCAyOTYuOTMzIDMwNi41NDdMMjgwLjE2MyAzMjUuMzYxQzI3OS43ODIgMzI1Ljc4NyAyNzkuOTc5IDMyNi40MDggMjgwLjUyIDMyNi40OTNMMjg1Ljc2NiAzMjcuMzE5QzI4Ni4xNjEgMzI3LjM4MiAyODYuMzk5IDMyNy43NDYgMjg2LjI5NyAzMjguMTMzTDI4Mi41MDQgMzQyLjUwMUMyODIuNDAyIDM0Mi44ODggMjgyLjYzOSAzNDMuMjUyIDI4My4wMzUgMzQzLjMxNEwyOTIuMzQ0IDM0NC43OEMyOTIuNzM5IDM0NC44NDIgMjkzLjE0MiAzNDQuNTc5IDI5My4yNDUgMzQ0LjE5MkwyOTcuMDM4IDMyOS44MjRDMjk3LjE0IDMyOS40MzcgMjk3LjU0MyAzMjkuMTc0IDI5Ny45MzkgMzI5LjIzNkwzMDMuMTg0IDMzMC4wNjJaIiBmaWxsPSJibGFjayIgZmlsbC1vcGFjaXR5PSIwLjUiIC8+PHBhdGggc3Ryb2tlPSJ1cmwoI21haW4pIiBzdHJva2Utd2lkdGg9IjYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTTI5MC4xMDkgNDYzLjQxOEMyOTIuMzU4IDQ1NC45MDIgMzAxLjIzMyA0NDkuMTEgMzA5LjkzMyA0NTAuNDhMNzcxLjA3IDUyMy4wOTZDNzc5Ljc3IDUyNC40NjcgNzg1IDUzMi40OCA3ODIuNzUyIDU0MC45OTZMNjkyLjA4NiA4ODQuNDE4TDE5OS40NDMgODA2Ljg0TDI5MC4xMDkgNDYzLjQxOFoiIGZpbGw9ImJsYWNrIiBmaWxsLW9wYWNpdHk9IjAuMTQiIC8+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0idXJsKCNtYWluKSIgc3Ryb2tlLXdpZHRoPSI2IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGQ9Ik03ODcuNTg5IDIzNy4zNDlMNDYwLjM1NCAxODUuODE4TDQwNi4zMjUgMzkwLjQ2OUM0MDMuODcyIDM5OS43NTkgNDA5LjU3OCA0MDguNTAxIDQxOS4wNjkgNDA5Ljk5Nkw3MTEuOTM0IDQ1Ni4xMTRDNzIxLjQyNSA0NTcuNjA5IDczMS4xMDcgNDUxLjI5IDczMy41NiA0NDJMNzg3LjU4OSAyMzcuMzQ5Wk02NjAuMjY5IDI0NS4wMUM2NTUuNTIzIDI0NC4yNjMgNjUwLjY4MiAyNDcuNDIzIDY0OS40NTYgMjUyLjA2OEw2MDcuMzg2IDQxMS40MThDNjA2LjE2IDQxNi4wNjMgNjA5LjAxMyA0MjAuNDM0IDYxMy43NTkgNDIxLjE4MUw2ODIuNDk5IDQzMi4wMDZDNjg3LjI0NSA0MzIuNzUzIDY5Mi4wODYgNDI5LjU5NCA2OTMuMzEyIDQyNC45NDlMNzM1LjM4MiAyNjUuNTk5QzczNi42MDggMjYwLjk1NCA3MzMuNzU1IDI1Ni41ODMgNzI5LjAxIDI1NS44MzVMNjYwLjI2OSAyNDUuMDFaIiBmaWxsPSJ1cmwoI21haW4pIiAvPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNODY0LjY0MyAyODMuOTM3Qzg2NS4xODYgMjgzLjYwNSA4NjUuNzA4IDI4NC4yNTcgODY1LjIzOSAyODQuNjgzTDg0NC4yNjggMzAzLjcxOUM4NDMuOTM4IDMwNC4wMTggODQ0LjA5MyAzMDQuNTE3IDg0NC41MjYgMzA0LjU0OEw4NTMuNzI2IDMwNS4yMDdDODU0LjE4NCAzMDUuMjQgODU0LjMyMSAzMDUuNzg3IDg1My45NDIgMzA2LjA3MUw4MzMuODg0IDMyMS4xMTJDODMzLjUwNiAzMjEuMzk2IDgzMy42NDMgMzIxLjk0MyA4MzQuMTAxIDMyMS45NzZMODQ0LjAwNyAzMjIuNjg1Qzg0NC40OTEgMzIyLjcyIDg0NC42MDUgMzIzLjMxOSA4NDQuMTc3IDMyMy41OEw3OTcuNzUyIDM1MS45NTRDNzk3LjIwOSAzNTIuMjg2IDc5Ni42ODcgMzUxLjYzNCA3OTcuMTU2IDM1MS4yMDlMODE4LjQwMyAzMzEuOTIyQzgxOC43MzMgMzMxLjYyMiA4MTguNTc3IDMzMS4xMjMgODE4LjE0NSAzMzEuMDkyTDgwOC43NDggMzMwLjQyQzgwOC4yOTIgMzMwLjM4NyA4MDguMTU0IDMyOS44NDMgODA4LjUyOSAzMjkuNTU4TDgyOC4wNTQgMzE0Ljc0NEM4MjguNDMgMzE0LjQ1OSA4MjguMjkxIDMxMy45MTUgODI3LjgzNSAzMTMuODgyTDgxOC4zODkgMzEzLjIwNkM4MTcuOTA0IDMxMy4xNzEgODE3Ljc5IDMxMi41NzIgODE4LjIxOCAzMTIuMzExTDg2NC42NDMgMjgzLjkzN1oiIGZpbGw9IndoaXRlIiAvPjxnIHRyYW5zZm9ybT0ibWF0cml4KDAuOTg3ODI3IDAuMTU1NTU3IC0wLjI1NTI2MSAwLjk2Njg3MiAyNTAgNzM1KSI+PHRleHQgZm9udC1mYW1pbHk9IkludGVyLCBzYW5zLXNlcmlmIiBmb250LXdlaWdodD0iYm9sZCIgZm9udC1zaXplPSI0MiIgZmlsbD0iI0U1RTdGOCI+RmxlZWsgVGVzdCBBcHA8L3RleHQ+PHRleHQgZm9udC1mYW1pbHk9IkludGVyLCBzYW5zLXNlcmlmIiBmb250LXdlaWdodD0ibm9ybWFsIiB5PSI0MCIgZm9udC1zaXplPSIyMiIgZmlsbD0iIzdGODE5MiI+ZmxlZWsuZXRoPC90ZXh0PjwvZz48aW1hZ2Ugd2lkdGg9IjE2NyIgaGVpZ2h0PSIxNjciIHRyYW5zZm9ybT0ibWF0cml4KDAuOTg3ODI3IDAuMTU1NTU3IC0wLjI1NTI2MSAwLjk2Njg3MiA0NDQuMTE3IDUyNC4xNykiIGhyZWY9ImRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEhOMlp5Qm1hV3hzUFNKdWIyNWxJaUJvWldsbmFIUTlJakkxTURBaUlIZHBaSFJvUFNJeU1UZ3pJaUI0Yld4dWN6MGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNakF3TUM5emRtY2lJSFpwWlhkQ2IzZzlJakFnTUNBeE1qUWdNVFF4TGpVek1UazVPVGs1T1RrNU9UazRJajQ4Y0dGMGFDQmtQU0pOTVRBdU16Z3pJREV5Tmk0NE9UUk1NQ0F3YkRFeU5DQXVNalUxTFRFd0xqazNPU0F4TWpZdU5qTTVMVFV3TGpVMU15QXhOQzQyTXpoNklpQm1hV3hzUFNJalpUTTBaakkySWk4K1BIQmhkR2dnWkQwaVRUWXlMalEyT0NBeE1qa3VNamMzVmpFeUxqQTROV3cxTVM0d05qUXVNVGN0T1M0eE1EWWdNVEEwTGpnMU1Yb2lJR1pwYkd3OUlpTmxaalkxTW1FaUx6NDhjR0YwYUNCa1BTSk5PVGt1TkRrZ05ERXVNell5YkRFdU5EUTJMVEUxTGpRNVNESXlMak00TTJ3MExqTTBJRFEzTGpRNWFEVTBMakl4TTB3M09DNDRNU0E1TXk0Mk1UZHNMVEUzTGpNMk1pQTBMalk0TFRFM0xqWXhOeTAxTGpFd05pMHVPVE0yTFRFeUxqQTROVWd5Tnk0ek1UbHNNaTR4TWpnZ01qUXVOamd4SURNeUlEZ3VPVE0ySURNeUxqSTFOUzA0TGprek5pQTBMak0wTFRRNExqRTNTRFF4TGpFd04wd3pPUzQwT1NBME1TNHpOako2SWlCbWFXeHNQU0lqWm1abUlpOCtQQzl6ZG1jKyIgLz48ZGVmcz48ZmlsdGVyIGlkPSJkaXNrZXR0ZS1zaGFkb3ciIHg9IjcwLjc0ODkiIHk9IjE5NS43MTIiIHdpZHRoPSI5NTUuNzMzIiBoZWlnaHQ9IjgzMi41NTgiIGZpbHRlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj48ZmVGbG9vZCBmbG9vZC1vcGFjaXR5PSIwIiAvPjxmZUJsZW5kIGluPSJTb3VyY2VHcmFwaGljIiAvPjxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjQyIiAvPjwvZmlsdGVyPjxsaW5lYXJHcmFkaWVudCBpZD0iYmFja2dyb3VuZCIgeDE9IjUzMi41IiB5MT0iMCIgeDI9IjUzMi41IiB5Mj0iMTA2NSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPjxzdG9wIC8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMTMxMzEzIiAvPjwvbGluZWFyR3JhZGllbnQ+PHJhZGlhbEdyYWRpZW50IGlkPSJiYWNrZ3JvdW5kLXJhZGlhbCIgY3g9IjAiIGN5PSIwIiByPSIxIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSg1MzIuNSA1MzIuNSkgcm90YXRlKDg5Ljk2MSkgc2NhbGUoNzM1KSI+PHN0b3Agc3RvcC1jb2xvcj0iI2UzNGYyNiIgLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNlMzRmMjYiIHN0b3Atb3BhY2l0eT0iMCIgLz48L3JhZGlhbEdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iZGlza2V0dGUtZ3JhZGllbnQiIHgxPSI5MjUuNjI2IiB5MT0iMjU2Ljg5NiIgeDI9IjEzNi43NzkiIHkyPSI4MDAuMjAzIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHN0b3Agc3RvcC1jb2xvcj0iI2UzNGYyNiIgLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMyQzMxM0YiIC8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9Im1haW4iPjxzdG9wIHN0b3AtY29sb3I9IiNlMzRmMjYiIC8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PC9zdmc+',
external_url: MINT_PARAMS.externalUrl,
attributes: [
{
@@ -196,6 +192,10 @@ describe('FleekERC721', () => {
trait_type: 'Version',
value: '0',
},
+ {
+ trait_type: 'Color',
+ value: `#${MINT_PARAMS.color.toString(16)}`,
+ },
],
});
});
@@ -216,7 +216,9 @@ describe('FleekERC721', () => {
MINT_PARAMS.externalUrl,
MINT_PARAMS.ens,
MINT_PARAMS.commitHash,
- MINT_PARAMS.gitRepository
+ MINT_PARAMS.gitRepository,
+ MINT_PARAMS.logo,
+ MINT_PARAMS.color
);
tokenId = response.value.toNumber();
@@ -618,7 +620,9 @@ describe('FleekERC721', () => {
MINT_PARAMS.externalUrl,
MINT_PARAMS.ens,
MINT_PARAMS.commitHash,
- MINT_PARAMS.gitRepository
+ MINT_PARAMS.gitRepository,
+ MINT_PARAMS.logo,
+ MINT_PARAMS.color
);
tokenId = response.value.toNumber();
@@ -840,4 +844,92 @@ describe('FleekERC721', () => {
]);
});
});
+
+ describe('Update Properties', () => {
+ let tokenId: number;
+ let fixture: Awaited>;
+
+ const OTHER_LOGO =
+ 'data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMTAwMCAxMDAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMDAwIDEwMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8Zz48cGF0aCBkPSJNNTAwLDEwQzIyOS40LDEwLDEwLDIyOS40LDEwLDUwMGMwLDI3MC42LDIxOS40LDQ5MCw0OTAsNDkwYzI3MC42LDAsNDkwLTIxOS40LDQ5MC00OTBDOTkwLDIyOS40LDc3MC42LDEwLDUwMCwxMHogTTgxNSw4MTVjLTQwLjksNDAuOS04OC42LDczLjEtMTQxLjYsOTUuNWMtNTQuOSwyMy4yLTExMy4yLDM1LTE3My40LDM1Yy02MC4yLDAtMTE4LjUtMTEuOC0xNzMuNC0zNUMyNzMuNiw4ODgsMjI1LjksODU1LjksMTg1LDgxNXMtNzMtODguNi05NS41LTE0MS42Yy0yMy4yLTU0LjktMzUtMTEzLjItMzUtMTczLjRjMC02MC4yLDExLjgtMTE4LjUsMzUtMTczLjRjMjIuNC01Myw1NC42LTEwMC43LDk1LjUtMTQxLjZzODguNi03MywxNDEuNi05NS41YzU0LjktMjMuMiwxMTMuMi0zNSwxNzMuNC0zNWM2MC4yLDAsMTE4LjUsMTEuOCwxNzMuNCwzNWM1MywyMi40LDEwMC43LDU0LjYsMTQxLjYsOTUuNWM0MC45LDQwLjksNzMsODguNiw5NS41LDE0MS42YzIzLjIsNTQuOSwzNSwxMTMuMiwzNSwxNzMuNGMwLDYwLjItMTEuOCwxMTguNS0zNSwxNzMuNEM4ODgsNzI2LjQsODU1LjksNzc0LjEsODE1LDgxNXoiLz48L2c+Cjwvc3ZnPg==';
+
+ beforeEach(async () => {
+ fixture = await loadFixture(defaultFixture);
+ const { contract } = fixture;
+
+ const response = await contract.mint(
+ fixture.owner.address,
+ MINT_PARAMS.name,
+ MINT_PARAMS.description,
+ MINT_PARAMS.externalUrl,
+ MINT_PARAMS.ens,
+ MINT_PARAMS.commitHash,
+ MINT_PARAMS.gitRepository,
+ MINT_PARAMS.logo,
+ MINT_PARAMS.color
+ );
+
+ tokenId = response.value.toNumber();
+ });
+
+ it('should update token logo', async () => {
+ const { contract } = fixture;
+ await contract.setTokenLogo(tokenId, OTHER_LOGO);
+
+ const tokenURI = await contract.tokenURI(tokenId);
+
+ const tokenURIDecoded = Buffer.from(
+ tokenURI.replace('data:application/json;base64,', ''),
+ 'base64'
+ ).toString('ascii');
+
+ const parsedURI = JSON.parse(tokenURIDecoded);
+ expect(parsedURI).to.have.property(
+ 'image',
+ 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTA2NSIgaGVpZ2h0PSIxMDY1IiB2aWV3Qm94PSIwIDAgMTA2NSAxMDY1IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48c3R5bGUgdHlwZT0idGV4dC9jc3MiPkBpbXBvcnQgdXJsKCJodHRwczovL2ZvbnRzLmdvb2dsZWFwaXMuY29tL2NzczI/ZmFtaWx5PUludGVyOndnaHRANTAwOzYwMCIpOzwvc3R5bGU+PHJlY3Qgd2lkdGg9IjEwNjUiIGhlaWdodD0iMTA2NSIgZmlsbD0idXJsKCNiYWNrZ3JvdW5kKSIgLz48cmVjdCBvcGFjaXR5PSIwLjIiIHdpZHRoPSIxMDY1IiBoZWlnaHQ9IjEwNjUiIGZpbGw9InVybCgjYmFja2dyb3VuZC1yYWRpYWwpIiAvPjxnIGZpbHRlcj0idXJsKCNkaXNrZXR0ZS1zaGFkb3cpIj48cGF0aCBkPSJNODU3LjIzMSAyNzkuNzEyTDkwMi4yNCAyODYuNjc1QzkxMC41NDcgMjg3Ljk2IDkxNy45MTUgMjkyLjcyMSA5MjIuNSAyOTkuNzY4TDkzOC44OTQgMzI0Ljk2NEM5NDIuMjQ5IDMzMC4xMiA5NDMuMzExIDMzNi40MzcgOTQxLjgyNyAzNDIuNDA2TDkzNy43OTggMzU4LjYxNUw5MjQuMDQ5IDM1Ni42NUw5MTkuNDE2IDM3NC4wODRMOTM0LjA2OCAzNzYuMjRMNzkxLjk0NyA5MjIuMTUyQzc4OC4xMDkgOTM2Ljg5NiA3NzMuNjk0IDk0Ni4zMDggNzU4LjY1MSA5NDMuODkzTDE3OS42MzYgODUwLjkyOEMxNjIuMzE4IDg0OC4xNDcgMTUxLjIxNSA4MzAuOTg3IDE1NS43NzYgODE0LjA1MUwxNjAuNDc4IDc5Ni41OUw3MDQuMzE1IDg3OS41NzRMODU3LjIzMSAyNzkuNzEyWiIgZmlsbD0iIzA1MDUwNSIgLz48L2c+PHBhdGggZD0iTTg0MC4yMzEgMjQwLjcxMkw4ODUuMjQgMjQ3LjY3NUM4OTMuNTQ3IDI0OC45NjEgOTAwLjkxNSAyNTMuNzIyIDkwNS41IDI2MC43NjhMOTIxLjg5NCAyODUuOTY1QzkyNS4yNDkgMjkxLjEyIDkyNi4zMTEgMjk3LjQzNyA5MjQuODI3IDMwMy40MDZMOTIwLjc5OCAzMTkuNjE2TDkwNy4wNDkgMzE3LjY1TDkwMi40MTYgMzM1LjA4NEw5MTcuMDY4IDMzNy4yNDFMNzc0Ljk0NyA4ODMuMTUyQzc3MS4xMDkgODk3Ljg5NiA3NTYuNjk0IDkwNy4zMDggNzQxLjY1MSA5MDQuODkzTDE2Mi42MzYgODExLjkyOEMxNDUuMzE4IDgwOS4xNDcgMTM0LjIxNSA3OTEuOTg3IDEzOC43NzYgNzc1LjA1MUwxNDMuNDc4IDc1Ny41OUw2ODcuMzE1IDg0MC41NzRMODQwLjIzMSAyNDAuNzEyWiIgZmlsbD0idXJsKCNtYWluKSIgLz48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTMxOS44NDcgMTYxLjUwMkMzMTAuMzU2IDE2MC4wMDcgMzAwLjY3NCAxNjYuMzI2IDI5OC4yMjEgMTc1LjYxNkwxMzguNzI0IDc3OS43NThDMTM2LjI3MSA3ODkuMDQ4IDE0MS45NzcgNzk3Ljc5IDE1MS40NjggNzk5LjI4NUw3NDAuMDYxIDg5MS45NzNDNzQ5LjU1MyA4OTMuNDY3IDc1OS4yMzUgODg3LjE0OCA3NjEuNjg3IDg3Ny44NThMOTAyLjQwNSAzNDQuODU0TDg4OS4xNTggMzQyLjc2OEw4OTguODcyIDMwNS45NzJMOTEyLjExOSAzMDguMDU5TDkxMy43MzMgMzAxLjk0NkM5MTQuODM3IDI5Ny43NjIgOTE0LjMwOSAyOTMuNDc2IDkxMi4yNTEgMjg5LjkyN0w4OTMuNDg0IDI1Ny41NjlDODkxLjE1MyAyNTMuNTQ5IDg4Ny4wNjMgMjUwLjgyMyA4ODIuMjIxIDI1MC4wNjFMODI4LjIwNSAyNDEuNTU0QzgyMi4yMjQgMjQwLjYxMyA4MTUuODY5IDI0Mi43ODMgODExLjQyNyAyNDcuMjg0TDgwNS42ODYgMjUzLjEwM0M4MDQuMjA1IDI1NC42MDMgODAyLjA4NyAyNTUuMzI2IDgwMC4wOTMgMjU1LjAxM0w3ODMuNjExIDI1Mi40MTdMNzM0LjMgNDM5LjE5NkM3MzEuNDM5IDQ1MC4wMzUgNzIwLjE0MyA0NTcuNDA3IDcwOS4wNyA0NTUuNjYzTDMyOC44NDcgMzk1Ljc4OEMzMTcuNzc0IDM5NC4wNDUgMzExLjExNyAzODMuODQ1IDMxMy45NzggMzczLjAwN0wzNjYuNTI4IDE3My45NjJMMzY2LjUzMyAxNzMuOTQxQzM2Ny4yMzQgMTcxLjI0IDM2NS41NzIgMTY4LjcwMiAzNjIuODEgMTY4LjI2N0wzMTkuODQ3IDE2MS41MDJaTTM2OS4zOTIgMTc0LjQxNEwzNjguNjUyIDE3Ny4yMTdMMzE2Ljg0MyAzNzMuNDU4QzMxNC4zOSAzODIuNzQ4IDMyMC4wOTYgMzkxLjQ5IDMyOS41ODcgMzkyLjk4NUw3MDkuODEgNDUyLjg2QzcxOS4zMDEgNDU0LjM1NCA3MjguOTgzIDQ0OC4wMzUgNzMxLjQzNiA0MzguNzQ1TDc4MC43NDcgMjUxLjk2Nkw3ODMuMjQ1IDI0Mi41MDRMNzgzLjk4NSAyMzkuNzAxTDM2OS4zOTIgMTc0LjQxNFoiIGZpbGw9IiMxMzEzMTYiIC8+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0idXJsKCNtYWluKSIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGQ9Ik0zMTkuODQ3IDE2MS41MDJDMzEwLjM1NiAxNjAuMDA3IDMwMC42NzQgMTY2LjMyNiAyOTguMjIxIDE3NS42MTZMMTM4LjcyNCA3NzkuNzU4QzEzNi4yNzEgNzg5LjA0OCAxNDEuOTc3IDc5Ny43OSAxNTEuNDY4IDc5OS4yODVMNzQwLjA2MSA4OTEuOTczQzc0OS41NTMgODkzLjQ2NyA3NTkuMjM1IDg4Ny4xNDggNzYxLjY4NyA4NzcuODU4TDkwMi40MDUgMzQ0Ljg1NEw4ODkuMTU4IDM0Mi43NjhMODk4Ljg3MiAzMDUuOTcyTDkxMi4xMTkgMzA4LjA1OUw5MTMuNzMzIDMwMS45NDZDOTE0LjgzNyAyOTcuNzYyIDkxNC4zMDkgMjkzLjQ3NiA5MTIuMjUxIDI4OS45MjdMODkzLjQ4NCAyNTcuNTY5Qzg5MS4xNTMgMjUzLjU0OSA4ODcuMDYzIDI1MC44MjMgODgyLjIyMSAyNTAuMDYxTDgyOC4yMDUgMjQxLjU1NEM4MjIuMjI0IDI0MC42MTMgODE1Ljg2OSAyNDIuNzgzIDgxMS40MjcgMjQ3LjI4NEw4MDUuNjg2IDI1My4xMDNDODA0LjIwNSAyNTQuNjAzIDgwMi4wODcgMjU1LjMyNiA4MDAuMDkzIDI1NS4wMTNMNzgzLjYxMSAyNTIuNDE3TDczNC4zIDQzOS4xOTZDNzMxLjQzOSA0NTAuMDM1IDcyMC4xNDMgNDU3LjQwNyA3MDkuMDcgNDU1LjY2M0wzMjguODQ3IDM5NS43ODhDMzE3Ljc3NCAzOTQuMDQ1IDMxMS4xMTcgMzgzLjg0NSAzMTMuOTc4IDM3My4wMDdMMzY2LjUyOCAxNzMuOTYyTDM2Ni41MzMgMTczLjk0MUMzNjcuMjM0IDE3MS4yNCAzNjUuNTcyIDE2OC43MDIgMzYyLjgxIDE2OC4yNjdMMzE5Ljg0NyAxNjEuNTAyWk0zNjkuMzkyIDE3NC40MTRMMzY4LjY1MiAxNzcuMjE3TDMxNi44NDMgMzczLjQ1OEMzMTQuMzkgMzgyLjc0OCAzMjAuMDk2IDM5MS40OSAzMjkuNTg3IDM5Mi45ODVMNzA5LjgxIDQ1Mi44NkM3MTkuMzAxIDQ1NC4zNTQgNzI4Ljk4MyA0NDguMDM1IDczMS40MzYgNDM4Ljc0NUw3ODAuNzQ3IDI1MS45NjZMNzgzLjI0NSAyNDIuNTA0TDc4My45ODUgMjM5LjcwMUwzNjkuMzkyIDE3NC40MTRaIiBmaWxsPSJ1cmwoI2Rpc2tldHRlLWdyYWRpZW50KSIgZmlsbC1vcGFjaXR5PSIwLjIiIC8+PHBhdGggZD0iTTMzNS4zOCAyMDguMTEzQzMzNS45MjIgMjA4LjE5OCAzMzYuNDE3IDIwNy42ODYgMzM2LjI4MyAyMDcuMTc5TDMzMC4zOSAxODQuNzk1QzMzMC4yNDkgMTg0LjI2MSAzMjkuNTI5IDE4NC4xNDggMzI5LjEyOSAxODQuNTk3TDMxMi4zNTggMjAzLjQxMUMzMTEuOTc4IDIwMy44MzggMzEyLjE3NCAyMDQuNDU4IDMxMi43MTYgMjA0LjU0NEwzMTcuOTYyIDIwNS4zN0MzMTguMzU3IDIwNS40MzIgMzE4LjU5NSAyMDUuNzk2IDMxOC40OTMgMjA2LjE4M0wzMTQuNyAyMjAuNTUxQzMxNC41OTcgMjIwLjkzOCAzMTQuODM1IDIyMS4zMDIgMzE1LjIzMSAyMjEuMzY0TDMyNC41MzkgMjIyLjgzQzMyNC45MzUgMjIyLjg5MyAzMjUuMzM4IDIyMi42MjkgMzI1LjQ0IDIyMi4yNDJMMzI5LjIzMyAyMDcuODc1QzMyOS4zMzYgMjA3LjQ4OCAzMjkuNzM5IDIwNy4yMjQgMzMwLjEzNSAyMDcuMjg2TDMzNS4zOCAyMDguMTEzWiIgZmlsbD0idXJsKCNtYWluKSIgLz48cGF0aCBkPSJNMzE5LjI4MiAyNjkuMDg3QzMxOS44MjQgMjY5LjE3MyAzMjAuMzE5IDI2OC42NjEgMzIwLjE4NiAyNjguMTU0TDMxNC4yOTIgMjQ1Ljc3QzMxNC4xNTEgMjQ1LjIzNiAzMTMuNDMxIDI0NS4xMjMgMzEzLjAzMSAyNDUuNTcyTDI5Ni4yNjEgMjY0LjM4NkMyOTUuODggMjY0LjgxMiAyOTYuMDc2IDI2NS40MzMgMjk2LjYxOCAyNjUuNTE4TDMwMS44NjQgMjY2LjM0NEMzMDIuMjU5IDI2Ni40MDcgMzAyLjQ5NyAyNjYuNzcxIDMwMi4zOTUgMjY3LjE1OEwyOTguNjAyIDI4MS41MjZDMjk4LjUgMjgxLjkxMyAyOTguNzM3IDI4Mi4yNzcgMjk5LjEzMyAyODIuMzM5TDMwOC40NDEgMjgzLjgwNUMzMDguODM3IDI4My44NjcgMzA5LjI0IDI4My42MDQgMzA5LjM0MyAyODMuMjE3TDMxMy4xMzYgMjY4Ljg0OUMzMTMuMjM4IDI2OC40NjIgMzEzLjY0MSAyNjguMTk5IDMxNC4wMzcgMjY4LjI2MUwzMTkuMjgyIDI2OS4wODdaIiBmaWxsPSJibGFjayIgZmlsbC1vcGFjaXR5PSIwLjUiIC8+PHBhdGggZD0iTTMwMy4xODQgMzMwLjA2MkMzMDMuNzI2IDMzMC4xNDggMzA0LjIyMSAzMjkuNjM2IDMwNC4wODggMzI5LjEyOEwyOTguMTk0IDMwNi43NDVDMjk4LjA1MyAzMDYuMjExIDI5Ny4zMzMgMzA2LjA5OCAyOTYuOTMzIDMwNi41NDdMMjgwLjE2MyAzMjUuMzYxQzI3OS43ODIgMzI1Ljc4NyAyNzkuOTc5IDMyNi40MDggMjgwLjUyIDMyNi40OTNMMjg1Ljc2NiAzMjcuMzE5QzI4Ni4xNjEgMzI3LjM4MiAyODYuMzk5IDMyNy43NDYgMjg2LjI5NyAzMjguMTMzTDI4Mi41MDQgMzQyLjUwMUMyODIuNDAyIDM0Mi44ODggMjgyLjYzOSAzNDMuMjUyIDI4My4wMzUgMzQzLjMxNEwyOTIuMzQ0IDM0NC43OEMyOTIuNzM5IDM0NC44NDIgMjkzLjE0MiAzNDQuNTc5IDI5My4yNDUgMzQ0LjE5MkwyOTcuMDM4IDMyOS44MjRDMjk3LjE0IDMyOS40MzcgMjk3LjU0MyAzMjkuMTc0IDI5Ny45MzkgMzI5LjIzNkwzMDMuMTg0IDMzMC4wNjJaIiBmaWxsPSJibGFjayIgZmlsbC1vcGFjaXR5PSIwLjUiIC8+PHBhdGggc3Ryb2tlPSJ1cmwoI21haW4pIiBzdHJva2Utd2lkdGg9IjYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTTI5MC4xMDkgNDYzLjQxOEMyOTIuMzU4IDQ1NC45MDIgMzAxLjIzMyA0NDkuMTEgMzA5LjkzMyA0NTAuNDhMNzcxLjA3IDUyMy4wOTZDNzc5Ljc3IDUyNC40NjcgNzg1IDUzMi40OCA3ODIuNzUyIDU0MC45OTZMNjkyLjA4NiA4ODQuNDE4TDE5OS40NDMgODA2Ljg0TDI5MC4xMDkgNDYzLjQxOFoiIGZpbGw9ImJsYWNrIiBmaWxsLW9wYWNpdHk9IjAuMTQiIC8+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0idXJsKCNtYWluKSIgc3Ryb2tlLXdpZHRoPSI2IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGQ9Ik03ODcuNTg5IDIzNy4zNDlMNDYwLjM1NCAxODUuODE4TDQwNi4zMjUgMzkwLjQ2OUM0MDMuODcyIDM5OS43NTkgNDA5LjU3OCA0MDguNTAxIDQxOS4wNjkgNDA5Ljk5Nkw3MTEuOTM0IDQ1Ni4xMTRDNzIxLjQyNSA0NTcuNjA5IDczMS4xMDcgNDUxLjI5IDczMy41NiA0NDJMNzg3LjU4OSAyMzcuMzQ5Wk02NjAuMjY5IDI0NS4wMUM2NTUuNTIzIDI0NC4yNjMgNjUwLjY4MiAyNDcuNDIzIDY0OS40NTYgMjUyLjA2OEw2MDcuMzg2IDQxMS40MThDNjA2LjE2IDQxNi4wNjMgNjA5LjAxMyA0MjAuNDM0IDYxMy43NTkgNDIxLjE4MUw2ODIuNDk5IDQzMi4wMDZDNjg3LjI0NSA0MzIuNzUzIDY5Mi4wODYgNDI5LjU5NCA2OTMuMzEyIDQyNC45NDlMNzM1LjM4MiAyNjUuNTk5QzczNi42MDggMjYwLjk1NCA3MzMuNzU1IDI1Ni41ODMgNzI5LjAxIDI1NS44MzVMNjYwLjI2OSAyNDUuMDFaIiBmaWxsPSJ1cmwoI21haW4pIiAvPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNODY0LjY0MyAyODMuOTM3Qzg2NS4xODYgMjgzLjYwNSA4NjUuNzA4IDI4NC4yNTcgODY1LjIzOSAyODQuNjgzTDg0NC4yNjggMzAzLjcxOUM4NDMuOTM4IDMwNC4wMTggODQ0LjA5MyAzMDQuNTE3IDg0NC41MjYgMzA0LjU0OEw4NTMuNzI2IDMwNS4yMDdDODU0LjE4NCAzMDUuMjQgODU0LjMyMSAzMDUuNzg3IDg1My45NDIgMzA2LjA3MUw4MzMuODg0IDMyMS4xMTJDODMzLjUwNiAzMjEuMzk2IDgzMy42NDMgMzIxLjk0MyA4MzQuMTAxIDMyMS45NzZMODQ0LjAwNyAzMjIuNjg1Qzg0NC40OTEgMzIyLjcyIDg0NC42MDUgMzIzLjMxOSA4NDQuMTc3IDMyMy41OEw3OTcuNzUyIDM1MS45NTRDNzk3LjIwOSAzNTIuMjg2IDc5Ni42ODcgMzUxLjYzNCA3OTcuMTU2IDM1MS4yMDlMODE4LjQwMyAzMzEuOTIyQzgxOC43MzMgMzMxLjYyMiA4MTguNTc3IDMzMS4xMjMgODE4LjE0NSAzMzEuMDkyTDgwOC43NDggMzMwLjQyQzgwOC4yOTIgMzMwLjM4NyA4MDguMTU0IDMyOS44NDMgODA4LjUyOSAzMjkuNTU4TDgyOC4wNTQgMzE0Ljc0NEM4MjguNDMgMzE0LjQ1OSA4MjguMjkxIDMxMy45MTUgODI3LjgzNSAzMTMuODgyTDgxOC4zODkgMzEzLjIwNkM4MTcuOTA0IDMxMy4xNzEgODE3Ljc5IDMxMi41NzIgODE4LjIxOCAzMTIuMzExTDg2NC42NDMgMjgzLjkzN1oiIGZpbGw9IndoaXRlIiAvPjxnIHRyYW5zZm9ybT0ibWF0cml4KDAuOTg3ODI3IDAuMTU1NTU3IC0wLjI1NTI2MSAwLjk2Njg3MiAyNTAgNzM1KSI+PHRleHQgZm9udC1mYW1pbHk9IkludGVyLCBzYW5zLXNlcmlmIiBmb250LXdlaWdodD0iYm9sZCIgZm9udC1zaXplPSI0MiIgZmlsbD0iI0U1RTdGOCI+RmxlZWsgVGVzdCBBcHA8L3RleHQ+PHRleHQgZm9udC1mYW1pbHk9IkludGVyLCBzYW5zLXNlcmlmIiBmb250LXdlaWdodD0ibm9ybWFsIiB5PSI0MCIgZm9udC1zaXplPSIyMiIgZmlsbD0iIzdGODE5MiI+ZmxlZWsuZXRoPC90ZXh0PjwvZz48aW1hZ2Ugd2lkdGg9IjE2NyIgaGVpZ2h0PSIxNjciIHRyYW5zZm9ybT0ibWF0cml4KDAuOTg3ODI3IDAuMTU1NTU3IC0wLjI1NTI2MSAwLjk2Njg3MiA0NDQuMTE3IDUyNC4xNykiIGhyZWY9ImRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEhOMlp5QjJaWEp6YVc5dVBTSXhMakVpSUhodGJHNXpQU0pvZEhSd09pOHZkM2QzTG5jekxtOXlaeTh5TURBd0wzTjJaeUlnZUcxc2JuTTZlR3hwYm1zOUltaDBkSEE2THk5M2QzY3Vkek11YjNKbkx6RTVPVGt2ZUd4cGJtc2lJSGc5SWpCd2VDSWdlVDBpTUhCNElpQjJhV1YzUW05NFBTSXdJREFnTVRBd01DQXhNREF3SWlCbGJtRmliR1V0WW1GamEyZHliM1Z1WkQwaWJtVjNJREFnTUNBeE1EQXdJREV3TURBaUlIaHRiRHB6Y0dGalpUMGljSEpsYzJWeWRtVWlQZ284Wno0OGNHRjBhQ0JrUFNKTk5UQXdMREV3UXpJeU9TNDBMREV3TERFd0xESXlPUzQwTERFd0xEVXdNR013TERJM01DNDJMREl4T1M0MExEUTVNQ3cwT1RBc05Ea3dZekkzTUM0MkxEQXNORGt3TFRJeE9TNDBMRFE1TUMwME9UQkRPVGt3TERJeU9TNDBMRGMzTUM0MkxERXdMRFV3TUN3eE1Ib2dUVGd4TlN3NE1UVmpMVFF3TGprc05EQXVPUzA0T0M0MkxEY3pMakV0TVRReExqWXNPVFV1TldNdE5UUXVPU3d5TXk0eUxURXhNeTR5TERNMUxURTNNeTQwTERNMVl5MDJNQzR5TERBdE1URTRMalV0TVRFdU9DMHhOek11TkMwek5VTXlOek11Tml3NE9EZ3NNakkxTGprc09EVTFMamtzTVRnMUxEZ3hOWE10TnpNdE9EZ3VOaTA1TlM0MUxURTBNUzQyWXkweU15NHlMVFUwTGprdE16VXRNVEV6TGpJdE16VXRNVGN6TGpSak1DMDJNQzR5TERFeExqZ3RNVEU0TGpVc016VXRNVGN6TGpSak1qSXVOQzAxTXl3MU5DNDJMVEV3TUM0M0xEazFMalV0TVRReExqWnpPRGd1TmkwM015d3hOREV1TmkwNU5TNDFZelUwTGprdE1qTXVNaXd4TVRNdU1pMHpOU3d4TnpNdU5DMHpOV00yTUM0eUxEQXNNVEU0TGpVc01URXVPQ3d4TnpNdU5Dd3pOV00xTXl3eU1pNDBMREV3TUM0M0xEVTBMallzTVRReExqWXNPVFV1TldNME1DNDVMRFF3TGprc056TXNPRGd1Tml3NU5TNDFMREUwTVM0Mll6SXpMaklzTlRRdU9Td3pOU3d4TVRNdU1pd3pOU3d4TnpNdU5HTXdMRFl3TGpJdE1URXVPQ3d4TVRndU5TMHpOU3d4TnpNdU5FTTRPRGdzTnpJMkxqUXNPRFUxTGprc056YzBMakVzT0RFMUxEZ3hOWG9pTHo0OEwyYytDand2YzNablBnPT0iIC8+PGRlZnM+PGZpbHRlciBpZD0iZGlza2V0dGUtc2hhZG93IiB4PSI3MC43NDg5IiB5PSIxOTUuNzEyIiB3aWR0aD0iOTU1LjczMyIgaGVpZ2h0PSI4MzIuNTU4IiBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+PGZlRmxvb2QgZmxvb2Qtb3BhY2l0eT0iMCIgLz48ZmVCbGVuZCBpbj0iU291cmNlR3JhcGhpYyIgLz48ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSI0MiIgLz48L2ZpbHRlcj48bGluZWFyR3JhZGllbnQgaWQ9ImJhY2tncm91bmQiIHgxPSI1MzIuNSIgeTE9IjAiIHgyPSI1MzIuNSIgeTI9IjEwNjUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj48c3RvcCAvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzEzMTMxMyIgLz48L2xpbmVhckdyYWRpZW50PjxyYWRpYWxHcmFkaWVudCBpZD0iYmFja2dyb3VuZC1yYWRpYWwiIGN4PSIwIiBjeT0iMCIgcj0iMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoNTMyLjUgNTMyLjUpIHJvdGF0ZSg4OS45NjEpIHNjYWxlKDczNSkiPjxzdG9wIHN0b3AtY29sb3I9IiNlMzRmMjYiIC8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZTM0ZjI2IiBzdG9wLW9wYWNpdHk9IjAiIC8+PC9yYWRpYWxHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImRpc2tldHRlLWdyYWRpZW50IiB4MT0iOTI1LjYyNiIgeTE9IjI1Ni44OTYiIHgyPSIxMzYuNzc5IiB5Mj0iODAwLjIwMyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPjxzdG9wIHN0b3AtY29sb3I9IiNlMzRmMjYiIC8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMkMzMTNGIiAvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJtYWluIj48c3RvcCBzdG9wLWNvbG9yPSIjZTM0ZjI2IiAvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjwvc3ZnPg=='
+ );
+ });
+
+ it('should update token color', async () => {
+ const { contract } = fixture;
+ await contract.setTokenColor(tokenId, 0x123456);
+
+ const tokenURI = await contract.tokenURI(tokenId);
+
+ const tokenURIDecoded = Buffer.from(
+ tokenURI.replace('data:application/json;base64,', ''),
+ 'base64'
+ ).toString('ascii');
+
+ const parsedURI = JSON.parse(tokenURIDecoded);
+
+ expect(parsedURI.attributes).to.have.deep.contain({
+ trait_type: 'Color',
+ value: '#123456',
+ });
+ });
+
+ it('should update the token logo and color', async () => {
+ const { contract } = fixture;
+ await contract.setTokenLogoAndColor(tokenId, OTHER_LOGO, 0x123456);
+
+ const tokenURI = await contract.tokenURI(tokenId);
+
+ const tokenURIDecoded = Buffer.from(
+ tokenURI.replace('data:application/json;base64,', ''),
+ 'base64'
+ ).toString('ascii');
+
+ const parsedURI = JSON.parse(tokenURIDecoded);
+
+ expect(parsedURI.attributes).to.have.deep.contain({
+ trait_type: 'Color',
+ value: '#123456',
+ });
+
+ expect(parsedURI).to.have.property(
+ 'image',
+ 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTA2NSIgaGVpZ2h0PSIxMDY1IiB2aWV3Qm94PSIwIDAgMTA2NSAxMDY1IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48c3R5bGUgdHlwZT0idGV4dC9jc3MiPkBpbXBvcnQgdXJsKCJodHRwczovL2ZvbnRzLmdvb2dsZWFwaXMuY29tL2NzczI/ZmFtaWx5PUludGVyOndnaHRANTAwOzYwMCIpOzwvc3R5bGU+PHJlY3Qgd2lkdGg9IjEwNjUiIGhlaWdodD0iMTA2NSIgZmlsbD0idXJsKCNiYWNrZ3JvdW5kKSIgLz48cmVjdCBvcGFjaXR5PSIwLjIiIHdpZHRoPSIxMDY1IiBoZWlnaHQ9IjEwNjUiIGZpbGw9InVybCgjYmFja2dyb3VuZC1yYWRpYWwpIiAvPjxnIGZpbHRlcj0idXJsKCNkaXNrZXR0ZS1zaGFkb3cpIj48cGF0aCBkPSJNODU3LjIzMSAyNzkuNzEyTDkwMi4yNCAyODYuNjc1QzkxMC41NDcgMjg3Ljk2IDkxNy45MTUgMjkyLjcyMSA5MjIuNSAyOTkuNzY4TDkzOC44OTQgMzI0Ljk2NEM5NDIuMjQ5IDMzMC4xMiA5NDMuMzExIDMzNi40MzcgOTQxLjgyNyAzNDIuNDA2TDkzNy43OTggMzU4LjYxNUw5MjQuMDQ5IDM1Ni42NUw5MTkuNDE2IDM3NC4wODRMOTM0LjA2OCAzNzYuMjRMNzkxLjk0NyA5MjIuMTUyQzc4OC4xMDkgOTM2Ljg5NiA3NzMuNjk0IDk0Ni4zMDggNzU4LjY1MSA5NDMuODkzTDE3OS42MzYgODUwLjkyOEMxNjIuMzE4IDg0OC4xNDcgMTUxLjIxNSA4MzAuOTg3IDE1NS43NzYgODE0LjA1MUwxNjAuNDc4IDc5Ni41OUw3MDQuMzE1IDg3OS41NzRMODU3LjIzMSAyNzkuNzEyWiIgZmlsbD0iIzA1MDUwNSIgLz48L2c+PHBhdGggZD0iTTg0MC4yMzEgMjQwLjcxMkw4ODUuMjQgMjQ3LjY3NUM4OTMuNTQ3IDI0OC45NjEgOTAwLjkxNSAyNTMuNzIyIDkwNS41IDI2MC43NjhMOTIxLjg5NCAyODUuOTY1QzkyNS4yNDkgMjkxLjEyIDkyNi4zMTEgMjk3LjQzNyA5MjQuODI3IDMwMy40MDZMOTIwLjc5OCAzMTkuNjE2TDkwNy4wNDkgMzE3LjY1TDkwMi40MTYgMzM1LjA4NEw5MTcuMDY4IDMzNy4yNDFMNzc0Ljk0NyA4ODMuMTUyQzc3MS4xMDkgODk3Ljg5NiA3NTYuNjk0IDkwNy4zMDggNzQxLjY1MSA5MDQuODkzTDE2Mi42MzYgODExLjkyOEMxNDUuMzE4IDgwOS4xNDcgMTM0LjIxNSA3OTEuOTg3IDEzOC43NzYgNzc1LjA1MUwxNDMuNDc4IDc1Ny41OUw2ODcuMzE1IDg0MC41NzRMODQwLjIzMSAyNDAuNzEyWiIgZmlsbD0idXJsKCNtYWluKSIgLz48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTMxOS44NDcgMTYxLjUwMkMzMTAuMzU2IDE2MC4wMDcgMzAwLjY3NCAxNjYuMzI2IDI5OC4yMjEgMTc1LjYxNkwxMzguNzI0IDc3OS43NThDMTM2LjI3MSA3ODkuMDQ4IDE0MS45NzcgNzk3Ljc5IDE1MS40NjggNzk5LjI4NUw3NDAuMDYxIDg5MS45NzNDNzQ5LjU1MyA4OTMuNDY3IDc1OS4yMzUgODg3LjE0OCA3NjEuNjg3IDg3Ny44NThMOTAyLjQwNSAzNDQuODU0TDg4OS4xNTggMzQyLjc2OEw4OTguODcyIDMwNS45NzJMOTEyLjExOSAzMDguMDU5TDkxMy43MzMgMzAxLjk0NkM5MTQuODM3IDI5Ny43NjIgOTE0LjMwOSAyOTMuNDc2IDkxMi4yNTEgMjg5LjkyN0w4OTMuNDg0IDI1Ny41NjlDODkxLjE1MyAyNTMuNTQ5IDg4Ny4wNjMgMjUwLjgyMyA4ODIuMjIxIDI1MC4wNjFMODI4LjIwNSAyNDEuNTU0QzgyMi4yMjQgMjQwLjYxMyA4MTUuODY5IDI0Mi43ODMgODExLjQyNyAyNDcuMjg0TDgwNS42ODYgMjUzLjEwM0M4MDQuMjA1IDI1NC42MDMgODAyLjA4NyAyNTUuMzI2IDgwMC4wOTMgMjU1LjAxM0w3ODMuNjExIDI1Mi40MTdMNzM0LjMgNDM5LjE5NkM3MzEuNDM5IDQ1MC4wMzUgNzIwLjE0MyA0NTcuNDA3IDcwOS4wNyA0NTUuNjYzTDMyOC44NDcgMzk1Ljc4OEMzMTcuNzc0IDM5NC4wNDUgMzExLjExNyAzODMuODQ1IDMxMy45NzggMzczLjAwN0wzNjYuNTI4IDE3My45NjJMMzY2LjUzMyAxNzMuOTQxQzM2Ny4yMzQgMTcxLjI0IDM2NS41NzIgMTY4LjcwMiAzNjIuODEgMTY4LjI2N0wzMTkuODQ3IDE2MS41MDJaTTM2OS4zOTIgMTc0LjQxNEwzNjguNjUyIDE3Ny4yMTdMMzE2Ljg0MyAzNzMuNDU4QzMxNC4zOSAzODIuNzQ4IDMyMC4wOTYgMzkxLjQ5IDMyOS41ODcgMzkyLjk4NUw3MDkuODEgNDUyLjg2QzcxOS4zMDEgNDU0LjM1NCA3MjguOTgzIDQ0OC4wMzUgNzMxLjQzNiA0MzguNzQ1TDc4MC43NDcgMjUxLjk2Nkw3ODMuMjQ1IDI0Mi41MDRMNzgzLjk4NSAyMzkuNzAxTDM2OS4zOTIgMTc0LjQxNFoiIGZpbGw9IiMxMzEzMTYiIC8+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0idXJsKCNtYWluKSIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGQ9Ik0zMTkuODQ3IDE2MS41MDJDMzEwLjM1NiAxNjAuMDA3IDMwMC42NzQgMTY2LjMyNiAyOTguMjIxIDE3NS42MTZMMTM4LjcyNCA3NzkuNzU4QzEzNi4yNzEgNzg5LjA0OCAxNDEuOTc3IDc5Ny43OSAxNTEuNDY4IDc5OS4yODVMNzQwLjA2MSA4OTEuOTczQzc0OS41NTMgODkzLjQ2NyA3NTkuMjM1IDg4Ny4xNDggNzYxLjY4NyA4NzcuODU4TDkwMi40MDUgMzQ0Ljg1NEw4ODkuMTU4IDM0Mi43NjhMODk4Ljg3MiAzMDUuOTcyTDkxMi4xMTkgMzA4LjA1OUw5MTMuNzMzIDMwMS45NDZDOTE0LjgzNyAyOTcuNzYyIDkxNC4zMDkgMjkzLjQ3NiA5MTIuMjUxIDI4OS45MjdMODkzLjQ4NCAyNTcuNTY5Qzg5MS4xNTMgMjUzLjU0OSA4ODcuMDYzIDI1MC44MjMgODgyLjIyMSAyNTAuMDYxTDgyOC4yMDUgMjQxLjU1NEM4MjIuMjI0IDI0MC42MTMgODE1Ljg2OSAyNDIuNzgzIDgxMS40MjcgMjQ3LjI4NEw4MDUuNjg2IDI1My4xMDNDODA0LjIwNSAyNTQuNjAzIDgwMi4wODcgMjU1LjMyNiA4MDAuMDkzIDI1NS4wMTNMNzgzLjYxMSAyNTIuNDE3TDczNC4zIDQzOS4xOTZDNzMxLjQzOSA0NTAuMDM1IDcyMC4xNDMgNDU3LjQwNyA3MDkuMDcgNDU1LjY2M0wzMjguODQ3IDM5NS43ODhDMzE3Ljc3NCAzOTQuMDQ1IDMxMS4xMTcgMzgzLjg0NSAzMTMuOTc4IDM3My4wMDdMMzY2LjUyOCAxNzMuOTYyTDM2Ni41MzMgMTczLjk0MUMzNjcuMjM0IDE3MS4yNCAzNjUuNTcyIDE2OC43MDIgMzYyLjgxIDE2OC4yNjdMMzE5Ljg0NyAxNjEuNTAyWk0zNjkuMzkyIDE3NC40MTRMMzY4LjY1MiAxNzcuMjE3TDMxNi44NDMgMzczLjQ1OEMzMTQuMzkgMzgyLjc0OCAzMjAuMDk2IDM5MS40OSAzMjkuNTg3IDM5Mi45ODVMNzA5LjgxIDQ1Mi44NkM3MTkuMzAxIDQ1NC4zNTQgNzI4Ljk4MyA0NDguMDM1IDczMS40MzYgNDM4Ljc0NUw3ODAuNzQ3IDI1MS45NjZMNzgzLjI0NSAyNDIuNTA0TDc4My45ODUgMjM5LjcwMUwzNjkuMzkyIDE3NC40MTRaIiBmaWxsPSJ1cmwoI2Rpc2tldHRlLWdyYWRpZW50KSIgZmlsbC1vcGFjaXR5PSIwLjIiIC8+PHBhdGggZD0iTTMzNS4zOCAyMDguMTEzQzMzNS45MjIgMjA4LjE5OCAzMzYuNDE3IDIwNy42ODYgMzM2LjI4MyAyMDcuMTc5TDMzMC4zOSAxODQuNzk1QzMzMC4yNDkgMTg0LjI2MSAzMjkuNTI5IDE4NC4xNDggMzI5LjEyOSAxODQuNTk3TDMxMi4zNTggMjAzLjQxMUMzMTEuOTc4IDIwMy44MzggMzEyLjE3NCAyMDQuNDU4IDMxMi43MTYgMjA0LjU0NEwzMTcuOTYyIDIwNS4zN0MzMTguMzU3IDIwNS40MzIgMzE4LjU5NSAyMDUuNzk2IDMxOC40OTMgMjA2LjE4M0wzMTQuNyAyMjAuNTUxQzMxNC41OTcgMjIwLjkzOCAzMTQuODM1IDIyMS4zMDIgMzE1LjIzMSAyMjEuMzY0TDMyNC41MzkgMjIyLjgzQzMyNC45MzUgMjIyLjg5MyAzMjUuMzM4IDIyMi42MjkgMzI1LjQ0IDIyMi4yNDJMMzI5LjIzMyAyMDcuODc1QzMyOS4zMzYgMjA3LjQ4OCAzMjkuNzM5IDIwNy4yMjQgMzMwLjEzNSAyMDcuMjg2TDMzNS4zOCAyMDguMTEzWiIgZmlsbD0idXJsKCNtYWluKSIgLz48cGF0aCBkPSJNMzE5LjI4MiAyNjkuMDg3QzMxOS44MjQgMjY5LjE3MyAzMjAuMzE5IDI2OC42NjEgMzIwLjE4NiAyNjguMTU0TDMxNC4yOTIgMjQ1Ljc3QzMxNC4xNTEgMjQ1LjIzNiAzMTMuNDMxIDI0NS4xMjMgMzEzLjAzMSAyNDUuNTcyTDI5Ni4yNjEgMjY0LjM4NkMyOTUuODggMjY0LjgxMiAyOTYuMDc2IDI2NS40MzMgMjk2LjYxOCAyNjUuNTE4TDMwMS44NjQgMjY2LjM0NEMzMDIuMjU5IDI2Ni40MDcgMzAyLjQ5NyAyNjYuNzcxIDMwMi4zOTUgMjY3LjE1OEwyOTguNjAyIDI4MS41MjZDMjk4LjUgMjgxLjkxMyAyOTguNzM3IDI4Mi4yNzcgMjk5LjEzMyAyODIuMzM5TDMwOC40NDEgMjgzLjgwNUMzMDguODM3IDI4My44NjcgMzA5LjI0IDI4My42MDQgMzA5LjM0MyAyODMuMjE3TDMxMy4xMzYgMjY4Ljg0OUMzMTMuMjM4IDI2OC40NjIgMzEzLjY0MSAyNjguMTk5IDMxNC4wMzcgMjY4LjI2MUwzMTkuMjgyIDI2OS4wODdaIiBmaWxsPSJibGFjayIgZmlsbC1vcGFjaXR5PSIwLjUiIC8+PHBhdGggZD0iTTMwMy4xODQgMzMwLjA2MkMzMDMuNzI2IDMzMC4xNDggMzA0LjIyMSAzMjkuNjM2IDMwNC4wODggMzI5LjEyOEwyOTguMTk0IDMwNi43NDVDMjk4LjA1MyAzMDYuMjExIDI5Ny4zMzMgMzA2LjA5OCAyOTYuOTMzIDMwNi41NDdMMjgwLjE2MyAzMjUuMzYxQzI3OS43ODIgMzI1Ljc4NyAyNzkuOTc5IDMyNi40MDggMjgwLjUyIDMyNi40OTNMMjg1Ljc2NiAzMjcuMzE5QzI4Ni4xNjEgMzI3LjM4MiAyODYuMzk5IDMyNy43NDYgMjg2LjI5NyAzMjguMTMzTDI4Mi41MDQgMzQyLjUwMUMyODIuNDAyIDM0Mi44ODggMjgyLjYzOSAzNDMuMjUyIDI4My4wMzUgMzQzLjMxNEwyOTIuMzQ0IDM0NC43OEMyOTIuNzM5IDM0NC44NDIgMjkzLjE0MiAzNDQuNTc5IDI5My4yNDUgMzQ0LjE5MkwyOTcuMDM4IDMyOS44MjRDMjk3LjE0IDMyOS40MzcgMjk3LjU0MyAzMjkuMTc0IDI5Ny45MzkgMzI5LjIzNkwzMDMuMTg0IDMzMC4wNjJaIiBmaWxsPSJibGFjayIgZmlsbC1vcGFjaXR5PSIwLjUiIC8+PHBhdGggc3Ryb2tlPSJ1cmwoI21haW4pIiBzdHJva2Utd2lkdGg9IjYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTTI5MC4xMDkgNDYzLjQxOEMyOTIuMzU4IDQ1NC45MDIgMzAxLjIzMyA0NDkuMTEgMzA5LjkzMyA0NTAuNDhMNzcxLjA3IDUyMy4wOTZDNzc5Ljc3IDUyNC40NjcgNzg1IDUzMi40OCA3ODIuNzUyIDU0MC45OTZMNjkyLjA4NiA4ODQuNDE4TDE5OS40NDMgODA2Ljg0TDI5MC4xMDkgNDYzLjQxOFoiIGZpbGw9ImJsYWNrIiBmaWxsLW9wYWNpdHk9IjAuMTQiIC8+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0idXJsKCNtYWluKSIgc3Ryb2tlLXdpZHRoPSI2IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGQ9Ik03ODcuNTg5IDIzNy4zNDlMNDYwLjM1NCAxODUuODE4TDQwNi4zMjUgMzkwLjQ2OUM0MDMuODcyIDM5OS43NTkgNDA5LjU3OCA0MDguNTAxIDQxOS4wNjkgNDA5Ljk5Nkw3MTEuOTM0IDQ1Ni4xMTRDNzIxLjQyNSA0NTcuNjA5IDczMS4xMDcgNDUxLjI5IDczMy41NiA0NDJMNzg3LjU4OSAyMzcuMzQ5Wk02NjAuMjY5IDI0NS4wMUM2NTUuNTIzIDI0NC4yNjMgNjUwLjY4MiAyNDcuNDIzIDY0OS40NTYgMjUyLjA2OEw2MDcuMzg2IDQxMS40MThDNjA2LjE2IDQxNi4wNjMgNjA5LjAxMyA0MjAuNDM0IDYxMy43NTkgNDIxLjE4MUw2ODIuNDk5IDQzMi4wMDZDNjg3LjI0NSA0MzIuNzUzIDY5Mi4wODYgNDI5LjU5NCA2OTMuMzEyIDQyNC45NDlMNzM1LjM4MiAyNjUuNTk5QzczNi42MDggMjYwLjk1NCA3MzMuNzU1IDI1Ni41ODMgNzI5LjAxIDI1NS44MzVMNjYwLjI2OSAyNDUuMDFaIiBmaWxsPSJ1cmwoI21haW4pIiAvPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNODY0LjY0MyAyODMuOTM3Qzg2NS4xODYgMjgzLjYwNSA4NjUuNzA4IDI4NC4yNTcgODY1LjIzOSAyODQuNjgzTDg0NC4yNjggMzAzLjcxOUM4NDMuOTM4IDMwNC4wMTggODQ0LjA5MyAzMDQuNTE3IDg0NC41MjYgMzA0LjU0OEw4NTMuNzI2IDMwNS4yMDdDODU0LjE4NCAzMDUuMjQgODU0LjMyMSAzMDUuNzg3IDg1My45NDIgMzA2LjA3MUw4MzMuODg0IDMyMS4xMTJDODMzLjUwNiAzMjEuMzk2IDgzMy42NDMgMzIxLjk0MyA4MzQuMTAxIDMyMS45NzZMODQ0LjAwNyAzMjIuNjg1Qzg0NC40OTEgMzIyLjcyIDg0NC42MDUgMzIzLjMxOSA4NDQuMTc3IDMyMy41OEw3OTcuNzUyIDM1MS45NTRDNzk3LjIwOSAzNTIuMjg2IDc5Ni42ODcgMzUxLjYzNCA3OTcuMTU2IDM1MS4yMDlMODE4LjQwMyAzMzEuOTIyQzgxOC43MzMgMzMxLjYyMiA4MTguNTc3IDMzMS4xMjMgODE4LjE0NSAzMzEuMDkyTDgwOC43NDggMzMwLjQyQzgwOC4yOTIgMzMwLjM4NyA4MDguMTU0IDMyOS44NDMgODA4LjUyOSAzMjkuNTU4TDgyOC4wNTQgMzE0Ljc0NEM4MjguNDMgMzE0LjQ1OSA4MjguMjkxIDMxMy45MTUgODI3LjgzNSAzMTMuODgyTDgxOC4zODkgMzEzLjIwNkM4MTcuOTA0IDMxMy4xNzEgODE3Ljc5IDMxMi41NzIgODE4LjIxOCAzMTIuMzExTDg2NC42NDMgMjgzLjkzN1oiIGZpbGw9IndoaXRlIiAvPjxnIHRyYW5zZm9ybT0ibWF0cml4KDAuOTg3ODI3IDAuMTU1NTU3IC0wLjI1NTI2MSAwLjk2Njg3MiAyNTAgNzM1KSI+PHRleHQgZm9udC1mYW1pbHk9IkludGVyLCBzYW5zLXNlcmlmIiBmb250LXdlaWdodD0iYm9sZCIgZm9udC1zaXplPSI0MiIgZmlsbD0iI0U1RTdGOCI+RmxlZWsgVGVzdCBBcHA8L3RleHQ+PHRleHQgZm9udC1mYW1pbHk9IkludGVyLCBzYW5zLXNlcmlmIiBmb250LXdlaWdodD0ibm9ybWFsIiB5PSI0MCIgZm9udC1zaXplPSIyMiIgZmlsbD0iIzdGODE5MiI+ZmxlZWsuZXRoPC90ZXh0PjwvZz48aW1hZ2Ugd2lkdGg9IjE2NyIgaGVpZ2h0PSIxNjciIHRyYW5zZm9ybT0ibWF0cml4KDAuOTg3ODI3IDAuMTU1NTU3IC0wLjI1NTI2MSAwLjk2Njg3MiA0NDQuMTE3IDUyNC4xNykiIGhyZWY9ImRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEhOMlp5QjJaWEp6YVc5dVBTSXhMakVpSUhodGJHNXpQU0pvZEhSd09pOHZkM2QzTG5jekxtOXlaeTh5TURBd0wzTjJaeUlnZUcxc2JuTTZlR3hwYm1zOUltaDBkSEE2THk5M2QzY3Vkek11YjNKbkx6RTVPVGt2ZUd4cGJtc2lJSGc5SWpCd2VDSWdlVDBpTUhCNElpQjJhV1YzUW05NFBTSXdJREFnTVRBd01DQXhNREF3SWlCbGJtRmliR1V0WW1GamEyZHliM1Z1WkQwaWJtVjNJREFnTUNBeE1EQXdJREV3TURBaUlIaHRiRHB6Y0dGalpUMGljSEpsYzJWeWRtVWlQZ284Wno0OGNHRjBhQ0JrUFNKTk5UQXdMREV3UXpJeU9TNDBMREV3TERFd0xESXlPUzQwTERFd0xEVXdNR013TERJM01DNDJMREl4T1M0MExEUTVNQ3cwT1RBc05Ea3dZekkzTUM0MkxEQXNORGt3TFRJeE9TNDBMRFE1TUMwME9UQkRPVGt3TERJeU9TNDBMRGMzTUM0MkxERXdMRFV3TUN3eE1Ib2dUVGd4TlN3NE1UVmpMVFF3TGprc05EQXVPUzA0T0M0MkxEY3pMakV0TVRReExqWXNPVFV1TldNdE5UUXVPU3d5TXk0eUxURXhNeTR5TERNMUxURTNNeTQwTERNMVl5MDJNQzR5TERBdE1URTRMalV0TVRFdU9DMHhOek11TkMwek5VTXlOek11Tml3NE9EZ3NNakkxTGprc09EVTFMamtzTVRnMUxEZ3hOWE10TnpNdE9EZ3VOaTA1TlM0MUxURTBNUzQyWXkweU15NHlMVFUwTGprdE16VXRNVEV6TGpJdE16VXRNVGN6TGpSak1DMDJNQzR5TERFeExqZ3RNVEU0TGpVc016VXRNVGN6TGpSak1qSXVOQzAxTXl3MU5DNDJMVEV3TUM0M0xEazFMalV0TVRReExqWnpPRGd1TmkwM015d3hOREV1TmkwNU5TNDFZelUwTGprdE1qTXVNaXd4TVRNdU1pMHpOU3d4TnpNdU5DMHpOV00yTUM0eUxEQXNNVEU0TGpVc01URXVPQ3d4TnpNdU5Dd3pOV00xTXl3eU1pNDBMREV3TUM0M0xEVTBMallzTVRReExqWXNPVFV1TldNME1DNDVMRFF3TGprc056TXNPRGd1Tml3NU5TNDFMREUwTVM0Mll6SXpMaklzTlRRdU9Td3pOU3d4TVRNdU1pd3pOU3d4TnpNdU5HTXdMRFl3TGpJdE1URXVPQ3d4TVRndU5TMHpOU3d4TnpNdU5FTTRPRGdzTnpJMkxqUXNPRFUxTGprc056YzBMakVzT0RFMUxEZ3hOWG9pTHo0OEwyYytDand2YzNablBnPT0iIC8+PGRlZnM+PGZpbHRlciBpZD0iZGlza2V0dGUtc2hhZG93IiB4PSI3MC43NDg5IiB5PSIxOTUuNzEyIiB3aWR0aD0iOTU1LjczMyIgaGVpZ2h0PSI4MzIuNTU4IiBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+PGZlRmxvb2QgZmxvb2Qtb3BhY2l0eT0iMCIgLz48ZmVCbGVuZCBpbj0iU291cmNlR3JhcGhpYyIgLz48ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSI0MiIgLz48L2ZpbHRlcj48bGluZWFyR3JhZGllbnQgaWQ9ImJhY2tncm91bmQiIHgxPSI1MzIuNSIgeTE9IjAiIHgyPSI1MzIuNSIgeTI9IjEwNjUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj48c3RvcCAvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzEzMTMxMyIgLz48L2xpbmVhckdyYWRpZW50PjxyYWRpYWxHcmFkaWVudCBpZD0iYmFja2dyb3VuZC1yYWRpYWwiIGN4PSIwIiBjeT0iMCIgcj0iMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoNTMyLjUgNTMyLjUpIHJvdGF0ZSg4OS45NjEpIHNjYWxlKDczNSkiPjxzdG9wIHN0b3AtY29sb3I9IiMxMjM0NTYiIC8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMTIzNDU2IiBzdG9wLW9wYWNpdHk9IjAiIC8+PC9yYWRpYWxHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImRpc2tldHRlLWdyYWRpZW50IiB4MT0iOTI1LjYyNiIgeTE9IjI1Ni44OTYiIHgyPSIxMzYuNzc5IiB5Mj0iODAwLjIwMyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPjxzdG9wIHN0b3AtY29sb3I9IiMxMjM0NTYiIC8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMkMzMTNGIiAvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJtYWluIj48c3RvcCBzdG9wLWNvbG9yPSIjMTIzNDU2IiAvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjwvc3ZnPg=='
+ );
+ });
+ });
});
diff --git a/test/deploy/proxy.ts b/test/deploy/proxy.ts
deleted file mode 100644
index afc1ed2..0000000
--- a/test/deploy/proxy.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { expect } from 'chai';
-import { ethers, upgrades } from 'hardhat';
-
-describe('Proxy', function () {
- it('FleekERC721', async () => {
- const Contract = await ethers.getContractFactory('FleekERC721');
- const ContractV2 = await ethers.getContractFactory('FleekERC721');
-
- const instance = await upgrades.deployProxy(Contract, [
- 'Collection Name',
- 'SYMBOL',
- ]);
- const upgraded = await upgrades.upgradeProxy(instance.address, ContractV2);
-
- const name = await upgraded.name();
- const symbol = await upgraded.symbol();
- expect(name).to.equal('Collection Name');
- expect(symbol).to.equal('SYMBOL');
- });
-});
diff --git a/test/foundry/apps.t.sol b/test/foundry/apps.t.sol
index 79173d3..57194b1 100644
--- a/test/foundry/apps.t.sol
+++ b/test/foundry/apps.t.sol
@@ -2,15 +2,17 @@ pragma solidity ^0.8.7;
import "forge-std/Test.sol";
import "../../contracts/FleekERC721.sol";
-import "../../contracts/util/FleekStrings.sol";
+import "./constants.t.sol";
contract FleekTest is Test {
FleekERC721 fleekContract;
using Strings for uint160;
- address constant DEPLOYER = 0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496;
+ using Strings for address;
string constant FLEEK_AP_URL = "https://fleek_cloned.xyz";
+ address DEPLOYER;
function setUp() public {
+ DEPLOYER = address(this);
fleekContract = new FleekERC721();
fleekContract.initialize("Test Contract", "FLKAPS");
}
@@ -31,7 +33,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -46,7 +50,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
uint256 second_mint = fleekContract.mint(
@@ -56,7 +62,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(first_mint, 0);
@@ -71,7 +79,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(first_mint, 0);
@@ -83,7 +93,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(second_mint, 1);
@@ -97,7 +109,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(first_mint, 0);
@@ -109,43 +123,14 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(second_mint, 1);
}
- function _generateSVG(string memory name, string memory ENS) internal pure returns (string memory) {
- return (
- string(
- abi.encodePacked(
- "data:application/json;base64,",
- Base64.encode(
- abi.encodePacked(
- '',
- "",
- "",
- '',
- '',
- "",
- '',
- 'Fleek NFAs',
- "",
- '',
- '',
- name,
- '',
- ENS,
- "",
- "",
- ""
- )
- )
- )
- )
- );
- }
-
function testTokenURI() public {
string memory name = "Foundry Test App";
string memory ens = "fleek_xyz";
@@ -157,38 +142,16 @@ contract FleekTest is Test {
"https://fleek.xyz",
ens,
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
string memory tokenURI = fleekContract.tokenURI(mint);
- bytes memory dataURI = abi.encodePacked(
- "{",
- '"name":"',
- name,
- '",',
- '"description":"This is a test application submitted by foundry tests.",',
- '"owner":"',
- Strings.toHexString(uint160(DEPLOYER), 20),
- '",',
- '"external_url":"https://fleek.xyz",',
- '"image":"',
- _generateSVG(name, ens),
- '",',
- '"attributes": [',
- '{"trait_type": "ENS", "value":"',
- ens,
- '"},',
- '{"trait_type": "Commit Hash", "value":"afff3f6"},',
- '{"trait_type": "Repository", "value":"https://github.com/fleekxyz/non-fungible-apps"},',
- '{"trait_type": "Version", "value":"0"}',
- "]",
- "}"
- );
-
- assertEq(tokenURI, string(abi.encodePacked("data:application/json;base64,", Base64.encode((dataURI)))));
+ assertEq(tokenURI, TestConstants.DEFAULT_TOKEN_URI);
}
function testCallingTokenURIAfterChangingAllPossibleFields() public {
@@ -199,7 +162,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -212,27 +177,10 @@ contract FleekTest is Test {
string memory tokenURI = fleekContract.tokenURI(mint);
- bytes memory dataURI = abi.encodePacked(
- "{",
- '"name":"Foundry Test App 2",',
- '"description":"This is a test application submitted by foundry tests. 2",',
- '"owner":"',
- Strings.toHexString(uint160(DEPLOYER), 20),
- '",',
- '"external_url":"https://fleek2.xyz",',
- '"image":"',
- _generateSVG("Foundry Test App 2", "fleek_xyz2"),
- '",',
- '"attributes": [',
- '{"trait_type": "ENS", "value":"fleek_xyz2"},',
- '{"trait_type": "Commit Hash", "value":"afff3f62"},',
- '{"trait_type": "Repository", "value":"https://github.com/fleekxyz/non-fungible-apps2"},',
- '{"trait_type": "Version", "value":"1"}',
- "]",
- "}"
+ assertEq(
+ tokenURI,
+ "data:application/json;base64,eyJuYW1lIjoiRm91bmRyeSBUZXN0IEFwcCAyIiwiZGVzY3JpcHRpb24iOiJUaGlzIGlzIGEgdGVzdCBhcHBsaWNhdGlvbiBzdWJtaXR0ZWQgYnkgZm91bmRyeSB0ZXN0cy4gMiIsIm93bmVyIjoiMHgzNGExZDNmZmYzOTU4ODQzYzQzYWQ4MGYzMGI5NGM1MTA2NDVjMzE2IiwiZXh0ZXJuYWxfdXJsIjoiaHR0cHM6Ly9mbGVlazIueHl6IiwiaW1hZ2UiOiJkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBITjJaeUIzYVdSMGFEMGlNVEEyTlNJZ2FHVnBaMmgwUFNJeE1EWTFJaUIyYVdWM1FtOTRQU0l3SURBZ01UQTJOU0F4TURZMUlpQm1hV3hzUFNKdWIyNWxJaUI0Yld4dWN6MGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNakF3TUM5emRtY2lJSGh0Ykc1ek9uaHNhVzVyUFNKb2RIUndPaTh2ZDNkM0xuY3pMbTl5Wnk4eE9UazVMM2hzYVc1cklqNDhjM1I1YkdVZ2RIbHdaVDBpZEdWNGRDOWpjM01pUGtCcGJYQnZjblFnZFhKc0tDSm9kSFJ3Y3pvdkwyWnZiblJ6TG1kdmIyZHNaV0Z3YVhNdVkyOXRMMk56Y3pJL1ptRnRhV3g1UFVsdWRHVnlPbmRuYUhSQU5UQXdPell3TUNJcE96d3ZjM1I1YkdVK1BISmxZM1FnZDJsa2RHZzlJakV3TmpVaUlHaGxhV2RvZEQwaU1UQTJOU0lnWm1sc2JEMGlkWEpzS0NOaVlXTnJaM0p2ZFc1a0tTSWdMejQ4Y21WamRDQnZjR0ZqYVhSNVBTSXdMaklpSUhkcFpIUm9QU0l4TURZMUlpQm9aV2xuYUhROUlqRXdOalVpSUdacGJHdzlJblZ5YkNnalltRmphMmR5YjNWdVpDMXlZV1JwWVd3cElpQXZQanhuSUdacGJIUmxjajBpZFhKc0tDTmthWE5yWlhSMFpTMXphR0ZrYjNjcElqNDhjR0YwYUNCa1BTSk5PRFUzTGpJek1TQXlOemt1TnpFeVREa3dNaTR5TkNBeU9EWXVOamMxUXpreE1DNDFORGNnTWpnM0xqazJJRGt4Tnk0NU1UVWdNamt5TGpjeU1TQTVNakl1TlNBeU9Ua3VOelk0VERrek9DNDRPVFFnTXpJMExqazJORU01TkRJdU1qUTVJRE16TUM0eE1pQTVORE11TXpFeElETXpOaTQwTXpjZ09UUXhMamd5TnlBek5ESXVOREEyVERrek55NDNPVGdnTXpVNExqWXhOVXc1TWpRdU1EUTVJRE0xTmk0Mk5VdzVNVGt1TkRFMklETTNOQzR3T0RSTU9UTTBMakEyT0NBek56WXVNalJNTnpreExqazBOeUE1TWpJdU1UVXlRemM0T0M0eE1Ea2dPVE0yTGpnNU5pQTNOek11TmprMElEazBOaTR6TURnZ056VTRMalkxTVNBNU5ETXVPRGt6VERFM09TNDJNellnT0RVd0xqa3lPRU14TmpJdU16RTRJRGcwT0M0eE5EY2dNVFV4TGpJeE5TQTRNekF1T1RnM0lERTFOUzQzTnpZZ09ERTBMakExTVV3eE5qQXVORGM0SURjNU5pNDFPVXczTURRdU16RTFJRGczT1M0MU56Uk1PRFUzTGpJek1TQXlOemt1TnpFeVdpSWdabWxzYkQwaUl6QTFNRFV3TlNJZ0x6NDhMMmMrUEhCaGRHZ2daRDBpVFRnME1DNHlNekVnTWpRd0xqY3hNa3c0T0RVdU1qUWdNalEzTGpZM05VTTRPVE11TlRRM0lESTBPQzQ1TmpFZ09UQXdMamt4TlNBeU5UTXVOekl5SURrd05TNDFJREkyTUM0M05qaE1PVEl4TGpnNU5DQXlPRFV1T1RZMVF6a3lOUzR5TkRrZ01qa3hMakV5SURreU5pNHpNVEVnTWprM0xqUXpOeUE1TWpRdU9ESTNJRE13TXk0ME1EWk1PVEl3TGpjNU9DQXpNVGt1TmpFMlREa3dOeTR3TkRrZ016RTNMalkxVERrd01pNDBNVFlnTXpNMUxqQTRORXc1TVRjdU1EWTRJRE16Tnk0eU5ERk1OemMwTGprME55QTRPRE11TVRVeVF6YzNNUzR4TURrZ09EazNMamc1TmlBM05UWXVOamswSURrd055NHpNRGdnTnpReExqWTFNU0E1TURRdU9Ea3pUREUyTWk0Mk16WWdPREV4TGpreU9FTXhORFV1TXpFNElEZ3dPUzR4TkRjZ01UTTBMakl4TlNBM09URXVPVGczSURFek9DNDNOellnTnpjMUxqQTFNVXd4TkRNdU5EYzRJRGMxTnk0MU9VdzJPRGN1TXpFMUlEZzBNQzQxTnpSTU9EUXdMakl6TVNBeU5EQXVOekV5V2lJZ1ptbHNiRDBpZFhKc0tDTnRZV2x1S1NJZ0x6NDhjR0YwYUNCbWFXeHNMWEoxYkdVOUltVjJaVzV2WkdRaUlHTnNhWEF0Y25Wc1pUMGlaWFpsYm05a1pDSWdaRDBpVFRNeE9TNDRORGNnTVRZeExqVXdNa016TVRBdU16VTJJREUyTUM0d01EY2dNekF3TGpZM05DQXhOall1TXpJMklESTVPQzR5TWpFZ01UYzFMall4Tmt3eE16Z3VOekkwSURjM09TNDNOVGhETVRNMkxqSTNNU0EzT0RrdU1EUTRJREUwTVM0NU56Y2dOemszTGpjNUlERTFNUzQwTmpnZ056azVMakk0TlV3M05EQXVNRFl4SURnNU1TNDVOek5ETnpRNUxqVTFNeUE0T1RNdU5EWTNJRGMxT1M0eU16VWdPRGczTGpFME9DQTNOakV1TmpnM0lEZzNOeTQ0TlRoTU9UQXlMalF3TlNBek5EUXVPRFUwVERnNE9TNHhOVGdnTXpReUxqYzJPRXc0T1RndU9EY3lJRE13TlM0NU56Sk1PVEV5TGpFeE9TQXpNRGd1TURVNVREa3hNeTQzTXpNZ016QXhMamswTmtNNU1UUXVPRE0zSURJNU55NDNOaklnT1RFMExqTXdPU0F5T1RNdU5EYzJJRGt4TWk0eU5URWdNamc1TGpreU4wdzRPVE11TkRnMElESTFOeTQxTmpsRE9Ea3hMakUxTXlBeU5UTXVOVFE1SURnNE55NHdOak1nTWpVd0xqZ3lNeUE0T0RJdU1qSXhJREkxTUM0d05qRk1PREk0TGpJd05TQXlOREV1TlRVMFF6Z3lNaTR5TWpRZ01qUXdMall4TXlBNE1UVXVPRFk1SURJME1pNDNPRE1nT0RFeExqUXlOeUF5TkRjdU1qZzBURGd3TlM0Mk9EWWdNalV6TGpFd00wTTRNRFF1TWpBMUlESTFOQzQyTURNZ09EQXlMakE0TnlBeU5UVXVNekkySURnd01DNHdPVE1nTWpVMUxqQXhNMHczT0RNdU5qRXhJREkxTWk0ME1UZE1Oek0wTGpNZ05ETTVMakU1TmtNM016RXVORE01SURRMU1DNHdNelVnTnpJd0xqRTBNeUEwTlRjdU5EQTNJRGN3T1M0d055QTBOVFV1TmpZelRETXlPQzQ0TkRjZ016azFMamM0T0VNek1UY3VOemMwSURNNU5DNHdORFVnTXpFeExqRXhOeUF6T0RNdU9EUTFJRE14TXk0NU56Z2dNemN6TGpBd04wd3pOall1TlRJNElERTNNeTQ1TmpKTU16WTJMalV6TXlBeE56TXVPVFF4UXpNMk55NHlNelFnTVRjeExqSTBJRE0yTlM0MU56SWdNVFk0TGpjd01pQXpOakl1T0RFZ01UWTRMakkyTjB3ek1Ua3VPRFEzSURFMk1TNDFNREphVFRNMk9TNHpPVElnTVRjMExqUXhORXd6TmpndU5qVXlJREUzTnk0eU1UZE1NekUyTGpnME15QXpOek11TkRVNFF6TXhOQzR6T1NBek9ESXVOelE0SURNeU1DNHdPVFlnTXpreExqUTVJRE15T1M0MU9EY2dNemt5TGprNE5VdzNNRGt1T0RFZ05EVXlMamcyUXpjeE9TNHpNREVnTkRVMExqTTFOQ0EzTWpndU9UZ3pJRFEwT0M0d016VWdOek14TGpRek5pQTBNemd1TnpRMVREYzRNQzQzTkRjZ01qVXhMamsyTmt3M09ETXVNalExSURJME1pNDFNRFJNTnpnekxqazROU0F5TXprdU56QXhURE0yT1M0ek9USWdNVGMwTGpReE5Gb2lJR1pwYkd3OUlpTXhNekV6TVRZaUlDOCtQSEJoZEdnZ1ptbHNiQzF5ZFd4bFBTSmxkbVZ1YjJSa0lpQmpiR2x3TFhKMWJHVTlJbVYyWlc1dlpHUWlJSE4wY205clpUMGlkWEpzS0NOdFlXbHVLU0lnYzNSeWIydGxMWGRwWkhSb1BTSTBJaUJ6ZEhKdmEyVXRiR2x1WldOaGNEMGljbTkxYm1RaUlITjBjbTlyWlMxc2FXNWxhbTlwYmowaWNtOTFibVFpSUdROUlrMHpNVGt1T0RRM0lERTJNUzQxTURKRE16RXdMak0xTmlBeE5qQXVNREEzSURNd01DNDJOelFnTVRZMkxqTXlOaUF5T1RndU1qSXhJREUzTlM0Mk1UWk1NVE00TGpjeU5DQTNOemt1TnpVNFF6RXpOaTR5TnpFZ056ZzVMakEwT0NBeE5ERXVPVGMzSURjNU55NDNPU0F4TlRFdU5EWTRJRGM1T1M0eU9EVk1OelF3TGpBMk1TQTRPVEV1T1RjelF6YzBPUzQxTlRNZ09Ea3pMalEyTnlBM05Ua3VNak0xSURnNE55NHhORGdnTnpZeExqWTROeUE0TnpjdU9EVTRURGt3TWk0ME1EVWdNelEwTGpnMU5FdzRPRGt1TVRVNElETTBNaTQzTmpoTU9EazRMamczTWlBek1EVXVPVGN5VERreE1pNHhNVGtnTXpBNExqQTFPVXc1TVRNdU56TXpJRE13TVM0NU5EWkRPVEUwTGpnek55QXlPVGN1TnpZeUlEa3hOQzR6TURrZ01qa3pMalEzTmlBNU1USXVNalV4SURJNE9TNDVNamRNT0RrekxqUTROQ0F5TlRjdU5UWTVRemc1TVM0eE5UTWdNalV6TGpVME9TQTRPRGN1TURZeklESTFNQzQ0TWpNZ09EZ3lMakl5TVNBeU5UQXVNRFl4VERneU9DNHlNRFVnTWpReExqVTFORU00TWpJdU1qSTBJREkwTUM0Mk1UTWdPREUxTGpnMk9TQXlOREl1TnpneklEZ3hNUzQwTWpjZ01qUTNMakk0TkV3NE1EVXVOamcySURJMU15NHhNRE5ET0RBMExqSXdOU0F5TlRRdU5qQXpJRGd3TWk0d09EY2dNalUxTGpNeU5pQTRNREF1TURreklESTFOUzR3TVROTU56Z3pMall4TVNBeU5USXVOREUzVERjek5DNHpJRFF6T1M0eE9UWkROek14TGpRek9TQTBOVEF1TURNMUlEY3lNQzR4TkRNZ05EVTNMalF3TnlBM01Ea3VNRGNnTkRVMUxqWTJNMHd6TWpndU9EUTNJRE01TlM0M09EaERNekUzTGpjM05DQXpPVFF1TURRMUlETXhNUzR4TVRjZ016Z3pMamcwTlNBek1UTXVPVGM0SURNM015NHdNRGRNTXpZMkxqVXlPQ0F4TnpNdU9UWXlURE0yTmk0MU16TWdNVGN6TGprME1VTXpOamN1TWpNMElERTNNUzR5TkNBek5qVXVOVGN5SURFMk9DNDNNRElnTXpZeUxqZ3hJREUyT0M0eU5qZE1NekU1TGpnME55QXhOakV1TlRBeVdrMHpOamt1TXpreUlERTNOQzQwTVRSTU16WTRMalkxTWlBeE56Y3VNakUzVERNeE5pNDRORE1nTXpjekxqUTFPRU16TVRRdU16a2dNemd5TGpjME9DQXpNakF1TURrMklETTVNUzQwT1NBek1qa3VOVGczSURNNU1pNDVPRFZNTnpBNUxqZ3hJRFExTWk0NE5rTTNNVGt1TXpBeElEUTFOQzR6TlRRZ056STRMams0TXlBME5EZ3VNRE0xSURjek1TNDBNellnTkRNNExqYzBOVXczT0RBdU56UTNJREkxTVM0NU5qWk1Oemd6TGpJME5TQXlOREl1TlRBMFREYzRNeTQ1T0RVZ01qTTVMamN3TVV3ek5qa3VNemt5SURFM05DNDBNVFJhSWlCbWFXeHNQU0oxY213b0kyUnBjMnRsZEhSbExXZHlZV1JwWlc1MEtTSWdabWxzYkMxdmNHRmphWFI1UFNJd0xqSWlJQzgrUEhCaGRHZ2daRDBpVFRNek5TNHpPQ0F5TURndU1URXpRek16TlM0NU1qSWdNakE0TGpFNU9DQXpNell1TkRFM0lESXdOeTQyT0RZZ016TTJMakk0TXlBeU1EY3VNVGM1VERNek1DNHpPU0F4T0RRdU56azFRek16TUM0eU5Ea2dNVGcwTGpJMk1TQXpNamt1TlRJNUlERTROQzR4TkRnZ016STVMakV5T1NBeE9EUXVOVGszVERNeE1pNHpOVGdnTWpBekxqUXhNVU16TVRFdU9UYzRJREl3TXk0NE16Z2dNekV5TGpFM05DQXlNRFF1TkRVNElETXhNaTQzTVRZZ01qQTBMalUwTkV3ek1UY3VPVFl5SURJd05TNHpOME16TVRndU16VTNJREl3TlM0ME16SWdNekU0TGpVNU5TQXlNRFV1TnprMklETXhPQzQwT1RNZ01qQTJMakU0TTB3ek1UUXVOeUF5TWpBdU5UVXhRek14TkM0MU9UY2dNakl3TGprek9DQXpNVFF1T0RNMUlESXlNUzR6TURJZ016RTFMakl6TVNBeU1qRXVNelkwVERNeU5DNDFNemtnTWpJeUxqZ3pRek15TkM0NU16VWdNakl5TGpnNU15QXpNalV1TXpNNElESXlNaTQyTWprZ016STFMalEwSURJeU1pNHlOREpNTXpJNUxqSXpNeUF5TURjdU9EYzFRek15T1M0ek16WWdNakEzTGpRNE9DQXpNamt1TnpNNUlESXdOeTR5TWpRZ016TXdMakV6TlNBeU1EY3VNamcyVERNek5TNHpPQ0F5TURndU1URXpXaUlnWm1sc2JEMGlkWEpzS0NOdFlXbHVLU0lnTHo0OGNHRjBhQ0JrUFNKTk16RTVMakk0TWlBeU5qa3VNRGczUXpNeE9TNDRNalFnTWpZNUxqRTNNeUF6TWpBdU16RTVJREkyT0M0Mk5qRWdNekl3TGpFNE5pQXlOamd1TVRVMFRETXhOQzR5T1RJZ01qUTFMamMzUXpNeE5DNHhOVEVnTWpRMUxqSXpOaUF6TVRNdU5ETXhJREkwTlM0eE1qTWdNekV6TGpBek1TQXlORFV1TlRjeVRESTVOaTR5TmpFZ01qWTBMak00TmtNeU9UVXVPRGdnTWpZMExqZ3hNaUF5T1RZdU1EYzJJREkyTlM0ME16TWdNamsyTGpZeE9DQXlOalV1TlRFNFRETXdNUzQ0TmpRZ01qWTJMak0wTkVNek1ESXVNalU1SURJMk5pNDBNRGNnTXpBeUxqUTVOeUF5TmpZdU56Y3hJRE13TWk0ek9UVWdNalkzTGpFMU9Fd3lPVGd1TmpBeUlESTRNUzQxTWpaRE1qazRMalVnTWpneExqa3hNeUF5T1RndU56TTNJREk0TWk0eU56Y2dNams1TGpFek15QXlPREl1TXpNNVRETXdPQzQwTkRFZ01qZ3pMamd3TlVNek1EZ3VPRE0zSURJNE15NDROamNnTXpBNUxqSTBJREk0TXk0Mk1EUWdNekE1TGpNME15QXlPRE11TWpFM1RETXhNeTR4TXpZZ01qWTRMamcwT1VNek1UTXVNak00SURJMk9DNDBOaklnTXpFekxqWTBNU0F5TmpndU1UazVJRE14TkM0d016Y2dNalk0TGpJMk1Vd3pNVGt1TWpneUlESTJPUzR3T0RkYUlpQm1hV3hzUFNKaWJHRmpheUlnWm1sc2JDMXZjR0ZqYVhSNVBTSXdMalVpSUM4K1BIQmhkR2dnWkQwaVRUTXdNeTR4T0RRZ016TXdMakEyTWtNek1ETXVOekkySURNek1DNHhORGdnTXpBMExqSXlNU0F6TWprdU5qTTJJRE13TkM0d09EZ2dNekk1TGpFeU9Fd3lPVGd1TVRrMElETXdOaTQzTkRWRE1qazRMakExTXlBek1EWXVNakV4SURJNU55NHpNek1nTXpBMkxqQTVPQ0F5T1RZdU9UTXpJRE13Tmk0MU5EZE1Namd3TGpFMk15QXpNalV1TXpZeFF6STNPUzQzT0RJZ016STFMamM0TnlBeU56a3VPVGM1SURNeU5pNDBNRGdnTWpnd0xqVXlJRE15Tmk0ME9UTk1NamcxTGpjMk5pQXpNamN1TXpFNVF6STROaTR4TmpFZ016STNMak00TWlBeU9EWXVNems1SURNeU55NDNORFlnTWpnMkxqSTVOeUF6TWpndU1UTXpUREk0TWk0MU1EUWdNelF5TGpVd01VTXlPREl1TkRBeUlETTBNaTQ0T0RnZ01qZ3lMall6T1NBek5ETXVNalV5SURJNE15NHdNelVnTXpRekxqTXhORXd5T1RJdU16UTBJRE0wTkM0M09FTXlPVEl1TnpNNUlETTBOQzQ0TkRJZ01qa3pMakUwTWlBek5EUXVOVGM1SURJNU15NHlORFVnTXpRMExqRTVNa3d5T1RjdU1ETTRJRE15T1M0NE1qUkRNamszTGpFMElETXlPUzQwTXpjZ01qazNMalUwTXlBek1qa3VNVGMwSURJNU55NDVNemtnTXpJNUxqSXpOa3d6TURNdU1UZzBJRE16TUM0d05qSmFJaUJtYVd4c1BTSmliR0ZqYXlJZ1ptbHNiQzF2Y0dGamFYUjVQU0l3TGpVaUlDOCtQSEJoZEdnZ2MzUnliMnRsUFNKMWNtd29JMjFoYVc0cElpQnpkSEp2YTJVdGQybGtkR2c5SWpZaUlITjBjbTlyWlMxc2FXNWxZMkZ3UFNKeWIzVnVaQ0lnYzNSeWIydGxMV3hwYm1WcWIybHVQU0p5YjNWdVpDSWdaRDBpVFRJNU1DNHhNRGtnTkRZekxqUXhPRU15T1RJdU16VTRJRFExTkM0NU1ESWdNekF4TGpJek15QTBORGt1TVRFZ016QTVMamt6TXlBME5UQXVORGhNTnpjeExqQTNJRFV5TXk0d09UWkROemM1TGpjM0lEVXlOQzQwTmpjZ056ZzFJRFV6TWk0ME9DQTNPREl1TnpVeUlEVTBNQzQ1T1RaTU5qa3lMakE0TmlBNE9EUXVOREU0VERFNU9TNDBORE1nT0RBMkxqZzBUREk1TUM0eE1Ea2dORFl6TGpReE9Gb2lJR1pwYkd3OUltSnNZV05ySWlCbWFXeHNMVzl3WVdOcGRIazlJakF1TVRRaUlDOCtQSEJoZEdnZ1ptbHNiQzF5ZFd4bFBTSmxkbVZ1YjJSa0lpQmpiR2x3TFhKMWJHVTlJbVYyWlc1dlpHUWlJSE4wY205clpUMGlkWEpzS0NOdFlXbHVLU0lnYzNSeWIydGxMWGRwWkhSb1BTSTJJaUJ6ZEhKdmEyVXRiR2x1WldOaGNEMGljbTkxYm1RaUlITjBjbTlyWlMxc2FXNWxhbTlwYmowaWNtOTFibVFpSUdROUlrMDNPRGN1TlRnNUlESXpOeTR6TkRsTU5EWXdMak0xTkNBeE9EVXVPREU0VERRd05pNHpNalVnTXprd0xqUTJPVU0wTURNdU9EY3lJRE01T1M0M05Ua2dOREE1TGpVM09DQTBNRGd1TlRBeElEUXhPUzR3TmprZ05EQTVMams1Tmt3M01URXVPVE0wSURRMU5pNHhNVFJETnpJeExqUXlOU0EwTlRjdU5qQTVJRGN6TVM0eE1EY2dORFV4TGpJNUlEY3pNeTQxTmlBME5ESk1OemczTGpVNE9TQXlNemN1TXpRNVdrMDJOakF1TWpZNUlESTBOUzR3TVVNMk5UVXVOVEl6SURJME5DNHlOak1nTmpVd0xqWTRNaUF5TkRjdU5ESXpJRFkwT1M0ME5UWWdNalV5TGpBMk9FdzJNRGN1TXpnMklEUXhNUzQwTVRoRE5qQTJMakUySURReE5pNHdOak1nTmpBNUxqQXhNeUEwTWpBdU5ETTBJRFl4TXk0M05Ua2dOREl4TGpFNE1VdzJPREl1TkRrNUlEUXpNaTR3TURaRE5qZzNMakkwTlNBME16SXVOelV6SURZNU1pNHdPRFlnTkRJNUxqVTVOQ0EyT1RNdU16RXlJRFF5TkM0NU5EbE1Oek0xTGpNNE1pQXlOalV1TlRrNVF6Y3pOaTQyTURnZ01qWXdMamsxTkNBM016TXVOelUxSURJMU5pNDFPRE1nTnpJNUxqQXhJREkxTlM0NE16Vk1Oall3TGpJMk9TQXlORFV1TURGYUlpQm1hV3hzUFNKMWNtd29JMjFoYVc0cElpQXZQanh3WVhSb0lHWnBiR3d0Y25Wc1pUMGlaWFpsYm05a1pDSWdZMnhwY0MxeWRXeGxQU0psZG1WdWIyUmtJaUJrUFNKTk9EWTBMalkwTXlBeU9ETXVPVE0zUXpnMk5TNHhPRFlnTWpnekxqWXdOU0E0TmpVdU56QTRJREk0TkM0eU5UY2dPRFkxTGpJek9TQXlPRFF1TmpnelREZzBOQzR5TmpnZ016QXpMamN4T1VNNE5ETXVPVE00SURNd05DNHdNVGdnT0RRMExqQTVNeUF6TURRdU5URTNJRGcwTkM0MU1qWWdNekEwTGpVME9FdzROVE11TnpJMklETXdOUzR5TURkRE9EVTBMakU0TkNBek1EVXVNalFnT0RVMExqTXlNU0F6TURVdU56ZzNJRGcxTXk0NU5ESWdNekEyTGpBM01VdzRNek11T0RnMElETXlNUzR4TVRKRE9ETXpMalV3TmlBek1qRXVNemsySURnek15NDJORE1nTXpJeExqazBNeUE0TXpRdU1UQXhJRE15TVM0NU56Wk1PRFEwTGpBd055QXpNakl1TmpnMVF6ZzBOQzQwT1RFZ016SXlMamN5SURnME5DNDJNRFVnTXpJekxqTXhPU0E0TkRRdU1UYzNJRE15TXk0MU9FdzNPVGN1TnpVeUlETTFNUzQ1TlRSRE56azNMakl3T1NBek5USXVNamcySURjNU5pNDJPRGNnTXpVeExqWXpOQ0EzT1RjdU1UVTJJRE0xTVM0eU1EbE1PREU0TGpRd015QXpNekV1T1RJeVF6Z3hPQzQzTXpNZ016TXhMall5TWlBNE1UZ3VOVGMzSURNek1TNHhNak1nT0RFNExqRTBOU0F6TXpFdU1Ea3lURGd3T0M0M05EZ2dNek13TGpReVF6Z3dPQzR5T1RJZ016TXdMak00TnlBNE1EZ3VNVFUwSURNeU9TNDRORE1nT0RBNExqVXlPU0F6TWprdU5UVTRURGd5T0M0d05UUWdNekUwTGpjME5FTTRNamd1TkRNZ016RTBMalExT1NBNE1qZ3VNamt4SURNeE15NDVNVFVnT0RJM0xqZ3pOU0F6TVRNdU9EZ3lURGd4T0M0ek9Ea2dNekV6TGpJd05rTTRNVGN1T1RBMElETXhNeTR4TnpFZ09ERTNMamM1SURNeE1pNDFOeklnT0RFNExqSXhPQ0F6TVRJdU16RXhURGcyTkM0Mk5ETWdNamd6TGprek4xb2lJR1pwYkd3OUluZG9hWFJsSWlBdlBqeG5JSFJ5WVc1elptOXliVDBpYldGMGNtbDRLREF1T1RnM09ESTNJREF1TVRVMU5UVTNJQzB3TGpJMU5USTJNU0F3TGprMk5qZzNNaUF5TlRBZ056TTFLU0krUEhSbGVIUWdabTl1ZEMxbVlXMXBiSGs5SWtsdWRHVnlMQ0J6WVc1ekxYTmxjbWxtSWlCbWIyNTBMWGRsYVdkb2REMGlZbTlzWkNJZ1ptOXVkQzF6YVhwbFBTSTBNaUlnWm1sc2JEMGlJMFUxUlRkR09DSStSbTkxYm1SeWVTQlVaWE4wSUVGd2NDQXlQQzkwWlhoMFBqeDBaWGgwSUdadmJuUXRabUZ0YVd4NVBTSkpiblJsY2l3Z2MyRnVjeTF6WlhKcFppSWdabTl1ZEMxM1pXbG5hSFE5SW01dmNtMWhiQ0lnZVQwaU5EQWlJR1p2Ym5RdGMybDZaVDBpTWpJaUlHWnBiR3c5SWlNM1JqZ3hPVElpUG1ac1pXVnJYM2g1ZWpJOEwzUmxlSFErUEM5blBqeHBiV0ZuWlNCM2FXUjBhRDBpTVRZM0lpQm9aV2xuYUhROUlqRTJOeUlnZEhKaGJuTm1iM0p0UFNKdFlYUnlhWGdvTUM0NU9EYzRNamNnTUM0eE5UVTFOVGNnTFRBdU1qVTFNall4SURBdU9UWTJPRGN5SURRME5DNHhNVGNnTlRJMExqRTNLU0lnYUhKbFpqMGlaR0YwWVRwcGJXRm5aUzl6ZG1jcmVHMXNPMkpoYzJVMk5DeFFTRTR5V25sQ2JXRlhlSE5RVTBwMVlqSTFiRWxwUW05YVYyeHVZVWhST1VscVNURk5SRUZwU1Voa2NGcElVbTlRVTBsNVRWUm5la2xwUWpSaVYzaDFZM293YVdGSVVqQmpSRzkyVEROa00yUjVOVE5OZVRWMlkyMWpkazFxUVhkTlF6bDZaRzFqYVVsSVduQmFXR1JEWWpObk9VbHFRV2ROUTBGNFRXcFJaMDFVVVhoTWFsVjZUVlJyTlU5VWF6VlBWR3MxVDFSck5FbHFORGhqUjBZd1lVTkNhMUJUU2s1TlZFRjFUWHBuZWtsRVJYbE9hVFEwVDFSU1RVMURRWGRpUkVWNVRrTkJkVTFxVlRGTVZFVjNUR3ByTTA5VFFYaE5hbGwxVG1wTk5VeFVWWGRNYWxVeFRYbEJlRTVETkRKTmVtZzJTV2xDYldGWGVITlFVMGxxV2xSTk1GcHFTVEpKYVRnclVFaENhR1JIWjJkYVJEQnBWRlJaZVV4cVVUSlBRMEY0VFdwcmRVMXFZek5XYWtWNVRHcEJORTVYZHpGTlV6UjNUbXBSZFUxVVkzUlBVelI0VFVSWlowMVVRVEJNYW1jeFRWaHZhVWxIV25CaVIzYzVTV2xPYkZwcVdURk5iVVZwVEhvME9HTkhSakJoUTBKclVGTktUazlVYTNWT1JHdG5Ua1JGZFUxNldYbGlSRVYxVGtSUk1reFVSVEZNYWxFMVUwUkplVXhxVFRSTk1uY3dUR3BOTUVsRVVUTk1hbEUxWVVSVk1FeHFTWGhOTUhjelQwTTBORTFUUVRWTmVUUXlUVlJrYzB4VVJUTk1hazB5VFdsQk1FeHFXVFJNVkVVelRHcFplRTU1TURGTWFrVjNUbWt3ZFU5VVRUSk1WRVY1VEdwQk5FNVZaM2xPZVRSNlRWUnNjMDFwTkhoTmFtZG5UV3BSZFU1cVozaEpSRTE1U1VSbmRVOVVUVEpKUkUxNVRHcEpNVTVUTURSTWFtdDZUbWxCTUV4cVRUQk1WRkUwVEdwRk0xTkVVWGhNYWtWM1RqQjNlazlUTkRCUFUwRXdUVk0wZWs1cVNqWkphVUp0WVZkNGMxQlRTV3BhYlZwdFNXazRLMUJET1hwa2JXTXJJaUF2UGp4a1pXWnpQanhtYVd4MFpYSWdhV1E5SW1ScGMydGxkSFJsTFhOb1lXUnZkeUlnZUQwaU56QXVOelE0T1NJZ2VUMGlNVGsxTGpjeE1pSWdkMmxrZEdnOUlqazFOUzQzTXpNaUlHaGxhV2RvZEQwaU9ETXlMalUxT0NJZ1ptbHNkR1Z5Vlc1cGRITTlJblZ6WlhKVGNHRmpaVTl1VlhObElpQmpiMnh2Y2kxcGJuUmxjbkJ2YkdGMGFXOXVMV1pwYkhSbGNuTTlJbk5TUjBJaVBqeG1aVVpzYjI5a0lHWnNiMjlrTFc5d1lXTnBkSGs5SWpBaUlDOCtQR1psUW14bGJtUWdhVzQ5SWxOdmRYSmpaVWR5WVhCb2FXTWlJQzgrUEdabFIyRjFjM05wWVc1Q2JIVnlJSE4wWkVSbGRtbGhkR2x2YmowaU5ESWlJQzgrUEM5bWFXeDBaWEkrUEd4cGJtVmhja2R5WVdScFpXNTBJR2xrUFNKaVlXTnJaM0p2ZFc1a0lpQjRNVDBpTlRNeUxqVWlJSGt4UFNJd0lpQjRNajBpTlRNeUxqVWlJSGt5UFNJeE1EWTFJaUJuY21Ga2FXVnVkRlZ1YVhSelBTSjFjMlZ5VTNCaFkyVlBibFZ6WlNJK1BITjBiM0FnTHo0OGMzUnZjQ0J2Wm1aelpYUTlJakVpSUhOMGIzQXRZMjlzYjNJOUlpTXhNekV6TVRNaUlDOCtQQzlzYVc1bFlYSkhjbUZrYVdWdWRENDhjbUZrYVdGc1IzSmhaR2xsYm5RZ2FXUTlJbUpoWTJ0bmNtOTFibVF0Y21Ga2FXRnNJaUJqZUQwaU1DSWdZM2s5SWpBaUlISTlJakVpSUdkeVlXUnBaVzUwVlc1cGRITTlJblZ6WlhKVGNHRmpaVTl1VlhObElpQm5jbUZrYVdWdWRGUnlZVzV6Wm05eWJUMGlkSEpoYm5Oc1lYUmxLRFV6TWk0MUlEVXpNaTQxS1NCeWIzUmhkR1VvT0RrdU9UWXhLU0J6WTJGc1pTZzNNelVwSWo0OGMzUnZjQ0J6ZEc5d0xXTnZiRzl5UFNJalpUTTBaakkySWlBdlBqeHpkRzl3SUc5bVpuTmxkRDBpTVNJZ2MzUnZjQzFqYjJ4dmNqMGlJMlV6TkdZeU5pSWdjM1J2Y0MxdmNHRmphWFI1UFNJd0lpQXZQand2Y21Ga2FXRnNSM0poWkdsbGJuUStQR3hwYm1WaGNrZHlZV1JwWlc1MElHbGtQU0prYVhOclpYUjBaUzFuY21Ga2FXVnVkQ0lnZURFOUlqa3lOUzQyTWpZaUlIa3hQU0l5TlRZdU9EazJJaUI0TWowaU1UTTJMamMzT1NJZ2VUSTlJamd3TUM0eU1ETWlJR2R5WVdScFpXNTBWVzVwZEhNOUluVnpaWEpUY0dGalpVOXVWWE5sSWo0OGMzUnZjQ0J6ZEc5d0xXTnZiRzl5UFNJalpUTTBaakkySWlBdlBqeHpkRzl3SUc5bVpuTmxkRDBpTVNJZ2MzUnZjQzFqYjJ4dmNqMGlJekpETXpFelJpSWdMejQ4TDJ4cGJtVmhja2R5WVdScFpXNTBQanhzYVc1bFlYSkhjbUZrYVdWdWRDQnBaRDBpYldGcGJpSStQSE4wYjNBZ2MzUnZjQzFqYjJ4dmNqMGlJMlV6TkdZeU5pSWdMejQ4TDJ4cGJtVmhja2R5WVdScFpXNTBQand2WkdWbWN6NDhMM04yWno0PSIsImF0dHJpYnV0ZXMiOiBbeyJ0cmFpdF90eXBlIjogIkVOUyIsICJ2YWx1ZSI6ImZsZWVrX3h5ejIifSx7InRyYWl0X3R5cGUiOiAiQ29tbWl0IEhhc2giLCAidmFsdWUiOiJhZmZmM2Y2MiJ9LHsidHJhaXRfdHlwZSI6ICJSZXBvc2l0b3J5IiwgInZhbHVlIjoiaHR0cHM6Ly9naXRodWIuY29tL2ZsZWVreHl6L25vbi1mdW5naWJsZS1hcHBzMiJ9LHsidHJhaXRfdHlwZSI6ICJWZXJzaW9uIiwgInZhbHVlIjoiMSJ9LHsidHJhaXRfdHlwZSI6ICJDb2xvciIsICJ2YWx1ZSI6IiNlMzRmMjYifV19"
);
-
- assertEq(tokenURI, string(abi.encodePacked("data:application/json;base64,", Base64.encode((dataURI)))));
}
function testFailChangingAllPossibleFieldsOnAnotherUsersTokenWithoutAccess() public {
@@ -243,7 +191,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -256,30 +206,6 @@ contract FleekTest is Test {
fleekContract.setTokenExternalURL(mint, "https://fleek2.xyz");
fleekContract.setTokenENS(mint, "fleek_xyz2");
fleekContract.setTokenBuild(mint, "afff3f62", "https://github.com/fleekxyz/non-fungible-apps2");
-
- string memory tokenURI = fleekContract.tokenURI(mint);
-
- bytes memory dataURI = abi.encodePacked(
- "{",
- '"name":"Foundry Test App 2",',
- '"description":"This is a test application submitted by foundry tests. 2",',
- '"owner":"',
- Strings.toHexString(uint160(DEPLOYER), 20),
- '",',
- '"external_url":"https://fleek2.xyz",',
- '"image":"',
- _generateSVG("Foundry Test App 2", "fleek_xyz2"),
- '",',
- '"attributes": [',
- '{"trait_type": "ENS", "value":"fleek_xyz2"},',
- '{"trait_type": "Commit Hash", "value":"afff3f62"},',
- '{"trait_type": "Repository", "value":"https://github.com/fleekxyz/non-fungible-apps2"},',
- '{"trait_type": "Version", "value":"1"}',
- "]",
- "}"
- );
-
- assertEq(tokenURI, string(abi.encodePacked("data:application/json;base64,", Base64.encode((dataURI)))));
}
function testFailCallingTokenURIOnNonExistantToken() public {
@@ -315,7 +241,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -335,7 +263,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -354,7 +284,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -379,7 +311,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -395,7 +329,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -414,7 +350,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -430,7 +368,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -449,7 +389,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -465,7 +407,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -484,7 +428,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -500,7 +446,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -519,7 +467,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -535,7 +485,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -554,7 +506,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -574,7 +528,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -597,7 +553,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -622,7 +580,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -647,7 +607,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -675,7 +637,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -705,7 +669,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -733,7 +699,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -759,7 +727,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -775,7 +745,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -802,7 +774,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -821,7 +795,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -841,7 +817,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -850,7 +828,13 @@ contract FleekTest is Test {
fleekContract.increaseAccessPointScore(FLEEK_AP_URL);
assertEq(
fleekContract.getAccessPointJSON(FLEEK_AP_URL),
- '{"tokenId":0,"score":1,"nameVerified":false,"contentVerified":false,"owner":"0x7fa9385be102ac3eac297483dd6233d62b3e1496"}'
+ string(
+ abi.encodePacked(
+ '{"tokenId":0,"score":1,"nameVerified":false,"contentVerified":false,"owner":"',
+ DEPLOYER.toHexString(),
+ '"}'
+ )
+ )
);
}
@@ -862,7 +846,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -880,7 +866,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -888,9 +876,16 @@ contract FleekTest is Test {
fleekContract.addAccessPoint(0, FLEEK_AP_URL);
fleekContract.increaseAccessPointScore(FLEEK_AP_URL);
fleekContract.decreaseAccessPointScore(FLEEK_AP_URL);
+
assertEq(
fleekContract.getAccessPointJSON(FLEEK_AP_URL),
- '{"tokenId":0,"score":0,"nameVerified":false,"contentVerified":false,"owner":"0x7fa9385be102ac3eac297483dd6233d62b3e1496"}'
+ string(
+ abi.encodePacked(
+ '{"tokenId":0,"score":0,"nameVerified":false,"contentVerified":false,"owner":"',
+ DEPLOYER.toHexString(),
+ '"}'
+ )
+ )
);
}
@@ -902,7 +897,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -926,7 +923,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -948,7 +947,9 @@ contract FleekTest is Test {
"https://fleek.xyz",
"fleek_xyz",
"afff3f6",
- "https://github.com/fleekxyz/non-fungible-apps"
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
);
assertEq(mint, 0);
@@ -961,4 +962,127 @@ contract FleekTest is Test {
fleekContract.setAccessPointContentVerify(FLEEK_AP_URL, true);
}
+
+ function testSetTokenLogo() public {
+ uint256 mint = fleekContract.mint(
+ DEPLOYER,
+ "Foundry Test App",
+ "This is a test application submitted by foundry tests.",
+ "https://fleek.xyz",
+ "fleek_xyz",
+ "afff3f6",
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
+ );
+
+ assertEq(mint, 0);
+
+ fleekContract.setTokenLogo(mint, TestConstants.LOGO_1);
+ }
+
+ function testFailSetTokenLogoForInvalidAccount() public {
+ uint256 mint = fleekContract.mint(
+ DEPLOYER,
+ "Foundry Test App",
+ "This is a test application submitted by foundry tests.",
+ "https://fleek.xyz",
+ "fleek_xyz",
+ "afff3f6",
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
+ );
+
+ assertEq(mint, 0);
+
+ vm.prank(address(0xb4c79daB8f259C7Aee6E5b2Aa729821864227e84));
+ fleekContract.setTokenLogo(mint, TestConstants.LOGO_1);
+ }
+
+ function testFailSetTokenLogoForInvalidToken() public {
+ fleekContract.setTokenLogo(3, TestConstants.LOGO_1);
+ }
+
+ function testSetTokenColor() public {
+ uint256 mint = fleekContract.mint(
+ DEPLOYER,
+ "Foundry Test App",
+ "This is a test application submitted by foundry tests.",
+ "https://fleek.xyz",
+ "fleek_xyz",
+ "afff3f6",
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
+ );
+
+ assertEq(mint, 0);
+
+ fleekContract.setTokenColor(mint, 0x000000);
+ }
+
+ function testFailSetTokenColorForInvalidAccount() public {
+ uint256 mint = fleekContract.mint(
+ DEPLOYER,
+ "Foundry Test App",
+ "This is a test application submitted by foundry tests.",
+ "https://fleek.xyz",
+ "fleek_xyz",
+ "afff3f6",
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
+ );
+
+ assertEq(mint, 0);
+
+ vm.prank(address(0xb4c79daB8f259C7Aee6E5b2Aa729821864227e84));
+ fleekContract.setTokenColor(mint, 0x000000);
+ }
+
+ function testFailSetTokenColorForInvalidToken() public {
+ fleekContract.setTokenColor(3, 0x000000);
+ }
+
+ function testSetTokenLogoAndColor() public {
+ uint256 mint = fleekContract.mint(
+ DEPLOYER,
+ "Foundry Test App",
+ "This is a test application submitted by foundry tests.",
+ "https://fleek.xyz",
+ "fleek_xyz",
+ "afff3f6",
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
+ );
+
+ assertEq(mint, 0);
+
+ fleekContract.setTokenLogoAndColor(mint, TestConstants.LOGO_1, 0x000000);
+ }
+
+ function testFailSetTokenLogoAndColorForInvalidAccount() public {
+ uint256 mint = fleekContract.mint(
+ DEPLOYER,
+ "Foundry Test App",
+ "This is a test application submitted by foundry tests.",
+ "https://fleek.xyz",
+ "fleek_xyz",
+ "afff3f6",
+ "https://github.com/fleekxyz/non-fungible-apps",
+ TestConstants.LOGO_0,
+ 0xe34f26
+ );
+
+ assertEq(mint, 0);
+
+ vm.prank(address(0xb4c79daB8f259C7Aee6E5b2Aa729821864227e84));
+ fleekContract.setTokenLogoAndColor(mint, TestConstants.LOGO_1, 0x000000);
+ }
+
+ function testFailSetTokenLogoAndColorForInvalidToken() public {
+ fleekContract.setTokenLogoAndColor(3, TestConstants.LOGO_1, 0x000000);
+ }
}
diff --git a/test/foundry/constants.t.sol b/test/foundry/constants.t.sol
new file mode 100644
index 0000000..31cba47
--- /dev/null
+++ b/test/foundry/constants.t.sol
@@ -0,0 +1,10 @@
+library TestConstants {
+ string public constant LOGO_0 =
+ "data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjI1MDAiIHdpZHRoPSIyMTgzIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjQgMTQxLjUzMTk5OTk5OTk5OTk4Ij48cGF0aCBkPSJNMTAuMzgzIDEyNi44OTRMMCAwbDEyNCAuMjU1LTEwLjk3OSAxMjYuNjM5LTUwLjU1MyAxNC42Mzh6IiBmaWxsPSIjZTM0ZjI2Ii8+PHBhdGggZD0iTTYyLjQ2OCAxMjkuMjc3VjEyLjA4NWw1MS4wNjQuMTctOS4xMDYgMTA0Ljg1MXoiIGZpbGw9IiNlZjY1MmEiLz48cGF0aCBkPSJNOTkuNDkgNDEuMzYybDEuNDQ2LTE1LjQ5SDIyLjM4M2w0LjM0IDQ3LjQ5aDU0LjIxM0w3OC44MSA5My42MTdsLTE3LjM2MiA0LjY4LTE3LjYxNy01LjEwNi0uOTM2LTEyLjA4NUgyNy4zMTlsMi4xMjggMjQuNjgxIDMyIDguOTM2IDMyLjI1NS04LjkzNiA0LjM0LTQ4LjE3SDQxLjEwN0wzOS40OSA0MS4zNjJ6IiBmaWxsPSIjZmZmIi8+PC9zdmc+";
+
+ string public constant LOGO_1 =
+ "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMTAwMCAxMDAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMDAwIDEwMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8Zz48cGF0aCBkPSJNNTAwLDEwQzIyOS40LDEwLDEwLDIyOS40LDEwLDUwMGMwLDI3MC42LDIxOS40LDQ5MCw0OTAsNDkwYzI3MC42LDAsNDkwLTIxOS40LDQ5MC00OTBDOTkwLDIyOS40LDc3MC42LDEwLDUwMCwxMHogTTgxNSw4MTVjLTQwLjksNDAuOS04OC42LDczLjEtMTQxLjYsOTUuNWMtNTQuOSwyMy4yLTExMy4yLDM1LTE3My40LDM1Yy02MC4yLDAtMTE4LjUtMTEuOC0xNzMuNC0zNUMyNzMuNiw4ODgsMjI1LjksODU1LjksMTg1LDgxNXMtNzMtODguNi05NS41LTE0MS42Yy0yMy4yLTU0LjktMzUtMTEzLjItMzUtMTczLjRjMC02MC4yLDExLjgtMTE4LjUsMzUtMTczLjRjMjIuNC01Myw1NC42LTEwMC43LDk1LjUtMTQxLjZzODguNi03MywxNDEuNi05NS41YzU0LjktMjMuMiwxMTMuMi0zNSwxNzMuNC0zNWM2MC4yLDAsMTE4LjUsMTEuOCwxNzMuNCwzNWM1MywyMi40LDEwMC43LDU0LjYsMTQxLjYsOTUuNWM0MC45LDQwLjksNzMsODguNiw5NS41LDE0MS42YzIzLjIsNTQuOSwzNSwxMTMuMiwzNSwxNzMuNGMwLDYwLjItMTEuOCwxMTguNS0zNSwxNzMuNEM4ODgsNzI2LjQsODU1LjksNzc0LjEsODE1LDgxNXoiLz48L2c+Cjwvc3ZnPg==";
+
+ string public constant DEFAULT_TOKEN_URI =
+ "data:application/json;base64,eyJuYW1lIjoiRm91bmRyeSBUZXN0IEFwcCIsImRlc2NyaXB0aW9uIjoiVGhpcyBpcyBhIHRlc3QgYXBwbGljYXRpb24gc3VibWl0dGVkIGJ5IGZvdW5kcnkgdGVzdHMuIiwib3duZXIiOiIweDM0YTFkM2ZmZjM5NTg4NDNjNDNhZDgwZjMwYjk0YzUxMDY0NWMzMTYiLCJleHRlcm5hbF91cmwiOiJodHRwczovL2ZsZWVrLnh5eiIsImltYWdlIjoiZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQSE4yWnlCM2FXUjBhRDBpTVRBMk5TSWdhR1ZwWjJoMFBTSXhNRFkxSWlCMmFXVjNRbTk0UFNJd0lEQWdNVEEyTlNBeE1EWTFJaUJtYVd4c1BTSnViMjVsSWlCNGJXeHVjejBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01DOXpkbWNpSUhodGJHNXpPbmhzYVc1clBTSm9kSFJ3T2k4dmQzZDNMbmN6TG05eVp5OHhPVGs1TDNoc2FXNXJJajQ4YzNSNWJHVWdkSGx3WlQwaWRHVjRkQzlqYzNNaVBrQnBiWEJ2Y25RZ2RYSnNLQ0pvZEhSd2N6b3ZMMlp2Ym5SekxtZHZiMmRzWldGd2FYTXVZMjl0TDJOemN6SS9abUZ0YVd4NVBVbHVkR1Z5T25kbmFIUkFOVEF3T3pZd01DSXBPend2YzNSNWJHVStQSEpsWTNRZ2QybGtkR2c5SWpFd05qVWlJR2hsYVdkb2REMGlNVEEyTlNJZ1ptbHNiRDBpZFhKc0tDTmlZV05yWjNKdmRXNWtLU0lnTHo0OGNtVmpkQ0J2Y0dGamFYUjVQU0l3TGpJaUlIZHBaSFJvUFNJeE1EWTFJaUJvWldsbmFIUTlJakV3TmpVaUlHWnBiR3c5SW5WeWJDZ2pZbUZqYTJkeWIzVnVaQzF5WVdScFlXd3BJaUF2UGp4bklHWnBiSFJsY2owaWRYSnNLQ05rYVhOclpYUjBaUzF6YUdGa2IzY3BJajQ4Y0dGMGFDQmtQU0pOT0RVM0xqSXpNU0F5TnprdU56RXlURGt3TWk0eU5DQXlPRFl1TmpjMVF6a3hNQzQxTkRjZ01qZzNMamsySURreE55NDVNVFVnTWpreUxqY3lNU0E1TWpJdU5TQXlPVGt1TnpZNFREa3pPQzQ0T1RRZ016STBMamsyTkVNNU5ESXVNalE1SURNek1DNHhNaUE1TkRNdU16RXhJRE16Tmk0ME16Y2dPVFF4TGpneU55QXpOREl1TkRBMlREa3pOeTQzT1RnZ016VTRMall4TlV3NU1qUXVNRFE1SURNMU5pNDJOVXc1TVRrdU5ERTJJRE0zTkM0d09EUk1PVE0wTGpBMk9DQXpOell1TWpSTU56a3hMamswTnlBNU1qSXVNVFV5UXpjNE9DNHhNRGtnT1RNMkxqZzVOaUEzTnpNdU5qazBJRGswTmk0ek1EZ2dOelU0TGpZMU1TQTVORE11T0RrelRERTNPUzQyTXpZZ09EVXdMamt5T0VNeE5qSXVNekU0SURnME9DNHhORGNnTVRVeExqSXhOU0E0TXpBdU9UZzNJREUxTlM0M056WWdPREUwTGpBMU1Vd3hOakF1TkRjNElEYzVOaTQxT1V3M01EUXVNekUxSURnM09TNDFOelJNT0RVM0xqSXpNU0F5TnprdU56RXlXaUlnWm1sc2JEMGlJekExTURVd05TSWdMejQ4TDJjK1BIQmhkR2dnWkQwaVRUZzBNQzR5TXpFZ01qUXdMamN4TWt3NE9EVXVNalFnTWpRM0xqWTNOVU00T1RNdU5UUTNJREkwT0M0NU5qRWdPVEF3TGpreE5TQXlOVE11TnpJeUlEa3dOUzQxSURJMk1DNDNOamhNT1RJeExqZzVOQ0F5T0RVdU9UWTFRemt5TlM0eU5Ea2dNamt4TGpFeUlEa3lOaTR6TVRFZ01qazNMalF6TnlBNU1qUXVPREkzSURNd015NDBNRFpNT1RJd0xqYzVPQ0F6TVRrdU5qRTJURGt3Tnk0d05Ea2dNekUzTGpZMVREa3dNaTQwTVRZZ016TTFMakE0TkV3NU1UY3VNRFk0SURNek55NHlOREZNTnpjMExqazBOeUE0T0RNdU1UVXlRemMzTVM0eE1Ea2dPRGszTGpnNU5pQTNOVFl1TmprMElEa3dOeTR6TURnZ056UXhMalkxTVNBNU1EUXVPRGt6VERFMk1pNDJNellnT0RFeExqa3lPRU14TkRVdU16RTRJRGd3T1M0eE5EY2dNVE0wTGpJeE5TQTNPVEV1T1RnM0lERXpPQzQzTnpZZ056YzFMakExTVV3eE5ETXVORGM0SURjMU55NDFPVXcyT0RjdU16RTFJRGcwTUM0MU56Uk1PRFF3TGpJek1TQXlOREF1TnpFeVdpSWdabWxzYkQwaWRYSnNLQ050WVdsdUtTSWdMejQ4Y0dGMGFDQm1hV3hzTFhKMWJHVTlJbVYyWlc1dlpHUWlJR05zYVhBdGNuVnNaVDBpWlhabGJtOWtaQ0lnWkQwaVRUTXhPUzQ0TkRjZ01UWXhMalV3TWtNek1UQXVNelUySURFMk1DNHdNRGNnTXpBd0xqWTNOQ0F4TmpZdU16STJJREk1T0M0eU1qRWdNVGMxTGpZeE5rd3hNemd1TnpJMElEYzNPUzQzTlRoRE1UTTJMakkzTVNBM09Ea3VNRFE0SURFME1TNDVOemNnTnprM0xqYzVJREUxTVM0ME5qZ2dOems1TGpJNE5VdzNOREF1TURZeElEZzVNUzQ1TnpORE56UTVMalUxTXlBNE9UTXVORFkzSURjMU9TNHlNelVnT0RnM0xqRTBPQ0EzTmpFdU5qZzNJRGczTnk0NE5UaE1PVEF5TGpRd05TQXpORFF1T0RVMFREZzRPUzR4TlRnZ016UXlMamMyT0V3NE9UZ3VPRGN5SURNd05TNDVOekpNT1RFeUxqRXhPU0F6TURndU1EVTVURGt4TXk0M016TWdNekF4TGprME5rTTVNVFF1T0RNM0lESTVOeTQzTmpJZ09URTBMak13T1NBeU9UTXVORGMySURreE1pNHlOVEVnTWpnNUxqa3lOMHc0T1RNdU5EZzBJREkxTnk0MU5qbERPRGt4TGpFMU15QXlOVE11TlRRNUlEZzROeTR3TmpNZ01qVXdMamd5TXlBNE9ESXVNakl4SURJMU1DNHdOakZNT0RJNExqSXdOU0F5TkRFdU5UVTBRemd5TWk0eU1qUWdNalF3TGpZeE15QTRNVFV1T0RZNUlESTBNaTQzT0RNZ09ERXhMalF5TnlBeU5EY3VNamcwVERnd05TNDJPRFlnTWpVekxqRXdNME00TURRdU1qQTFJREkxTkM0Mk1ETWdPREF5TGpBNE55QXlOVFV1TXpJMklEZ3dNQzR3T1RNZ01qVTFMakF4TTB3M09ETXVOakV4SURJMU1pNDBNVGRNTnpNMExqTWdORE01TGpFNU5rTTNNekV1TkRNNUlEUTFNQzR3TXpVZ056SXdMakUwTXlBME5UY3VOREEzSURjd09TNHdOeUEwTlRVdU5qWXpURE15T0M0NE5EY2dNemsxTGpjNE9FTXpNVGN1TnpjMElETTVOQzR3TkRVZ016RXhMakV4TnlBek9ETXVPRFExSURNeE15NDVOemdnTXpjekxqQXdOMHd6TmpZdU5USTRJREUzTXk0NU5qSk1NelkyTGpVek15QXhOek11T1RReFF6TTJOeTR5TXpRZ01UY3hMakkwSURNMk5TNDFOeklnTVRZNExqY3dNaUF6TmpJdU9ERWdNVFk0TGpJMk4wd3pNVGt1T0RRM0lERTJNUzQxTURKYVRUTTJPUzR6T1RJZ01UYzBMalF4TkV3ek5qZ3VOalV5SURFM055NHlNVGRNTXpFMkxqZzBNeUF6TnpNdU5EVTRRek14TkM0ek9TQXpPREl1TnpRNElETXlNQzR3T1RZZ016a3hMalE1SURNeU9TNDFPRGNnTXpreUxqazROVXczTURrdU9ERWdORFV5TGpnMlF6Y3hPUzR6TURFZ05EVTBMak0xTkNBM01qZ3VPVGd6SURRME9DNHdNelVnTnpNeExqUXpOaUEwTXpndU56UTFURGM0TUM0M05EY2dNalV4TGprMk5rdzNPRE11TWpRMUlESTBNaTQxTURSTU56Z3pMams0TlNBeU16a3VOekF4VERNMk9TNHpPVElnTVRjMExqUXhORm9pSUdacGJHdzlJaU14TXpFek1UWWlJQzgrUEhCaGRHZ2dabWxzYkMxeWRXeGxQU0psZG1WdWIyUmtJaUJqYkdsd0xYSjFiR1U5SW1WMlpXNXZaR1FpSUhOMGNtOXJaVDBpZFhKc0tDTnRZV2x1S1NJZ2MzUnliMnRsTFhkcFpIUm9QU0kwSWlCemRISnZhMlV0YkdsdVpXTmhjRDBpY205MWJtUWlJSE4wY205clpTMXNhVzVsYW05cGJqMGljbTkxYm1RaUlHUTlJazB6TVRrdU9EUTNJREUyTVM0MU1ESkRNekV3TGpNMU5pQXhOakF1TURBM0lETXdNQzQyTnpRZ01UWTJMak15TmlBeU9UZ3VNakl4SURFM05TNDJNVFpNTVRNNExqY3lOQ0EzTnprdU56VTRRekV6Tmk0eU56RWdOemc1TGpBME9DQXhOREV1T1RjM0lEYzVOeTQzT1NBeE5URXVORFk0SURjNU9TNHlPRFZNTnpRd0xqQTJNU0E0T1RFdU9UY3pRemMwT1M0MU5UTWdPRGt6TGpRMk55QTNOVGt1TWpNMUlEZzROeTR4TkRnZ056WXhMalk0TnlBNE56Y3VPRFU0VERrd01pNDBNRFVnTXpRMExqZzFORXc0T0RrdU1UVTRJRE0wTWk0M05qaE1PRGs0TGpnM01pQXpNRFV1T1RjeVREa3hNaTR4TVRrZ016QTRMakExT1V3NU1UTXVOek16SURNd01TNDVORFpET1RFMExqZ3pOeUF5T1RjdU56WXlJRGt4TkM0ek1Ea2dNamt6TGpRM05pQTVNVEl1TWpVeElESTRPUzQ1TWpkTU9Ea3pMalE0TkNBeU5UY3VOVFk1UXpnNU1TNHhOVE1nTWpVekxqVTBPU0E0T0RjdU1EWXpJREkxTUM0NE1qTWdPRGd5TGpJeU1TQXlOVEF1TURZeFREZ3lPQzR5TURVZ01qUXhMalUxTkVNNE1qSXVNakkwSURJME1DNDJNVE1nT0RFMUxqZzJPU0F5TkRJdU56Z3pJRGd4TVM0ME1qY2dNalEzTGpJNE5FdzRNRFV1TmpnMklESTFNeTR4TURORE9EQTBMakl3TlNBeU5UUXVOakF6SURnd01pNHdPRGNnTWpVMUxqTXlOaUE0TURBdU1Ea3pJREkxTlM0d01UTk1Oemd6TGpZeE1TQXlOVEl1TkRFM1REY3pOQzR6SURRek9TNHhPVFpETnpNeExqUXpPU0EwTlRBdU1ETTFJRGN5TUM0eE5ETWdORFUzTGpRd055QTNNRGt1TURjZ05EVTFMalkyTTB3ek1qZ3VPRFEzSURNNU5TNDNPRGhETXpFM0xqYzNOQ0F6T1RRdU1EUTFJRE14TVM0eE1UY2dNemd6TGpnME5TQXpNVE11T1RjNElETTNNeTR3TURkTU16WTJMalV5T0NBeE56TXVPVFl5VERNMk5pNDFNek1nTVRjekxqazBNVU16TmpjdU1qTTBJREUzTVM0eU5DQXpOalV1TlRjeUlERTJPQzQzTURJZ016WXlMamd4SURFMk9DNHlOamRNTXpFNUxqZzBOeUF4TmpFdU5UQXlXazB6TmprdU16a3lJREUzTkM0ME1UUk1Nelk0TGpZMU1pQXhOemN1TWpFM1RETXhOaTQ0TkRNZ016Y3pMalExT0VNek1UUXVNemtnTXpneUxqYzBPQ0F6TWpBdU1EazJJRE01TVM0ME9TQXpNamt1TlRnM0lETTVNaTQ1T0RWTU56QTVMamd4SURRMU1pNDROa00zTVRrdU16QXhJRFExTkM0ek5UUWdOekk0TGprNE15QTBORGd1TURNMUlEY3pNUzQwTXpZZ05ETTRMamMwTlV3M09EQXVOelEzSURJMU1TNDVOalpNTnpnekxqSTBOU0F5TkRJdU5UQTBURGM0TXk0NU9EVWdNak01TGpjd01Vd3pOamt1TXpreUlERTNOQzQwTVRSYUlpQm1hV3hzUFNKMWNtd29JMlJwYzJ0bGRIUmxMV2R5WVdScFpXNTBLU0lnWm1sc2JDMXZjR0ZqYVhSNVBTSXdMaklpSUM4K1BIQmhkR2dnWkQwaVRUTXpOUzR6T0NBeU1EZ3VNVEV6UXpNek5TNDVNaklnTWpBNExqRTVPQ0F6TXpZdU5ERTNJREl3Tnk0Mk9EWWdNek0yTGpJNE15QXlNRGN1TVRjNVRETXpNQzR6T1NBeE9EUXVOemsxUXpNek1DNHlORGtnTVRnMExqSTJNU0F6TWprdU5USTVJREU0TkM0eE5EZ2dNekk1TGpFeU9TQXhPRFF1TlRrM1RETXhNaTR6TlRnZ01qQXpMalF4TVVNek1URXVPVGM0SURJd015NDRNemdnTXpFeUxqRTNOQ0F5TURRdU5EVTRJRE14TWk0M01UWWdNakEwTGpVME5Fd3pNVGN1T1RZeUlESXdOUzR6TjBNek1UZ3VNelUzSURJd05TNDBNeklnTXpFNExqVTVOU0F5TURVdU56azJJRE14T0M0ME9UTWdNakEyTGpFNE0wd3pNVFF1TnlBeU1qQXVOVFV4UXpNeE5DNDFPVGNnTWpJd0xqa3pPQ0F6TVRRdU9ETTFJREl5TVM0ek1ESWdNekUxTGpJek1TQXlNakV1TXpZMFRETXlOQzQxTXprZ01qSXlMamd6UXpNeU5DNDVNelVnTWpJeUxqZzVNeUF6TWpVdU16TTRJREl5TWk0Mk1qa2dNekkxTGpRMElESXlNaTR5TkRKTU16STVMakl6TXlBeU1EY3VPRGMxUXpNeU9TNHpNellnTWpBM0xqUTRPQ0F6TWprdU56TTVJREl3Tnk0eU1qUWdNek13TGpFek5TQXlNRGN1TWpnMlRETXpOUzR6T0NBeU1EZ3VNVEV6V2lJZ1ptbHNiRDBpZFhKc0tDTnRZV2x1S1NJZ0x6NDhjR0YwYUNCa1BTSk5NekU1TGpJNE1pQXlOamt1TURnM1F6TXhPUzQ0TWpRZ01qWTVMakUzTXlBek1qQXVNekU1SURJMk9DNDJOakVnTXpJd0xqRTROaUF5TmpndU1UVTBURE14TkM0eU9USWdNalExTGpjM1F6TXhOQzR4TlRFZ01qUTFMakl6TmlBek1UTXVORE14SURJME5TNHhNak1nTXpFekxqQXpNU0F5TkRVdU5UY3lUREk1Tmk0eU5qRWdNalkwTGpNNE5rTXlPVFV1T0RnZ01qWTBMamd4TWlBeU9UWXVNRGMySURJMk5TNDBNek1nTWprMkxqWXhPQ0F5TmpVdU5URTRURE13TVM0NE5qUWdNalkyTGpNME5FTXpNREl1TWpVNUlESTJOaTQwTURjZ016QXlMalE1TnlBeU5qWXVOemN4SURNd01pNHpPVFVnTWpZM0xqRTFPRXd5T1RndU5qQXlJREk0TVM0MU1qWkRNams0TGpVZ01qZ3hMamt4TXlBeU9UZ3VOek0zSURJNE1pNHlOemNnTWprNUxqRXpNeUF5T0RJdU16TTVURE13T0M0ME5ERWdNamd6TGpnd05VTXpNRGd1T0RNM0lESTRNeTQ0TmpjZ016QTVMakkwSURJNE15NDJNRFFnTXpBNUxqTTBNeUF5T0RNdU1qRTNURE14TXk0eE16WWdNalk0TGpnME9VTXpNVE11TWpNNElESTJPQzQwTmpJZ016RXpMalkwTVNBeU5qZ3VNVGs1SURNeE5DNHdNemNnTWpZNExqSTJNVXd6TVRrdU1qZ3lJREkyT1M0d09EZGFJaUJtYVd4c1BTSmliR0ZqYXlJZ1ptbHNiQzF2Y0dGamFYUjVQU0l3TGpVaUlDOCtQSEJoZEdnZ1pEMGlUVE13TXk0eE9EUWdNek13TGpBMk1rTXpNRE11TnpJMklETXpNQzR4TkRnZ016QTBMakl5TVNBek1qa3VOak0ySURNd05DNHdPRGdnTXpJNUxqRXlPRXd5T1RndU1UazBJRE13Tmk0M05EVkRNams0TGpBMU15QXpNRFl1TWpFeElESTVOeTR6TXpNZ016QTJMakE1T0NBeU9UWXVPVE16SURNd05pNDFORGRNTWpnd0xqRTJNeUF6TWpVdU16WXhRekkzT1M0M09ESWdNekkxTGpjNE55QXlOemt1T1RjNUlETXlOaTQwTURnZ01qZ3dMalV5SURNeU5pNDBPVE5NTWpnMUxqYzJOaUF6TWpjdU16RTVRekk0Tmk0eE5qRWdNekkzTGpNNE1pQXlPRFl1TXprNUlETXlOeTQzTkRZZ01qZzJMakk1TnlBek1qZ3VNVE16VERJNE1pNDFNRFFnTXpReUxqVXdNVU15T0RJdU5EQXlJRE0wTWk0NE9EZ2dNamd5TGpZek9TQXpORE11TWpVeUlESTRNeTR3TXpVZ016UXpMak14TkV3eU9USXVNelEwSURNME5DNDNPRU15T1RJdU56TTVJRE0wTkM0NE5ESWdNamt6TGpFME1pQXpORFF1TlRjNUlESTVNeTR5TkRVZ016UTBMakU1TWt3eU9UY3VNRE00SURNeU9TNDRNalJETWprM0xqRTBJRE15T1M0ME16Y2dNamszTGpVME15QXpNamt1TVRjMElESTVOeTQ1TXprZ016STVMakl6Tmt3ek1ETXVNVGcwSURNek1DNHdOakphSWlCbWFXeHNQU0ppYkdGamF5SWdabWxzYkMxdmNHRmphWFI1UFNJd0xqVWlJQzgrUEhCaGRHZ2djM1J5YjJ0bFBTSjFjbXdvSTIxaGFXNHBJaUJ6ZEhKdmEyVXRkMmxrZEdnOUlqWWlJSE4wY205clpTMXNhVzVsWTJGd1BTSnliM1Z1WkNJZ2MzUnliMnRsTFd4cGJtVnFiMmx1UFNKeWIzVnVaQ0lnWkQwaVRUSTVNQzR4TURrZ05EWXpMalF4T0VNeU9USXVNelU0SURRMU5DNDVNRElnTXpBeExqSXpNeUEwTkRrdU1URWdNekE1TGprek15QTBOVEF1TkRoTU56Y3hMakEzSURVeU15NHdPVFpETnpjNUxqYzNJRFV5TkM0ME5qY2dOemcxSURVek1pNDBPQ0EzT0RJdU56VXlJRFUwTUM0NU9UWk1Oamt5TGpBNE5pQTRPRFF1TkRFNFRERTVPUzQwTkRNZ09EQTJMamcwVERJNU1DNHhNRGtnTkRZekxqUXhPRm9pSUdacGJHdzlJbUpzWVdOcklpQm1hV3hzTFc5d1lXTnBkSGs5SWpBdU1UUWlJQzgrUEhCaGRHZ2dabWxzYkMxeWRXeGxQU0psZG1WdWIyUmtJaUJqYkdsd0xYSjFiR1U5SW1WMlpXNXZaR1FpSUhOMGNtOXJaVDBpZFhKc0tDTnRZV2x1S1NJZ2MzUnliMnRsTFhkcFpIUm9QU0kySWlCemRISnZhMlV0YkdsdVpXTmhjRDBpY205MWJtUWlJSE4wY205clpTMXNhVzVsYW05cGJqMGljbTkxYm1RaUlHUTlJazAzT0RjdU5UZzVJREl6Tnk0ek5EbE1ORFl3TGpNMU5DQXhPRFV1T0RFNFREUXdOaTR6TWpVZ016a3dMalEyT1VNME1ETXVPRGN5SURNNU9TNDNOVGtnTkRBNUxqVTNPQ0EwTURndU5UQXhJRFF4T1M0d05qa2dOREE1TGprNU5rdzNNVEV1T1RNMElEUTFOaTR4TVRSRE56SXhMalF5TlNBME5UY3VOakE1SURjek1TNHhNRGNnTkRVeExqSTVJRGN6TXk0MU5pQTBOREpNTnpnM0xqVTRPU0F5TXpjdU16UTVXazAyTmpBdU1qWTVJREkwTlM0d01VTTJOVFV1TlRJeklESTBOQzR5TmpNZ05qVXdMalk0TWlBeU5EY3VOREl6SURZME9TNDBOVFlnTWpVeUxqQTJPRXcyTURjdU16ZzJJRFF4TVM0ME1UaEROakEyTGpFMklEUXhOaTR3TmpNZ05qQTVMakF4TXlBME1qQXVORE0wSURZeE15NDNOVGtnTkRJeExqRTRNVXcyT0RJdU5EazVJRFF6TWk0d01EWkROamczTGpJME5TQTBNekl1TnpVeklEWTVNaTR3T0RZZ05ESTVMalU1TkNBMk9UTXVNekV5SURReU5DNDVORGxNTnpNMUxqTTRNaUF5TmpVdU5UazVRemN6Tmk0Mk1EZ2dNall3TGprMU5DQTNNek11TnpVMUlESTFOaTQxT0RNZ056STVMakF4SURJMU5TNDRNelZNTmpZd0xqSTJPU0F5TkRVdU1ERmFJaUJtYVd4c1BTSjFjbXdvSTIxaGFXNHBJaUF2UGp4d1lYUm9JR1pwYkd3dGNuVnNaVDBpWlhabGJtOWtaQ0lnWTJ4cGNDMXlkV3hsUFNKbGRtVnViMlJrSWlCa1BTSk5PRFkwTGpZME15QXlPRE11T1RNM1F6ZzJOUzR4T0RZZ01qZ3pMall3TlNBNE5qVXVOekE0SURJNE5DNHlOVGNnT0RZMUxqSXpPU0F5T0RRdU5qZ3pURGcwTkM0eU5qZ2dNekF6TGpjeE9VTTRORE11T1RNNElETXdOQzR3TVRnZ09EUTBMakE1TXlBek1EUXVOVEUzSURnME5DNDFNallnTXpBMExqVTBPRXc0TlRNdU56STJJRE13TlM0eU1EZERPRFUwTGpFNE5DQXpNRFV1TWpRZ09EVTBMak15TVNBek1EVXVOemczSURnMU15NDVORElnTXpBMkxqQTNNVXc0TXpNdU9EZzBJRE15TVM0eE1USkRPRE16TGpVd05pQXpNakV1TXprMklEZ3pNeTQyTkRNZ016SXhMamswTXlBNE16UXVNVEF4SURNeU1TNDVOelpNT0RRMExqQXdOeUF6TWpJdU5qZzFRemcwTkM0ME9URWdNekl5TGpjeUlEZzBOQzQyTURVZ016SXpMak14T1NBNE5EUXVNVGMzSURNeU15NDFPRXczT1RjdU56VXlJRE0xTVM0NU5UUkROemszTGpJd09TQXpOVEl1TWpnMklEYzVOaTQyT0RjZ016VXhMall6TkNBM09UY3VNVFUySURNMU1TNHlNRGxNT0RFNExqUXdNeUF6TXpFdU9USXlRemd4T0M0M016TWdNek14TGpZeU1pQTRNVGd1TlRjM0lETXpNUzR4TWpNZ09ERTRMakUwTlNBek16RXVNRGt5VERnd09DNDNORGdnTXpNd0xqUXlRemd3T0M0eU9USWdNek13TGpNNE55QTRNRGd1TVRVMElETXlPUzQ0TkRNZ09EQTRMalV5T1NBek1qa3VOVFU0VERneU9DNHdOVFFnTXpFMExqYzBORU00TWpndU5ETWdNekUwTGpRMU9TQTRNamd1TWpreElETXhNeTQ1TVRVZ09ESTNMamd6TlNBek1UTXVPRGd5VERneE9DNHpPRGtnTXpFekxqSXdOa000TVRjdU9UQTBJRE14TXk0eE56RWdPREUzTGpjNUlETXhNaTQxTnpJZ09ERTRMakl4T0NBek1USXVNekV4VERnMk5DNDJORE1nTWpnekxqa3pOMW9pSUdacGJHdzlJbmRvYVhSbElpQXZQanhuSUhSeVlXNXpabTl5YlQwaWJXRjBjbWw0S0RBdU9UZzNPREkzSURBdU1UVTFOVFUzSUMwd0xqSTFOVEkyTVNBd0xqazJOamczTWlBeU5UQWdOek0xS1NJK1BIUmxlSFFnWm05dWRDMW1ZVzFwYkhrOUlrbHVkR1Z5TENCellXNXpMWE5sY21sbUlpQm1iMjUwTFhkbGFXZG9kRDBpWW05c1pDSWdabTl1ZEMxemFYcGxQU0kwTWlJZ1ptbHNiRDBpSTBVMVJUZEdPQ0krUm05MWJtUnllU0JVWlhOMElFRndjRHd2ZEdWNGRENDhkR1Y0ZENCbWIyNTBMV1poYldsc2VUMGlTVzUwWlhJc0lITmhibk10YzJWeWFXWWlJR1p2Ym5RdGQyVnBaMmgwUFNKdWIzSnRZV3dpSUhrOUlqUXdJaUJtYjI1MExYTnBlbVU5SWpJeUlpQm1hV3hzUFNJak4wWTRNVGt5SWo1bWJHVmxhMTk0ZVhvOEwzUmxlSFErUEM5blBqeHBiV0ZuWlNCM2FXUjBhRDBpTVRZM0lpQm9aV2xuYUhROUlqRTJOeUlnZEhKaGJuTm1iM0p0UFNKdFlYUnlhWGdvTUM0NU9EYzRNamNnTUM0eE5UVTFOVGNnTFRBdU1qVTFNall4SURBdU9UWTJPRGN5SURRME5DNHhNVGNnTlRJMExqRTNLU0lnYUhKbFpqMGlaR0YwWVRwcGJXRm5aUzl6ZG1jcmVHMXNPMkpoYzJVMk5DeFFTRTR5V25sQ2JXRlhlSE5RVTBwMVlqSTFiRWxwUW05YVYyeHVZVWhST1VscVNURk5SRUZwU1Voa2NGcElVbTlRVTBsNVRWUm5la2xwUWpSaVYzaDFZM293YVdGSVVqQmpSRzkyVEROa00yUjVOVE5OZVRWMlkyMWpkazFxUVhkTlF6bDZaRzFqYVVsSVduQmFXR1JEWWpObk9VbHFRV2ROUTBGNFRXcFJaMDFVVVhoTWFsVjZUVlJyTlU5VWF6VlBWR3MxVDFSck5FbHFORGhqUjBZd1lVTkNhMUJUU2s1TlZFRjFUWHBuZWtsRVJYbE9hVFEwVDFSU1RVMURRWGRpUkVWNVRrTkJkVTFxVlRGTVZFVjNUR3ByTTA5VFFYaE5hbGwxVG1wTk5VeFVWWGRNYWxVeFRYbEJlRTVETkRKTmVtZzJTV2xDYldGWGVITlFVMGxxV2xSTk1GcHFTVEpKYVRnclVFaENhR1JIWjJkYVJEQnBWRlJaZVV4cVVUSlBRMEY0VFdwcmRVMXFZek5XYWtWNVRHcEJORTVYZHpGTlV6UjNUbXBSZFUxVVkzUlBVelI0VFVSWlowMVVRVEJNYW1jeFRWaHZhVWxIV25CaVIzYzVTV2xPYkZwcVdURk5iVVZwVEhvME9HTkhSakJoUTBKclVGTktUazlVYTNWT1JHdG5Ua1JGZFUxNldYbGlSRVYxVGtSUk1reFVSVEZNYWxFMVUwUkplVXhxVFRSTk1uY3dUR3BOTUVsRVVUTk1hbEUxWVVSVk1FeHFTWGhOTUhjelQwTTBORTFUUVRWTmVUUXlUVlJrYzB4VVJUTk1hazB5VFdsQk1FeHFXVFJNVkVVelRHcFplRTU1TURGTWFrVjNUbWt3ZFU5VVRUSk1WRVY1VEdwQk5FNVZaM2xPZVRSNlRWUnNjMDFwTkhoTmFtZG5UV3BSZFU1cVozaEpSRTE1U1VSbmRVOVVUVEpKUkUxNVRHcEpNVTVUTURSTWFtdDZUbWxCTUV4cVRUQk1WRkUwVEdwRk0xTkVVWGhNYWtWM1RqQjNlazlUTkRCUFUwRXdUVk0wZWs1cVNqWkphVUp0WVZkNGMxQlRTV3BhYlZwdFNXazRLMUJET1hwa2JXTXJJaUF2UGp4a1pXWnpQanhtYVd4MFpYSWdhV1E5SW1ScGMydGxkSFJsTFhOb1lXUnZkeUlnZUQwaU56QXVOelE0T1NJZ2VUMGlNVGsxTGpjeE1pSWdkMmxrZEdnOUlqazFOUzQzTXpNaUlHaGxhV2RvZEQwaU9ETXlMalUxT0NJZ1ptbHNkR1Z5Vlc1cGRITTlJblZ6WlhKVGNHRmpaVTl1VlhObElpQmpiMnh2Y2kxcGJuUmxjbkJ2YkdGMGFXOXVMV1pwYkhSbGNuTTlJbk5TUjBJaVBqeG1aVVpzYjI5a0lHWnNiMjlrTFc5d1lXTnBkSGs5SWpBaUlDOCtQR1psUW14bGJtUWdhVzQ5SWxOdmRYSmpaVWR5WVhCb2FXTWlJQzgrUEdabFIyRjFjM05wWVc1Q2JIVnlJSE4wWkVSbGRtbGhkR2x2YmowaU5ESWlJQzgrUEM5bWFXeDBaWEkrUEd4cGJtVmhja2R5WVdScFpXNTBJR2xrUFNKaVlXTnJaM0p2ZFc1a0lpQjRNVDBpTlRNeUxqVWlJSGt4UFNJd0lpQjRNajBpTlRNeUxqVWlJSGt5UFNJeE1EWTFJaUJuY21Ga2FXVnVkRlZ1YVhSelBTSjFjMlZ5VTNCaFkyVlBibFZ6WlNJK1BITjBiM0FnTHo0OGMzUnZjQ0J2Wm1aelpYUTlJakVpSUhOMGIzQXRZMjlzYjNJOUlpTXhNekV6TVRNaUlDOCtQQzlzYVc1bFlYSkhjbUZrYVdWdWRENDhjbUZrYVdGc1IzSmhaR2xsYm5RZ2FXUTlJbUpoWTJ0bmNtOTFibVF0Y21Ga2FXRnNJaUJqZUQwaU1DSWdZM2s5SWpBaUlISTlJakVpSUdkeVlXUnBaVzUwVlc1cGRITTlJblZ6WlhKVGNHRmpaVTl1VlhObElpQm5jbUZrYVdWdWRGUnlZVzV6Wm05eWJUMGlkSEpoYm5Oc1lYUmxLRFV6TWk0MUlEVXpNaTQxS1NCeWIzUmhkR1VvT0RrdU9UWXhLU0J6WTJGc1pTZzNNelVwSWo0OGMzUnZjQ0J6ZEc5d0xXTnZiRzl5UFNJalpUTTBaakkySWlBdlBqeHpkRzl3SUc5bVpuTmxkRDBpTVNJZ2MzUnZjQzFqYjJ4dmNqMGlJMlV6TkdZeU5pSWdjM1J2Y0MxdmNHRmphWFI1UFNJd0lpQXZQand2Y21Ga2FXRnNSM0poWkdsbGJuUStQR3hwYm1WaGNrZHlZV1JwWlc1MElHbGtQU0prYVhOclpYUjBaUzFuY21Ga2FXVnVkQ0lnZURFOUlqa3lOUzQyTWpZaUlIa3hQU0l5TlRZdU9EazJJaUI0TWowaU1UTTJMamMzT1NJZ2VUSTlJamd3TUM0eU1ETWlJR2R5WVdScFpXNTBWVzVwZEhNOUluVnpaWEpUY0dGalpVOXVWWE5sSWo0OGMzUnZjQ0J6ZEc5d0xXTnZiRzl5UFNJalpUTTBaakkySWlBdlBqeHpkRzl3SUc5bVpuTmxkRDBpTVNJZ2MzUnZjQzFqYjJ4dmNqMGlJekpETXpFelJpSWdMejQ4TDJ4cGJtVmhja2R5WVdScFpXNTBQanhzYVc1bFlYSkhjbUZrYVdWdWRDQnBaRDBpYldGcGJpSStQSE4wYjNBZ2MzUnZjQzFqYjJ4dmNqMGlJMlV6TkdZeU5pSWdMejQ4TDJ4cGJtVmhja2R5WVdScFpXNTBQand2WkdWbWN6NDhMM04yWno0PSIsImF0dHJpYnV0ZXMiOiBbeyJ0cmFpdF90eXBlIjogIkVOUyIsICJ2YWx1ZSI6ImZsZWVrX3h5eiJ9LHsidHJhaXRfdHlwZSI6ICJDb21taXQgSGFzaCIsICJ2YWx1ZSI6ImFmZmYzZjYifSx7InRyYWl0X3R5cGUiOiAiUmVwb3NpdG9yeSIsICJ2YWx1ZSI6Imh0dHBzOi8vZ2l0aHViLmNvbS9mbGVla3h5ei9ub24tZnVuZ2libGUtYXBwcyJ9LHsidHJhaXRfdHlwZSI6ICJWZXJzaW9uIiwgInZhbHVlIjoiMCJ9LHsidHJhaXRfdHlwZSI6ICJDb2xvciIsICJ2YWx1ZSI6IiNlMzRmMjYifV19";
+}
diff --git a/yarn.lock b/yarn.lock
index 03c7d8a..f3d34d4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -17,9 +17,9 @@
"@babel/highlight" "^7.18.6"
"@babel/generator@^7.18.13", "@babel/generator@^7.20.7":
- version "7.20.7"
- resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.7.tgz#f8ef57c8242665c5929fe2e8d82ba75460187b4a"
- integrity sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==
+ version "7.20.14"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.14.tgz#9fa772c9f86a46c6ac9b321039400712b96f64ce"
+ integrity sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==
dependencies:
"@babel/types" "^7.20.7"
"@jridgewell/gen-mapping" "^0.3.2"
@@ -76,10 +76,10 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
-"@babel/parser@^7.16.8", "@babel/parser@^7.20.7":
- version "7.20.7"
- resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.7.tgz#66fe23b3c8569220817d5feb8b9dcdc95bb4f71b"
- integrity sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==
+"@babel/parser@^7.16.8", "@babel/parser@^7.20.13", "@babel/parser@^7.20.7":
+ version "7.20.13"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.13.tgz#ddf1eb5a813588d2fb1692b70c6fce75b945c088"
+ integrity sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw==
"@babel/plugin-syntax-import-assertions@7.20.0":
version "7.20.0"
@@ -98,9 +98,9 @@
"@babel/types" "^7.20.7"
"@babel/traverse@^7.16.8":
- version "7.20.12"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.12.tgz#7f0f787b3a67ca4475adef1f56cb94f6abd4a4b5"
- integrity sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ==
+ version "7.20.13"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.13.tgz#817c1ba13d11accca89478bd5481b2d168d07473"
+ integrity sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==
dependencies:
"@babel/code-frame" "^7.18.6"
"@babel/generator" "^7.20.7"
@@ -108,7 +108,7 @@
"@babel/helper-function-name" "^7.19.0"
"@babel/helper-hoist-variables" "^7.18.6"
"@babel/helper-split-export-declaration" "^7.18.6"
- "@babel/parser" "^7.20.7"
+ "@babel/parser" "^7.20.13"
"@babel/types" "^7.20.7"
debug "^4.1.0"
globals "^11.1.0"
@@ -501,14 +501,14 @@
"@ethersproject/strings" "^5.7.0"
"@graphql-codegen/cli@^2.16.4":
- version "2.16.4"
- resolved "https://registry.yarnpkg.com/@graphql-codegen/cli/-/cli-2.16.4.tgz#c8e6df2dc8cccfd61a088de0ada9a05842ad8ad6"
- integrity sha512-MBbdzIIaNZ8BTlFXG00toxU5rIV7Ltf2myaze88HpI5YPVfVJKlfccE6l0/Gv+nLv88CIM/PZrnFLdVtlBmrZw==
+ version "2.16.5"
+ resolved "https://registry.yarnpkg.com/@graphql-codegen/cli/-/cli-2.16.5.tgz#b3b5eeec357af01c1cb72f6a4ea96e52bd49e662"
+ integrity sha512-XYPIp+q7fB0xAGSAoRykiTe4oY80VU+z+dw5nuv4mLY0+pv7+pa2C6Nwhdw7a65lXOhFviBApWCCZeqd54SMnA==
dependencies:
"@babel/generator" "^7.18.13"
"@babel/template" "^7.18.10"
"@babel/types" "^7.18.13"
- "@graphql-codegen/core" "2.6.8"
+ "@graphql-codegen/core" "^2.6.8"
"@graphql-codegen/plugin-helpers" "^3.1.2"
"@graphql-tools/apollo-engine-loader" "^7.3.6"
"@graphql-tools/code-file-loader" "^7.3.13"
@@ -516,7 +516,7 @@
"@graphql-tools/github-loader" "^7.3.20"
"@graphql-tools/graphql-file-loader" "^7.5.0"
"@graphql-tools/json-file-loader" "^7.4.1"
- "@graphql-tools/load" "7.8.0"
+ "@graphql-tools/load" "^7.8.0"
"@graphql-tools/prisma-loader" "^7.2.49"
"@graphql-tools/url-loader" "^7.13.2"
"@graphql-tools/utils" "^9.0.0"
@@ -524,10 +524,10 @@
chalk "^4.1.0"
chokidar "^3.5.2"
cosmiconfig "^7.0.0"
- cosmiconfig-typescript-loader "4.3.0"
+ cosmiconfig-typescript-loader "^4.3.0"
debounce "^1.2.0"
detect-indent "^6.0.0"
- graphql-config "4.4.0"
+ graphql-config "^4.4.0"
inquirer "^8.0.0"
is-glob "^4.0.1"
json-to-pretty-yaml "^1.2.2"
@@ -536,11 +536,12 @@
shell-quote "^1.7.3"
string-env-interpolation "^1.0.1"
ts-log "^2.2.3"
+ ts-node "^10.9.1"
tslib "^2.4.0"
yaml "^1.10.0"
yargs "^17.0.0"
-"@graphql-codegen/core@2.6.8":
+"@graphql-codegen/core@^2.6.8":
version "2.6.8"
resolved "https://registry.yarnpkg.com/@graphql-codegen/core/-/core-2.6.8.tgz#00c4011e3619ddbc6af5e41b2f254d6f6759556e"
integrity sha512-JKllNIipPrheRgl+/Hm/xuWMw9++xNQ12XJR/OHHgFopOg4zmN3TdlRSyYcv/K90hCFkkIwhlHFUQTfKrm8rxQ==
@@ -563,209 +564,191 @@
tslib "~2.4.0"
"@graphql-tools/apollo-engine-loader@^7.3.6":
- version "7.3.21"
- resolved "https://registry.yarnpkg.com/@graphql-tools/apollo-engine-loader/-/apollo-engine-loader-7.3.21.tgz#416e548f6343342c1e8ef6c83139264589802172"
- integrity sha512-mCf5CRZ64Cj4pmXpcgSJDkHj93owntvAmyHpY651yAmQKYJ5Kltrw6rreo2VJr1Eu4BWdHqcMS++NLq5GPGewg==
+ version "7.3.22"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/apollo-engine-loader/-/apollo-engine-loader-7.3.22.tgz#ace09442dd0aa758a7a42dac3b73252c7935c531"
+ integrity sha512-4zbL2k7Tcr+qDHBmqKTfrxgOgGkRw0x8NAmrNQVyDYhpP9NiRANmq4DTUgqSPEFiZ6Dx6FYGD4fldRq1JYSYqQ==
dependencies:
"@ardatan/sync-fetch" "0.0.1"
- "@graphql-tools/utils" "9.1.3"
- "@whatwg-node/fetch" "^0.5.0"
+ "@graphql-tools/utils" "9.1.4"
+ "@whatwg-node/fetch" "^0.6.0"
tslib "^2.4.0"
-"@graphql-tools/batch-execute@8.5.14":
- version "8.5.14"
- resolved "https://registry.yarnpkg.com/@graphql-tools/batch-execute/-/batch-execute-8.5.14.tgz#d241adedc53df534263bfaed9c6fc15c3890bb90"
- integrity sha512-m6yXqqmFAH2V5JuSIC/geiGLBQA1Y6RddOJfUtkc9Z7ttkULRCd1W39TpYS6IlrCwYyTj+klO1/kdWiny38f5g==
+"@graphql-tools/batch-execute@8.5.15":
+ version "8.5.15"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/batch-execute/-/batch-execute-8.5.15.tgz#f61ac71d11e57c9b9f8b8b60fc882e4e9762d182"
+ integrity sha512-qb12M8XCK6SBJmZDS8Lzd4PVJFsIwNUkYmFuqcTiBqOI/WsoDlQDZI++ghRpGcusLkL9uzcIOTT/61OeHhsaLg==
dependencies:
- "@graphql-tools/utils" "9.1.3"
+ "@graphql-tools/utils" "9.1.4"
dataloader "2.1.0"
tslib "^2.4.0"
- value-or-promise "1.0.11"
+ value-or-promise "1.0.12"
"@graphql-tools/code-file-loader@^7.3.13":
- version "7.3.15"
- resolved "https://registry.yarnpkg.com/@graphql-tools/code-file-loader/-/code-file-loader-7.3.15.tgz#3834033e1f58876d6c95248d8eb451d84d600eab"
- integrity sha512-cF8VNc/NANTyVSIK8BkD/KSXRF64DvvomuJ0evia7tJu4uGTXgDjimTMWsTjKRGOOBSTEbL6TA8e4DdIYq6Udw==
+ version "7.3.17"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/code-file-loader/-/code-file-loader-7.3.17.tgz#bfe854c2d61f429a62ca0976fbd0f12045142abc"
+ integrity sha512-LqJgYJCau1/uIOZmnFixl8yJT99jTjQlNhUP3Vj0oQ0HODdPUKUjWA87SkwZR1TJzX19iKf/iGzfbLCAAhFRbA==
dependencies:
- "@graphql-tools/graphql-tag-pluck" "7.4.2"
- "@graphql-tools/utils" "9.1.3"
+ "@graphql-tools/graphql-tag-pluck" "7.4.3"
+ "@graphql-tools/utils" "9.1.4"
globby "^11.0.3"
tslib "^2.4.0"
unixify "^1.0.0"
-"@graphql-tools/delegate@9.0.21":
- version "9.0.21"
- resolved "https://registry.yarnpkg.com/@graphql-tools/delegate/-/delegate-9.0.21.tgz#914d59e6a10457fe1ddcac9270336648cfa8ca58"
- integrity sha512-SM8tFeq6ogFGhIxDE82WTS44/3IQ/wz9QksAKT7xWkcICQnyR9U6Qyt+W7VGnHiybqNsVK3kHNNS/i4KGSF85g==
+"@graphql-tools/delegate@9.0.24":
+ version "9.0.24"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/delegate/-/delegate-9.0.24.tgz#69ae776175f41696f16a9a1c9074af525be4152b"
+ integrity sha512-8+ircuaz51+yLip2qBBYenNlV8xiP7i44C+H+kO82ARmo2h47/q488K38DMbOL5//7G2Qt0GEZwTEF4h8ICGJQ==
dependencies:
- "@graphql-tools/batch-execute" "8.5.14"
- "@graphql-tools/executor" "0.0.11"
- "@graphql-tools/schema" "9.0.12"
- "@graphql-tools/utils" "9.1.3"
+ "@graphql-tools/batch-execute" "8.5.15"
+ "@graphql-tools/executor" "0.0.12"
+ "@graphql-tools/schema" "9.0.14"
+ "@graphql-tools/utils" "9.1.4"
dataloader "2.1.0"
- tslib "~2.4.0"
- value-or-promise "1.0.11"
+ tslib "~2.5.0"
+ value-or-promise "1.0.12"
-"@graphql-tools/executor-graphql-ws@0.0.5":
- version "0.0.5"
- resolved "https://registry.yarnpkg.com/@graphql-tools/executor-graphql-ws/-/executor-graphql-ws-0.0.5.tgz#eb81fb72ef1eb095be1b2d377b846bff6bf6d102"
- integrity sha512-1bJfZdSBPCJWz1pJ5g/YHMtGt6YkNRDdmqNQZ8v+VlQTNVfuBpY2vzj15uvf5uDrZLg2MSQThrKlL8av4yFpsA==
+"@graphql-tools/executor-graphql-ws@0.0.7":
+ version "0.0.7"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/executor-graphql-ws/-/executor-graphql-ws-0.0.7.tgz#5e7b0e6d02d3b64727bfb37c0f2c1e13badcb829"
+ integrity sha512-C6EExKoukn4vu3BbvlqsqtC91F4pTLPDZvRceYjpFzTCQSGFSjfrxQGP/haGlemXVRpIDxBy7wpXoQlsF8UmFA==
dependencies:
- "@graphql-tools/utils" "9.1.3"
+ "@graphql-tools/utils" "9.1.4"
"@repeaterjs/repeater" "3.0.4"
"@types/ws" "^8.0.0"
graphql-ws "5.11.2"
isomorphic-ws "5.0.0"
tslib "^2.4.0"
- ws "8.11.0"
+ ws "8.12.0"
-"@graphql-tools/executor-http@0.0.8":
- version "0.0.8"
- resolved "https://registry.yarnpkg.com/@graphql-tools/executor-http/-/executor-http-0.0.8.tgz#ede3f3104f27f2ed8f8a6f8c49eb704785823c99"
- integrity sha512-Y0WzbBW2dDm68EqjRO7eaCC38H6mNFUCcy8ivwnv0hon/N4GjQJhrR0cApJh/xqn/YqCY0Sn2ScmdGVuSdaCcA==
+"@graphql-tools/executor-http@0.1.2":
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/executor-http/-/executor-http-0.1.2.tgz#3be2fc629810b12068ce75780c4906d77f74d596"
+ integrity sha512-XowkX6UwVxe80N4YMBLlojZJS8PhqC5KaxckyZjlIx6ratmF+sMn/IHAc0Ea4kEXsBHs6JoE3mZrQ6NGVGRY2w==
dependencies:
- "@graphql-tools/utils" "9.1.3"
+ "@graphql-tools/utils" "9.1.4"
"@repeaterjs/repeater" "3.0.4"
- "@whatwg-node/fetch" "0.5.4"
+ "@whatwg-node/fetch" "0.6.5"
dset "3.1.2"
extract-files "^11.0.0"
meros "1.2.1"
tslib "^2.4.0"
- value-or-promise "1.0.11"
+ value-or-promise "1.0.12"
-"@graphql-tools/executor-legacy-ws@0.0.5":
- version "0.0.5"
- resolved "https://registry.yarnpkg.com/@graphql-tools/executor-legacy-ws/-/executor-legacy-ws-0.0.5.tgz#0246d930ed53bc185093bee78fb614473f465d51"
- integrity sha512-j2ZQVTI4rKIT41STzLPK206naYDhHxmGHot0siJKBKX1vMqvxtWBqvL66v7xYEOaX79wJrFc8l6oeURQP2LE6g==
+"@graphql-tools/executor-legacy-ws@0.0.6":
+ version "0.0.6"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/executor-legacy-ws/-/executor-legacy-ws-0.0.6.tgz#236dd5b3d4d19492978b1458b74928e8c69d16ff"
+ integrity sha512-L1hRuSvBUCNerYDhfeSZXFeqliDlnNXa3fDHTp7efI3Newpbevqa19Fm0mVzsCL7gqIKOwzrPORwh7kOVE/vew==
dependencies:
- "@graphql-tools/utils" "9.1.3"
+ "@graphql-tools/utils" "9.1.4"
"@types/ws" "^8.0.0"
isomorphic-ws "5.0.0"
tslib "^2.4.0"
- ws "8.11.0"
+ ws "8.12.0"
-"@graphql-tools/executor@0.0.11":
- version "0.0.11"
- resolved "https://registry.yarnpkg.com/@graphql-tools/executor/-/executor-0.0.11.tgz#a95823478e8edba05e55fd8ed43aceff7bd04022"
- integrity sha512-GjtXW0ZMGZGKad6A1HXFPArkfxE0AIpznusZuQdy4laQx+8Ut3Zx8SAFJNnDfZJ2V5kU29B5Xv3Fr0/DiMBHOQ==
+"@graphql-tools/executor@0.0.12":
+ version "0.0.12"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/executor/-/executor-0.0.12.tgz#d885c7fa98a8aaeaa771163b71fb98ce9f52f9bd"
+ integrity sha512-bWpZcYRo81jDoTVONTnxS9dDHhEkNVjxzvFCH4CRpuyzD3uL+5w3MhtxIh24QyWm4LvQ4f+Bz3eMV2xU2I5+FA==
dependencies:
- "@graphql-tools/utils" "9.1.3"
+ "@graphql-tools/utils" "9.1.4"
"@graphql-typed-document-node/core" "3.1.1"
"@repeaterjs/repeater" "3.0.4"
tslib "^2.4.0"
- value-or-promise "1.0.11"
+ value-or-promise "1.0.12"
"@graphql-tools/git-loader@^7.2.13":
- version "7.2.15"
- resolved "https://registry.yarnpkg.com/@graphql-tools/git-loader/-/git-loader-7.2.15.tgz#875968e5c4680247211e55523988b05a12bc1a46"
- integrity sha512-1d5HmeuxhSNjQ2+k2rfKgcKcnZEC6H5FM2pY5lSXHMv8VdBELZd7pYDs5/JxoZarDVYfYOJ5xTeVzxf+Du3VNg==
+ version "7.2.16"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/git-loader/-/git-loader-7.2.16.tgz#8c025cad12a623ac91e421eb01380cc177070e7c"
+ integrity sha512-8DsxYfSouhgKPOBcc7MzuOTM4M/j2UNFn2ehXD0MX9q41t3dKffufJZKsKxE6VyyCUoVYdlRFhUWEyOHPVdcfQ==
dependencies:
- "@graphql-tools/graphql-tag-pluck" "7.4.2"
- "@graphql-tools/utils" "9.1.3"
+ "@graphql-tools/graphql-tag-pluck" "7.4.3"
+ "@graphql-tools/utils" "9.1.4"
is-glob "4.0.3"
micromatch "^4.0.4"
tslib "^2.4.0"
unixify "^1.0.0"
"@graphql-tools/github-loader@^7.3.20":
- version "7.3.22"
- resolved "https://registry.yarnpkg.com/@graphql-tools/github-loader/-/github-loader-7.3.22.tgz#28aff4f33ffcd4e2d6b0836115fb41df8addd755"
- integrity sha512-JE5F/ObbwknO7+gDfeuKAZtLS831WV8/SsLzQLMGY0hdgTbsAg2/xziAGprNToK4GMSD7ygCer9ZryvxBKMwbQ==
+ version "7.3.23"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/github-loader/-/github-loader-7.3.23.tgz#9688f4b9cd9596229f0f8c7eed7a8f500806defa"
+ integrity sha512-oYTZCvW520KNVVonjucDSMhabCFnHwtM1rJbyUkA1JFyzpmmNAAyNMWOOPcU/Q9rTESrsH+Hbja0mfpjpnBKLA==
dependencies:
"@ardatan/sync-fetch" "0.0.1"
- "@graphql-tools/graphql-tag-pluck" "7.4.2"
- "@graphql-tools/utils" "9.1.3"
- "@whatwg-node/fetch" "^0.5.0"
+ "@graphql-tools/graphql-tag-pluck" "7.4.3"
+ "@graphql-tools/utils" "9.1.4"
+ "@whatwg-node/fetch" "^0.6.0"
tslib "^2.4.0"
"@graphql-tools/graphql-file-loader@^7.3.7", "@graphql-tools/graphql-file-loader@^7.5.0":
- version "7.5.13"
- resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-file-loader/-/graphql-file-loader-7.5.13.tgz#2e60b7e9752334ee030276c9493d411da8a30e43"
- integrity sha512-VWFVnw3aB6sykGfpb/Dn3sxQswqvp2FsVwDy8ubH1pgLuxlDuurhHjRHvMG2+p7IaHC7q8T3Vk/rLtZftrwOBQ==
+ version "7.5.14"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-file-loader/-/graphql-file-loader-7.5.14.tgz#6c6527e353cf9adcbda2cdc8a85face03ad8fe04"
+ integrity sha512-JGer4g57kq4wtsvqv8uZsT4ZG1lLsz1x5yHDfSj2OxyiWw2f1jFkzgby7Ut3H2sseJiQzeeDYZcbm06qgR32pg==
dependencies:
- "@graphql-tools/import" "6.7.14"
- "@graphql-tools/utils" "9.1.3"
+ "@graphql-tools/import" "6.7.15"
+ "@graphql-tools/utils" "9.1.4"
globby "^11.0.3"
tslib "^2.4.0"
unixify "^1.0.0"
-"@graphql-tools/graphql-tag-pluck@7.4.2":
- version "7.4.2"
- resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-7.4.2.tgz#0e72a142e2fb7e0cb6a86b910e44682772e5d7f1"
- integrity sha512-SXM1wR5TExrxocQTxZK5r74jTbg8GxSYLY3mOPCREGz6Fu7PNxMxfguUzGUAB43Mf44Dn8oVztzd2eitv2Qgww==
+"@graphql-tools/graphql-tag-pluck@7.4.3":
+ version "7.4.3"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-7.4.3.tgz#b07f2263c383d9605d941c836dc01a7bbc6e56a7"
+ integrity sha512-w+nrJVQw+NTuaZNQG5AwSh4Qe+urP/s4rUz5s1T007rDnv1kvkiX+XHOCnIfJzXOTuvFmG4GGYw/x0CuSRaGZQ==
dependencies:
"@babel/parser" "^7.16.8"
"@babel/plugin-syntax-import-assertions" "7.20.0"
"@babel/traverse" "^7.16.8"
"@babel/types" "^7.16.8"
- "@graphql-tools/utils" "9.1.3"
+ "@graphql-tools/utils" "9.1.4"
tslib "^2.4.0"
-"@graphql-tools/import@6.7.14":
- version "6.7.14"
- resolved "https://registry.yarnpkg.com/@graphql-tools/import/-/import-6.7.14.tgz#4f3278841217686eed8950db0aa5040bc35f6970"
- integrity sha512-lRX/MHM0Km497kg4VXMvtV1DeG/AfPJFO2ovaL0kDujWEdyCsWxsB4whY7nPeiNaPA/nT3mQ8MU7yFzVjogF/Q==
+"@graphql-tools/import@6.7.15":
+ version "6.7.15"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/import/-/import-6.7.15.tgz#7553e48140797255588b26d423a89aa042196928"
+ integrity sha512-WNhvauAt2I2iUg+JdQK5oQebKLXqUZWe8naP13K1jOkbTQT7hK3P/4I9AaVmzt0KXRJW5Uow3RgdHZ7eUBKVsA==
dependencies:
- "@graphql-tools/utils" "9.1.3"
+ "@graphql-tools/utils" "9.1.4"
resolve-from "5.0.0"
tslib "^2.4.0"
"@graphql-tools/json-file-loader@^7.3.7", "@graphql-tools/json-file-loader@^7.4.1":
- version "7.4.14"
- resolved "https://registry.yarnpkg.com/@graphql-tools/json-file-loader/-/json-file-loader-7.4.14.tgz#a174fc488f35340dcbbcdb0f2b82a57d19b723d0"
- integrity sha512-AD9v3rN08wvVqgbrUSiHa8Ztrlk3EgwctcxuNE5qm47zPNL4gLaJ7Tw/KlGOR7Cm+pjlQylJHMUKNfaRLPZ0og==
+ version "7.4.15"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/json-file-loader/-/json-file-loader-7.4.15.tgz#ed229d98784350623d2ef32628690db405fa6780"
+ integrity sha512-pH+hbsDetcEpj+Tmi7ZRUkxzJez2DLdSQuvK5Qi38FX/Nz/5nZKRfW9nqIptGYbuS9+2JPrt9WWNn1aGtegIFQ==
dependencies:
- "@graphql-tools/utils" "9.1.3"
+ "@graphql-tools/utils" "9.1.4"
globby "^11.0.3"
tslib "^2.4.0"
unixify "^1.0.0"
-"@graphql-tools/load@7.8.0":
- version "7.8.0"
- resolved "https://registry.yarnpkg.com/@graphql-tools/load/-/load-7.8.0.tgz#bd4d2e2a5117de9a60f9691a218217e96afc2ea7"
- integrity sha512-l4FGgqMW0VOqo+NMYizwV8Zh+KtvVqOf93uaLo9wJ3sS3y/egPCgxPMDJJ/ufQZG3oZ/0oWeKt68qop3jY0yZg==
+"@graphql-tools/load@^7.5.5", "@graphql-tools/load@^7.8.0":
+ version "7.8.10"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/load/-/load-7.8.10.tgz#c62ccc850e6f846e8214f1ae05e675a864d79b80"
+ integrity sha512-Mc1p7ZSxrW5yGG3BLQnhiL8RPG0HdxFVoHV7fpx2adp4o1V7BzDjKRSbCnAxShA1wA4n8wbA+n7NTC0edi4eNA==
dependencies:
- "@graphql-tools/schema" "9.0.4"
- "@graphql-tools/utils" "8.12.0"
+ "@graphql-tools/schema" "9.0.14"
+ "@graphql-tools/utils" "9.1.4"
p-limit "3.1.0"
tslib "^2.4.0"
-"@graphql-tools/load@^7.5.5":
- version "7.8.8"
- resolved "https://registry.yarnpkg.com/@graphql-tools/load/-/load-7.8.8.tgz#e55aaca84a9e6348a730d92ba4cb3ec17cee45df"
- integrity sha512-gMuQdO2jXmI0BNUc1MafxRQTWVMUtuH500pZAQtOdDdNJppV7lJdY6mMhITQ2qnhYDuMrcZPHhIkcftyQfkgUg==
+"@graphql-tools/merge@8.3.16", "@graphql-tools/merge@^8.2.6":
+ version "8.3.16"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.3.16.tgz#fede610687b148e34ff861e8b038dcd71e20039b"
+ integrity sha512-In0kcOZcPIpYOKaqdrJ3thdLPE7TutFnL9tbrHUy2zCinR2O/blpRC48jPckcs0HHrUQ0pGT4HqvzMkZUeEBAw==
dependencies:
- "@graphql-tools/schema" "9.0.12"
- "@graphql-tools/utils" "9.1.3"
- p-limit "3.1.0"
- tslib "^2.4.0"
-
-"@graphql-tools/merge@8.3.14", "@graphql-tools/merge@^8.2.6":
- version "8.3.14"
- resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.3.14.tgz#d4d0a645656691d35e90e0686a6fa3d4091a34da"
- integrity sha512-zV0MU1DnxJLIB0wpL4N3u21agEiYFsjm6DI130jqHpwF0pR9HkF+Ni65BNfts4zQelP0GjkHltG+opaozAJ1NA==
- dependencies:
- "@graphql-tools/utils" "9.1.3"
- tslib "^2.4.0"
-
-"@graphql-tools/merge@8.3.6":
- version "8.3.6"
- resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.3.6.tgz#97a936d4c8e8f935e58a514bb516c476437b5b2c"
- integrity sha512-uUBokxXi89bj08P+iCvQk3Vew4vcfL5ZM6NTylWi8PIpoq4r5nJ625bRuN8h2uubEdRiH8ntN9M4xkd/j7AybQ==
- dependencies:
- "@graphql-tools/utils" "8.12.0"
+ "@graphql-tools/utils" "9.1.4"
tslib "^2.4.0"
"@graphql-tools/prisma-loader@^7.2.49":
- version "7.2.50"
- resolved "https://registry.yarnpkg.com/@graphql-tools/prisma-loader/-/prisma-loader-7.2.50.tgz#f99114a5eaae4d5ff4babedcce34422d67238fd3"
- integrity sha512-tSZFtx5GP5LBHmChwVCkvFw9oCwc0QVP2xR/Pyp61c3Fb2gyqzFq/8lnbcmxR+Oi9/Cwt3JsSc4Jkg8jBi5HLw==
+ version "7.2.57"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/prisma-loader/-/prisma-loader-7.2.57.tgz#9d05597b448e8e3cb4ee9c09d4ad3bfbcf895509"
+ integrity sha512-BMupfl/XbAoFfs33pkxMRKfbyeij/Ife8QE4Opd3YmjY1B0/iY2IvlFrLcbX6ZHjB5Vy+26kFM5TerjDCnNXDw==
dependencies:
- "@graphql-tools/url-loader" "7.16.29"
- "@graphql-tools/utils" "9.1.3"
+ "@graphql-tools/url-loader" "7.17.6"
+ "@graphql-tools/utils" "9.1.4"
"@types/js-yaml" "^4.0.0"
"@types/json-stable-stringify" "^1.0.32"
- "@types/jsonwebtoken" "^8.5.0"
+ "@types/jsonwebtoken" "^9.0.0"
chalk "^4.1.0"
debug "^4.3.1"
dotenv "^16.0.0"
@@ -781,69 +764,52 @@
tslib "^2.4.0"
yaml-ast-parser "^0.0.43"
-"@graphql-tools/schema@9.0.12", "@graphql-tools/schema@^9.0.0":
- version "9.0.12"
- resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-9.0.12.tgz#73910fab315bd16098b989db22f967a1dc7f93dd"
- integrity sha512-DmezcEltQai0V1y96nwm0Kg11FDS/INEFekD4nnVgzBqawvznWqK6D6bujn+cw6kivoIr3Uq//QmU/hBlBzUlQ==
+"@graphql-tools/schema@9.0.14", "@graphql-tools/schema@^9.0.0":
+ version "9.0.14"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-9.0.14.tgz#9a658ab82d5a7d4db73f68a44900d4c88a98f0bc"
+ integrity sha512-U6k+HY3Git+dsOEhq+dtWQwYg2CAgue8qBvnBXoKu5eEeH284wymMUoNm0e4IycOgMCJANVhClGEBIkLRu3FQQ==
dependencies:
- "@graphql-tools/merge" "8.3.14"
- "@graphql-tools/utils" "9.1.3"
+ "@graphql-tools/merge" "8.3.16"
+ "@graphql-tools/utils" "9.1.4"
tslib "^2.4.0"
- value-or-promise "1.0.11"
+ value-or-promise "1.0.12"
-"@graphql-tools/schema@9.0.4":
- version "9.0.4"
- resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-9.0.4.tgz#1a74608b57abf90fae6fd929d25e5482c57bc05d"
- integrity sha512-B/b8ukjs18fq+/s7p97P8L1VMrwapYc3N2KvdG/uNThSazRRn8GsBK0Nr+FH+mVKiUfb4Dno79e3SumZVoHuOQ==
- dependencies:
- "@graphql-tools/merge" "8.3.6"
- "@graphql-tools/utils" "8.12.0"
- tslib "^2.4.0"
- value-or-promise "1.0.11"
-
-"@graphql-tools/url-loader@7.16.29", "@graphql-tools/url-loader@^7.13.2", "@graphql-tools/url-loader@^7.9.7":
- version "7.16.29"
- resolved "https://registry.yarnpkg.com/@graphql-tools/url-loader/-/url-loader-7.16.29.tgz#86ea852870a3a1b66bcb06143422f2512cecd0ab"
- integrity sha512-e7c0rLH4BIaYxOgglHhWbupTn3JZFXYIHXpY+T1CcTF3nQQCaKy8o59+R2AjtEgx3Az1WNahGn4xgkKUxUwCBw==
+"@graphql-tools/url-loader@7.17.6", "@graphql-tools/url-loader@^7.13.2", "@graphql-tools/url-loader@^7.9.7":
+ version "7.17.6"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/url-loader/-/url-loader-7.17.6.tgz#23c07f69f8a8aabb0c659355d3f1e04254204293"
+ integrity sha512-xMmdXYjcDn0qWKhsredI/jLgUwTV+EinQUDj/lo2BOXYzAaJkP47UFLwFrRpQmpf7l2VdOUyHjZXGnDB10NBjQ==
dependencies:
"@ardatan/sync-fetch" "0.0.1"
- "@graphql-tools/delegate" "9.0.21"
- "@graphql-tools/executor-graphql-ws" "0.0.5"
- "@graphql-tools/executor-http" "0.0.8"
- "@graphql-tools/executor-legacy-ws" "0.0.5"
- "@graphql-tools/utils" "9.1.3"
- "@graphql-tools/wrap" "9.2.23"
+ "@graphql-tools/delegate" "9.0.24"
+ "@graphql-tools/executor-graphql-ws" "0.0.7"
+ "@graphql-tools/executor-http" "0.1.2"
+ "@graphql-tools/executor-legacy-ws" "0.0.6"
+ "@graphql-tools/utils" "9.1.4"
+ "@graphql-tools/wrap" "9.3.3"
"@types/ws" "^8.0.0"
- "@whatwg-node/fetch" "^0.5.0"
+ "@whatwg-node/fetch" "^0.6.0"
isomorphic-ws "5.0.0"
tslib "^2.4.0"
value-or-promise "^1.0.11"
- ws "8.11.0"
+ ws "8.12.0"
-"@graphql-tools/utils@8.12.0":
- version "8.12.0"
- resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.12.0.tgz#243bc4f5fc2edbc9e8fd1038189e57d837cbe31f"
- integrity sha512-TeO+MJWGXjUTS52qfK4R8HiPoF/R7X+qmgtOYd8DTH0l6b+5Y/tlg5aGeUJefqImRq7nvi93Ms40k/Uz4D5CWw==
+"@graphql-tools/utils@9.1.4", "@graphql-tools/utils@^9.0.0", "@graphql-tools/utils@^9.1.1":
+ version "9.1.4"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-9.1.4.tgz#2c9e0aefc9655dd73247667befe3c850ec014f3f"
+ integrity sha512-hgIeLt95h9nQgQuzbbdhuZmh+8WV7RZ/6GbTj6t3IU4Zd2zs9yYJ2jgW/krO587GMOY8zCwrjNOMzD40u3l7Vg==
dependencies:
tslib "^2.4.0"
-"@graphql-tools/utils@9.1.3", "@graphql-tools/utils@^9.0.0", "@graphql-tools/utils@^9.1.1":
- version "9.1.3"
- resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-9.1.3.tgz#861f87057b313726136fa6ddfbd2380eae906599"
- integrity sha512-bbJyKhs6awp1/OmP+WKA1GOyu9UbgZGkhIj5srmiMGLHohEOKMjW784Sk0BZil1w2x95UPu0WHw6/d/HVCACCg==
+"@graphql-tools/wrap@9.3.3":
+ version "9.3.3"
+ resolved "https://registry.yarnpkg.com/@graphql-tools/wrap/-/wrap-9.3.3.tgz#d69a21f9d13ccff89bc95cc479b45ab23683e55b"
+ integrity sha512-KN+mWFXqUAZVYWotp396lAestMZx7SYwvCWwi6D9HNy89PLK2XYBfXKlvTUYZ5zEC5s2Qhc/DbnHJ3hSFyX7Gg==
dependencies:
+ "@graphql-tools/delegate" "9.0.24"
+ "@graphql-tools/schema" "9.0.14"
+ "@graphql-tools/utils" "9.1.4"
tslib "^2.4.0"
-
-"@graphql-tools/wrap@9.2.23":
- version "9.2.23"
- resolved "https://registry.yarnpkg.com/@graphql-tools/wrap/-/wrap-9.2.23.tgz#fb008d8d7b493aeb6b6b0821dff45c0129aed2eb"
- integrity sha512-R+ar8lHdSnRQtfvkwQMOkBRlYLcBPdmFzZPiAj+tL9Nii4VNr4Oub37jcHiPBvRZSdKa9FHcKq5kKSQcbg1xuQ==
- dependencies:
- "@graphql-tools/delegate" "9.0.21"
- "@graphql-tools/schema" "9.0.12"
- "@graphql-tools/utils" "9.1.3"
- tslib "^2.4.0"
- value-or-promise "1.0.11"
+ value-or-promise "1.0.12"
"@graphql-typed-document-node/core@3.1.1", "@graphql-typed-document-node/core@^3.1.1":
version "3.1.1"
@@ -1089,9 +1055,9 @@
ethereumjs-util "^7.1.4"
"@nomicfoundation/hardhat-toolbox@^2.0.0":
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-2.0.0.tgz#7f86e35c380babb8f26440b7f9a92d7febc1a8ac"
- integrity sha512-BoOPbzLQ1GArnBZd4Jz4IU8FY3RY4nUwpXlfymXwxlXNimngkPRJj7ivVNurD7igohEjf90v/Axn2M5WwAdCJQ==
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-2.0.1.tgz#3d8c620a54df2c0086c9109fb0f987bf29329deb"
+ integrity sha512-/pr8m9xlqiNlq6fXv4hEPNwdNwUhysoB2qbDCKqERfPpq34EydUQTC3Vis4aIea8RLwSrU8sDXFdv4TQxYstKw==
"@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.0":
version "0.1.0"
@@ -1160,14 +1126,14 @@
"@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.0"
"@nomiclabs/hardhat-ethers@^2.2.1":
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.1.tgz#8057b43566a0e41abeb8142064a3c0d3f23dca86"
- integrity sha512-RHWYwnxryWR8hzRmU4Jm/q4gzvXpetUOJ4OPlwH2YARcDB+j79+yAYCwO0lN1SUOb4++oOTJEe6AWLEc42LIvg==
+ version "2.2.2"
+ resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.2.tgz#812d48929c3bf8fe840ec29eab4b613693467679"
+ integrity sha512-NLDlDFL2us07C0jB/9wzvR0kuLivChJWCXTKcj3yqjZqMoYp7g7wwS157F70VHx/+9gHIBGzak5pKDwG8gEefA==
"@nomiclabs/hardhat-etherscan@^3.1.0":
- version "3.1.3"
- resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.3.tgz#c9dbaa4174edfa075a464a0e9142bc8710a2c4e2"
- integrity sha512-UeNO97j0lwOHqX7mrH6SfQQBdXq1Ng6eFr7uJKuQOrq2UVTWGD70lE5QO4fAFVPz9ao+xlNpMyIqSR7+OaDR+Q==
+ version "3.1.5"
+ resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.5.tgz#24f3f3272d3c79acdc933b557810ca85caef0fee"
+ integrity sha512-PxPX28AGBAlxgXLU27NB3oiMsklxbNhM75SDC4v1QPCyPeAxGm4xV0WpYbR10W7sxY2WF3Ek7u7GhjbQWa2Fcg==
dependencies:
"@ethersproject/abi" "^5.1.2"
"@ethersproject/address" "^5.0.2"
@@ -1178,7 +1144,7 @@
lodash "^4.17.11"
semver "^6.3.0"
table "^6.8.0"
- undici "^5.4.0"
+ undici "^5.14.0"
"@nomiclabs/hardhat-web3@^2.0.0":
version "2.0.0"
@@ -1188,19 +1154,19 @@
"@types/bignumber.js" "^5.0.0"
"@openzeppelin/contracts-upgradeable@^4.8.0":
- version "4.8.0"
- resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.0.tgz#26688982f46969018e3ed3199e72a07c8d114275"
- integrity sha512-5GeFgqMiDlqGT8EdORadp1ntGF0qzWZLmEY7Wbp/yVhN7/B3NNzCxujuI77ktlyG81N3CUZP8cZe3ZAQ/cW10w==
+ version "4.8.1"
+ resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.1.tgz#363f7dd08f25f8f77e16d374350c3d6b43340a7a"
+ integrity sha512-1wTv+20lNiC0R07jyIAbHU7TNHKRwGiTGRfiNnA8jOWjKT98g5OgLpYWOi40Vgpk8SPLA9EvfJAbAeIyVn+7Bw==
"@openzeppelin/contracts@^4.7.3":
- version "4.8.0"
- resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.8.0.tgz#6854c37df205dd2c056bdfa1b853f5d732109109"
- integrity sha512-AGuwhRRL+NaKx73WKRNzeCxOCOCxpaqF+kp8TJ89QzAipSwZy/NoflkWaL9bywXFRhIzXt8j38sfF7KBKCPWLw==
+ version "4.8.1"
+ resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.8.1.tgz#709cfc4bbb3ca9f4460d60101f15dac6b7a2d5e4"
+ integrity sha512-xQ6eUZl+RDyb/FiZe1h+U7qr/f4p/SrTSQcTPH2bjur3C5DbuW/zFgCU/b1P/xcIaEqJep+9ju4xDRi3rmChdQ==
"@openzeppelin/hardhat-upgrades@^1.22.0":
- version "1.22.0"
- resolved "https://registry.yarnpkg.com/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.22.0.tgz#2a432c72a428a9f277201646bc1a248021538f06"
- integrity sha512-1qyZnDaxl0C8tne7ykNRa/fxw3FrNCY2M3fGuCiQW5DDkJoXhLgm3JVsXwl6X7q9mQSrik4vgBbI3ErmxmZTYg==
+ version "1.22.1"
+ resolved "https://registry.yarnpkg.com/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.22.1.tgz#93e2b3f870c57b00a1ae8a330a2cdd9c2d634eb8"
+ integrity sha512-MdoitCTLl4zwMU8MeE/bCj+7JMWBEvd38XqJkw36PkJrXlbv6FedDVCPoumMAhpmtymm0nTwTYYklYG+L6WiiQ==
dependencies:
"@openzeppelin/upgrades-core" "^1.20.0"
chalk "^4.1.0"
@@ -1208,9 +1174,9 @@
proper-lockfile "^4.1.1"
"@openzeppelin/upgrades-core@^1.20.0":
- version "1.20.6"
- resolved "https://registry.yarnpkg.com/@openzeppelin/upgrades-core/-/upgrades-core-1.20.6.tgz#74f43d600151b8fda6e2d375f46ae0da55922620"
- integrity sha512-KWdtlahm+iunlAlzLsdpBueanwEx0LLPfAkDL1p0C4SPjMiUqHHFlyGtmmWwdiqDpJ//605vfwkd5RqfnFrHSg==
+ version "1.22.0"
+ resolved "https://registry.yarnpkg.com/@openzeppelin/upgrades-core/-/upgrades-core-1.22.0.tgz#41ffda6a9161845fc6b82bd945e530529feefa00"
+ integrity sha512-TcTabzRbYOzWJnwiToj0LRzje25d9QbDPe2dOT9eHlLDRhOMiep39FDibJjkYd5IdF3s8M9IcK+YSnf49renEg==
dependencies:
cbor "^8.0.0"
chalk "^4.1.0"
@@ -1478,10 +1444,10 @@
resolved "https://registry.yarnpkg.com/@types/json-stable-stringify/-/json-stable-stringify-1.0.34.tgz#c0fb25e4d957e0ee2e497c1f553d7f8bb668fd75"
integrity sha512-s2cfwagOQAS8o06TcwKfr9Wx11dNGbH2E9vJz1cqV+a/LOyhWNLUNd6JSRYNzvB4d29UuJX2M0Dj9vE1T8fRXw==
-"@types/jsonwebtoken@^8.5.0":
- version "8.5.9"
- resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.9.tgz#2c064ecb0b3128d837d2764aa0b117b0ff6e4586"
- integrity sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==
+"@types/jsonwebtoken@^9.0.0":
+ version "9.0.1"
+ resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.1.tgz#29b1369c4774200d6d6f63135bf3d1ba3ef997a4"
+ integrity sha512-c5ltxazpWabia/4UzhIoaDcIza4KViOQhdbjRlfcIGVnsE3c3brkz9Z+F/EeJIECOQP7W7US2hNE930cWWkPiw==
dependencies:
"@types/node" "*"
@@ -1508,9 +1474,9 @@
integrity sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==
"@types/node@*":
- version "18.11.17"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.17.tgz#5c009e1d9c38f4a2a9d45c0b0c493fe6cdb4bcb5"
- integrity sha512-HJSUJmni4BeDHhfzn6nF0sVmd1SMezP7/4F0Lq+aXzmp2xm9O7WXrUtHW/CHlYVtZUbByEvWidHqRtcJXGF2Ng==
+ version "18.11.18"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f"
+ integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==
"@types/node@^10.0.3":
version "10.17.60"
@@ -1565,34 +1531,30 @@
dependencies:
"@types/node" "*"
-"@whatwg-node/fetch@0.5.4", "@whatwg-node/fetch@^0.5.0":
- version "0.5.4"
- resolved "https://registry.yarnpkg.com/@whatwg-node/fetch/-/fetch-0.5.4.tgz#ef7c409078fc4a5087415043f87c9d9589cda8d6"
- integrity sha512-dR5PCzvOeS7OaW6dpIlPt+Ou3pak7IEG+ZVAV26ltcaiDB3+IpuvjqRdhsY6FKHcqBo1qD+S99WXY9Z6+9Rwnw==
- dependencies:
- "@peculiar/webcrypto" "^1.4.0"
- abort-controller "^3.0.0"
- busboy "^1.6.0"
- form-data-encoder "^1.7.1"
- formdata-node "^4.3.1"
- node-fetch "^2.6.7"
- undici "^5.12.0"
- web-streams-polyfill "^3.2.0"
+"@whatwg-node/events@0.0.2":
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/@whatwg-node/events/-/events-0.0.2.tgz#7b7107268d2982fc7b7aff5ee6803c64018f84dd"
+ integrity sha512-WKj/lI4QjnLuPrim0cfO7i+HsDSXHxNv1y0CrJhdntuO3hxWZmnXCwNDnwOvry11OjRin6cgWNF+j/9Pn8TN4w==
-"@whatwg-node/fetch@^0.6.0":
- version "0.6.1"
- resolved "https://registry.yarnpkg.com/@whatwg-node/fetch/-/fetch-0.6.1.tgz#802a3e71ade25c04211efc2f1520a25a8829924f"
- integrity sha512-sG39WLvcJxGZ+gDstnLSXR2IcnuvIOB51KxCFo0mEhFW0q2u8fZgolr0HPkL+zXwOJsnmT+9V3IRcqLnTXdqVQ==
+"@whatwg-node/fetch@0.6.5", "@whatwg-node/fetch@^0.6.0":
+ version "0.6.5"
+ resolved "https://registry.yarnpkg.com/@whatwg-node/fetch/-/fetch-0.6.5.tgz#ff96288e9a6295faafac79f13e3b3fd831cad11f"
+ integrity sha512-3XQ78RAMX8Az0LlUqMoGM3jbT+FE0S+IKr4yiTiqzQ5S/pNxD52K/kFLcLQiEbL+3rkk/glCHqjxF1QI5155Ig==
dependencies:
"@peculiar/webcrypto" "^1.4.0"
- abort-controller "^3.0.0"
+ "@whatwg-node/node-fetch" "0.0.1"
busboy "^1.6.0"
- form-data-encoder "^1.7.1"
- formdata-node "^4.3.1"
- node-fetch "^2.6.7"
- undici "^5.12.0"
urlpattern-polyfill "^6.0.2"
- web-streams-polyfill "^3.2.0"
+ web-streams-polyfill "^3.2.1"
+
+"@whatwg-node/node-fetch@0.0.1":
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/@whatwg-node/node-fetch/-/node-fetch-0.0.1.tgz#ffad65f3f8b73d6d2c2e8b179d557a5863b0db13"
+ integrity sha512-dMbh604yf2jl37IzvYGA6z3heQg3dMzlqoNsiNToe46SVmKusfJXGf4KYIuiJTzh9mEEu/uVF//QakUfsLJpwA==
+ dependencies:
+ "@whatwg-node/events" "0.0.2"
+ busboy "1.6.0"
+ tslib "^2.3.1"
abbrev@1:
version "1.1.1"
@@ -1643,9 +1605,9 @@ acorn-walk@^8.1.1:
integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
acorn@^8.4.1:
- version "8.8.1"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73"
- integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==
+ version "8.8.2"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a"
+ integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==
address@^1.0.1:
version "1.2.2"
@@ -1688,9 +1650,9 @@ ajv@^6.12.3:
uri-js "^4.2.2"
ajv@^8.0.1:
- version "8.11.2"
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.2.tgz#aecb20b50607acf2569b6382167b65a96008bb78"
- integrity sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==
+ version "8.12.0"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1"
+ integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==
dependencies:
fast-deep-equal "^3.1.1"
json-schema-traverse "^1.0.0"
@@ -1824,16 +1786,6 @@ asap@~2.0.6:
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==
-asn1.js@^5.2.0:
- version "5.4.1"
- resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07"
- integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==
- dependencies:
- bn.js "^4.0.0"
- inherits "^2.0.1"
- minimalistic-assert "^1.0.0"
- safer-buffer "^2.1.0"
-
asn1@~0.2.3:
version "0.2.6"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d"
@@ -1905,9 +1857,9 @@ aws-sign2@~0.7.0:
integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==
aws4@^1.8.0:
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59"
- integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==
+ version "1.12.0"
+ resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3"
+ integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==
balanced-match@^1.0.0:
version "1.0.2"
@@ -1939,9 +1891,9 @@ bech32@1.1.4:
integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==
bigint-crypto-utils@^3.0.23:
- version "3.1.7"
- resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.1.7.tgz#c4c1b537c7c1ab7aadfaecf3edfd45416bf2c651"
- integrity sha512-zpCQpIE2Oy5WIQpjC9iYZf8Uh9QqoS51ZCooAcNvzv1AQ3VWdT52D0ksr1+/faeK8HVIej1bxXcP75YcqH3KPA==
+ version "3.1.8"
+ resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.1.8.tgz#e2e0f40cf45488f9d7f0e32ff84152aa73819d5d"
+ integrity sha512-+VMV9Laq8pXLBKKKK49nOoq9bfR3j7NNQAtbA617a4nw9bVLo8rsqkKMBgM2AJWlNX9fEIyYaYX+d0laqYV4tw==
dependencies:
bigint-mod-arith "^3.1.0"
@@ -1960,7 +1912,7 @@ binary-extensions@^2.0.0:
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
-bl@^4.1.0:
+bl@^4.0.3, bl@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
@@ -1984,12 +1936,12 @@ bn.js@4.11.6:
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215"
integrity sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==
-bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9:
+bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9:
version "4.12.0"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
-bn.js@^5.0.0, bn.js@^5.1.1, bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1:
+bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70"
integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==
@@ -2034,7 +1986,7 @@ braces@^3.0.2, braces@~3.0.2:
dependencies:
fill-range "^7.0.1"
-brorand@^1.0.1, brorand@^1.1.0:
+brorand@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==
@@ -2054,7 +2006,7 @@ browser-stdout@1.3.1:
resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
-browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.2.0:
+browserify-aes@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48"
integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==
@@ -2066,48 +2018,6 @@ browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.2.0:
inherits "^2.0.1"
safe-buffer "^5.0.1"
-browserify-cipher@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0"
- integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==
- dependencies:
- browserify-aes "^1.0.4"
- browserify-des "^1.0.0"
- evp_bytestokey "^1.0.0"
-
-browserify-des@^1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c"
- integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==
- dependencies:
- cipher-base "^1.0.1"
- des.js "^1.0.0"
- inherits "^2.0.1"
- safe-buffer "^5.1.2"
-
-browserify-rsa@^4.0.0, browserify-rsa@^4.0.1:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d"
- integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==
- dependencies:
- bn.js "^5.0.0"
- randombytes "^2.0.1"
-
-browserify-sign@^4.0.0:
- version "4.2.1"
- resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3"
- integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==
- dependencies:
- bn.js "^5.1.1"
- browserify-rsa "^4.0.1"
- create-hash "^1.2.0"
- create-hmac "^1.1.7"
- elliptic "^6.5.3"
- inherits "^2.0.4"
- parse-asn1 "^5.1.5"
- readable-stream "^3.6.0"
- safe-buffer "^5.2.0"
-
bs58@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a"
@@ -2167,7 +2077,7 @@ bufferutil@^4.0.1:
dependencies:
node-gyp-build "^4.3.0"
-busboy@^1.6.0:
+busboy@1.6.0, busboy@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893"
integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==
@@ -2375,7 +2285,7 @@ chokidar@3.5.3, chokidar@^3.4.0, chokidar@^3.5.2:
optionalDependencies:
fsevents "~2.3.2"
-chownr@^1.1.4:
+chownr@^1.1.1, chownr@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
@@ -2535,11 +2445,27 @@ color-name@1.1.3:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
-color-name@~1.1.4:
+color-name@^1.0.0, color-name@~1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
+color-string@^1.9.0:
+ version "1.9.1"
+ resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4"
+ integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==
+ dependencies:
+ color-name "^1.0.0"
+ simple-swizzle "^0.2.2"
+
+color@^4.2.3:
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a"
+ integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==
+ dependencies:
+ color-convert "^2.0.1"
+ color-string "^1.9.0"
+
colorette@^2.0.16, colorette@^2.0.19:
version "2.0.19"
resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798"
@@ -2550,6 +2476,14 @@ colors@1.4.0, colors@^1.1.2:
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
+colorthief@^2.3.2:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/colorthief/-/colorthief-2.3.2.tgz#00b984f421abe5a2af71c4d464c9d80d407fd53d"
+ integrity sha512-1r4nPW553JviRcFRvN3fS2V9nUSQGjRIws8UfEeFLIxk8j1tvtaX+AAYTkH3A4B5Muiys8SA1WJxf+00xVTXyg==
+ dependencies:
+ get-pixels "^3.3.2"
+ quantize "github:lokesh/quantize"
+
combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
@@ -2568,9 +2502,9 @@ commander@3.0.2:
integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==
commander@^9.4.1:
- version "9.4.1"
- resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.1.tgz#d1dd8f2ce6faf93147295c0df13c7c21141cfbdd"
- integrity sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==
+ version "9.5.0"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30"
+ integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==
common-tags@1.8.2:
version "1.8.2"
@@ -2623,9 +2557,9 @@ content-hash@^2.5.2:
multihashes "^0.4.15"
content-type@~1.0.4:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
- integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
+ integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==
cookie-signature@1.0.6:
version "1.0.6"
@@ -2660,7 +2594,7 @@ cors@^2.8.1:
object-assign "^4"
vary "^1"
-cosmiconfig-typescript-loader@4.3.0:
+cosmiconfig-typescript-loader@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.3.0.tgz#c4259ce474c9df0f32274ed162c0447c951ef073"
integrity sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q==
@@ -2691,14 +2625,6 @@ crc-32@^1.2.0:
resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff"
integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==
-create-ecdh@^4.0.0:
- version "4.0.4"
- resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e"
- integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==
- dependencies:
- bn.js "^4.1.0"
- elliptic "^6.5.3"
-
create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196"
@@ -2710,7 +2636,7 @@ create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0:
ripemd160 "^2.0.1"
sha.js "^2.4.0"
-create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7:
+create-hmac@^1.1.4, create-hmac@^1.1.7:
version "1.1.7"
resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff"
integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==
@@ -2748,22 +2674,12 @@ cross-spawn@^7.0.3:
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==
-crypto-browserify@3.12.0:
- version "3.12.0"
- resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
- integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==
+cwise-compiler@^1.1.2:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/cwise-compiler/-/cwise-compiler-1.1.3.tgz#f4d667410e850d3a313a7d2db7b1e505bb034cc5"
+ integrity sha512-WXlK/m+Di8DMMcCjcWr4i+XzcQra9eCdXIJrgh4TUgh0pIS/yJduLxS9JgefsHJ/YVLdgPtXm9r62W92MvanEQ==
dependencies:
- browserify-cipher "^1.0.0"
- browserify-sign "^4.0.0"
- create-ecdh "^4.0.0"
- create-hash "^1.1.0"
- create-hmac "^1.1.0"
- diffie-hellman "^5.0.0"
- inherits "^2.0.1"
- pbkdf2 "^3.0.3"
- public-encrypt "^4.0.0"
- randombytes "^2.0.0"
- randomfill "^1.0.3"
+ uniq "^1.0.0"
d@1, d@^1.0.1:
version "1.0.1"
@@ -2780,6 +2696,11 @@ dashdash@^1.12.0:
dependencies:
assert-plus "^1.0.0"
+data-uri-to-buffer@0.0.3:
+ version "0.0.3"
+ resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-0.0.3.tgz#18ae979a6a0ca994b0625853916d2662bbae0b1a"
+ integrity sha512-Cp+jOa8QJef5nXS5hU7M1DWzXPEIoVR3kbV0dQuVGwROZg8bGf1DcCnkmajBTnvghTtSNMUdRrPjgaT6ZQucbw==
+
dataloader@2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-2.1.0.tgz#c69c538235e85e7ac6c6c444bae8ecabf5de9df7"
@@ -2852,6 +2773,11 @@ deep-eql@^4.0.1, deep-eql@^4.1.2:
dependencies:
type-detect "^4.0.0"
+deep-extend@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
+ integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
+
deep-is@~0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
@@ -2887,14 +2813,6 @@ depd@2.0.0:
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
-des.js@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843"
- integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==
- dependencies:
- inherits "^2.0.1"
- minimalistic-assert "^1.0.0"
-
destroy@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
@@ -2905,6 +2823,11 @@ detect-indent@^6.0.0:
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6"
integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==
+detect-libc@^2.0.0, detect-libc@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd"
+ integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==
+
detect-port@^1.3.0:
version "1.5.1"
resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.5.1.tgz#451ca9b6eaf20451acb0799b8ab40dff7718727b"
@@ -2928,15 +2851,6 @@ diff@^4.0.1:
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
-diffie-hellman@^5.0.0:
- version "5.0.3"
- resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
- integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==
- dependencies:
- bn.js "^4.1.0"
- miller-rabin "^4.0.0"
- randombytes "^2.0.0"
-
difflib@^0.2.4:
version "0.2.4"
resolved "https://registry.yarnpkg.com/difflib/-/difflib-0.2.4.tgz#b5e30361a6db023176d562892db85940a718f47e"
@@ -2999,7 +2913,7 @@ ee-first@1.1.1:
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
-elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4:
+elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.4:
version "6.5.4"
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==
@@ -3012,11 +2926,6 @@ elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5
minimalistic-assert "^1.0.1"
minimalistic-crypto-utils "^1.0.1"
-emoji-regex@^10.2.1:
- version "10.2.1"
- resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.2.1.tgz#a41c330d957191efd3d9dfe6e1e8e1e9ab048b3f"
- integrity sha512-97g6QgOk8zlDRdgq1WxwgTMgEWGVAQvB5Fdpgc1MkNy56la5SKP9GsMXKDOdqwn90/41a8yPwIGk1Y6WVbeMQA==
-
emoji-regex@^7.0.1:
version "7.0.3"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
@@ -3037,7 +2946,7 @@ encodeurl@~1.0.2:
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
-end-of-stream@^1.1.0:
+end-of-stream@^1.1.0, end-of-stream@^1.4.1:
version "1.4.4"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
@@ -3064,26 +2973,32 @@ error-ex@^1.3.1:
is-arrayish "^0.2.1"
es-abstract@^1.19.0, es-abstract@^1.20.4:
- version "1.20.5"
- resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.5.tgz#e6dc99177be37cacda5988e692c3fa8b218e95d2"
- integrity sha512-7h8MM2EQhsCA7pU/Nv78qOXFpD8Rhqd12gYiSJVkrH9+e8VuA8JlPJK/hQjjlLv6pJvx/z1iRFKzYb0XT/RuAQ==
+ version "1.21.1"
+ resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.1.tgz#e6105a099967c08377830a0c9cb589d570dd86c6"
+ integrity sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==
dependencies:
+ available-typed-arrays "^1.0.5"
call-bind "^1.0.2"
+ es-set-tostringtag "^2.0.1"
es-to-primitive "^1.2.1"
function-bind "^1.1.1"
function.prototype.name "^1.1.5"
get-intrinsic "^1.1.3"
get-symbol-description "^1.0.0"
+ globalthis "^1.0.3"
gopd "^1.0.1"
has "^1.0.3"
has-property-descriptors "^1.0.0"
+ has-proto "^1.0.1"
has-symbols "^1.0.3"
- internal-slot "^1.0.3"
+ internal-slot "^1.0.4"
+ is-array-buffer "^3.0.1"
is-callable "^1.2.7"
is-negative-zero "^2.0.2"
is-regex "^1.1.4"
is-shared-array-buffer "^1.0.2"
is-string "^1.0.7"
+ is-typed-array "^1.1.10"
is-weakref "^1.0.2"
object-inspect "^1.12.2"
object-keys "^1.1.1"
@@ -3092,13 +3007,24 @@ es-abstract@^1.19.0, es-abstract@^1.20.4:
safe-regex-test "^1.0.0"
string.prototype.trimend "^1.0.6"
string.prototype.trimstart "^1.0.6"
+ typed-array-length "^1.0.4"
unbox-primitive "^1.0.2"
+ which-typed-array "^1.1.9"
es-array-method-boxes-properly@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e"
integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==
+es-set-tostringtag@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8"
+ integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==
+ dependencies:
+ get-intrinsic "^1.1.3"
+ has "^1.0.3"
+ has-tostringtag "^1.0.0"
+
es-to-primitive@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
@@ -3154,7 +3080,7 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
-escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0:
+escape-string-regexp@4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
@@ -3305,7 +3231,7 @@ ethereumjs-util@^6.0.0, ethereumjs-util@^6.2.1:
ethjs-util "0.1.6"
rlp "^2.2.3"
-ethereumjs-util@^7.0.10, ethereumjs-util@^7.0.3, ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.2, ethereumjs-util@^7.1.4, ethereumjs-util@^7.1.5:
+ethereumjs-util@^7.0.3, ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.2, ethereumjs-util@^7.1.4, ethereumjs-util@^7.1.5:
version "7.1.5"
resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz#9ecf04861e4fbbeed7465ece5f23317ad1129181"
integrity sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==
@@ -3393,7 +3319,7 @@ eventemitter3@4.0.4:
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384"
integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==
-evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
+evp_bytestokey@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02"
integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==
@@ -3416,6 +3342,11 @@ execa@^6.1.0:
signal-exit "^3.0.7"
strip-final-newline "^3.0.0"
+expand-template@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c"
+ integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==
+
express@^4.14.0:
version "4.18.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
@@ -3521,9 +3452,9 @@ fast-levenshtein@~2.0.6:
integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
fastq@^1.6.0:
- version "1.14.0"
- resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.14.0.tgz#107f69d7295b11e0fccc264e1fc6389f623731ce"
- integrity sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==
+ version "1.15.0"
+ resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a"
+ integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==
dependencies:
reusify "^1.0.4"
@@ -3610,11 +3541,6 @@ form-data-encoder@1.7.1:
resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.1.tgz#ac80660e4f87ee0d3d3c3638b7da8278ddb8ec96"
integrity sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==
-form-data-encoder@^1.7.1:
- version "1.7.2"
- resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.2.tgz#1f1ae3dccf58ed4690b86d87e4f57c654fbab040"
- integrity sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==
-
form-data@^2.2.0:
version "2.5.1"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4"
@@ -3642,14 +3568,6 @@ form-data@~2.3.2:
combined-stream "^1.0.6"
mime-types "^2.1.12"
-formdata-node@^4.3.1:
- version "4.4.1"
- resolved "https://registry.yarnpkg.com/formdata-node/-/formdata-node-4.4.1.tgz#23f6a5cb9cb55315912cbec4ff7b0f59bbd191e2"
- integrity sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==
- dependencies:
- node-domexception "1.0.0"
- web-streams-polyfill "4.0.0-beta.3"
-
forwarded@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
@@ -3670,6 +3588,11 @@ fresh@0.5.2:
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
+fs-constants@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
+ integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
+
fs-extra@^0.30.0:
version "0.30.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0"
@@ -3771,14 +3694,31 @@ get-func-name@^2.0.0:
integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==
get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385"
- integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f"
+ integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==
dependencies:
function-bind "^1.1.1"
has "^1.0.3"
has-symbols "^1.0.3"
+get-pixels@^3.3.2:
+ version "3.3.3"
+ resolved "https://registry.yarnpkg.com/get-pixels/-/get-pixels-3.3.3.tgz#71e2dfd4befb810b5478a61c6354800976ce01c7"
+ integrity sha512-5kyGBn90i9tSMUVHTqkgCHsoWoR+/lGbl4yC83Gefyr0HLIhgSWEx/2F/3YgsZ7UpYNuM6pDhDK7zebrUJ5nXg==
+ dependencies:
+ data-uri-to-buffer "0.0.3"
+ jpeg-js "^0.4.1"
+ mime-types "^2.0.1"
+ ndarray "^1.0.13"
+ ndarray-pack "^1.1.1"
+ node-bitmap "0.0.1"
+ omggif "^1.0.5"
+ parse-data-uri "^0.2.0"
+ pngjs "^3.3.3"
+ request "^2.44.0"
+ through "^2.3.4"
+
get-port@^3.1.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc"
@@ -3819,6 +3759,11 @@ ghost-testrpc@^0.0.2:
chalk "^2.4.2"
node-emoji "^1.10.0"
+github-from-package@0.0.0:
+ version "0.0.0"
+ resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce"
+ integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==
+
glob-parent@^5.1.2, glob-parent@~5.1.0, glob-parent@~5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
@@ -3902,6 +3847,13 @@ globals@^11.1.0:
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
+globalthis@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf"
+ integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==
+ dependencies:
+ define-properties "^1.1.3"
+
globby@^10.0.1:
version "10.0.2"
resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543"
@@ -3976,7 +3928,7 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0,
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
-graphql-config@4.4.0:
+graphql-config@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-4.4.0.tgz#4b2d34d846bd4b9a40afbadfc5a4426668963c43"
integrity sha512-QUrX7R4htnTBTi83a0IlIilWVfiLEG8ANFlHRcxoZiTvOXTbgan67SUdGe1OlopbDuyNgtcy4ladl3Gvk4C36A==
@@ -4038,9 +3990,9 @@ har-validator@~5.1.3:
har-schema "^2.0.0"
hardhat-contract-sizer@^2.6.1:
- version "2.6.1"
- resolved "https://registry.yarnpkg.com/hardhat-contract-sizer/-/hardhat-contract-sizer-2.6.1.tgz#2b0046a55fa1ec96f19fdab7fde372377401c874"
- integrity sha512-b8wS7DBvyo22kmVwpzstAQTdDCThpl/ySBqZh5ga9Yxjf61/uTL12TEg5nl7lDeWy73ntEUzxMwY6XxbQEc2wA==
+ version "2.7.0"
+ resolved "https://registry.yarnpkg.com/hardhat-contract-sizer/-/hardhat-contract-sizer-2.7.0.tgz#d892a741135628a77d25709a29ae164f2750b7eb"
+ integrity sha512-QcncKiEku9TInKH++frfCPaYaVvw6OR5C5dNUcb05WozeVOJGspbWbHOkOlfiaZUbEKTvHA6OY9LtMMvja9nzQ==
dependencies:
chalk "^4.0.0"
cli-table3 "^0.6.0"
@@ -4055,9 +4007,9 @@ hardhat-gas-reporter@^1.0.9:
sha1 "^1.1.1"
hardhat@^2.11.2:
- version "2.12.4"
- resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.12.4.tgz#e539ba58bee9ba1a1ced823bfdcec0b3c5a3e70f"
- integrity sha512-rc9S2U/4M+77LxW1Kg7oqMMmjl81tzn5rNFARhbXKUA1am/nhfMJEujOjuKvt+ZGMiZ11PYSe8gyIpB/aRNDgw==
+ version "2.12.6"
+ resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.12.6.tgz#ea3c058bbd81850867389d10f76037cfa52a0019"
+ integrity sha512-0Ent1O5DsPgvaVb5sxEgsQ3bJRt/Ex92tsoO+xjoNH2Qc4bFmhI5/CHVlFikulalxOPjNmw5XQ2vJFuVQFESAA==
dependencies:
"@ethersproject/abi" "^5.1.2"
"@metamask/eth-sig-util" "^4.0.0"
@@ -4106,7 +4058,7 @@ hardhat@^2.11.2:
source-map-support "^0.5.13"
stacktrace-parser "^0.1.10"
tsort "0.0.1"
- undici "^5.4.0"
+ undici "^5.14.0"
uuid "^8.3.2"
ws "^7.4.6"
@@ -4137,6 +4089,11 @@ has-property-descriptors@^1.0.0:
dependencies:
get-intrinsic "^1.1.1"
+has-proto@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0"
+ integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==
+
has-symbols@^1.0.0, has-symbols@^1.0.2, has-symbols@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
@@ -4219,9 +4176,9 @@ http-basic@^8.1.1:
parse-cache-control "^1.0.1"
http-cache-semantics@^4.0.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
- integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a"
+ integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==
http-errors@2.0.0:
version "2.0.0"
@@ -4294,9 +4251,9 @@ human-signals@^3.0.1:
integrity sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==
husky@^8.0.2:
- version "8.0.2"
- resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.2.tgz#5816a60db02650f1f22c8b69b928fd6bcd77a236"
- integrity sha512-Tkv80jtvbnkK3mYWxPZePGFpQ/tT3HNSs/sasF9P2YfkMezDl3ON37YN6jUUI4eTg5LcyVynlb6r4eyvOmspvg==
+ version "8.0.3"
+ resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.3.tgz#4936d7212e46d1dea28fef29bb3a108872cd9184"
+ integrity sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==
iconv-lite@0.4.24, iconv-lite@^0.4.24:
version "0.4.24"
@@ -4323,9 +4280,9 @@ ignore@^5.1.1, ignore@^5.2.0:
integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==
immutable@^4.0.0-rc.12:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.1.0.tgz#f795787f0db780183307b9eb2091fcac1f6fafef"
- integrity sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==
+ version "4.2.2"
+ resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.2.2.tgz#2da9ff4384a4330c36d4d1bc88e90f9e0b0ccd16"
+ integrity sha512-fTMKDwtbvO5tldky9QZ2fMX7slR0mYpY5nbnFWYp0fOzDhHqhgIw9KoYgxLWsoNTS9ZHGauHj18DTyEw6BK3Og==
import-fresh@^3.2.1:
version "3.3.0"
@@ -4358,7 +4315,7 @@ inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, i
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
-ini@^1.3.5:
+ini@^1.3.5, ini@~1.3.0:
version "1.3.8"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
@@ -4384,7 +4341,7 @@ inquirer@^8.0.0:
through "^2.3.6"
wrap-ansi "^7.0.0"
-internal-slot@^1.0.3:
+internal-slot@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.4.tgz#8551e7baf74a7a6ba5f749cfb16aa60722f0d6f3"
integrity sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==
@@ -4405,6 +4362,11 @@ io-ts@1.10.4:
dependencies:
fp-ts "^1.0.0"
+iota-array@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/iota-array/-/iota-array-1.0.0.tgz#81ef57fe5d05814cd58c2483632a99c30a0e8087"
+ integrity sha512-pZ2xT+LOHckCatGQ3DcG/a+QuEqvoxqkiL7tvE8nn3uuu+f6i1TtpB5/FtWFbxUuVr5PZCx8KskuGatbJDXOWA==
+
ipaddr.js@1.9.1:
version "1.9.1"
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
@@ -4418,11 +4380,25 @@ is-arguments@^1.0.4:
call-bind "^1.0.2"
has-tostringtag "^1.0.0"
+is-array-buffer@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.1.tgz#deb1db4fcae48308d54ef2442706c0393997052a"
+ integrity sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==
+ dependencies:
+ call-bind "^1.0.2"
+ get-intrinsic "^1.1.3"
+ is-typed-array "^1.1.10"
+
is-arrayish@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==
+is-arrayish@^0.3.1:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
+ integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
+
is-bigint@^1.0.1:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3"
@@ -4445,6 +4421,11 @@ is-boolean-object@^1.1.0:
call-bind "^1.0.2"
has-tostringtag "^1.0.0"
+is-buffer@^1.0.2:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
+ integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
+
is-buffer@^2.0.5, is-buffer@~2.0.3:
version "2.0.5"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191"
@@ -4581,7 +4562,7 @@ is-symbol@^1.0.2, is-symbol@^1.0.3:
dependencies:
has-symbols "^1.0.2"
-is-typed-array@^1.1.10, is-typed-array@^1.1.3:
+is-typed-array@^1.1.10, is-typed-array@^1.1.3, is-typed-array@^1.1.9:
version "1.1.10"
resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f"
integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==
@@ -4644,6 +4625,11 @@ isstream@~0.1.2:
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==
+jpeg-js@^0.4.1:
+ version "0.4.4"
+ resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.4.tgz#a9f1c6f1f9f0fa80cdb3484ed9635054d28936aa"
+ integrity sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==
+
js-sha3@0.5.7, js-sha3@^0.5.7:
version "0.5.7"
resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7"
@@ -4799,9 +4785,9 @@ jws@^3.2.2:
safe-buffer "^5.0.1"
keccak@^3.0.0, keccak@^3.0.2:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.2.tgz#4c2c6e8c54e04f2670ee49fa734eb9da152206e0"
- integrity sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.3.tgz#4bc35ad917be1ef54ff246f904c2bbbf9ac61276"
+ integrity sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ==
dependencies:
node-addon-api "^2.0.0"
node-gyp-build "^4.2.0"
@@ -4899,16 +4885,16 @@ listr2@^4.0.5:
wrap-ansi "^7.0.0"
listr2@^5.0.5:
- version "5.0.6"
- resolved "https://registry.yarnpkg.com/listr2/-/listr2-5.0.6.tgz#3c61153383869ffaad08a8908d63edfde481dff8"
- integrity sha512-u60KxKBy1BR2uLJNTWNptzWQ1ob/gjMzIJPZffAENzpZqbMZ/5PrXXOomDcevIS/+IB7s1mmCEtSlT2qHWMqag==
+ version "5.0.7"
+ resolved "https://registry.yarnpkg.com/listr2/-/listr2-5.0.7.tgz#de69ccc4caf6bea7da03c74f7a2ffecf3904bd53"
+ integrity sha512-MD+qXHPmtivrHIDRwPYdfNkrzqDiuaKU/rfBcec3WMyMF3xylQj3jMq344OtvQxz7zaCFViRAeqlr2AFhPvXHw==
dependencies:
cli-truncate "^2.1.0"
colorette "^2.0.19"
log-update "^4.0.0"
p-map "^4.0.0"
rfdc "^1.3.0"
- rxjs "^7.5.7"
+ rxjs "^7.8.0"
through "^2.3.8"
wrap-ansi "^7.0.0"
@@ -5096,20 +5082,12 @@ micromatch@^4.0.4, micromatch@^4.0.5:
braces "^3.0.2"
picomatch "^2.3.1"
-miller-rabin@^4.0.0:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
- integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==
- dependencies:
- bn.js "^4.0.0"
- brorand "^1.0.1"
-
mime-db@1.52.0:
version "1.52.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
-mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34:
+mime-types@^2.0.1, mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34:
version "2.1.35"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
@@ -5186,7 +5164,7 @@ minimatch@5.0.1:
dependencies:
brace-expansion "^2.0.1"
-minimist@^1.2.5, minimist@^1.2.6:
+minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6:
version "1.2.7"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18"
integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==
@@ -5206,6 +5184,11 @@ minizlib@^1.3.3:
dependencies:
minipass "^2.9.0"
+mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3:
+ version "0.5.3"
+ resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
+ integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
+
mkdirp-promise@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1"
@@ -5214,9 +5197,9 @@ mkdirp-promise@^5.0.1:
mkdirp "*"
mkdirp@*:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
- integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.3.tgz#b083ff37be046fd3d6552468c1f0ff44c1545d1f"
+ integrity sha512-sjAkg21peAG9HS+Dkx7hlG9Ztx7HLeKnvB3NQRcu/mltCVmvkF0pisbiTSfDVYTT86XEfZrTUosLdZLStquZUw==
mkdirp@0.5.5:
version "0.5.5"
@@ -5411,11 +5394,32 @@ nanoid@3.3.3:
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25"
integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==
+napi-build-utils@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806"
+ integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==
+
napi-macros@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b"
integrity sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==
+ndarray-pack@^1.1.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/ndarray-pack/-/ndarray-pack-1.2.1.tgz#8caebeaaa24d5ecf70ff86020637977da8ee585a"
+ integrity sha512-51cECUJMT0rUZNQa09EoKsnFeDL4x2dHRT0VR5U2H5ZgEcm95ZDWcMA5JShroXjHOejmAD/fg8+H+OvUnVXz2g==
+ dependencies:
+ cwise-compiler "^1.1.2"
+ ndarray "^1.0.13"
+
+ndarray@^1.0.13:
+ version "1.0.19"
+ resolved "https://registry.yarnpkg.com/ndarray/-/ndarray-1.0.19.tgz#6785b5f5dfa58b83e31ae5b2a058cfd1ab3f694e"
+ integrity sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ==
+ dependencies:
+ iota-array "^1.0.0"
+ is-buffer "^1.0.2"
+
negotiator@0.6.3:
version "0.6.3"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
@@ -5439,15 +5443,27 @@ no-case@^3.0.4:
lower-case "^2.0.2"
tslib "^2.0.3"
+node-abi@^3.3.0:
+ version "3.31.0"
+ resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.31.0.tgz#dfb2ea3d01188eb80859f69bb4a4354090c1b355"
+ integrity sha512-eSKV6s+APenqVh8ubJyiu/YhZgxQpGP66ntzUb3lY1xB9ukSRaGnx0AIxI+IM+1+IVYC1oWobgG5L3Lt9ARykQ==
+ dependencies:
+ semver "^7.3.5"
+
node-addon-api@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32"
integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==
-node-domexception@1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5"
- integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==
+node-addon-api@^5.0.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.1.0.tgz#49da1ca055e109a23d537e9de43c09cca21eb762"
+ integrity sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==
+
+node-bitmap@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/node-bitmap/-/node-bitmap-0.0.1.tgz#180eac7003e0c707618ef31368f62f84b2a69091"
+ integrity sha512-Jx5lPaaLdIaOsj2mVLWMWulXF6GQVdyLvNSxmiYCvZ8Ma2hfKX0POoR2kgKOqz+oFsRreq0yYZjQ2wjE9VNzCA==
node-emoji@^1.10.0:
version "1.11.0"
@@ -5464,17 +5480,24 @@ node-environment-flags@1.0.6:
object.getownpropertydescriptors "^2.0.3"
semver "^5.7.0"
-node-fetch@2.6.7, node-fetch@^2.6.1, node-fetch@^2.6.7:
+node-fetch@2.6.7:
version "2.6.7"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
dependencies:
whatwg-url "^5.0.0"
+node-fetch@^2.6.1:
+ version "2.6.9"
+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6"
+ integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==
+ dependencies:
+ whatwg-url "^5.0.0"
+
node-gyp-build@^4.2.0, node-gyp-build@^4.3.0:
- version "4.5.0"
- resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.5.0.tgz#7a64eefa0b21112f89f58379da128ac177f20e40"
- integrity sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055"
+ integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==
nofilter@^3.1.0:
version "3.1.0"
@@ -5531,9 +5554,9 @@ object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1:
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
object-inspect@^1.12.2, object-inspect@^1.9.0:
- version "1.12.2"
- resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea"
- integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==
+ version "1.12.3"
+ resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9"
+ integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==
object-keys@^1.0.11, object-keys@^1.1.1:
version "1.1.1"
@@ -5582,6 +5605,11 @@ oboe@2.1.5:
dependencies:
http-https "^1.0.0"
+omggif@^1.0.5:
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19"
+ integrity sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==
+
on-finished@2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
@@ -5731,22 +5759,18 @@ parent-module@^1.0.0:
dependencies:
callsites "^3.0.0"
-parse-asn1@^5.0.0, parse-asn1@^5.1.5:
- version "5.1.6"
- resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4"
- integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==
- dependencies:
- asn1.js "^5.2.0"
- browserify-aes "^1.0.0"
- evp_bytestokey "^1.0.0"
- pbkdf2 "^3.0.3"
- safe-buffer "^5.1.1"
-
parse-cache-control@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/parse-cache-control/-/parse-cache-control-1.0.1.tgz#8eeab3e54fa56920fe16ba38f77fa21aacc2d74e"
integrity sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==
+parse-data-uri@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/parse-data-uri/-/parse-data-uri-0.2.0.tgz#bf04d851dd5c87b0ab238e5d01ace494b604b4c9"
+ integrity sha512-uOtts8NqDcaCt1rIsO3VFDRsAfgE4c6osG4d9z3l4dCBlxYFzni6Di/oNU270SDrjkfZuUvLZx1rxMyqh46Y9w==
+ dependencies:
+ data-uri-to-buffer "0.0.3"
+
parse-headers@^2.0.0:
version "2.0.5"
resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.5.tgz#069793f9356a54008571eb7f9761153e6c770da9"
@@ -5828,7 +5852,7 @@ pathval@^1.1.1:
resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d"
integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==
-pbkdf2@^3.0.17, pbkdf2@^3.0.3:
+pbkdf2@^3.0.17:
version "3.1.2"
resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075"
integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==
@@ -5864,27 +5888,47 @@ pinst@^3.0.0:
resolved "https://registry.yarnpkg.com/pinst/-/pinst-3.0.0.tgz#80dec0a85f1f993c6084172020f3dbf512897eec"
integrity sha512-cengSmBxtCyaJqtRSvJorIIZXMXg+lJ3sIljGmtBGUVonMnMsVJbnzl6jGN1HkOWwxNuJynCJ2hXxxqCQrFDdw==
+pngjs@^3.3.3:
+ version "3.4.0"
+ resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
+ integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
+
+prebuild-install@^7.1.1:
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45"
+ integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==
+ dependencies:
+ detect-libc "^2.0.0"
+ expand-template "^2.0.3"
+ github-from-package "0.0.0"
+ minimist "^1.2.3"
+ mkdirp-classic "^0.5.3"
+ napi-build-utils "^1.0.1"
+ node-abi "^3.3.0"
+ pump "^3.0.0"
+ rc "^1.2.7"
+ simple-get "^4.0.0"
+ tar-fs "^2.0.0"
+ tunnel-agent "^0.6.0"
+
prelude-ls@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==
prettier-plugin-solidity@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.0.tgz#a417d104b48a43af3adbfb96b65dbce34fd21429"
- integrity sha512-5gq0T49ifvXH/6x1STuKyWjTUgi6ICoV65yNtKlg/vZEvocFtSpByJOJICBfqPwNsnv4vhhWIqkLGSUJmWum2w==
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.1.tgz#4d3375b85f97812ffcbe48d5a8b3fe914d69c91f"
+ integrity sha512-uD24KO26tAHF+zMN2nt1OUzfknzza5AgxjogQQrMLZc7j8xiQrDoNWNeOlfFC0YLTwo12CLD10b9niLyP6AqXg==
dependencies:
"@solidity-parser/parser" "^0.14.5"
- emoji-regex "^10.2.1"
- escape-string-regexp "^4.0.0"
semver "^7.3.8"
solidity-comments-extractor "^0.0.7"
- string-width "^4.2.3"
prettier@^2.7.1:
- version "2.8.1"
- resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.1.tgz#4e1fd11c34e2421bc1da9aea9bd8127cd0a35efc"
- integrity sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==
+ version "2.8.3"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.3.tgz#ab697b1d3dd46fb4626fbe2f543afe0cc98d8632"
+ integrity sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==
process-nextick-args@~2.0.0:
version "2.0.1"
@@ -5925,18 +5969,6 @@ psl@^1.1.28:
resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"
integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==
-public-encrypt@^4.0.0:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0"
- integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==
- dependencies:
- bn.js "^4.1.0"
- browserify-rsa "^4.0.0"
- create-hash "^1.1.0"
- parse-asn1 "^5.0.0"
- randombytes "^2.0.1"
- safe-buffer "^5.1.2"
-
pump@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
@@ -5951,9 +5983,9 @@ punycode@2.1.0:
integrity sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==
punycode@^2.1.0, punycode@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
- integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f"
+ integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==
pvtsutils@^1.3.2:
version "1.3.2"
@@ -5979,6 +6011,10 @@ qs@~6.5.2:
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==
+"quantize@github:lokesh/quantize":
+ version "1.2.0"
+ resolved "https://codeload.github.com/lokesh/quantize/tar.gz/f572abd2646b5944852535c8a26fdb958a5d7c4b"
+
query-string@^5.0.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb"
@@ -5998,21 +6034,13 @@ quick-lru@^5.1.1:
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
-randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0:
+randombytes@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
dependencies:
safe-buffer "^5.1.0"
-randomfill@^1.0.3:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458"
- integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==
- dependencies:
- randombytes "^2.0.5"
- safe-buffer "^5.1.0"
-
range-parser@~1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
@@ -6028,6 +6056,16 @@ raw-body@2.5.1, raw-body@^2.4.1:
iconv-lite "0.4.24"
unpipe "1.0.0"
+rc@^1.2.7:
+ version "1.2.8"
+ resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
+ integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
+ dependencies:
+ deep-extend "^0.6.0"
+ ini "~1.3.0"
+ minimist "^1.2.0"
+ strip-json-comments "~2.0.1"
+
readable-stream@^2.2.2:
version "2.3.7"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
@@ -6041,7 +6079,7 @@ readable-stream@^2.2.2:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
-readable-stream@^3.4.0, readable-stream@^3.6.0:
+readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
@@ -6132,7 +6170,7 @@ request-promise-native@^1.0.5:
stealthy-require "^1.1.1"
tough-cookie "^2.3.3"
-request@^2.79.0, request@^2.88.0:
+request@^2.44.0, request@^2.79.0, request@^2.88.0:
version "2.88.2"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
@@ -6290,7 +6328,7 @@ rustbn.js@~0.2.0:
resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca"
integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==
-rxjs@^7.5.5, rxjs@^7.5.7:
+rxjs@^7.5.5, rxjs@^7.8.0:
version "7.8.0"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4"
integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==
@@ -6375,7 +6413,7 @@ semver@^6.3.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
-semver@^7.3.4, semver@^7.3.8:
+semver@^7.3.4, semver@^7.3.5, semver@^7.3.8:
version "7.3.8"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798"
integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==
@@ -6474,6 +6512,20 @@ sha1@^1.1.1:
charenc ">= 0.0.1"
crypt ">= 0.0.1"
+sharp@^0.31.3:
+ version "0.31.3"
+ resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.31.3.tgz#60227edc5c2be90e7378a210466c99aefcf32688"
+ integrity sha512-XcR4+FCLBFKw1bdB+GEhnUNXNXvnt0tDo4WsBsraKymuo/IAuPuCBVAL2wIkUw2r/dwFW5Q5+g66Kwl2dgDFVg==
+ dependencies:
+ color "^4.2.3"
+ detect-libc "^2.0.1"
+ node-addon-api "^5.0.0"
+ prebuild-install "^7.1.1"
+ semver "^7.3.8"
+ simple-get "^4.0.1"
+ tar-fs "^2.1.1"
+ tunnel-agent "^0.6.0"
+
shebang-command@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
@@ -6487,9 +6539,9 @@ shebang-regex@^3.0.0:
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
shell-quote@^1.7.3:
- version "1.7.4"
- resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.4.tgz#33fe15dee71ab2a81fcbd3a52106c5cfb9fb75d8"
- integrity sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==
+ version "1.8.0"
+ resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.0.tgz#20d078d0eaf71d54f43bd2ba14a1b5b9bfa5c8ba"
+ integrity sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ==
shelljs@^0.8.3:
version "0.8.5"
@@ -6528,6 +6580,22 @@ simple-get@^2.7.0:
once "^1.3.1"
simple-concat "^1.0.0"
+simple-get@^4.0.0, simple-get@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543"
+ integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==
+ dependencies:
+ decompress-response "^6.0.0"
+ once "^1.3.1"
+ simple-concat "^1.0.0"
+
+simple-swizzle@^0.2.2:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
+ integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==
+ dependencies:
+ is-arrayish "^0.3.1"
+
slash@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
@@ -6583,9 +6651,9 @@ solc@0.7.3:
tmp "0.0.33"
solidity-ast@^0.4.15:
- version "0.4.40"
- resolved "https://registry.yarnpkg.com/solidity-ast/-/solidity-ast-0.4.40.tgz#182709271b4e55efb34e2da934dfaa96ee0cf40b"
- integrity sha512-M8uLBT2jgFB7B0iVAC5a2l71J8vim7aEm03AZkaHbDqyrl1pE+i5PriMEw6WlwGfHp3/Ym7cn9BqvVLQgRk+Yw==
+ version "0.4.44"
+ resolved "https://registry.yarnpkg.com/solidity-ast/-/solidity-ast-0.4.44.tgz#dd6732bd65bb1d01777fc537de99cbb3d4e0089d"
+ integrity sha512-Ct3ppqWS0uTWNYxM2cgruUeWYzqYmeikANsCHgGBnMjAMsqONgqnYrlpifQxNFwXOPHD3vZQLmCjaYnQ+i3eQA==
solidity-comments-extractor@^0.0.7:
version "0.0.7"
@@ -6809,7 +6877,7 @@ strip-hex-prefix@1.0.0:
dependencies:
is-hex-prefixed "1.0.0"
-strip-json-comments@2.0.1:
+strip-json-comments@2.0.1, strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==
@@ -6910,6 +6978,27 @@ table@^6.8.0:
string-width "^4.2.3"
strip-ansi "^6.0.1"
+tar-fs@^2.0.0, tar-fs@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784"
+ integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==
+ dependencies:
+ chownr "^1.1.1"
+ mkdirp-classic "^0.5.2"
+ pump "^3.0.0"
+ tar-stream "^2.1.4"
+
+tar-stream@^2.1.4:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
+ integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==
+ dependencies:
+ bl "^4.0.3"
+ end-of-stream "^1.4.1"
+ fs-constants "^1.0.0"
+ inherits "^2.0.3"
+ readable-stream "^3.1.1"
+
tar@^4.0.2:
version "4.4.19"
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3"
@@ -6940,7 +7029,7 @@ then-request@^6.0.0:
promise "^8.0.0"
qs "^6.4.0"
-through@^2.3.6, through@^2.3.8:
+through@^2.3.4, through@^2.3.6, through@^2.3.8:
version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
@@ -7023,7 +7112,12 @@ tslib@^1.9.3:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
-tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.4.1, tslib@~2.4.0:
+tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.1, tslib@^2.4.0, tslib@^2.4.1, tslib@~2.5.0:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf"
+ integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==
+
+tslib@~2.4.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e"
integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==
@@ -7095,6 +7189,15 @@ type@^2.7.2:
resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0"
integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==
+typed-array-length@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb"
+ integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==
+ dependencies:
+ call-bind "^1.0.2"
+ for-each "^0.3.3"
+ is-typed-array "^1.1.9"
+
typedarray-to-buffer@^3.1.5:
version "3.1.5"
resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
@@ -7108,9 +7211,9 @@ typedarray@^0.0.6:
integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==
typescript@^4.9.3:
- version "4.9.4"
- resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.4.tgz#a2a3d2756c079abda241d75f149df9d561091e78"
- integrity sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==
+ version "4.9.5"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
+ integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
uglify-js@^3.1.4:
version "3.17.4"
@@ -7132,19 +7235,17 @@ unbox-primitive@^1.0.2:
has-symbols "^1.0.3"
which-boxed-primitive "^1.0.2"
-undici@^5.12.0:
- version "5.15.0"
- resolved "https://registry.yarnpkg.com/undici/-/undici-5.15.0.tgz#cb8437c43718673a8be59df0fdd4856ff6689283"
- integrity sha512-wCAZJDyjw9Myv+Ay62LAoB+hZLPW9SmKbQkbHIhMw/acKSlpn7WohdMUc/Vd4j1iSMBO0hWwU8mjB7a5p5bl8g==
+undici@^5.14.0:
+ version "5.16.0"
+ resolved "https://registry.yarnpkg.com/undici/-/undici-5.16.0.tgz#6b64f9b890de85489ac6332bd45ca67e4f7d9943"
+ integrity sha512-KWBOXNv6VX+oJQhchXieUznEmnJMqgXMbs0xxH2t8q/FUAWSJvOSr/rMaZKnX5RIVq7JDn0JbP4BOnKG2SGXLQ==
dependencies:
busboy "^1.6.0"
-undici@^5.4.0:
- version "5.14.0"
- resolved "https://registry.yarnpkg.com/undici/-/undici-5.14.0.tgz#1169d0cdee06a4ffdd30810f6228d57998884d00"
- integrity sha512-yJlHYw6yXPPsuOH0x2Ib1Km61vu4hLiRRQoafs+WUgX1vO64vgnxiCEN9dpIrhZyHFsai3F0AEj4P9zy19enEQ==
- dependencies:
- busboy "^1.6.0"
+uniq@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"
+ integrity sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==
universalify@^0.1.0:
version "0.1.2"
@@ -7213,7 +7314,7 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1:
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
-util@^0.12.0:
+util@^0.12.5:
version "0.12.5"
resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc"
integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==
@@ -7254,12 +7355,7 @@ v8-compile-cache-lib@^3.0.1:
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
-value-or-promise@1.0.11:
- version "1.0.11"
- resolved "https://registry.yarnpkg.com/value-or-promise/-/value-or-promise-1.0.11.tgz#3e90299af31dd014fe843fe309cefa7c1d94b140"
- integrity sha512-41BrgH+dIbCFXClcSapVs5M6GkENd3gQOJpEfPDNa71LsUGMXDL0jMWpI/Rh7WhX+Aalfz2TTS3Zt5pUsbnhLg==
-
-value-or-promise@^1.0.11:
+value-or-promise@1.0.12, value-or-promise@^1.0.11:
version "1.0.12"
resolved "https://registry.yarnpkg.com/value-or-promise/-/value-or-promise-1.0.12.tgz#0e5abfeec70148c78460a849f6b003ea7986f15c"
integrity sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q==
@@ -7290,224 +7386,218 @@ wcwidth@^1.0.1:
dependencies:
defaults "^1.0.3"
-web-streams-polyfill@4.0.0-beta.3:
- version "4.0.0-beta.3"
- resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz#2898486b74f5156095e473efe989dcf185047a38"
- integrity sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==
-
-web-streams-polyfill@^3.2.0:
+web-streams-polyfill@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6"
integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==
-web3-bzz@1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.8.1.tgz#81397be5ce262d03d82b92e9d8acc11f8a609ea1"
- integrity sha512-dJJHS84nvpoxv6ijTMkdUSlRr5beCXNtx4UZcrFLHBva8dT63QEtKdLyDt2AyMJJdVzTCk78uir/6XtVWrdS6w==
+web3-bzz@1.8.2:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.8.2.tgz#67ea1c775874056250eece551ded22905ed08784"
+ integrity sha512-1EEnxjPnFnvNWw3XeeKuTR8PBxYd0+XWzvaLK7OJC/Go9O8llLGxrxICbKV+8cgIE0sDRBxiYx02X+6OhoAQ9w==
dependencies:
"@types/node" "^12.12.6"
got "12.1.0"
swarm-js "^0.1.40"
-web3-core-helpers@1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.8.1.tgz#7904747b23fd0afa4f2c86ed98ea9418ccad7672"
- integrity sha512-ClzNO6T1S1gifC+BThw0+GTfcsjLEY8T1qUp6Ly2+w4PntAdNtKahxWKApWJ0l9idqot/fFIDXwO3Euu7I0Xqw==
+web3-core-helpers@1.8.2:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.8.2.tgz#82066560f8085e6c7b93bcc8e88b441289ea9f9f"
+ integrity sha512-6B1eLlq9JFrfealZBomd1fmlq1o4A09vrCVQSa51ANoib/jllT3atZrRDr0zt1rfI7TSZTZBXdN/aTdeN99DWw==
dependencies:
- web3-eth-iban "1.8.1"
- web3-utils "1.8.1"
+ web3-eth-iban "1.8.2"
+ web3-utils "1.8.2"
-web3-core-method@1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.8.1.tgz#0fc5a433a9fc784c447522f141c0a8e0163c7790"
- integrity sha512-oYGRodktfs86NrnFwaWTbv2S38JnpPslFwSSARwFv4W9cjbGUW3LDeA5MKD/dRY+ssZ5OaekeMsUCLoGhX68yA==
+web3-core-method@1.8.2:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.8.2.tgz#ba5ec68084e903f0516415010477618be017eac2"
+ integrity sha512-1qnr5mw5wVyULzLOrk4B+ryO3gfGjGd/fx8NR+J2xCGLf1e6OSjxT9vbfuQ3fErk/NjSTWWreieYWLMhaogcRA==
dependencies:
"@ethersproject/transactions" "^5.6.2"
- web3-core-helpers "1.8.1"
- web3-core-promievent "1.8.1"
- web3-core-subscriptions "1.8.1"
- web3-utils "1.8.1"
+ web3-core-helpers "1.8.2"
+ web3-core-promievent "1.8.2"
+ web3-core-subscriptions "1.8.2"
+ web3-utils "1.8.2"
-web3-core-promievent@1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.8.1.tgz#f334c8b2ceac6c2228f06d2a515f6d103157f036"
- integrity sha512-9mxqHlgB0MrZI4oUIRFkuoJMNj3E7btjrMv3sMer/Z9rYR1PfoSc1aAokw4rxKIcAh+ylVtd/acaB2HKB7aRPg==
+web3-core-promievent@1.8.2:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.8.2.tgz#e670d6b4453632e6ecfd9ad82da44f77ac1585c9"
+ integrity sha512-nvkJWDVgoOSsolJldN33tKW6bKKRJX3MCPDYMwP5SUFOA/mCzDEoI88N0JFofDTXkh1k7gOqp1pvwi9heuaxGg==
dependencies:
eventemitter3 "4.0.4"
-web3-core-requestmanager@1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.8.1.tgz#272ffa55b7b568ecbc8e4a257ca080355c31c60e"
- integrity sha512-x+VC2YPPwZ1khvqA6TA69LvfFCOZXsoUVOxmTx/vIN22PrY9KzKhxcE7pBSiGhmab1jtmRYXUbcQSVpAXqL8cw==
+web3-core-requestmanager@1.8.2:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.8.2.tgz#dda95e83ca4808949612a41e54ecea557f78ef26"
+ integrity sha512-p1d090RYs5Mu7DK1yyc3GCBVZB/03rBtFhYFoS2EruGzOWs/5Q0grgtpwS/DScdRAm8wB8mYEBhY/RKJWF6B2g==
dependencies:
- util "^0.12.0"
- web3-core-helpers "1.8.1"
- web3-providers-http "1.8.1"
- web3-providers-ipc "1.8.1"
- web3-providers-ws "1.8.1"
+ util "^0.12.5"
+ web3-core-helpers "1.8.2"
+ web3-providers-http "1.8.2"
+ web3-providers-ipc "1.8.2"
+ web3-providers-ws "1.8.2"
-web3-core-subscriptions@1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.8.1.tgz#f5ae1380e92746eadfab6475b8a70ef5a1be6bbf"
- integrity sha512-bmCMq5OeA3E2vZUh8Js1HcJbhwtsE+yeMqGC4oIZB3XsL5SLqyKLB/pU+qUYqQ9o4GdcrFTDPhPg1bgvf7p1Pw==
+web3-core-subscriptions@1.8.2:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.8.2.tgz#0c8bd49439d83c6f0a03c70f00b24a915a70a5ed"
+ integrity sha512-vXQogHDmAIQcKpXvGiMddBUeP9lnKgYF64+yQJhPNE5PnWr1sAibXuIPV7mIPihpFr/n/DORRj6Wh1pUv9zaTw==
dependencies:
eventemitter3 "4.0.4"
- web3-core-helpers "1.8.1"
+ web3-core-helpers "1.8.2"
-web3-core@1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.8.1.tgz#050b1c408d1f9b7ae539e90f7f7d1b7a7d10578b"
- integrity sha512-LbRZlJH2N6nS3n3Eo9Y++25IvzMY7WvYnp4NM/Ajhh97dAdglYs6rToQ2DbL2RLvTYmTew4O/y9WmOk4nq9COw==
+web3-core@1.8.2:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.8.2.tgz#333e93d7872b1a36efe758ed8b89a7acbdd962c2"
+ integrity sha512-DJTVEAYcNqxkqruJE+Rxp3CIv0y5AZMwPHQmOkz/cz+MM75SIzMTc0AUdXzGyTS8xMF8h3YWMQGgGEy8SBf1PQ==
dependencies:
"@types/bn.js" "^5.1.0"
"@types/node" "^12.12.6"
bignumber.js "^9.0.0"
- web3-core-helpers "1.8.1"
- web3-core-method "1.8.1"
- web3-core-requestmanager "1.8.1"
- web3-utils "1.8.1"
+ web3-core-helpers "1.8.2"
+ web3-core-method "1.8.2"
+ web3-core-requestmanager "1.8.2"
+ web3-utils "1.8.2"
-web3-eth-abi@1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.8.1.tgz#47455d6513217c4b0866fea6f97b1c4afa0b6535"
- integrity sha512-0mZvCRTIG0UhDhJwNQJgJxu4b4DyIpuMA0GTfqxqeuqzX4Q/ZvmoNurw0ExTfXaGPP82UUmmdkRi6FdZOx+C6w==
+web3-eth-abi@1.8.2:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.8.2.tgz#16e1e9be40e2527404f041a4745111211488f31a"
+ integrity sha512-Om9g3kaRNjqiNPAgKwGT16y+ZwtBzRe4ZJFGjLiSs6v5I7TPNF+rRMWuKnR6jq0azQZDj6rblvKFMA49/k48Og==
dependencies:
"@ethersproject/abi" "^5.6.3"
- web3-utils "1.8.1"
+ web3-utils "1.8.2"
-web3-eth-accounts@1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.8.1.tgz#1ce7387721f118aeb0376291e4d8bbe2ac323406"
- integrity sha512-mgzxSYgN54/NsOFBO1Fq1KkXp1S5KlBvI/DlgvajU72rupoFMq6Cu6Yp9GUaZ/w2ij9PzEJuFJk174XwtfMCmg==
+web3-eth-accounts@1.8.2:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.8.2.tgz#b894f5d5158fcae429da42de75d96520d0712971"
+ integrity sha512-c367Ij63VCz9YdyjiHHWLFtN85l6QghgwMQH2B1eM/p9Y5lTlTX7t/Eg/8+f1yoIStXbk2w/PYM2lk+IkbqdLA==
dependencies:
"@ethereumjs/common" "2.5.0"
"@ethereumjs/tx" "3.3.2"
- crypto-browserify "3.12.0"
eth-lib "0.2.8"
- ethereumjs-util "^7.0.10"
+ ethereumjs-util "^7.1.5"
scrypt-js "^3.0.1"
uuid "^9.0.0"
- web3-core "1.8.1"
- web3-core-helpers "1.8.1"
- web3-core-method "1.8.1"
- web3-utils "1.8.1"
+ web3-core "1.8.2"
+ web3-core-helpers "1.8.2"
+ web3-core-method "1.8.2"
+ web3-utils "1.8.2"
-web3-eth-contract@1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.8.1.tgz#bdf3e33bbcb79a1b6144dffd6a0deefd2e459272"
- integrity sha512-1wphnl+/xwCE2io44JKnN+ti3oa47BKRiVzvWd42icwRbcpFfRxH9QH+aQX3u8VZIISNH7dAkTWpGIIJgGFTmg==
+web3-eth-contract@1.8.2:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.8.2.tgz#5388b7130923d2b790c09a420391a81312a867fb"
+ integrity sha512-ID5A25tHTSBNwOPjiXSVzxruz006ULRIDbzWTYIFTp7NJ7vXu/kynKK2ag/ObuTqBpMbobP8nXcA9b5EDkIdQA==
dependencies:
"@types/bn.js" "^5.1.0"
- web3-core "1.8.1"
- web3-core-helpers "1.8.1"
- web3-core-method "1.8.1"
- web3-core-promievent "1.8.1"
- web3-core-subscriptions "1.8.1"
- web3-eth-abi "1.8.1"
- web3-utils "1.8.1"
+ web3-core "1.8.2"
+ web3-core-helpers "1.8.2"
+ web3-core-method "1.8.2"
+ web3-core-promievent "1.8.2"
+ web3-core-subscriptions "1.8.2"
+ web3-eth-abi "1.8.2"
+ web3-utils "1.8.2"
-web3-eth-ens@1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.8.1.tgz#e78a9651fea8282abe8565b001819e2d645e5929"
- integrity sha512-FT8xTI9uN8RxeBQa/W8pLa2aoFh4+EE34w7W2271LICKzla1dtLyb6XSdn48vsUcPmhWsTVk9mO9RTU0l4LGQQ==
+web3-eth-ens@1.8.2:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.8.2.tgz#0a086ad4d919102e28b9fd3036df246add9df22a"
+ integrity sha512-PWph7C/CnqdWuu1+SH4U4zdrK4t2HNt0I4XzPYFdv9ugE8EuojselioPQXsVGvjql+Nt3jDLvQvggPqlMbvwRw==
dependencies:
content-hash "^2.5.2"
eth-ens-namehash "2.0.8"
- web3-core "1.8.1"
- web3-core-helpers "1.8.1"
- web3-core-promievent "1.8.1"
- web3-eth-abi "1.8.1"
- web3-eth-contract "1.8.1"
- web3-utils "1.8.1"
+ web3-core "1.8.2"
+ web3-core-helpers "1.8.2"
+ web3-core-promievent "1.8.2"
+ web3-eth-abi "1.8.2"
+ web3-eth-contract "1.8.2"
+ web3-utils "1.8.2"
-web3-eth-iban@1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.8.1.tgz#c6484e5d68ca644aa78431301e7acd5df24598d1"
- integrity sha512-DomoQBfvIdtM08RyMGkMVBOH0vpOIxSSQ+jukWk/EkMLGMWJtXw/K2c2uHAeq3L/VPWNB7zXV2DUEGV/lNE2Dg==
+web3-eth-iban@1.8.2:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.8.2.tgz#5cb3022234b13986f086353b53f0379a881feeaf"
+ integrity sha512-h3vNblDWkWMuYx93Q27TAJz6lhzpP93EiC3+45D6xoz983p6si773vntoQ+H+5aZhwglBtoiBzdh7PSSOnP/xQ==
dependencies:
bn.js "^5.2.1"
- web3-utils "1.8.1"
+ web3-utils "1.8.2"
-web3-eth-personal@1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.8.1.tgz#00b5ff1898b62044d25ed5fddd8486168d4827cf"
- integrity sha512-myIYMvj7SDIoV9vE5BkVdon3pya1WinaXItugoii2VoTcQNPOtBxmYVH+XS5ErzCJlnxzphpQrkywyY64bbbCA==
+web3-eth-personal@1.8.2:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.8.2.tgz#3526c1ebaa4e7bf3a0a8ec77e34f067cc9a750b2"
+ integrity sha512-Vg4HfwCr7doiUF/RC+Jz0wT4+cYaXcOWMAW2AHIjHX6Z7Xwa8nrURIeQgeEE62qcEHAzajyAdB1u6bJyTfuCXw==
dependencies:
"@types/node" "^12.12.6"
- web3-core "1.8.1"
- web3-core-helpers "1.8.1"
- web3-core-method "1.8.1"
- web3-net "1.8.1"
- web3-utils "1.8.1"
+ web3-core "1.8.2"
+ web3-core-helpers "1.8.2"
+ web3-core-method "1.8.2"
+ web3-net "1.8.2"
+ web3-utils "1.8.2"
-web3-eth@1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.8.1.tgz#395f6cd56edaac5dbb23e8cec9886c3fd32c430e"
- integrity sha512-LgyzbhFqiFRd8M8sBXoFN4ztzOnkeckl3H/9lH5ek7AdoRMhBg7tYpYRP3E5qkhd/q+yiZmcUgy1AF6NHrC1wg==
+web3-eth@1.8.2:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.8.2.tgz#8562287ae1803c30eb54dc7d832092e5739ce06a"
+ integrity sha512-JoTiWWc4F4TInpbvDUGb0WgDYJsFhuIjJlinc5ByjWD88Gvh+GKLsRjjFdbqe5YtwIGT4NymwoC5LQd1K6u/QQ==
dependencies:
- web3-core "1.8.1"
- web3-core-helpers "1.8.1"
- web3-core-method "1.8.1"
- web3-core-subscriptions "1.8.1"
- web3-eth-abi "1.8.1"
- web3-eth-accounts "1.8.1"
- web3-eth-contract "1.8.1"
- web3-eth-ens "1.8.1"
- web3-eth-iban "1.8.1"
- web3-eth-personal "1.8.1"
- web3-net "1.8.1"
- web3-utils "1.8.1"
+ web3-core "1.8.2"
+ web3-core-helpers "1.8.2"
+ web3-core-method "1.8.2"
+ web3-core-subscriptions "1.8.2"
+ web3-eth-abi "1.8.2"
+ web3-eth-accounts "1.8.2"
+ web3-eth-contract "1.8.2"
+ web3-eth-ens "1.8.2"
+ web3-eth-iban "1.8.2"
+ web3-eth-personal "1.8.2"
+ web3-net "1.8.2"
+ web3-utils "1.8.2"
-web3-net@1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.8.1.tgz#2bed4d4b93166724129ec33d0e5dea98880285f4"
- integrity sha512-LyEJAwogdFo0UAXZqoSJGFjopdt+kLw0P00FSZn2yszbgcoI7EwC+nXiOsEe12xz4LqpYLOtbR7+gxgiTVjjHQ==
+web3-net@1.8.2:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.8.2.tgz#97e1e0015fabc4cda31017813e98d0b5468dd04f"
+ integrity sha512-1itkDMGmbgb83Dg9nporFes9/fxsU7smJ3oRXlFkg4ZHn8YJyP1MSQFPJWWwSc+GrcCFt4O5IrUTvEkHqE3xag==
dependencies:
- web3-core "1.8.1"
- web3-core-method "1.8.1"
- web3-utils "1.8.1"
+ web3-core "1.8.2"
+ web3-core-method "1.8.2"
+ web3-utils "1.8.2"
-web3-providers-http@1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.8.1.tgz#8aa89c11a9272f11ddb74b871273c92225faa28d"
- integrity sha512-1Zyts4O9W/UNEPkp+jyL19Jc3D15S4yp8xuLTjVhcUEAlHo24NDWEKxtZGUuHk4HrKL2gp8OlsDbJ7MM+ESDgg==
+web3-providers-http@1.8.2:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.8.2.tgz#fbda3a3bbc8db004af36e91bec35f80273b37885"
+ integrity sha512-2xY94IIEQd16+b+vIBF4IC1p7GVaz9q4EUFscvMUjtEq4ru4Atdzjs9GP+jmcoo49p70II0UV3bqQcz0TQfVyQ==
dependencies:
abortcontroller-polyfill "^1.7.3"
cross-fetch "^3.1.4"
es6-promise "^4.2.8"
- web3-core-helpers "1.8.1"
+ web3-core-helpers "1.8.2"
-web3-providers-ipc@1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.8.1.tgz#6128a3a3a824d06bf0efcfe86325401f8691a5ca"
- integrity sha512-nw/W5nclvi+P2z2dYkLWReKLnocStflWqFl+qjtv0xn3MrUTyXMzSF0+61i77+16xFsTgzo4wS/NWIOVkR0EFA==
+web3-providers-ipc@1.8.2:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.8.2.tgz#e52a7250f40c83b99a2482ec5b4cf2728377ae5c"
+ integrity sha512-p6fqKVGFg+WiXGHWnB1hu43PbvPkDHTz4RgoEzbXugv5rtv5zfYLqm8Ba6lrJOS5ks9kGKR21a0y3NzE3u7V4w==
dependencies:
oboe "2.1.5"
- web3-core-helpers "1.8.1"
+ web3-core-helpers "1.8.2"
-web3-providers-ws@1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.8.1.tgz#5e5370e07eb8c615ed298ebc8602b283c7b7d649"
- integrity sha512-TNefIDAMpdx57+YdWpYZ/xdofS0P+FfKaDYXhn24ie/tH9G+AB+UBSOKnjN0KSadcRSCMBwGPRiEmNHPavZdsA==
+web3-providers-ws@1.8.2:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.8.2.tgz#56a2b701387011aca9154ca4bc06ea4b5f27e4ef"
+ integrity sha512-3s/4K+wHgbiN+Zrp9YjMq2eqAF6QGABw7wFftPdx+m5hWImV27/MoIx57c6HffNRqZXmCHnfWWFCNHHsi7wXnA==
dependencies:
eventemitter3 "4.0.4"
- web3-core-helpers "1.8.1"
+ web3-core-helpers "1.8.2"
websocket "^1.0.32"
-web3-shh@1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.8.1.tgz#028a95cf9d3a36020380938b9a127610efbb9be7"
- integrity sha512-sqHgarnfcY2Qt3PYS4R6YveHrDy7hmL09yeLLHHCI+RKirmjLVqV0rc5LJWUtlbYI+kDoa5gbgde489M9ZAC0g==
+web3-shh@1.8.2:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.8.2.tgz#217a417f0d6e243dd4d441848ffc2bd164cea8a0"
+ integrity sha512-uZ+3MAoNcaJsXXNCDnizKJ5viBNeHOFYsCbFhV755Uu52FswzTOw6DtE7yK9nYXMtIhiSgi7nwl1RYzP8pystw==
dependencies:
- web3-core "1.8.1"
- web3-core-method "1.8.1"
- web3-core-subscriptions "1.8.1"
- web3-net "1.8.1"
+ web3-core "1.8.2"
+ web3-core-method "1.8.2"
+ web3-core-subscriptions "1.8.2"
+ web3-net "1.8.2"
-web3-utils@1.8.1, web3-utils@^1.3.6:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.8.1.tgz#f2f7ca7eb65e6feb9f3d61056d0de6bbd57125ff"
- integrity sha512-LgnM9p6V7rHHUGfpMZod+NST8cRfGzJ1BTXAyNo7A9cJX9LczBfSRxJp+U/GInYe9mby40t3v22AJdlELibnsQ==
+web3-utils@1.8.2, web3-utils@^1.3.6:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.8.2.tgz#c32dec5e9b955acbab220eefd7715bc540b75cc9"
+ integrity sha512-v7j6xhfLQfY7xQDrUP0BKbaNrmZ2/+egbqP9q3KYmOiPpnvAfol+32slgL0WX/5n8VPvKCK5EZ1HGrAVICSToA==
dependencies:
bn.js "^5.2.1"
ethereum-bloom-filters "^1.0.6"
@@ -7518,17 +7608,17 @@ web3-utils@1.8.1, web3-utils@^1.3.6:
utf8 "3.0.0"
web3@^1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/web3/-/web3-1.8.1.tgz#8ea67215ef5f3a6f6d3381800b527242ea22885a"
- integrity sha512-tAqFsQhGv340C9OgRJIuoScN7f7wa1tUvsnnDUMt9YE6J4gcm7TV2Uwv+KERnzvV+xgdeuULYpsioRRNKrUvoQ==
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/web3/-/web3-1.8.2.tgz#95a4e5398fd0f01325264bf8e5e8cdc69a7afe86"
+ integrity sha512-92h0GdEHW9wqDICQQKyG4foZBYi0OQkyg4CRml2F7XBl/NG+fu9o6J19kzfFXzSBoA4DnJXbyRgj/RHZv5LRiw==
dependencies:
- web3-bzz "1.8.1"
- web3-core "1.8.1"
- web3-eth "1.8.1"
- web3-eth-personal "1.8.1"
- web3-net "1.8.1"
- web3-shh "1.8.1"
- web3-utils "1.8.1"
+ web3-bzz "1.8.2"
+ web3-core "1.8.2"
+ web3-eth "1.8.2"
+ web3-eth-personal "1.8.2"
+ web3-net "1.8.2"
+ web3-shh "1.8.2"
+ web3-utils "1.8.2"
webcrypto-core@^1.7.4:
version "1.7.5"
@@ -7587,7 +7677,7 @@ which-module@^2.0.0:
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==
-which-typed-array@^1.1.2:
+which-typed-array@^1.1.2, which-typed-array@^1.1.9:
version "1.1.9"
resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6"
integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==
@@ -7672,10 +7762,10 @@ ws@7.4.6:
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
-ws@8.11.0:
- version "8.11.0"
- resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143"
- integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==
+ws@8.12.0:
+ version "8.12.0"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-8.12.0.tgz#485074cc392689da78e1828a9ff23585e06cddd8"
+ integrity sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==
ws@^3.0.0:
version "3.3.3"
@@ -7767,9 +7857,9 @@ yaml@^1.10.0:
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
yaml@^2.1.3:
- version "2.1.3"
- resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.1.3.tgz#9b3a4c8aff9821b696275c79a8bee8399d945207"
- integrity sha512-AacA8nRULjKMX2DvWvOAdBZMOfQlypSFkjcOcu9FalllIDJ1kvlREzcdIZmidQUqqeMv7jorHjq2HlLv/+c2lg==
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.2.1.tgz#3014bf0482dcd15147aa8e56109ce8632cd60ce4"
+ integrity sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==
yargs-parser@13.1.2, yargs-parser@^13.1.2:
version "13.1.2"