diff --git a/package-lock.json b/package-lock.json index 39e4e2e0c..a78b2d502 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2009,6 +2009,10 @@ "resolved": "packages/lsp25-contracts", "link": true }, + "node_modules/@lukso/lsp26-contracts": { + "resolved": "packages/lsp26-contracts", + "link": true + }, "node_modules/@lukso/lsp3-contracts": { "resolved": "packages/lsp3-contracts", "link": true @@ -22540,62 +22544,62 @@ }, "packages/lsp-smart-contracts": { "name": "@lukso/lsp-smart-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { - "@lukso/lsp0-contracts": "~0.15.0-rc.5", - "@lukso/lsp1-contracts": "~0.15.0-rc.5", - "@lukso/lsp10-contracts": "~0.15.0-rc.5", - "@lukso/lsp12-contracts": "~0.15.0-rc.5", - "@lukso/lsp14-contracts": "~0.15.0-rc.5", - "@lukso/lsp16-contracts": "~0.15.0-rc.5", - "@lukso/lsp17-contracts": "~0.15.0-rc.5", - "@lukso/lsp17contractextension-contracts": "~0.15.0-rc.5", - "@lukso/lsp1delegate-contracts": "~0.15.0-rc.5", - "@lukso/lsp2-contracts": "~0.15.0-rc.5", - "@lukso/lsp20-contracts": "~0.15.0-rc.5", - "@lukso/lsp23-contracts": "~0.15.0-rc.5", - "@lukso/lsp25-contracts": "~0.15.0-rc.5", - "@lukso/lsp3-contracts": "~0.15.0-rc.5", - "@lukso/lsp4-contracts": "~0.15.0-rc.5", - "@lukso/lsp5-contracts": "~0.15.0-rc.5", - "@lukso/lsp6-contracts": "~0.15.0-rc.5", - "@lukso/lsp7-contracts": "~0.15.0-rc.5", - "@lukso/lsp8-contracts": "~0.15.0-rc.5", - "@lukso/lsp9-contracts": "~0.15.0-rc.5", - "@lukso/universalprofile-contracts": "~0.15.0-rc.5" + "@lukso/lsp0-contracts": "~0.15.0", + "@lukso/lsp1-contracts": "~0.15.0", + "@lukso/lsp10-contracts": "~0.15.0", + "@lukso/lsp12-contracts": "~0.15.0", + "@lukso/lsp14-contracts": "~0.15.0", + "@lukso/lsp16-contracts": "~0.15.0", + "@lukso/lsp17-contracts": "~0.15.0", + "@lukso/lsp17contractextension-contracts": "~0.15.0", + "@lukso/lsp1delegate-contracts": "~0.15.0", + "@lukso/lsp2-contracts": "~0.15.0", + "@lukso/lsp20-contracts": "~0.15.0", + "@lukso/lsp23-contracts": "~0.15.0", + "@lukso/lsp25-contracts": "~0.15.0", + "@lukso/lsp3-contracts": "~0.15.0", + "@lukso/lsp4-contracts": "~0.15.0", + "@lukso/lsp5-contracts": "~0.15.0", + "@lukso/lsp6-contracts": "~0.15.0", + "@lukso/lsp7-contracts": "~0.15.0", + "@lukso/lsp8-contracts": "~0.15.0", + "@lukso/lsp9-contracts": "~0.15.0", + "@lukso/universalprofile-contracts": "~0.15.0" } }, "packages/lsp0-contracts": { "name": "@lukso/lsp0-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp1-contracts": "~0.15.0-rc.5", - "@lukso/lsp14-contracts": "~0.15.0-rc.5", - "@lukso/lsp17contractextension-contracts": "~0.15.0-rc.5", - "@lukso/lsp2-contracts": "~0.15.0-rc.5", - "@lukso/lsp20-contracts": "~0.15.0-rc.5", + "@lukso/lsp1-contracts": "~0.15.0", + "@lukso/lsp14-contracts": "~0.15.0", + "@lukso/lsp17contractextension-contracts": "~0.15.0", + "@lukso/lsp2-contracts": "~0.15.0", + "@lukso/lsp20-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } }, "packages/lsp1-contracts": { "name": "@lukso/lsp1-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { - "@lukso/lsp2-contracts": "~0.15.0-rc.5", + "@lukso/lsp2-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } }, "packages/lsp10-contracts": { "name": "@lukso/lsp10-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^6.0.0", - "@lukso/lsp2-contracts": "~0.15.0-rc.5" + "@lukso/lsp2-contracts": "~0.15.0" } }, "packages/lsp10-contracts/node_modules/@erc725/smart-contracts": { @@ -22609,24 +22613,24 @@ }, "packages/lsp12-contracts": { "name": "@lukso/lsp12-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { - "@lukso/lsp2-contracts": "~0.15.0-rc.5" + "@lukso/lsp2-contracts": "~0.15.0" } }, "packages/lsp14-contracts": { "name": "@lukso/lsp14-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp1-contracts": "~0.15.0-rc.5" + "@lukso/lsp1-contracts": "~0.15.0" } }, "packages/lsp16-contracts": { "name": "@lukso/lsp16-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", @@ -22636,21 +22640,21 @@ }, "packages/lsp17-contracts": { "name": "@lukso/lsp17-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@account-abstraction/contracts": "^0.6.0", "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp14-contracts": "~0.15.0-rc.5", - "@lukso/lsp17contractextension-contracts": "~0.15.0-rc.5", - "@lukso/lsp20-contracts": "~0.15.0-rc.5", - "@lukso/lsp6-contracts": "~0.15.0-rc.5", + "@lukso/lsp14-contracts": "~0.15.0", + "@lukso/lsp17contractextension-contracts": "~0.15.0", + "@lukso/lsp20-contracts": "~0.15.0", + "@lukso/lsp6-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } }, "packages/lsp17contractextension-contracts": { "name": "@lukso/lsp17contractextension-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", @@ -22659,22 +22663,22 @@ }, "packages/lsp1delegate-contracts": { "name": "@lukso/lsp1delegate-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp1-contracts": "~0.15.0-rc.5", - "@lukso/lsp10-contracts": "~0.15.0-rc.5", - "@lukso/lsp5-contracts": "~0.15.0-rc.5", - "@lukso/lsp7-contracts": "~0.15.0-rc.5", - "@lukso/lsp8-contracts": "~0.15.0-rc.5", - "@lukso/lsp9-contracts": "~0.15.0-rc.5", + "@lukso/lsp1-contracts": "~0.15.0", + "@lukso/lsp10-contracts": "~0.15.0", + "@lukso/lsp5-contracts": "~0.15.0", + "@lukso/lsp7-contracts": "~0.15.0", + "@lukso/lsp8-contracts": "~0.15.0", + "@lukso/lsp9-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } }, "packages/lsp2-contracts": { "name": "@lukso/lsp2-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", @@ -22683,113 +22687,123 @@ }, "packages/lsp20-contracts": { "name": "@lukso/lsp20-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0" }, "packages/lsp23-contracts": { "name": "@lukso/lsp23-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/universalprofile-contracts": "~0.15.0-rc.5", + "@lukso/universalprofile-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } }, "packages/lsp25-contracts": { "name": "@lukso/lsp25-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", + "license": "Apache-2.0", + "dependencies": { + "@openzeppelin/contracts": "^4.9.3" + } + }, + "packages/lsp26-contracts": { + "name": "@lukso/lsp26-contracts", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { + "@lukso/lsp0-contracts": "*", + "@lukso/lsp1-contracts": "*", "@openzeppelin/contracts": "^4.9.3" } }, "packages/lsp3-contracts": { "name": "@lukso/lsp3-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { - "@lukso/lsp2-contracts": "~0.15.0-rc.5" + "@lukso/lsp2-contracts": "~0.15.0" } }, "packages/lsp4-contracts": { "name": "@lukso/lsp4-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp2-contracts": "~0.15.0-rc.5" + "@lukso/lsp2-contracts": "~0.15.0" } }, "packages/lsp5-contracts": { "name": "@lukso/lsp5-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp2-contracts": "~0.15.0-rc.5" + "@lukso/lsp2-contracts": "~0.15.0" } }, "packages/lsp6-contracts": { "name": "@lukso/lsp6-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp1-contracts": "~0.15.0-rc.5", - "@lukso/lsp14-contracts": "~0.15.0-rc.5", - "@lukso/lsp17contractextension-contracts": "~0.15.0-rc.5", - "@lukso/lsp2-contracts": "~0.15.0-rc.5", - "@lukso/lsp20-contracts": "~0.15.0-rc.5", - "@lukso/lsp25-contracts": "~0.15.0-rc.5", + "@lukso/lsp1-contracts": "~0.15.0", + "@lukso/lsp14-contracts": "~0.15.0", + "@lukso/lsp17contractextension-contracts": "~0.15.0", + "@lukso/lsp2-contracts": "~0.15.0", + "@lukso/lsp20-contracts": "~0.15.0", + "@lukso/lsp25-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } }, "packages/lsp7-contracts": { "name": "@lukso/lsp7-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp1-contracts": "~0.15.0-rc.5", - "@lukso/lsp17contractextension-contracts": "~0.15.0-rc.5", - "@lukso/lsp2-contracts": "~0.15.0-rc.5", - "@lukso/lsp4-contracts": "~0.15.0-rc.5", + "@lukso/lsp1-contracts": "~0.15.0", + "@lukso/lsp17contractextension-contracts": "~0.15.0", + "@lukso/lsp2-contracts": "~0.15.0", + "@lukso/lsp4-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } }, "packages/lsp8-contracts": { "name": "@lukso/lsp8-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp1-contracts": "~0.15.0-rc.5", - "@lukso/lsp17contractextension-contracts": "~0.15.0-rc.5", - "@lukso/lsp2-contracts": "~0.15.0-rc.5", - "@lukso/lsp4-contracts": "~0.15.0-rc.5", + "@lukso/lsp1-contracts": "~0.15.0", + "@lukso/lsp17contractextension-contracts": "~0.15.0", + "@lukso/lsp2-contracts": "~0.15.0", + "@lukso/lsp4-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } }, "packages/lsp9-contracts": { "name": "@lukso/lsp9-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp1-contracts": "~0.15.0-rc.5", - "@lukso/lsp6-contracts": "~0.15.0-rc.5", + "@lukso/lsp1-contracts": "~0.15.0", + "@lukso/lsp6-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } }, "packages/universalprofile-contracts": { "name": "@lukso/universalprofile-contracts", - "version": "0.15.0-rc.5", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@erc725/smart-contracts": "^7.0.0", - "@lukso/lsp0-contracts": "~0.15.0-rc.5", - "@lukso/lsp3-contracts": "~0.15.0-rc.5", + "@lukso/lsp0-contracts": "~0.15.0", + "@lukso/lsp3-contracts": "~0.15.0", "@openzeppelin/contracts": "^4.9.3" } } diff --git a/packages/lsp26-contracts/.eslintrc.js b/packages/lsp26-contracts/.eslintrc.js new file mode 100644 index 000000000..03ee7431b --- /dev/null +++ b/packages/lsp26-contracts/.eslintrc.js @@ -0,0 +1,4 @@ +module.exports = { + root: true, + extends: ['custom'], +}; diff --git a/packages/lsp26-contracts/.solhint.json b/packages/lsp26-contracts/.solhint.json new file mode 100644 index 000000000..26e01c48a --- /dev/null +++ b/packages/lsp26-contracts/.solhint.json @@ -0,0 +1,25 @@ +{ + "extends": "solhint:recommended", + "rules": { + "avoid-sha3": "error", + "avoid-suicide": "error", + "avoid-throw": "error", + "avoid-tx-origin": "error", + "check-send-result": "error", + "compiler-version": ["error", "^0.8.0"], + "func-visibility": ["error", { "ignoreConstructors": true }], + "not-rely-on-block-hash": "error", + "not-rely-on-time": "error", + "reentrancy": "error", + "constructor-syntax": "error", + "private-vars-leading-underscore": ["error", { "strict": false }], + "imports-on-top": "error", + "visibility-modifier-order": "error", + "no-unused-import": "error", + "no-global-import": "error", + "reason-string": ["warn", { "maxLength": 120 }], + "avoid-low-level-calls": "off", + "no-empty-blocks": ["error", { "ignoreConstructors": true }], + "custom-errors": "off" + } +} diff --git a/packages/lsp26-contracts/README.md b/packages/lsp26-contracts/README.md new file mode 100644 index 000000000..44c90d86b --- /dev/null +++ b/packages/lsp26-contracts/README.md @@ -0,0 +1,51 @@ +# LSP Package Template + +This project can be used as a skeleton to build a package for a LSP implementation in Solidity (LUKSO Standard Proposal) + +It is based on Hardhat. + +## How to setup a LSP as a package? + +1. Copy the `template/` folder and paste it under the `packages/` folder. Then rename this `template/` folder that you copied with the LSP name. + +You can do so either: + +- manually, by copying the folder and pasting it inside `packages` and then renaming it. + or +- by running the following command from the root of the repository. + +```bash +cp -r template packages/lsp-name +``` + +2. Update the `"name"` and `"description"` field inside the `package.json` for this LSP package you just created. + +3. Setup the dependencies + +If this LSP uses external dependencies like `@openzeppelin/contracts`, put them under `dependencies` with the version number. + +```json +"@openzeppelin/contracts": "^4.9.3" +``` + +If this LSP uses other LSP as dependencies, put each LSP dependency as shown below. This will use the current code in the package: + +```json +"@lsp2": "*" +``` + +4. Setup the npm commands for linting, building, testing, etc... under the `"scripts"` in the `package.json` + +5. Test that all commands you setup run successfully + +By running the commands below, your LSP package should come up in the list of packages that Turbo is running this command for. + +```bash +turbo build +turbo lint +turbo lint:solidity +turbo test +turbo test:foundry +``` + +6. Finally update the relevant information in the `README.md` file in the folder of the newly created package, such as the title at the top, some description, etc... diff --git a/packages/lsp26-contracts/build.config.ts b/packages/lsp26-contracts/build.config.ts new file mode 100644 index 000000000..71798d1ff --- /dev/null +++ b/packages/lsp26-contracts/build.config.ts @@ -0,0 +1,9 @@ +import { defineBuildConfig } from 'unbuild'; + +export default defineBuildConfig({ + entries: ['./constants'], + declaration: 'compatible', // generate .d.ts files + rollup: { + emitCJS: true, + }, +}); diff --git a/packages/lsp26-contracts/constants.ts b/packages/lsp26-contracts/constants.ts new file mode 100644 index 000000000..7ae3bf471 --- /dev/null +++ b/packages/lsp26-contracts/constants.ts @@ -0,0 +1,4 @@ +// Define your constants to be exported here + +// example +export const LSPN_CONSTANT_VALUE = 123; diff --git a/packages/lsp26-contracts/contracts/ILSP26FollowingSystem.sol b/packages/lsp26-contracts/contracts/ILSP26FollowingSystem.sol new file mode 100644 index 000000000..0485eb5b3 --- /dev/null +++ b/packages/lsp26-contracts/contracts/ILSP26FollowingSystem.sol @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.17; + +interface ILSP26FollowingSystem { + event Follow(address follower, address addr); + event Unfollow(address unfollower, address addr); + + /// @notice Followed `addr`. + /// @custom:events {Follow} event when following someone. + /// @param addr The address of the user to start following. + function follow(address addr) external; + + /// @notice Unfollowed `addr`. + /// @custom:events {Unfollow} event when unfollowing someone. + /// @param addr The address of the user to stop following. + function unfollow(address addr) external; + + /// @notice Checks if `follower` is following `addr`. + /// @param follower The address of the follower to check. + /// @param addr The address of the user being followed. + /// @return True if `follower` is following `addr`, false otherwise. + function isFollowing( + address follower, + address addr + ) external view returns (bool); + + /// @notice Get the number of followers for `addr`. + /// @param addr The address of the user whose followers count is requested. + /// @return The number of followers of `addr`. + function followerCount(address addr) external view returns (uint256); + + /// @notice Get the number of users that `addr` is following. + /// @param addr The address of the follower whose following count is requested. + /// @return The number of users that `addr` is following. + function followingCount(address addr) external view returns (uint256); + + /// @notice Get a list of users followed by `addr` within a specified range. + /// @param addr The address of the follower whose followed users are requested. + /// @param startIndex The start index of the range (inclusive). + /// @param endIndex The end index of the range (exclusive). + /// @return An array of addresses representing the users followed by `addr`. + function getFollowingByIndex( + address addr, + uint256 startIndex, + uint256 endIndex + ) external view returns (address[] memory); + + /// @notice Get a list of users following `addr` within a specified range. + /// @param addr The address of the user whose followers are requested. + /// @param startIndex The start index of the range (inclusive). + /// @param endIndex The end index of the range (exclusive). + /// @return An array of addresses representing the users following `addr`. + function getFollowersByIndex( + address addr, + uint256 startIndex, + uint256 endIndex + ) external view returns (address[] memory); +} diff --git a/packages/lsp26-contracts/contracts/Imports.sol b/packages/lsp26-contracts/contracts/Imports.sol new file mode 100644 index 000000000..262912d42 --- /dev/null +++ b/packages/lsp26-contracts/contracts/Imports.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.17; + +// solhint-disable no-unused-import +import { + LSP0ERC725Account +} from "@lukso/lsp0-contracts/contracts/LSP0ERC725Account.sol"; diff --git a/packages/lsp26-contracts/contracts/LSP26Constants.sol b/packages/lsp26-contracts/contracts/LSP26Constants.sol new file mode 100644 index 000000000..41aa959a4 --- /dev/null +++ b/packages/lsp26-contracts/contracts/LSP26Constants.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.17; + +// keccak256('LSP26FollowerSystem_FollowNotification') +bytes32 constant _TYPEID_LSP26_FOLLOW = 0x71e02f9f05bcd5816ec4f3134aa2e5a916669537ec6c77fe66ea595fabc2d51a; + +// keccak256('LSP26FollowerSystem_UnfollowNotification') +bytes32 constant _TYPEID_LSP26_UNFOLLOW = 0x9d3c0b4012b69658977b099bdaa51eff0f0460f421fba96d15669506c00d1c4f; diff --git a/packages/lsp26-contracts/contracts/LSP26Errors.sol b/packages/lsp26-contracts/contracts/LSP26Errors.sol new file mode 100644 index 000000000..93c39e4aa --- /dev/null +++ b/packages/lsp26-contracts/contracts/LSP26Errors.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.17; + +error LSP26CannotSelfFollow(); + +error LSP26CannotSelfUnfollow(); + +error LSP26AlreadyFollowing(address addr); + +error LSP26NotFollowing(address addr); diff --git a/packages/lsp26-contracts/contracts/LSP26FollowingSystem.sol b/packages/lsp26-contracts/contracts/LSP26FollowingSystem.sol new file mode 100644 index 000000000..932bbd83d --- /dev/null +++ b/packages/lsp26-contracts/contracts/LSP26FollowingSystem.sol @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.17; + +// interafces +import {ILSP26FollowingSystem} from "./ILSP26FollowingSystem.sol"; +import { + ILSP1UniversalReceiver +} from "@lukso/lsp1-contracts/contracts/ILSP1UniversalReceiver.sol"; + +// libraries +import { + EnumerableSet +} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { + ERC165Checker +} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; + +// constants +import { + _TYPEID_LSP26_FOLLOW, + _TYPEID_LSP26_UNFOLLOW +} from "./LSP26Constants.sol"; +import { + _INTERFACEID_LSP1 +} from "@lukso/lsp1-contracts/contracts/LSP1Constants.sol"; + +// errors +import { + LSP26CannotSelfFollow, + LSP26CannotSelfUnfollow, + LSP26AlreadyFollowing, + LSP26NotFollowing +} from "./LSP26Errors.sol"; + +contract LSP26FollowingSystem is ILSP26FollowingSystem { + using EnumerableSet for EnumerableSet.AddressSet; + using ERC165Checker for address; + + mapping(address => EnumerableSet.AddressSet) private _followersOf; + mapping(address => EnumerableSet.AddressSet) private _followingsOf; + + // @inheritdoc ILSP26FollowingSystem + function follow(address addr) public { + _follow(addr); + } + + // @inheritdoc ILSP26FollowingSystem + function followBatch(address[] memory addresses) public { + for (uint256 index = 0; index < addresses.length; index++) { + _follow(addresses[index]); + } + } + + // @inheritdoc ILSP26FollowingSystem + function unfollow(address addr) public { + if (msg.sender == addr) { + revert LSP26CannotSelfUnfollow(); + } + + if (!_followingsOf[msg.sender].contains(addr)) { + revert LSP26NotFollowing(addr); + } + + _followingsOf[msg.sender].add(addr); + _followersOf[addr].remove(msg.sender); + + if (addr.supportsERC165InterfaceUnchecked(_INTERFACEID_LSP1)) { + // solhint-disable no-empty-blocks + try + ILSP1UniversalReceiver(addr).universalReceiver( + _TYPEID_LSP26_UNFOLLOW, + abi.encodePacked(msg.sender) + ) + {} catch {} + // returns (bytes memory data) {} catch {} + } + + emit Unfollow(msg.sender, addr); + } + + // @inheritdoc ILSP26FollowingSystem + function isFollowing( + address follower, + address addr + ) public view returns (bool) { + return _followingsOf[follower].contains(addr); + } + + // @inheritdoc ILSP26FollowingSystem + function followerCount(address addr) public view returns (uint256) { + return _followersOf[addr].length(); + } + + // @inheritdoc ILSP26FollowingSystem + function followingCount(address addr) public view returns (uint256) { + return _followingsOf[addr].length(); + } + + // @inheritdoc ILSP26FollowingSystem + function getFollowingByIndex( + address addr, + uint256 startIndex, + uint256 endIndex + ) public view returns (address[] memory) { + address[] memory followings = new address[](endIndex - startIndex); + + for (uint256 index = 0; index < endIndex - startIndex; index++) { + followings[index] = _followingsOf[addr].at(startIndex + index); + } + + return followings; + } + + // @inheritdoc ILSP26FollowingSystem + function getFollowersByIndex( + address addr, + uint256 startIndex, + uint256 endIndex + ) public view returns (address[] memory) { + address[] memory followers = new address[](endIndex - startIndex); + + for (uint256 index = 0; index < endIndex - startIndex; index++) { + followers[index] = _followersOf[addr].at(startIndex + index); + } + + return followers; + } + + function _follow(address addr) internal { + if (msg.sender == addr) { + revert LSP26CannotSelfFollow(); + } + + if (_followingsOf[msg.sender].contains(addr)) { + revert LSP26AlreadyFollowing(addr); + } + + _followingsOf[msg.sender].add(addr); + _followersOf[addr].add(msg.sender); + + if (addr.supportsERC165InterfaceUnchecked(_INTERFACEID_LSP1)) { + // solhint-disable no-empty-blocks + try + ILSP1UniversalReceiver(addr).universalReceiver( + _TYPEID_LSP26_FOLLOW, + abi.encodePacked(msg.sender) + ) + {} catch {} + // returns (bytes memory data) {} catch {} + } + + emit Follow(msg.sender, addr); + } +} diff --git a/packages/lsp26-contracts/gasCost.json b/packages/lsp26-contracts/gasCost.json new file mode 100644 index 000000000..000832ffe --- /dev/null +++ b/packages/lsp26-contracts/gasCost.json @@ -0,0 +1,1120 @@ +{ + "followCost": 143167, + "unfollowCost": 35700, + "batchFollowCost": 1227152, + "executeBatchFollowCost": 1264096, + "followingGasCost": [ + 160255, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, 143155, + 143155 + ] +} diff --git a/packages/lsp26-contracts/hardhat.config.ts b/packages/lsp26-contracts/hardhat.config.ts new file mode 100644 index 000000000..80627f056 --- /dev/null +++ b/packages/lsp26-contracts/hardhat.config.ts @@ -0,0 +1,133 @@ +import { HardhatUserConfig } from 'hardhat/config'; +import { NetworkUserConfig } from 'hardhat/types'; +import { config as dotenvConfig } from 'dotenv'; +import { resolve } from 'path'; + +/** + * this package includes: + * - @nomiclabs/hardhat-ethers + * - @nomicfoundation/hardhat-chai-matchers + * - @nomicfoundation/hardhat-network-helpers + * - @nomiclabs/hardhat-etherscan + * - hardhat-gas-reporter (is this true? Why do we have it as a separate dependency?) + * - @typechain/hardhat + * - solidity-coverage + */ +import '@nomicfoundation/hardhat-toolbox'; + +// additional hardhat plugins +import 'hardhat-packager'; +import 'hardhat-contract-sizer'; +import 'hardhat-deploy'; +import { hexlify, randomBytes } from 'ethers'; + +// custom built hardhat plugins and scripts +// can be imported here (e.g: docs generation, gas benchmark, etc...) + +dotenvConfig({ path: resolve(__dirname, './.env') }); + +function getTestnetChainConfig(): NetworkUserConfig { + const config: NetworkUserConfig = { + live: true, + url: 'https://rpc.testnet.lukso.network', + chainId: 4201, + }; + + if (process.env.CONTRACT_VERIFICATION_TESTNET_PK !== undefined) { + config['accounts'] = [process.env.CONTRACT_VERIFICATION_TESTNET_PK]; + } + + return config; +} + +const config: HardhatUserConfig = { + defaultNetwork: 'hardhat', + networks: { + hardhat: { + live: false, + saveDeployments: false, + allowBlocksWithSameTimestamp: true, + accounts: new Array(10_100).fill('').map(() => ({ + privateKey: hexlify(randomBytes(32)), + balance: '1000000000000000000', + })), + }, + luksoTestnet: getTestnetChainConfig(), + }, + namedAccounts: { + owner: 0, + }, + // uncomment if the contracts from this LSP package must be deployed at deterministic + // // addresses across multiple chains + // deterministicDeployment: { + // luksoTestnet: { + // // Nick Factory. See https://github.com/Arachnid/deterministic-deployment-proxy + // factory: '0x4e59b44847b379578588920ca78fbf26c0b4956c', + // deployer: '0x3fab184622dc19b6109349b94811493bf2a45362', + // funding: '0x0000000000000000000000000000000000000000000000000000000000000000', + // signedTx: + // '0xf8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222', + // }, + // }, + etherscan: { + apiKey: 'no-api-key-needed', + customChains: [ + { + network: 'luksoTestnet', + chainId: 4201, + urls: { + apiURL: 'https://api.explorer.execution.testnet.lukso.network/api', + browserURL: 'https://explorer.execution.testnet.lukso.network/', + }, + }, + ], + }, + gasReporter: { + enabled: true, + currency: 'USD', + gasPrice: 21, + excludeContracts: ['Helpers/'], + src: './contracts', + showMethodSig: true, + }, + solidity: { + version: '0.8.17', + settings: { + optimizer: { + enabled: true, + /** + * Optimize for how many times you intend to run the code. + * Lower values will optimize more for initial deployment cost, higher + * values will optimize more for high-frequency usage. + * @see https://docs.soliditylang.org/en/v0.8.6/internals/optimizer.html#opcode-based-optimizer-module + */ + runs: 1000, + }, + outputSelection: { + '*': { + '*': ['storageLayout'], + }, + }, + }, + }, + packager: { + // What contracts to keep the artifacts and the bindings for. + contracts: [], + // Whether to include the TypeChain factories or not. + // If this is enabled, you need to run the TypeChain files through the TypeScript compiler before shipping to the registry. + includeFactories: true, + }, + paths: { + artifacts: 'artifacts', + tests: 'tests', + }, + typechain: { + outDir: 'types', + target: 'ethers-v6', + }, + mocha: { + timeout: 10000000, + }, +}; + +export default config; diff --git a/packages/lsp26-contracts/index.ts b/packages/lsp26-contracts/index.ts new file mode 100644 index 000000000..c94f80f84 --- /dev/null +++ b/packages/lsp26-contracts/index.ts @@ -0,0 +1 @@ +export * from './constants'; diff --git a/packages/lsp26-contracts/package.json b/packages/lsp26-contracts/package.json new file mode 100644 index 000000000..bf7832ff1 --- /dev/null +++ b/packages/lsp26-contracts/package.json @@ -0,0 +1,55 @@ +{ + "name": "@lukso/lsp26-contracts", + "version": "0.15.0", + "description": "Package for the LSP26 Following System standard", + "license": "Apache-2.0", + "author": "", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "typings": "./dist/index.d.ts", + "exports": { + ".": { + "require": "./dist/index.cjs", + "import": "./dist/index.mjs", + "types": "./dist/index.d.ts" + }, + "./artifacts/*": "./artifacts/*", + "./package.json": "./package.json" + }, + "keywords": [ + "LUKSO", + "LSP", + "Blockchain", + "Standards", + "Smart Contracts", + "Ethereum", + "EVM", + "Solidity" + ], + "files": [ + "contracts/**/*.sol", + "!contracts/Mocks/**/*.sol", + "artifacts/*.json", + "dist", + "types", + "!types/factories", + "./README.md" + ], + "scripts": { + "build": "hardhat compile --show-stack-traces", + "build:types": "npx wagmi generate", + "clean": "hardhat clean && rm -Rf dist/", + "format": "prettier --write .", + "lint": "eslint . --ext .ts,.js", + "lint:solidity": "solhint 'contracts/**/*.sol' && prettier --check 'contracts/**/*.sol'", + "test": "hardhat test --no-compile tests/*.test.ts", + "test:foundry": "FOUNDRY_PROFILE=lspN forge test --no-match-test Skip -vvv", + "test:coverage": "hardhat coverage", + "package": "hardhat prepare-package" + }, + "dependencies": { + "@openzeppelin/contracts": "^4.9.3", + "@lukso/lsp0-contracts": "*", + "@lukso/lsp1-contracts": "*" + } +} diff --git a/packages/lsp26-contracts/tests/LSP26FollowingSystem.test.ts b/packages/lsp26-contracts/tests/LSP26FollowingSystem.test.ts new file mode 100644 index 000000000..33c563232 --- /dev/null +++ b/packages/lsp26-contracts/tests/LSP26FollowingSystem.test.ts @@ -0,0 +1,178 @@ +import { expect } from 'chai'; +import { ethers } from 'hardhat'; +import { ContractTransactionResponse, getAddress, hexlify, randomBytes } from 'ethers'; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import { writeFileSync } from 'fs'; + +// constants +import { OPERATION_TYPES } from '@lukso/lsp0-contracts'; + +// types +import { + LSP26FollowingSystem, + LSP26FollowingSystem__factory, + LSP0ERC725Account, + LSP0ERC725Account__factory, +} from '../types'; + +describe('testing `LSP26FollowingSystem`', () => { + let context: { + followerSystem: LSP26FollowingSystem; + followerSystemAddress: string; + universalProfile: LSP0ERC725Account; + owner: SignerWithAddress; + singleFollowSigner: SignerWithAddress; + executeBatchFollowSigners: SignerWithAddress[]; + batchFollowSigners: SignerWithAddress[]; + multiFollowSigners: SignerWithAddress[]; + }; + + before(async () => { + const signers = await ethers.getSigners(); + const [owner, singleFollowSigner] = signers; + const followerSystem = await new LSP26FollowingSystem__factory(owner).deploy(); + const followerSystemAddress = await followerSystem.getAddress(); + const universalProfile = await new LSP0ERC725Account__factory(owner).deploy(owner.address); + + const executeBatchFollowSigners = signers.slice(2, 12); + const batchFollowSigners = signers.slice(12, 22); + const multiFollowSigners = signers.slice(22, 10_022); + + context = { + followerSystem, + followerSystemAddress, + universalProfile, + owner, + singleFollowSigner, + executeBatchFollowSigners, + batchFollowSigners, + multiFollowSigners, + }; + }); + + describe('testing `follow(address)`', () => { + it('should revert when following your own address', async () => { + await expect( + context.followerSystem.connect(context.owner).follow(context.owner.address), + ).to.be.revertedWithCustomError(context.followerSystem, 'LSP26CannotSelfFollow'); + }); + + it('should revert when following an address that is already followed', async () => { + const randomAddress = getAddress(hexlify(randomBytes(20))); + + await context.followerSystem.connect(context.owner).follow(randomAddress); + + await expect(context.followerSystem.connect(context.owner).follow(randomAddress)) + .to.be.revertedWithCustomError(context.followerSystem, 'LSP26AlreadyFollowing') + .withArgs(randomAddress); + }); + }); + + describe('testing `unfollow(address)`', () => { + it('should revert when unfollowing your own address', async () => { + await expect( + context.followerSystem.connect(context.owner).unfollow(context.owner.address), + ).to.be.revertedWithCustomError(context.followerSystem, 'LSP26CannotSelfUnfollow'); + }); + + it('should revert when unfollowing an address that is not followed', async () => { + const randomAddress = getAddress(hexlify(randomBytes(20))); + + await expect(context.followerSystem.connect(context.owner).unfollow(randomAddress)) + .to.be.revertedWithCustomError(context.followerSystem, 'LSP26NotFollowing') + .withArgs(randomAddress); + }); + }); + + describe('gas tests', () => { + const gasCostResult: { + followingGasCost?: number[]; + followCost?: number; + unfollowCost?: number; + batchFollowCost?: number; + executeBatchFollowCost?: number; + } = {}; + + after(() => { + writeFileSync('gasCost.json', JSON.stringify(gasCostResult)); + }); + + it('gas: testing follow', async () => { + const txResponse = await context.followerSystem + .connect(context.owner) + .follow(context.singleFollowSigner.address); + const txReceipt = await txResponse.wait(); + + gasCostResult.followCost = Number(txReceipt.gasUsed); + }); + + it('gas: testing unfollow', async () => { + const txResponse = await context.followerSystem + .connect(context.owner) + .unfollow(context.singleFollowSigner.address); + const txReceipt = await txResponse.wait(); + + gasCostResult.unfollowCost = Number(txReceipt.gasUsed); + }); + + it('gas: testing `followBatch`', async () => { + const followBatch = context.followerSystem.interface.encodeFunctionData('followBatch', [ + context.batchFollowSigners.map(({ address }) => address), + ]); + + const txResponse = (await context.universalProfile + .connect(context.owner) + .execute( + OPERATION_TYPES.CALL, + context.followerSystemAddress, + 0, + followBatch, + )) as ContractTransactionResponse; + const txReceipt = await txResponse.wait(); + + gasCostResult.batchFollowCost = Number(txReceipt.gasUsed); + }); + + it('gas: testing `executeBatchFollow`', async () => { + const follows = context.executeBatchFollowSigners.map(({ address }) => + context.followerSystem.interface.encodeFunctionData('follow', [address]), + ); + + const txResponse = (await context.universalProfile.connect(context.owner).executeBatch( + follows.map(() => OPERATION_TYPES.CALL), + follows.map(() => context.followerSystemAddress), + follows.map(() => 0), + follows, + )) as ContractTransactionResponse; + const txReceipt = await txResponse.wait(); + + gasCostResult.executeBatchFollowCost = Number(txReceipt.gasUsed); + }); + + describe('gas: testing following a single account 10_000 times', () => { + const followingGasCost: number[] = []; + + after(() => { + gasCostResult.followingGasCost = followingGasCost; + }); + + it(`testing signers`, async () => { + let count = 1; + + for (const signer of context.multiFollowSigners) { + if (count % 1000 === 0) { + console.log(`Testing signer #${count}`); + } + + const txResponse = await context.followerSystem + .connect(signer) + .follow(context.owner.address); + const txReceipt = await txResponse.wait(); + + followingGasCost.push(Number(txReceipt.gasUsed)); + count++; + } + }); + }); + }); +}); diff --git a/packages/lsp26-contracts/tsconfig.json b/packages/lsp26-contracts/tsconfig.json new file mode 100644 index 000000000..b7a34e03f --- /dev/null +++ b/packages/lsp26-contracts/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "tsconfig/contracts.json", + "include": ["**/*.ts"] +} diff --git a/packages/lsp26-contracts/wagmi.config.ts b/packages/lsp26-contracts/wagmi.config.ts new file mode 100644 index 000000000..9f838fb8d --- /dev/null +++ b/packages/lsp26-contracts/wagmi.config.ts @@ -0,0 +1,19 @@ +import { defineConfig } from '@wagmi/cli'; +import { react } from '@wagmi/cli/plugins'; +import fs from 'fs'; + +const artifacts = fs.readdirSync('./artifacts', {}); + +const contractsWagmiInputs = artifacts.map((artifact) => { + const jsonArtifact = JSON.parse(fs.readFileSync(`./artifacts/${artifact}`, 'utf-8')); + return { + name: jsonArtifact.contractName, + abi: jsonArtifact.abi, + }; +}); + +export default defineConfig({ + out: 'types/index.ts', + contracts: contractsWagmiInputs, + plugins: [react()], +}); diff --git a/template/package.json b/template/package.json index 806ae2641..d9439ca23 100644 --- a/template/package.json +++ b/template/package.json @@ -1,6 +1,6 @@ { "name": "lspN", - "version": "0.12.1", + "version": "0.15.0", "description": "Package for the LSPN standard", "license": "Apache-2.0", "author": "",