diff --git a/InvestmentDAO/.gitattributes b/InvestmentDAO/.gitattributes new file mode 100644 index 00000000..dfe07704 --- /dev/null +++ b/InvestmentDAO/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/InvestmentDAO/.gitignore b/InvestmentDAO/.gitignore new file mode 100644 index 00000000..59e04893 --- /dev/null +++ b/InvestmentDAO/.gitignore @@ -0,0 +1,42 @@ +node_modules +.env +packages/*/.env +packages/*/.env.* + +# IntelliJ project files +*.iml +*.ipr +*.iws +.idea + +*.gitkeep + +# eclipse project file +.settings/ +.classpath +.project + +# NetBeans specific +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +nbactions.xml +nb-configuration.xml + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# OS +.DS_Store + +# Miscellaneous +*.class +*.log +*.pyc +*.swp + +PROPOSAL.md diff --git a/InvestmentDAO/LICENSE b/InvestmentDAO/LICENSE new file mode 100644 index 00000000..335ebbe7 --- /dev/null +++ b/InvestmentDAO/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 DevRel Team & Community + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/InvestmentDAO/README.md b/InvestmentDAO/README.md new file mode 100644 index 00000000..4a22a040 --- /dev/null +++ b/InvestmentDAO/README.md @@ -0,0 +1,41 @@ +# Investment DAO + +## Description +DAOalyzer is a data visualization platform that aggregates and displays key metrics of investment activity within an investment DAO. The platform will be designed to provide value to both existing and potential investors in the DAO, and enable them to make informed decisions about their investments. + +‌ +Features: + +Real-time visualization: The platform will display investment data and key performance metrics in real-time. This will include data on assets invested, performance of those assets, investment strategies employed, and more. + +Customizable dashboard: The platform will allow users to customize their dashboard to display only the metrics that matter most to them. + +Historical data: Users can also view historical data on investment activity. This can be used to track the performance of investments over time and make better-informed investment decisions. + +Comparison features: The platform will allow users to compare the performance of various assets and investment strategies within the DAO. This can help investors understand which investments are performing best and why. + +Investment functionality: The platform will enable investors to make investments in the DAO directly from the platform. + + + +## Requirements + +- [Remix](https://remix.ethereum.org/) - Online editor for writing smart contracts or any code editor you choose. +- [Metamask](https://metamask.io/) - For managing our wallet. +- [Hardhat](https://hardhat.org/) - For compiling and deploying the smart contract +- [Alfajores Testnet Account](https://developers.celo.org/3-simple-steps-to-connect-your-metamask-wallet-to-celo-732d4a139587) - Required to connect to the dApp and make test transactions. +- [Node.js](https://nodejs.org/en/) - From V12. or higher +- [Celo Composer](https://github.com/celo-org/celo-composer) - For quick web3 project scaffolding +- [Open Zeppelin Defender Account](https://defender.openzeppelin.com/) — You need an account with Open Zeppelin for automating on-chain data. + +## Installation + +```js +npm install +``` + +## Start + +```js +npm run dev +``` \ No newline at end of file diff --git a/InvestmentDAO/netlify.toml b/InvestmentDAO/netlify.toml new file mode 100644 index 00000000..d14bf083 --- /dev/null +++ b/InvestmentDAO/netlify.toml @@ -0,0 +1,12 @@ +# Settings in the [build] context are global and are applied to +# all contexts unless otherwise overridden by more specific contexts. +[build] + # Directory to change to before starting a build. + # This is where we will look for package.json/.nvmrc/etc. + # If not set, defaults to the root directory. + base = "/" + publish = "packages/react-app/.next" + command = "yarn build-ui" + +[[plugins]] +package = "@netlify/plugin-nextjs" \ No newline at end of file diff --git a/InvestmentDAO/package-lock.json b/InvestmentDAO/package-lock.json new file mode 100644 index 00000000..e87e0cd7 --- /dev/null +++ b/InvestmentDAO/package-lock.json @@ -0,0 +1,1486 @@ +{ + "name": "@celo/celo-composer", + "version": "1.0.8", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "@celo/celo-composer", + "version": "1.0.8", + "license": "MIT", + "workspaces": [ + "bin/*" + ], + "dependencies": { + "chalk": "4.1.2", + "commander": "^9.4.0", + "fs-extra": "^10.1.0", + "inquirer": "^8.2.4", + "node-emoji": "^1.11.0", + "ora": "5.4.1", + "shelljs": "^0.8.5", + "yargs": "17.5.1" + }, + "bin": { + "celo-composer": "bin/index.js" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", + "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/commander": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", + "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/inquirer": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.5.tgz", + "integrity": "sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "node_modules/node-emoji": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "dependencies": { + "lodash": "^4.17.21" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/rxjs": { + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz", + "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.5.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", + "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + } + }, + "dependencies": { + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "requires": { + "type-fest": "^0.21.3" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-spinners": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", + "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==" + }, + "cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==" + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==" + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "commander": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", + "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "requires": { + "clone": "^1.0.2" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "inquirer": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.5.tgz", + "integrity": "sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==", + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^7.0.0" + } + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "requires": { + "has": "^1.0.3" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==" + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "node-emoji": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "requires": { + "lodash": "^4.17.21" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "requires": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "requires": { + "resolve": "^1.1.6" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" + }, + "rxjs": { + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz", + "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==", + "requires": { + "tslib": "^2.1.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "requires": { + "defaults": "^1.0.3" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yargs": { + "version": "17.5.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", + "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + } + } +} diff --git a/InvestmentDAO/package.json b/InvestmentDAO/package.json new file mode 100644 index 00000000..3b1ff8ae --- /dev/null +++ b/InvestmentDAO/package.json @@ -0,0 +1,39 @@ +{ + "name": "@celo/celo-composer", + "version": "1.0.8", + "description": "Get started building dApps on Celo", + "repository": { + "type": "git", + "url": "git+https://github.com/celo-org/celo-composer.git" + }, + "author": "celo", + "license": "MIT", + "bugs": { + "url": "https://github.com/celo-org/celo-composer/issues" + }, + "homepage": "https://github.com/celo-org/celo-composer/blob/main/README.md", + "workspaces": [ + "bin/*" + ], + "dependencies": { + "chalk": "4.1.2", + "commander": "^9.4.0", + "fs-extra": "^10.1.0", + "inquirer": "^8.2.4", + "node-emoji": "^1.11.0", + "ora": "5.4.1", + "shelljs": "^0.8.5", + "yargs": "17.5.1" + }, + "main": "bin/index.js", + "keywords": [ + "celo-composer", + "celo" + ], + "bin": { + "celo-composer": "bin/index.js" + }, + "files": [ + "bin" + ] +} diff --git a/InvestmentDAO/packages/hardhat/.envexample b/InvestmentDAO/packages/hardhat/.envexample new file mode 100644 index 00000000..389ae223 --- /dev/null +++ b/InvestmentDAO/packages/hardhat/.envexample @@ -0,0 +1,3 @@ +MNEMONIC="" +PRIVATE_KEY="" +CELOSCAN_API_KEY="" \ No newline at end of file diff --git a/InvestmentDAO/packages/hardhat/.gitignore b/InvestmentDAO/packages/hardhat/.gitignore new file mode 100644 index 00000000..e36f7e18 --- /dev/null +++ b/InvestmentDAO/packages/hardhat/.gitignore @@ -0,0 +1,13 @@ +node_modules +.env +coverage +coverage.json +typechain + +#Hardhat files +cache +artifacts +deployments + +# hardhat typechain generated files +types/ diff --git a/InvestmentDAO/packages/hardhat/.npmrc b/InvestmentDAO/packages/hardhat/.npmrc new file mode 100644 index 00000000..4fd02195 --- /dev/null +++ b/InvestmentDAO/packages/hardhat/.npmrc @@ -0,0 +1 @@ +engine-strict=true \ No newline at end of file diff --git a/InvestmentDAO/packages/hardhat/README.md b/InvestmentDAO/packages/hardhat/README.md new file mode 100644 index 00000000..7a9cf6ba --- /dev/null +++ b/InvestmentDAO/packages/hardhat/README.md @@ -0,0 +1 @@ +# About project \ No newline at end of file diff --git a/InvestmentDAO/packages/hardhat/account_keys.json b/InvestmentDAO/packages/hardhat/account_keys.json new file mode 100644 index 00000000..03627dd9 --- /dev/null +++ b/InvestmentDAO/packages/hardhat/account_keys.json @@ -0,0 +1 @@ +{"addresses":{"0x5409ed021d9299bf6814279a6a1411a7e866a631":"0x5409ed021d9299bf6814279a6a1411a7e866a631","0x6ecbe1db9ef729cbe972c83fb886247691fb6beb":"0x6ecbe1db9ef729cbe972c83fb886247691fb6beb","0xe36ea790bc9d7ab70c55260c66d52b1eca985f84":"0xe36ea790bc9d7ab70c55260c66d52b1eca985f84","0xe834ec434daba538cd1b9fe1582052b880bd7e63":"0xe834ec434daba538cd1b9fe1582052b880bd7e63","0x78dc5d2d739606d31509c31d654056a45185ecb6":"0x78dc5d2d739606d31509c31d654056a45185ecb6","0xa8dda8d7f5310e4a9e24f8eba77e091ac264f872":"0xa8dda8d7f5310e4a9e24f8eba77e091ac264f872","0x06cef8e666768cc40cc78cf93d9611019ddcb628":"0x06cef8e666768cc40cc78cf93d9611019ddcb628","0x4404ac8bd8f9618d27ad2f1485aa1b2cfd82482d":"0x4404ac8bd8f9618d27ad2f1485aa1b2cfd82482d","0x7457d5e02197480db681d3fdf256c7aca21bdc12":"0x7457d5e02197480db681d3fdf256c7aca21bdc12","0x91c987bf62d25945db517bdaa840a6c661374402":"0x91c987bf62d25945db517bdaa840a6c661374402"},"private_keys":{"0x5409ed021d9299bf6814279a6a1411a7e866a631":"0xf2f48ee19680706196e2e339e5da3491186e0c4c5030670656b0e0164837257d","0x6ecbe1db9ef729cbe972c83fb886247691fb6beb":"0x5d862464fe9303452126c8bc94274b8c5f9874cbd219789b3eb2128075a76f72","0xe36ea790bc9d7ab70c55260c66d52b1eca985f84":"0xdf02719c4df8b9b8ac7f551fcb5d9ef48fa27eef7a66453879f4d8fdc6e78fb1","0xe834ec434daba538cd1b9fe1582052b880bd7e63":"0xff12e391b79415e941a94de3bf3a9aee577aed0731e297d5cfa0b8a1e02fa1d0","0x78dc5d2d739606d31509c31d654056a45185ecb6":"0x752dd9cf65e68cfaba7d60225cbdbc1f4729dd5e5507def72815ed0d8abc6249","0xa8dda8d7f5310e4a9e24f8eba77e091ac264f872":"0xefb595a0178eb79a8df953f87c5148402a224cdf725e88c0146727c6aceadccd","0x06cef8e666768cc40cc78cf93d9611019ddcb628":"0x83c6d2cc5ddcf9711a6d59b417dc20eb48afd58d45290099e5987e3d768f328f","0x4404ac8bd8f9618d27ad2f1485aa1b2cfd82482d":"0xbb2d3f7c9583780a7d3904a2f55d792707c345f21de1bacb2d389934d82796b2","0x7457d5e02197480db681d3fdf256c7aca21bdc12":"0xb2fd4d29c1390b71b8795ae81196bfd60293adf99f9d32a0aff06288fcdac55f","0x91c987bf62d25945db517bdaa840a6c661374402":"0x23cb7121166b9a2f93ae0b7c05bde02eae50d64449b2cbb42bc84e9d38d6cc89"}} \ No newline at end of file diff --git a/InvestmentDAO/packages/hardhat/contracts/InvestmentDAO.sol b/InvestmentDAO/packages/hardhat/contracts/InvestmentDAO.sol new file mode 100644 index 00000000..ac23a5ac --- /dev/null +++ b/InvestmentDAO/packages/hardhat/contracts/InvestmentDAO.sol @@ -0,0 +1,307 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; +import "./NFTMarketPlace.sol"; +import "./Token.sol"; + +contract InvestmentDAO { + struct Proposal { + uint256 id; + address creator; + string title; + string description; + uint256 startTime; + uint256 endTime; + uint256 yesVotes; + uint256 noVotes; + bool executed; + } + + struct Voter { + uint256 proposerIndex; + address voterAddress; + uint256 voteChoice; + } + + struct Member { + address memberAddress; + uint256 tokenBalance; + } + + enum ProposalStatus { Pending, Active, Closed } + + address payable owner; + IERC20 public token; + ERC1155 public nft; + Proposal[] public proposals; + Voter[] public voters; + Member[] public members; + address[] whiteList; + address[] blacklist; + uint256 public proposalCount; + uint256 public votingPeriod; + uint256 public memberCount; + + mapping(address => mapping(uint256 => bool)) hasVoted; + mapping(address => Member) public membersMap; + mapping(address => bool) public whiteListed; + mapping (address => bool) public blackListed; + + event AddMember(address memberAddress, uint256 tokenBalance); + event ProposalCreated(uint256 proposalId, string title, string description, uint256 startTime, uint256 endTime); + event Voted(uint256 proposalId, address voter, uint256 choice, uint256 yesVotes, uint256 noVotes); + + NFTMarketplace private nftMarketPlace; + Token private mtToken; + + constructor(address _tokenAddress, address _nft) { + token = IERC20(_tokenAddress); + nft = ERC1155(_nft); + mtToken = new Token(); + nftMarketPlace = new NFTMarketplace(); + owner = payable(msg.sender); + membersMap[owner].memberAddress = payable(msg.sender); + whiteListed[owner] = true; + // members.push(Member(msg.sender, token.balanceOf(msg.sender))); + } + + bool internal locked; + + modifier noReentrant() { + require(!locked, "No re-entrancy"); + locked = true; + _; + locked = false; + } + + modifier onlyOwner { + msg.sender == owner; + _; + } + + modifier onlyWhitListed { + require(!whiteListed[msg.sender], "Already whiteListed"); + whiteListed[msg.sender] = true; + _; + whiteListed[msg.sender] = false; + } + + modifier onlyBlacklist{ + require(!whiteListed[msg.sender], "Already whiteListed"); + whiteListed[msg.sender] = true; + _; + whiteListed[msg.sender] = false; + } + + modifier nftHolderOnly(uint256 tokenId) { + require(nft.balanceOf(msg.sender, tokenId) > 0, "You don't have the NFT"); + _; + } + + modifier onlyTokenHolders() { + require(token.balanceOf(msg.sender) > 0, "You don't have the dao token"); + _; + } + + modifier activeProposalOnly(uint256 _proposalIndex) { + require(proposals[_proposalIndex].endTime > block.timestamp, "Proposal expired"); + _; + } + + modifier OnlyExecutionPeriod(uint256 _proposalIndex) { + //execution should be done after a day to the close of the proposal + require(proposals[_proposalIndex].endTime + 1 days > block.timestamp, "Not yet execution period"); + _; + } + + modifier votingOngoing(uint256 _startTime, uint256 _endTime) { + require(block.timestamp >= _startTime, "Voting has not started yet"); + require(block.timestamp <= _endTime, "Voting has already ended"); + _; + } + + modifier onlyMember(){ + require(membersMap[msg.sender].memberAddress == msg.sender, "You are not yet a member of this community"); + _; + } + + function addMember() public onlyTokenHolders { + require(msg.sender != address(0), "Invalid address"); + + // Check if member already exists + require(membersMap[msg.sender].memberAddress == address(0), "Already a member"); + + // Add new member + Member storage member = membersMap[msg.sender]; + member.memberAddress = msg.sender; + member.tokenBalance = token.balanceOf(msg.sender); + members.push(Member(msg.sender, token.balanceOf(msg.sender))); + memberCount++; + emit AddMember(msg.sender, token.balanceOf(msg.sender)); + } + + function createProposal(string calldata _title, string calldata _description, uint256 _startTime, uint256 _endTime) external onlyMember { + require(token.balanceOf(msg.sender) > 100 ether, "You must hold up to 100 tokens to create a proposal"); + require(_startTime > block.timestamp, "Proposal start time must be in the future"); + require(_endTime > _startTime, "Proposal end time must be after start time"); + require(membersMap[msg.sender].memberAddress == msg.sender, "You are not yet a member of this community"); + proposals.push(Proposal(proposalCount, msg.sender, _title, _description, _startTime, _endTime, 0, 0, false)); + proposalCount++; + emit ProposalCreated(proposals.length - 1, _title, _description, _startTime, _endTime); + } + + function vote(uint256 _proposalIndex, uint256 _choice) external onlyMember votingOngoing(proposals[_proposalIndex].startTime, proposals[_proposalIndex].endTime){ + require(_proposalIndex < proposalCount, "Invalid proposal index"); + require(!hasVoted[msg.sender][_proposalIndex], "You have already voted for this proposal"); + require(token.balanceOf(msg.sender) > 50 ether, "You must hold up to 50 tokens to vote"); + require(membersMap[msg.sender].memberAddress == msg.sender, "You are not yet a member of this community"); + uint256 voterMtTokenBalance = token.balanceOf(msg.sender); + + if (_choice == 1) { + proposals[_proposalIndex].yesVotes += voterMtTokenBalance; + } else { + proposals[_proposalIndex].noVotes += voterMtTokenBalance; + } + voters.push(Voter(_proposalIndex, msg.sender, _choice)); + hasVoted[msg.sender][_proposalIndex] = true; // Record the vote of the user for the current proposal + + emit Voted(_proposalIndex, msg.sender, _choice, proposals[_proposalIndex].yesVotes, proposals[_proposalIndex].noVotes); + + } + + function getProposal(uint256 _proposalIndex) external view returns ( + address creator, + string memory title, + string memory description, + uint256 startTime, + uint256 endTime, + uint256 yesVotes, + uint256 noVotes, + bool executed + ) { + require(_proposalIndex < proposalCount, "Invalid proposal index"); + Proposal memory proposal = proposals[_proposalIndex]; + return ( + proposal.creator, + proposal.title, + proposal.description, + proposal.startTime, + proposal.endTime, + proposal.yesVotes, + proposal.noVotes, + proposal.executed + ); + } + + function executeProposal(uint256 _proposalIndex, uint256 _nftId) payable external onlyOwner OnlyExecutionPeriod(_proposalIndex) noReentrant { + require(_proposalIndex < proposalCount, "Invalid proposal index"); + require(proposals[_proposalIndex].executed, "Proposal already executed"); + Proposal memory proposal = proposals[_proposalIndex]; + require(block.timestamp >= votingPeriod, "Voting period has not ended yet"); + + if (proposal.yesVotes > proposal.noVotes) { + // Execute the proposal if it has more yes votes + // (e.g., transfer funds, call external contract, etc.) + // ... + //transfer fund to creator + // (bool sent, bytes memory data) = proposal.creator.call{value: msg.value}(""); + require(address(this).balance > msg.value, "insufficient balance"); + nftMarketPlace.buy(_nftId); + proposal.executed = true; + } else { + // Reject the proposal if it has more no votes + // ... + } + } + + function stakeToken(uint256 amount) external noReentrant { + require(membersMap[msg.sender].memberAddress == msg.sender, "You are not yet a member of this DAO"); + require(token.balanceOf(msg.sender) > 0 ether, "Insufficient token balance"); + payable(address(this)).transfer(amount); + } + + function removeProposal(uint256 proposalId) external returns (Proposal memory) { + require(proposalId < proposalCount, "Invalid proposal index"); + require(proposals[proposalId].creator == msg.sender, "Only the creator of the proposal can remove the proposal"); + require(proposals.length > 0 ether, "Proposal is empty"); + + // Remove and return the last item from the array + Proposal storage lastItem = proposals[proposals.length - 1]; + proposals.pop(); + + return lastItem; + // Update the proposalCount by decrementing it + } + function removeMember(address _memberAddress) external onlyOwner noReentrant { + require(membersMap[_memberAddress].memberAddress == _memberAddress, "Member does not exist"); + if(token.balanceOf(_memberAddress) > 0){ + require(token.balanceOf(address(this)) > 0, "Insufficient token balance"); + payable(address(this)).transfer(token.balanceOf(_memberAddress)/100); + members[members.length - 1]; + members.pop(); + } + } + + function buyToken(address _receiver, uint256 amount) external noReentrant { + require(token.balanceOf(address(this)) > amount, "Insufficient token balance"); + // current mt token price. For every 100 MT token buyer pays 1 CELO + token.transferFrom(address(this), _receiver, amount); + payable(address(this)).transfer(amount/100 ether); + } + + function buyNFT(uint256 _tokenId) payable external noReentrant { + require(msg.sender.balance > 0, "Insufficient balance"); + nftMarketPlace.buy(_tokenId); + } + + function getAllProposals() public view returns(Proposal[] memory){ + return proposals; + } + + function getVoters() public view returns(Voter[] memory){ + return voters; + } + + function getMembers() public view returns(Member[] memory){ + return members; + } + + function getTokenBalance(address _address) public view returns(uint256) { + return token.balanceOf(_address); + } + + function getProposalStatus(uint256 _proposalIndex) public view returns (uint256) { + ProposalStatus status; + // uint256 _status = 0; + if (block.timestamp < proposals[_proposalIndex].startTime) { + //proposal is pending + status = ProposalStatus.Pending; + } else if (block.timestamp <= proposals[_proposalIndex].endTime) { + //proposal is active + status = ProposalStatus.Active; + } else if (block.timestamp > proposals[_proposalIndex].endTime) { + //proposal voting has ended + status = ProposalStatus.Closed; + } + return uint256(status); + } + + function getMemberVoteStatus(uint256 proposalId, address _address ) public view returns(bool){ + return hasVoted[_address][proposalId]; + } + + function getMemberStatus(address _address) public view returns(bool){ + return membersMap[_address].memberAddress == _address; + } + + function getTreasuryBalance() public view returns(uint256){ + return address(this).balance; + } + + function getDAOATokenBalance() public view returns(uint256) { + return token.balanceOf(address(this)); + } +} \ No newline at end of file diff --git a/InvestmentDAO/packages/hardhat/contracts/NFTMarketPlace.sol b/InvestmentDAO/packages/hardhat/contracts/NFTMarketPlace.sol new file mode 100644 index 00000000..5dd6c2cf --- /dev/null +++ b/InvestmentDAO/packages/hardhat/contracts/NFTMarketPlace.sol @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; +import "@openzeppelin/contracts/utils/Counters.sol"; + +contract NFTMarketplace is ERC1155 { + using Counters for Counters.Counter; + + uint256 private constant COLLECTIONS_COUNT = 10; + uint256 private constant PRICE_PER_NFT = 1 ether; + + mapping(uint256 => address) private collectionOwners; + Counters.Counter private collectionIds; + + constructor() ERC1155("https://bafybeig7dmxlomwj77frr7froply7bkfy2gfxlmay2lxauba25fawt2yxy.ipfs.nftstorage.link/{id}.json") { + // Mint 100 NFT collections + for (uint256 i = 1; i <= COLLECTIONS_COUNT; i++) { + _mint(msg.sender, i, 1, ""); + collectionOwners[i] = msg.sender; + collectionIds.increment(); + } + } + + function buy(uint256 collectionId) external payable { + require(collectionId > 0 && collectionId <= COLLECTIONS_COUNT, "Invalid collection ID"); + require(collectionOwners[collectionId] != address(0), "Collection does not exist"); + require(msg.value == PRICE_PER_NFT, "Incorrect payment amount"); + + // Transfer the NFT to the caller + safeTransferFrom(collectionOwners[collectionId], msg.sender, collectionId, 1, ""); + + // Transfer payment to the collection owner + payable(collectionOwners[collectionId]).transfer(msg.value); + + // Update the collection owner + collectionOwners[collectionId] = msg.sender; + } +} \ No newline at end of file diff --git a/InvestmentDAO/packages/hardhat/contracts/Token.sol b/InvestmentDAO/packages/hardhat/contracts/Token.sol new file mode 100644 index 00000000..38f519dc --- /dev/null +++ b/InvestmentDAO/packages/hardhat/contracts/Token.sol @@ -0,0 +1,71 @@ +// SPDX-License-Identifier:GPL-3.0 + +pragma solidity ^0.8.0; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +contract Token is IERC20 { + + string public name; + string public symbol; + uint8 public decimals; + uint256 private _totalSupply; + + mapping(address => uint256) private _balances; + mapping(address => mapping(address => uint256)) private _allowances; + + constructor() { + _totalSupply = 200000000000000000000000; + _balances[msg.sender] = _totalSupply; + name = "MyToken"; + symbol = "MT"; + decimals = 18; + + emit Transfer(address(0), msg.sender, _totalSupply); + } + + function totalSupply() public view override returns (uint256) { + return _totalSupply; + } + + function balanceOf(address account) public view override returns (uint256) { + return _balances[account]; + } + + function transfer(address recipient, uint256 amount) public override returns (bool) { + require(recipient != address(0), "ERC20: transfer to the zero address"); + require(_balances[msg.sender] >= amount, "ERC20: transfer amount exceeds balance"); + + _balances[msg.sender] -= amount; + _balances[recipient] += amount; + + emit Transfer(msg.sender, recipient, amount); + + return true; + } + + function allowance(address owner, address spender) public view override returns (uint256) { + return _allowances[owner][spender]; + } + + function approve(address spender, uint256 amount) public override returns (bool) { + _allowances[msg.sender][spender] = amount; + + emit Approval(msg.sender, spender, amount); + + return true; + } + + function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) { + require(recipient != address(0), "ERC20: transfer to the zero address"); + require(_balances[sender] >= amount, "ERC20: transfer amount exceeds balance"); + require(_allowances[sender][msg.sender] >= amount, "ERC20: transfer amount exceeds allowance"); + + _balances[sender] -= amount; + _balances[recipient] += amount; + _allowances[sender][msg.sender] -= amount; + + emit Transfer(sender, recipient, amount); + + return true; + } +} diff --git a/InvestmentDAO/packages/hardhat/deploy/00-deploy.js b/InvestmentDAO/packages/hardhat/deploy/00-deploy.js new file mode 100644 index 00000000..b2364a01 --- /dev/null +++ b/InvestmentDAO/packages/hardhat/deploy/00-deploy.js @@ -0,0 +1,61 @@ +// deploy/00_deploy_my_contract.js + +// const { ethers } = require("hardhat"); + +// const sleep = (ms) => +// new Promise((r) => +// setTimeout(() => { +// console.log(`waited for ${(ms / 1000).toFixed(3)} seconds`); +// r(); +// }, ms) +// ); + +module.exports = async ({ getNamedAccounts, deployments }) => { + const { deploy } = deployments; + const { deployer } = await getNamedAccounts(); + + await deploy("TokenGatedDao", { + from: deployer, + log: true, + }); + + await deploy("Token", { + // Learn more about args here: https://www.npmjs.com/package/hardhat-deploy#deploymentsdeploy + from: deployer, + args: [ "Hello"], + log: true, + }); + + + // Getting a previously deployed contract + // const Greeter = new ethers.Contract("Greeter", deployer); + + // await Greeter.setGreeting("Hello Celo!"); + + /* + // If you want to send value to an address from the deployer + + const deployerWallet = ethers.provider.getSigner() + await deployerWallet.sendTransaction({ + to: "0x34aA3F359A9D614239015126635CE7732c18fDF3", + value: ethers.utils.parseEther("0.001") + }) + */ + + /* + //If you want to send some CELO to a contract on deploy (make your constructor payable!) + const yourContract = await deploy("YourContract", [], { + value: ethers.utils.parseEther("0.05") + }); + */ + + /* + //If you want to link a library into your contract: + // reference: https://github.com/austintgriffith/scaffold-eth/blob/using-libraries-example/packages/hardhat/scripts/deploy.js#L19 + const yourContract = await deploy("YourContract", [], {}, { + LibraryName: **LibraryAddress** + }); + */ +}; + +module.exports.tags = ["TokenGatedDao", "Token"]; diff --git a/InvestmentDAO/packages/hardhat/hardhat.config.js b/InvestmentDAO/packages/hardhat/hardhat.config.js new file mode 100644 index 00000000..0f1a0e05 --- /dev/null +++ b/InvestmentDAO/packages/hardhat/hardhat.config.js @@ -0,0 +1,98 @@ +require("@nomicfoundation/hardhat-chai-matchers"); +require("dotenv").config({ path: ".env" }); +require("hardhat-deploy"); +const { task } = require("hardhat/config"); +require("@nomiclabs/hardhat-ethers"); +require("@typechain/hardhat"); +require("hardhat-celo"); + +const defaultNetwork = "alfajores"; +const mnemonicPath = "m/44'/52752'/0'/0"; // derivation path used by Celo + +// This is the mnemonic used by celo-devchain +const DEVCHAIN_MNEMONIC = + "concert load couple harbor equip island argue ramp clarify fence smart topic"; + +// You need to export an object to set up your config +// Go to https://hardhat.org/config/ to learn more + +/** + * @type import('hardhat/config').HardhatUserConfig + */ +module.exports = { + // defaultNetwork, + networks: { + localhost: { + url: "http://127.0.0.1:8545", + accounts: { + mnemonic: DEVCHAIN_MNEMONIC, + }, + }, + alfajores: { + url: "https://alfajores-forno.celo-testnet.org", + accounts: [process.env.PRIVATE_KEY], + chainId: 44787, + }, + celo: { + url: "https://forno.celo.org", + accounts: [process.env.PRIVATE_KEY], + chainId: 42220, + }, + }, + etherscan: { + apiKey: { + alfajores: process.env.CELOSCAN_API_KEY, + celo: process.env.CELOSCAN_API_KEY, + }, + }, + solidity: { + version: "0.8.17", + }, + namedAccounts: { + deployer: 0, + }, + typechain: { + outDir: "types", + target: "web3-v1", + alwaysGenerateOverloads: false, // should overloads with full signatures like deposit(uint256) be generated always, even if there are no overloads? + externalArtifacts: ["externalArtifacts/*.json"], // optional array of glob patterns with external artifacts to process (for example external libs from node_modules) + }, +}; + +// This is a sample Hardhat task. To learn how to create your own go to +// https://hardhat.org/guides/create-task.html + +task("accounts", "Prints the list of accounts", async (taskArgs, hre) => { + const accounts = await hre.ethers.getSigners(); + + for (const account of accounts) { + console.log(account.address); + } +}); + +task( + "devchain-keys", + "Prints the private keys associated with the devchain", + async (taskArgs, hre) => { + const accounts = await hre.ethers.getSigners(); + const hdNode = hre.ethers.utils.HDNode.fromMnemonic(DEVCHAIN_MNEMONIC); + for (let i = 0; i < accounts.length; i++) { + const account = hdNode.derivePath(`m/44'/60'/0'/0/${i}`); + console.log( + `Account ${i}\nAddress: ${account.address}\nKey: ${account.privateKey}` + ); + } + } +); + +task("create-account", "Prints a new private key", async (taskArgs, hre) => { + const wallet = new hre.ethers.Wallet.createRandom(); + console.log(`PRIVATE_KEY="` + wallet.privateKey + `"`); + console.log(); + console.log(`Your account address: `, wallet.address); +}); + +task("print-account", "Prints the address of the account", () => { + const wallet = new hre.ethers.Wallet(process.env.PRIVATE_KEY); + console.log(`Account: `, wallet.address); +}); diff --git a/InvestmentDAO/packages/hardhat/images/generateImages.js b/InvestmentDAO/packages/hardhat/images/generateImages.js new file mode 100644 index 00000000..c9c0590c --- /dev/null +++ b/InvestmentDAO/packages/hardhat/images/generateImages.js @@ -0,0 +1,67 @@ +const { createCanvas, loadImage } = require('canvas'); +const fs = require('fs'); + +// Set the canvas size +const canvasSize = 500; +const profileCount = 100; + +async function generateProfilePictures() { + // Create the canvas + const canvas = createCanvas(canvasSize, canvasSize); + const context = canvas.getContext('2d'); + + // Generate profile pictures + for (let i = 0; i < profileCount; i++) { + await generateProfilePicture(context); + const buffer = canvas.toBuffer('image/png'); + fs.writeFileSync(`profile_${i}.png`, buffer); + } +} + +async function generateProfilePicture(context) { + // Set the background color + context.fillStyle = getRandomColor(); + context.fillRect(0, 0, canvasSize, canvasSize); + + // Generate shapes and patterns + for (let i = 0; i < 10; i++) { + const shapeType = getRandomShapeType(); + const shapeSize = getRandomShapeSize(); + const shapeX = getRandomPosition(); + const shapeY = getRandomPosition(); + const shapeColor = getRandomColor(); + + // Draw the shape + context.fillStyle = shapeColor; + if (shapeType === 'circle') { + context.beginPath(); + context.arc(shapeX, shapeY, shapeSize, 0, Math.PI * 2, false); + context.closePath(); + context.fill(); + } else if (shapeType === 'rectangle') { + context.fillRect(shapeX, shapeY, shapeSize, shapeSize); + } + } +} + +function getRandomShapeType() { + const shapeTypes = ['circle', 'rectangle']; + return shapeTypes[Math.floor(Math.random() * shapeTypes.length)]; +} + +function getRandomShapeSize() { + return Math.random() * (150 - 50) + 50; +} + +function getRandomPosition() { + return Math.random() * canvasSize; +} + +function getRandomColor() { + const r = Math.floor(Math.random() * 256); + const g = Math.floor(Math.random() * 256); + const b = Math.floor(Math.random() * 256); + return `rgb(${r}, ${g}, ${b})`; +} + +generateProfilePictures(); \ No newline at end of file diff --git a/InvestmentDAO/packages/hardhat/images/metadata/0.json b/InvestmentDAO/packages/hardhat/images/metadata/0.json new file mode 100644 index 00000000..401c59d4 --- /dev/null +++ b/InvestmentDAO/packages/hardhat/images/metadata/0.json @@ -0,0 +1,5 @@ +{ + "image": "https://bafybeibf44walvy3lw6ju5j62wvpgxaruplaijyptd5hvg3ygiht5udlqq.ipfs.nftstorage.link/profile_0.png", + "name": "DaoAnalyzer 0", + "description": "Your DaoAnalyzer Ticket" +} \ No newline at end of file diff --git a/InvestmentDAO/packages/hardhat/images/metadata/1.json b/InvestmentDAO/packages/hardhat/images/metadata/1.json new file mode 100644 index 00000000..36ced6c9 --- /dev/null +++ b/InvestmentDAO/packages/hardhat/images/metadata/1.json @@ -0,0 +1,5 @@ +{ + "image": "https://bafybeibf44walvy3lw6ju5j62wvpgxaruplaijyptd5hvg3ygiht5udlqq.ipfs.nftstorage.link/profile_1.png", + "name": "DaoAnalyzer 1", + "description": "Your DaoAnalyzer Ticket" +} \ No newline at end of file diff --git a/InvestmentDAO/packages/hardhat/images/metadata/2.json b/InvestmentDAO/packages/hardhat/images/metadata/2.json new file mode 100644 index 00000000..8c3bb27f --- /dev/null +++ b/InvestmentDAO/packages/hardhat/images/metadata/2.json @@ -0,0 +1,5 @@ +{ + "image": "https://bafybeibf44walvy3lw6ju5j62wvpgxaruplaijyptd5hvg3ygiht5udlqq.ipfs.nftstorage.link/profile_2.png", + "name": "DaoAnalyzer 2", + "description": "Your DaoAnalyzer Ticket" +} \ No newline at end of file diff --git a/InvestmentDAO/packages/hardhat/images/metadata/3.json b/InvestmentDAO/packages/hardhat/images/metadata/3.json new file mode 100644 index 00000000..41a4ad47 --- /dev/null +++ b/InvestmentDAO/packages/hardhat/images/metadata/3.json @@ -0,0 +1,5 @@ +{ + "image": "https://bafybeibf44walvy3lw6ju5j62wvpgxaruplaijyptd5hvg3ygiht5udlqq.ipfs.nftstorage.link/profile_3.png", + "name": "DaoAnalyzer 3", + "description": "Your DaoAnalyzer Ticket" +} \ No newline at end of file diff --git a/InvestmentDAO/packages/hardhat/images/metadata/4.json b/InvestmentDAO/packages/hardhat/images/metadata/4.json new file mode 100644 index 00000000..a4c306d7 --- /dev/null +++ b/InvestmentDAO/packages/hardhat/images/metadata/4.json @@ -0,0 +1,5 @@ +{ + "image": "https://bafybeibf44walvy3lw6ju5j62wvpgxaruplaijyptd5hvg3ygiht5udlqq.ipfs.nftstorage.link/profile_4.png", + "name": "DaoAnalyzer 4", + "description": "Your DaoAnalyzer Ticket" +} \ No newline at end of file diff --git a/InvestmentDAO/packages/hardhat/images/metadata/5.json b/InvestmentDAO/packages/hardhat/images/metadata/5.json new file mode 100644 index 00000000..54698b87 --- /dev/null +++ b/InvestmentDAO/packages/hardhat/images/metadata/5.json @@ -0,0 +1,5 @@ +{ + "image": "https://bafybeibf44walvy3lw6ju5j62wvpgxaruplaijyptd5hvg3ygiht5udlqq.ipfs.nftstorage.link/profile_5.png", + "name": "DaoAnalyzer 5", + "description": "Your DaoAnalyzer Ticket" +} \ No newline at end of file diff --git a/InvestmentDAO/packages/hardhat/images/metadata/6.json b/InvestmentDAO/packages/hardhat/images/metadata/6.json new file mode 100644 index 00000000..2ec7f3d7 --- /dev/null +++ b/InvestmentDAO/packages/hardhat/images/metadata/6.json @@ -0,0 +1,5 @@ +{ + "image": "https://bafybeibf44walvy3lw6ju5j62wvpgxaruplaijyptd5hvg3ygiht5udlqq.ipfs.nftstorage.link/profile_6.png", + "name": "DaoAnalyzer 6", + "description": "Your DaoAnalyzer Ticket" +} \ No newline at end of file diff --git a/InvestmentDAO/packages/hardhat/images/metadata/7.json b/InvestmentDAO/packages/hardhat/images/metadata/7.json new file mode 100644 index 00000000..62f5a351 --- /dev/null +++ b/InvestmentDAO/packages/hardhat/images/metadata/7.json @@ -0,0 +1,5 @@ +{ + "image": "https://bafybeibf44walvy3lw6ju5j62wvpgxaruplaijyptd5hvg3ygiht5udlqq.ipfs.nftstorage.link/profile_7.png", + "name": "DaoAnalyzer 7", + "description": "Your DaoAnalyzer Ticket" +} \ No newline at end of file diff --git a/InvestmentDAO/packages/hardhat/images/metadata/8.json b/InvestmentDAO/packages/hardhat/images/metadata/8.json new file mode 100644 index 00000000..a19157da --- /dev/null +++ b/InvestmentDAO/packages/hardhat/images/metadata/8.json @@ -0,0 +1,5 @@ +{ + "image": "https://bafybeibf44walvy3lw6ju5j62wvpgxaruplaijyptd5hvg3ygiht5udlqq.ipfs.nftstorage.link/profile_8.png", + "name": "DaoAnalyzer 8", + "description": "Your DaoAnalyzer Ticket" +} \ No newline at end of file diff --git a/InvestmentDAO/packages/hardhat/images/metadata/9.json b/InvestmentDAO/packages/hardhat/images/metadata/9.json new file mode 100644 index 00000000..d3be4c3e --- /dev/null +++ b/InvestmentDAO/packages/hardhat/images/metadata/9.json @@ -0,0 +1,5 @@ +{ + "image": "https://bafybeibf44walvy3lw6ju5j62wvpgxaruplaijyptd5hvg3ygiht5udlqq.ipfs.nftstorage.link/profile_9.png", + "name": "DaoAnalyzer 9", + "description": "Your DaoAnalyzer Ticket" +} \ No newline at end of file diff --git a/InvestmentDAO/packages/hardhat/package.json b/InvestmentDAO/packages/hardhat/package.json new file mode 100644 index 00000000..56b22b83 --- /dev/null +++ b/InvestmentDAO/packages/hardhat/package.json @@ -0,0 +1,59 @@ +{ + "name": "@TokenGatedDao/hardhat", + "version": "1.0.0", + "license": "MIT", + "scripts": { + "test": "hardhat test", + "test-local": "hardhat test --network hardhat", + "accounts": "hardhat accounts", + "devchain": "npx celo-devchain --port 8545", + "deploy": "hardhat deploy --export-all deployments/hardhat_contracts.json", + "deploy-reset-watch": "hardhat deploy --reset --watch --export-all deployments/hardhat_contracts.json", + "watch": "node scripts/watch.js", + "fork-mainnet": "ganache --fork.url https://forno.celo.org --wallet.mnemonic 'concert load couple harbor equip island argue ramp clarify fence smart topic' --wallet.accountKeysPath './account_keys.json' --gasPrice 875000000" + }, + "devDependencies": { + "@nomicfoundation/hardhat-chai-matchers": "^1.0.0", + "@nomicfoundation/hardhat-network-helpers": "^1.0.0", + "@nomiclabs/hardhat-ethers": "^2.2.1", + "@nomiclabs/hardhat-etherscan": "^3.0.0", + "@terminal-fi/celo-devchain": "^4.0.1", + "@typechain/ethers-v5": "^10.1.0", + "@typechain/hardhat": "^6.1.3", + "@typechain/web3-v1": "^6.0.1", + "@types/mocha": "^9.1.0", + "bip39": "^3.0.4", + "chai": "^4.3.6", + "dotenv": "^16.0.3", + "ethereumjs-util": "^7.1.5", + "ethereumjs-wallet": "^1.0.2", + "ethers": "^5.7.2", + "hardhat": "^2.14.0", + "hardhat-celo": "^0.0.3", + "hardhat-deploy": "^0.11.19", + "hardhat-gas-reporter": "^1.0.8", + "node-watch": "^0.7.3", + "solidity-coverage": "^0.7.21", + "ts-node": ">=8.0.0", + "typechain": "^8.1.0" + }, + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/providers": "^5.7.2", + "@redstone-finance/evm-connector": "^0.0.15", + "canvas": "^2.11.2", + "canvas-sketch": "^0.7.7", + "face-api.js": "^0.22.2", + "faker": "^6.6.6", + "fs": "^0.0.1-security", + "ganache": "^7.5.0", + "random-js": "^2.1.0", + "source-map-support": "^0.5.21", + "svg.js": "^2.7.1", + "typescript": "^4.8.4", + "web3": "^1.8.0", + "web3-core": "^1.8.0", + "web3-eth-contract": "^1.8.0" + } +} diff --git a/InvestmentDAO/packages/hardhat/scripts/deploy.js b/InvestmentDAO/packages/hardhat/scripts/deploy.js new file mode 100644 index 00000000..60ab2324 --- /dev/null +++ b/InvestmentDAO/packages/hardhat/scripts/deploy.js @@ -0,0 +1,32 @@ +// We require the Hardhat Runtime Environment explicitly here. This is optional +// but useful for running the script in a standalone fashion through `node