├── .gitignore
├── .vscode
└── settings.json
├── LICENSE
├── README.md
├── package.json
├── packages
├── app
│ ├── .env
│ ├── .env.production
│ ├── .gitignore
│ ├── README.md
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ ├── src
│ │ ├── abi
│ │ │ └── EntropyNFT.json
│ │ ├── components
│ │ │ ├── App.tsx
│ │ │ ├── Navigation
│ │ │ │ ├── NavBar.tsx
│ │ │ │ └── Navigation.jsx
│ │ │ ├── Pages
│ │ │ │ ├── Arts
│ │ │ │ │ └── Arts.tsx
│ │ │ │ ├── Compose
│ │ │ │ │ └── Compose.tsx
│ │ │ │ ├── Create
│ │ │ │ │ └── Create.tsx
│ │ │ │ └── Token
│ │ │ │ │ └── Token.tsx
│ │ │ ├── atoms
│ │ │ │ ├── ActivateWalletAlert.tsx
│ │ │ │ ├── Button.tsx
│ │ │ │ ├── Link.tsx
│ │ │ │ ├── MatrixDetails
│ │ │ │ │ └── MatrixDetails.tsx
│ │ │ │ ├── MatrixTile
│ │ │ │ │ └── MatrixTile.tsx
│ │ │ │ └── Toast
│ │ │ │ │ └── Toast.tsx
│ │ │ └── molecules
│ │ │ │ ├── Matrix
│ │ │ │ └── Matrix.tsx
│ │ │ │ └── SimpleMatrix
│ │ │ │ └── SimpleMatrix.tsx
│ │ ├── context
│ │ │ └── Entropy.tsx
│ │ ├── dummyData
│ │ │ └── tunes.ts
│ │ ├── icons
│ │ │ ├── and.svg
│ │ │ ├── clear.svg
│ │ │ ├── close.svg
│ │ │ ├── diamond.svg
│ │ │ ├── eye.svg
│ │ │ ├── mm-logo.svg
│ │ │ ├── or.svg
│ │ │ ├── pause.svg
│ │ │ ├── play.svg
│ │ │ └── xor.svg
│ │ ├── index.scss
│ │ ├── index.tsx
│ │ ├── lib
│ │ │ ├── EntropyNFT.ts
│ │ │ ├── connectors.ts
│ │ │ ├── intToBuffer.ts
│ │ │ └── square.ts
│ │ ├── react-app-env.d.ts
│ │ ├── styles
│ │ │ ├── index.scss
│ │ │ └── reset.scss
│ │ └── test
│ │ │ └── index.ts
│ ├── tsconfig.json
│ └── yarn.lock
├── contracts
│ ├── .env
│ ├── .env.production
│ ├── .gitignore
│ ├── contracts
│ │ ├── Entropy.sol
│ │ └── Migrations.sol
│ ├── migrations
│ │ ├── 1_initial_migration.js
│ │ └── 2_entropy_nft.js
│ ├── package.json
│ ├── test
│ │ ├── .gitkeep
│ │ └── entropy.js
│ ├── truffle-config.js
│ └── yarn.lock
└── metadata
│ ├── .gitignore
│ ├── package.json
│ ├── src
│ ├── api
│ │ ├── image.js
│ │ └── token.js
│ ├── generators
│ │ ├── emily.js
│ │ ├── geometric.js
│ │ ├── index.js
│ │ └── matrix.js
│ ├── lib
│ │ ├── extractParameters.js
│ │ └── square.js
│ └── vercel.json
│ └── yarn.lock
├── tsconfig.json
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 | *.lcov
24 |
25 | # nyc test coverage
26 | .nyc_output
27 |
28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29 | .grunt
30 |
31 | # Bower dependency directory (https://bower.io/)
32 | bower_components
33 |
34 | # node-waf configuration
35 | .lock-wscript
36 |
37 | # Compiled binary addons (https://nodejs.org/api/addons.html)
38 | build/Release
39 |
40 | # Dependency directories
41 | node_modules/
42 | jspm_packages/
43 |
44 | # TypeScript v1 declaration files
45 | typings/
46 |
47 | # TypeScript cache
48 | *.tsbuildinfo
49 |
50 | # Optional npm cache directory
51 | .npm
52 |
53 | # Optional eslint cache
54 | .eslintcache
55 |
56 | # Microbundle cache
57 | .rpt2_cache/
58 | .rts2_cache_cjs/
59 | .rts2_cache_es/
60 | .rts2_cache_umd/
61 |
62 | # Optional REPL history
63 | .node_repl_history
64 |
65 | # Output of 'npm pack'
66 | *.tgz
67 |
68 | # Yarn Integrity file
69 | .yarn-integrity
70 |
71 | # dotenv environment variables file
72 | .env.test
73 | .env.local
74 | # parcel-bundler cache (https://parceljs.org/)
75 | .cache
76 |
77 | # Next.js build output
78 | .next
79 |
80 | # Nuxt.js build / generate output
81 | .nuxt
82 | dist
83 |
84 | # Gatsby files
85 | .cache/
86 | # Comment in the public line in if your project uses Gatsby and *not* Next.js
87 | # https://nextjs.org/blog/next-9-1#public-directory-support
88 | # public
89 |
90 | # vuepress build output
91 | .vuepress/dist
92 |
93 | # Serverless directories
94 | .serverless/
95 |
96 | # FuseBox cache
97 | .fusebox/
98 |
99 | # DynamoDB Local files
100 | .dynamodb/
101 |
102 | # TernJS port file
103 | .tern-port
104 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "typescript.tsdk": "node_modules/typescript/lib"
3 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 coding earth
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Entropy
2 |
3 | Entropy is about building new art based on composable collections of seed NFTs.
4 |
5 | The baseline of Entropy are 8x8 bitmap "tiles" that can be interpreted as bitmap pictures if you want so, e.g.
6 |
7 |
8 | the binary hex string `b44861ea32a51020` yields these bits:
9 |
10 | ```
11 | [
12 | 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0,
13 | 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1,
14 | 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1,
15 | 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1,
16 | 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0,
17 | 0, 0, 0, 0
18 | ]
19 | ```
20 |
21 | and if you paint them, looks like:
22 |
23 | ```
24 | █ ██ █
25 | █ █
26 | ██ █
27 | ███ █ █
28 | ██ █
29 | █ █ █ █
30 | █
31 | █
32 | ```
33 |
34 | Bitmaps can be easily manipulated using bit shifting operations so you can combine two patterns, e.g like this (an OR operation)
35 |
36 | ```
37 | █ █
38 | █ █
39 | █ █
40 | █ █
41 | █ ████████ ████████
42 | █ █
43 | █ █
44 | █ █
45 |
46 | ```
47 |
48 |
49 |
50 | An Entropy NFT is defined by an bitmap pattern, denoted by the patterns hex string / byte representation (e.g. `b44861ea32a51020`)
51 |
52 |
53 |
54 | ### Entropy rules
55 |
56 | 1. minting out of seeds
57 |
58 | Everybody *can* mint NFTs, but only if you they bring two or more seed NFTs along.
59 |
60 | The game starts with 64 single pixel NFTs (each with a single bit set) who are sold to new owners
61 |
62 | During the minting process the contract combines the two input patterns and (undecided) burns the seed patterns.
63 |
64 | By repeating this process new NFTs are born.
65 |
66 | 2. goal: mint the "nicest" NFTs
67 |
68 | Everyone will try to achieve minting the "nicest looking" bitmap that can be created out of seed bitmaps.
69 |
70 | The "nicer" a seed NFT the more "valuable" it gets because it can be used to mint even nicer NFTs, aka creating sth like:
71 |
72 | ```
73 | ██ ██
74 | █ ██ █
75 | █ ██ █
76 | ██ ██
77 | ██ ██
78 | █ ██ █
79 | █ ██ █
80 | ██ ██
81 | ```
82 |
83 | ### (optional) intrinsic economic challenges
84 |
85 | first, add a computational "niceness" indicator to the contract that can compute some "structuredness" feature out of a bitmap. For example, using a very naive Shannon entropy definition:
86 |
87 | ```
88 | █ █
89 | █ █
90 | ████
91 | █ █
92 | █ █
93 | ████
94 | █ █
95 | █ █
96 | {
97 | s: { x: 40, y: 40 },
98 | sq: { x: 43.31370849898476, y: 43.31370849898476 },
99 | sym: { '0': 0, '1': 0, '2': 8, '3': 0, '4': 8, '5': 0, '6': 0, '7': 0 },
100 | symbolicEntropy: 10
101 | }
102 |
103 |
104 | █ █ █ █
105 | █ █ █ █
106 | █ █ █ █
107 | █ █ █ █
108 | █ █ █ █
109 | █ █ █ █
110 | █ █ █ █
111 | █ █ █ █
112 | {
113 | s: { x: 157.21187563522582, y: 157.21187563522582 },
114 | sq: { x: 148.1620734196171, y: 148.1620734196171 },
115 | sym: { '0': 0, '1': 0, '2': 0, '3': 0, '4': 0, '5': 0, '6': 0, '7': 16 },
116 | symbolicEntropy: 7
117 | }
118 |
119 | █ █ ██
120 | █ █ █ █
121 | █ ████
122 | ██
123 | █
124 | ████ █
125 | █ █ ██
126 | ██ █ ██
127 | {
128 | s: { x: 56.62919048309068, y: 49.60964047443681 },
129 | sq: { x: 58.05949817513566, y: 51.66562126173752 },
130 | sym: { '0': 0, '1': 1, '2': 6, '3': 0, '4': 5, '5': 2, '6': 2, '7': 0 },
131 | symbolicEntropy: 67
132 | }
133 | ```
134 |
135 | according to the algorithm used here, the "nicest" tiles are those with an 3 < entropy < 12 (that's to be determined)
136 |
137 | The more "niceness" exists in a pattern, the more expensive it gets to mint.
138 |
139 | Minters have not only to bring seed NFTs along, but also some money (e.g. ERC20) that's locked into the resulting asset (if you use interest bearing tokens like aDAI they even accrue interest, adding to the NFTs intrinsic value over time, see Charged Particles)
140 |
141 | An amount of the "minting" charge is paid as a royalty to the previous owners of the seed NFTs.
142 |
143 | ### display
144 |
145 | Bitmap patterns look really boring, so lets add some mechanism to display "generated" art by interpreting them.
146 |
147 | **Music**: each bitmap cell corresponds with a sample tune (mp3) that also can be covered by an MP3 NFT itself . The first row is the percussion line, the second a bass line, the third piano tunes, etc.
148 |
149 | **Generated images**: each row represents a feature of an resulting image, e.g. background color, art frequency, item shape. An algorithm creates the final artwork out of the pattern
150 |
151 | **Generated lineart**: each row represents a coefficient for a vector function or an IFS that creates fractal images
152 |
153 |
154 |
155 | ### multi generation nfts
156 |
157 | To make the whole thing much more fun, lets consider everything above to happen on the first epoch of the contract.
158 |
159 | At some point in time a second "epoch" begins, e.g. after a month or a sufficient amount of "nice" NFTs have been minted
160 |
161 | From here on one can mint 2-gen NFTs. These are minted by using 4 1-gen NFTs and are a combination of those. Effectively a 2-gen NFT has a square border length of 16 (2 1-get NFTs horizontally and vertically)
162 |
163 | That instantly adds a whole dimension to the display part: the 2-gen feature bits can create a totally new "world" of how to display the 4 seed NFTs with much more complex algorithms, creating much more complex generative art
164 |
165 |
166 |
167 | #### multi generation with sound
168 |
169 | on epoch 1 the NFTs are representing the input features for a sound generator, e.g. defining tune, pitch, distortion etc. of a single constant "sound" (e.g. a vibrating tune or a guitar sound or a kick snare)
170 |
171 | on epoch 2 those "sound" NFTs are combined to a harmony / set of sounds, e.g. a basic drum line or a chord or a melody
172 |
173 | on epoch 3 those building blocks are assembled to a verses and chorus lines
174 |
175 | on epoch 4 these lines are assembled to songs
176 |
177 | on epoch 5 thse songs are assembled to a disco night.
178 |
179 |
180 |
181 | ## high level development tasks
182 |
183 | gas-optimized bit shift operations on solidity
184 |
185 | business rules on solidity (e.g. add / distribute minting charges, burn, airdrop etc.)
186 |
187 | these are NFTs without an "URL" input. To display them on marketplaces, the resulting images / sounds should be pregenerated client side so they can be displayed after minting
188 |
189 | display features: "play" / "show" NFT representations
190 |
191 | frontend simulations: find all existing nfts on chain and simulate what happens when you assemble them locally. If the result looks nice, ask their owners to buy them to produce the simulated result on chain
192 |
193 | frontend "dreaming" simulation: paint an NFT freely until you find one you're wishing for, check first simulator how close you come to that result by using existing NFTs, find the NFT that you "need" to create your "dream" and repeat until you find a path that would lead to your "idea". Publish that path so others can mint the missing pieces
194 |
195 |
196 |
197 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@entropy/monorepo",
3 | "private": true,
4 | "version": "1.0.0",
5 | "workspaces": [
6 | "./packages/*"
7 | ],
8 | "scripts": {
9 | "start:app": "cd packages/app && yarn start"
10 | }
11 | }
--------------------------------------------------------------------------------
/packages/app/.env:
--------------------------------------------------------------------------------
1 | REACT_APP_IPFS_GATEWAY=https://ipfs.depa.digital/ipfs/
2 | REACT_APP_IPFS_TUNES_DIR=QmP45p1jJyYBzbCywn6XkLtN9eZ7UqnJC2G19W8Lwfc9eN
3 | REACT_APP_CONTRACT_ADDRESS=
--------------------------------------------------------------------------------
/packages/app/.env.production:
--------------------------------------------------------------------------------
1 | REACT_APP_IPFS_GATEWAY=https://ipfs.depa.digital/ipfs/
2 | REACT_APP_IPFS_TUNES_DIR=QmP45p1jJyYBzbCywn6XkLtN9eZ7UqnJC2G19W8Lwfc9eN
3 | REACT_APP_CONTRACT_ADDRESS=0x851E1c5C33663fC96f63B35262955d3156F756A1
--------------------------------------------------------------------------------
/packages/app/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/packages/app/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `yarn start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
13 |
14 | The page will reload if you make edits.\
15 | You will also see any lint errors in the console.
16 |
17 | ### `yarn test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `yarn build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `yarn eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!**
35 |
36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
39 |
40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `yarn build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
--------------------------------------------------------------------------------
/packages/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@entropy/app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "proxy": "https://entropy-elmariachi.vercel.app",
6 | "dependencies": {
7 | "@apollo/client": "^3.3.12",
8 | "@testing-library/jest-dom": "^5.11.4",
9 | "@testing-library/react": "^11.1.0",
10 | "@testing-library/user-event": "^12.1.10",
11 | "@types/howler": "^2.2.1",
12 | "@types/node": "^12.0.0",
13 | "@types/react": "^17.0.3",
14 | "@types/react-dom": "^16.9.0",
15 | "@types/react-router-dom": "^5.1.7",
16 | "@types/styled-components": "^5.1.7",
17 | "@web3-react/core": "^6.1.9",
18 | "@web3-react/injected-connector": "^6.0.7",
19 | "bn.js": "^5.2.0",
20 | "ethereum-blockies-base64": "^1.0.2",
21 | "graphql": "^15.5.0",
22 | "howler": "^2.2.1",
23 | "node-sass": "^5.0.0",
24 | "react": "^17.0.1",
25 | "react-async": "^10.0.1",
26 | "react-dom": "^17.0.1",
27 | "react-router-dom": "^5.2.0",
28 | "react-scripts": "4.0.3",
29 | "react-toast-notifications": "^2.4.3",
30 | "reactronica": "^0.4.6",
31 | "styled-components": "^5.2.1",
32 | "typescript": "^4.2.3",
33 | "web-vitals": "^1.0.1",
34 | "web3": "^1.3.4"
35 | },
36 | "scripts": {
37 | "start": "react-scripts start",
38 | "build": "react-scripts build",
39 | "test": "react-scripts test",
40 | "eject": "react-scripts eject"
41 | },
42 | "eslintConfig": {
43 | "extends": [
44 | "react-app",
45 | "react-app/jest"
46 | ]
47 | },
48 | "browserslist": {
49 | "production": [
50 | ">0.2%",
51 | "not dead",
52 | "not op_mini all"
53 | ],
54 | "development": [
55 | "last 1 chrome version",
56 | "last 1 firefox version",
57 | "last 1 safari version"
58 | ]
59 | },
60 | "devDependencies": {
61 | "ts-node": "^9.1.1"
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/packages/app/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cod1ng-earth/entropy/3631e20eb805b07b01fc7ef0330ab5decec6c7fb/packages/app/public/favicon.ico
--------------------------------------------------------------------------------
/packages/app/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | Entropy
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/packages/app/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cod1ng-earth/entropy/3631e20eb805b07b01fc7ef0330ab5decec6c7fb/packages/app/public/logo192.png
--------------------------------------------------------------------------------
/packages/app/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cod1ng-earth/entropy/3631e20eb805b07b01fc7ef0330ab5decec6c7fb/packages/app/public/logo512.png
--------------------------------------------------------------------------------
/packages/app/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/packages/app/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/packages/app/src/components/App.tsx:
--------------------------------------------------------------------------------
1 | import { useWeb3React } from '@web3-react/core';
2 | import { HashRouter } from 'react-router-dom';
3 | import styled from 'styled-components';
4 | import Web3 from 'web3';
5 | import ActivateWalletAlert from './atoms/ActivateWalletAlert';
6 | import NavBar from './Navigation/NavBar';
7 | import Navigation from './Navigation/Navigation';
8 |
9 | const Main = styled.main`
10 | padding-top: 1rem;
11 | @media (min-width: 1280px) {
12 | max-width: 100vw;
13 | }
14 |
15 | @media (min-width: 1440px) {
16 | max-width: 1200px;
17 | margin: 0 auto;
18 | }
19 | `
20 |
21 | function App() {
22 |
23 | const { account } = useWeb3React();
24 |
25 | return (
26 |
27 |
28 |
29 | {account ? : }
30 |
31 |
32 | );
33 | }
34 |
35 | export default App;
36 |
--------------------------------------------------------------------------------
/packages/app/src/components/Navigation/NavBar.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react'
2 | import { Link, useLocation } from 'react-router-dom'
3 | import styled from 'styled-components'
4 | import { Button } from '../atoms/Button'
5 | import { injected } from '../../lib/connectors';
6 | import { useWeb3React } from '@web3-react/core';
7 | import Web3 from 'web3';
8 | import makeBlockie from 'ethereum-blockies-base64';
9 |
10 | const Wrapper = styled.div`
11 | background-color: #1e1e1e;
12 | display: flex;
13 | flex-direction: row;
14 | `
15 | const Nav = styled.nav`
16 | height: 60px;
17 | display: flex;
18 | align-items: center;
19 | margin-left: 1rem;
20 | margin-right: 1rem;
21 |
22 | margin: 0 auto;
23 | max-width: 1200px;
24 |
25 | ul {
26 | padding: 0;
27 | list-style: none;
28 | display: flex;
29 | gap: 15px;
30 | li:hover {
31 | color: turquoise;
32 | }
33 | }
34 | `
35 | const Account = styled.div`
36 | display: flex;
37 | flex-direction: row;
38 | align-items: center;
39 | `;
40 | const Blockie = styled.img`
41 | position: relative;
42 | border-radius: 100%;
43 | max-height: 40px;
44 | margin: 3px;
45 | `
46 |
47 | const NavBar = () => {
48 | const { pathname } = useLocation()
49 | const { account, library, activate, chainId } = useWeb3React();
50 | const [balance, setBalance] = useState();
51 |
52 | useEffect(() => {
53 | if (library && account) {
54 | (async () => {
55 | const _balance = await library.eth.getBalance(account);
56 | setBalance(library.utils.fromWei(_balance, 'ether'))
57 | })()
58 | }
59 | }, [library,account]);
60 |
61 | return (
62 |
63 |
76 |
85 |
86 | )
87 | }
88 |
89 | export default NavBar
90 |
--------------------------------------------------------------------------------
/packages/app/src/components/Navigation/Navigation.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Switch, Route } from 'react-router-dom';
3 | import Create from '../Pages/Create/Create';
4 | import Compose from '../Pages/Compose/Compose';
5 | import Arts from '../Pages/Arts/Arts';
6 | import Token from '../Pages/Token/Token';
7 |
8 | const Navigation = () => {
9 | return (
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | );
25 | };
26 |
27 | export default Navigation;
28 |
--------------------------------------------------------------------------------
/packages/app/src/components/Pages/Arts/Arts.tsx:
--------------------------------------------------------------------------------
1 | import React, { useCallback, useEffect, useState } from 'react'
2 | import { useAsync } from 'react-async'
3 | import styled from 'styled-components'
4 | import { useEntropy } from '../../../context/Entropy'
5 | import { ReactComponent as And } from '../../../icons/and.svg'
6 | import { ReactComponent as Or } from '../../../icons/or.svg'
7 | import { ReactComponent as Xor } from '../../../icons/xor.svg'
8 | import intToBuffer from '../../../lib/intToBuffer'
9 | import * as Square from '../../../lib/square'
10 | import Matrix from '../../molecules/Matrix/Matrix'
11 | import SimpleMatrix from '../../molecules/SimpleMatrix/SimpleMatrix'
12 |
13 | const List = styled.ul`
14 | display: grid;
15 | grid-template-columns: 1fr 1fr 1fr 1fr;
16 | `
17 |
18 | const Filter = styled.div`
19 | margin-left: 2rem;
20 | label {
21 |
22 | }
23 | select {
24 | background: gray;
25 | width: 200px;
26 | padding: .2rem;
27 | font-size: 18px;
28 | color: white;
29 | border-radius: 2px;
30 |
31 | }
32 |
33 | `;
34 | const ArtPiece = styled.li<{ isSelected: boolean }>`
35 | display: flex;
36 | flex-direction: column;
37 | align-items: center;
38 | justify-content: center;
39 | box-shadow: ${({ isSelected }) => isSelected ? '2px 1px 14px #00ffea' : '0px 0px 2px'};
40 | width: 180px;
41 | height: 180px;
42 | background: #00203b;
43 | margin: 2rem;
44 | `
45 |
46 | const Artist = styled.p`
47 | display: flex;
48 | margin-top: 15px;
49 | align-items: baseline;
50 |
51 | & h2 {
52 | font-size: 18px;
53 | font-weight: 700;
54 | }
55 | `
56 |
57 | const Price = styled.p`
58 | display: flex;
59 | margin-top: 15px;
60 | align-items: baseline;
61 |
62 | & h2 {
63 | font-size: 18px;
64 | font-weight: 700;
65 | }
66 | `
67 |
68 | const Name = styled.h1`
69 | font-size: 24px;
70 | text-transform: uppercase;
71 | position: absolute;
72 | top: 0;
73 | left: 0;
74 |
75 | background: none;
76 |
77 | transform-origin: 0 0;
78 | transform: rotate(90deg);
79 | `
80 |
81 | const FabIconList = styled.div`
82 | position: absolute;
83 | bottom: 3rem;
84 | right: 3rem;
85 | display: flex;
86 | padding: 0.5rem;
87 | background: gray;
88 | border-radius: 8px;
89 | `
90 |
91 | const Button = styled.button`
92 | display: flex;
93 | align-items: center;
94 | cursor: pointer;
95 |
96 | & svg {
97 | fill: white;
98 | width: 40px;
99 | height: 40px;
100 | }
101 | `
102 |
103 | const Modal = styled.div`
104 | position: fixed;
105 | z-index: 1;
106 | left: 0;
107 | top: 0;
108 | width: 100%;
109 | height: 100%;
110 | overflow: auto;
111 | background-color: rgba(0,0,0,0.75); /* Black w/ opacity */
112 | `;
113 |
114 | const ModalContent = styled.div`
115 | background-color: #373737;
116 | margin: 15% auto; /* 15% from the top and centered */
117 | padding: 20px;
118 | border: 1px solid #888;
119 | width: 33%; /* Could be more or less, depending on screen size */
120 | `;
121 |
122 | const CloseButton = styled.span`
123 | color: #aaa;
124 | float: right;
125 | font-size: 18px;
126 | font-weight: bold;
127 | cursor: pointer;
128 | `;
129 |
130 | const Arts = () => {
131 | const [arts, setArts] = useState>([])
132 | const [showActions, setShowActions] = useState(false)
133 | const [selected, setSelected] = useState>({});
134 | const [composedSquare, setComposedSquare] = useState([]);
135 | const [showMyTokens, setShowMyTokens] = useState(true);
136 |
137 | const { entropyFacade } = useEntropy();
138 |
139 | const handleClick = (index: number) => {
140 | const newSelected = { ...selected, [index]: !selected[index] };
141 | setSelected(newSelected)
142 | }
143 |
144 | const handleOperation = (op: Square.Operation): void => {
145 | const selectedTokens = [];
146 | for (const item in selected) {
147 |
148 | if (selected[item]) {
149 | selectedTokens.push(JSON.parse(JSON.stringify(arts[item].mx)));
150 | }
151 | }
152 |
153 | setComposedSquare(Square.operate(selectedTokens, op));
154 | setShowActions(false);
155 | }
156 |
157 | const closeModal = () => {
158 | setComposedSquare([]);
159 | setShowActions(false);
160 | }
161 |
162 | useEffect(() => {
163 | let numberOfSelection = 0;
164 | for (const item in selected) {
165 | if (selected[item]) {
166 | numberOfSelection += 1;
167 | }
168 | }
169 | setShowActions(numberOfSelection > 1);
170 | setComposedSquare([]);
171 |
172 | }, [selected])
173 |
174 | const fetchAllTokens = async () => {
175 | if (entropyFacade) {
176 | const all = await entropyFacade.getAllTokens();
177 | const allTokens = all.map((num: string, index: number) => {
178 | const sq = Square.fromBytes(intToBuffer(num));
179 | return { id: index, mx: sq }
180 | })
181 | setArts(allTokens);
182 | }
183 | }
184 |
185 | const fetchMyTokens = async () => {
186 | if (entropyFacade) {
187 | const all = await entropyFacade.getMyTokens();
188 | const myTokens = all.map((num: string, index: number) => {
189 | //const bnId = entropyFacade.idToBn(num);
190 | //const hx = bnId.toBuffer().toString('hex');
191 | //const sq = Square.fromBytes(bnId.toBuffer());
192 | const sq = Square.fromBytes(intToBuffer(num));
193 | return { id: index, mx: sq }
194 | });
195 | setArts(myTokens);
196 | }
197 | }
198 |
199 | const fetchTokens = useCallback(async () => {
200 | if (entropyFacade) {
201 | return showMyTokens ? fetchMyTokens(): fetchAllTokens();
202 | }
203 | }, [showMyTokens, entropyFacade])
204 |
205 | const { isPending: isTokensPending } = useAsync({
206 | promiseFn: fetchTokens,
207 | });
208 |
209 | return (
210 | <>
211 |
212 |
213 |
217 |
218 |
219 | {isTokensPending
220 | ? Loading
221 | : arts.map((art, index) => (
222 | handleClick(index)}>
223 | null} isSelected={false} />
224 |
225 | ))
226 | }
227 | {showActions && (
228 |
229 |
232 |
235 |
238 |
239 | )}
240 | {composedSquare.length &&
241 |
242 |
243 |
244 | ×
245 |
246 |
247 |
248 |
249 | }
250 |
251 | >
252 | )
253 | }
254 |
255 | export default Arts
256 |
--------------------------------------------------------------------------------
/packages/app/src/components/Pages/Compose/Compose.tsx:
--------------------------------------------------------------------------------
1 | import React, { useCallback, useEffect, useState } from 'react'
2 | import * as Square from '../../../lib/square'
3 | import styled from 'styled-components'
4 | import SimpleMatrix from '../../molecules/SimpleMatrix/SimpleMatrix'
5 | import { ReactComponent as And } from '../../../icons/and.svg'
6 | import { ReactComponent as Xor } from '../../../icons/xor.svg'
7 | import { ReactComponent as Or } from '../../../icons/or.svg'
8 | import Matrix from '../../molecules/Matrix/Matrix'
9 | import { useEntropy } from '../../../context/Entropy'
10 | import { useAsync } from 'react-async';
11 | import { useToasts } from 'react-toast-notifications';
12 | import intToBuffer from '../../../lib/intToBuffer';
13 |
14 | const Container = styled.div`
15 | padding-left: 1rem;
16 | padding-right: 1rem;
17 | @media (min-width: 1280px) {
18 | padding-left: 0;
19 | padding-right: 0;
20 | }
21 | `;
22 |
23 | const Button = styled.button`
24 | display: flex;
25 | align-items: center;
26 | cursor: pointer;
27 |
28 | & svg {
29 | fill: white;
30 | }
31 |
32 | & svg:hover {
33 | fill: #1adede;
34 | }
35 | `;
36 |
37 | const Headline = styled.h1`
38 | font-size: 36px;
39 | font-weight: 700;
40 | text-align: center;
41 | margin-bottom: 10px;
42 | `
43 |
44 | const Subtitle = styled.h2`
45 | font-size: 18px;
46 | text-align: center;
47 | margin-bottom: 10px;
48 | `
49 |
50 | const Tokens = styled.div`
51 | margin-top: 2rem;
52 | display: flex;
53 | flex-wrap:wrap;
54 | gap: 15px;
55 | `;
56 |
57 | const Actions = styled.div`
58 | display: flex;
59 | justify-content: center;
60 | gap: 2rem;
61 | & svg {
62 | width: 60px;
63 | height: 60px;
64 | }
65 | `;
66 |
67 | const ActionWrapper = styled.div`
68 | margin-top: 3rem;
69 | `;
70 |
71 |
72 | const Compose = () => {
73 | const [tokens, setTokens] = useState>([]);
74 | const [tokenIds, setTokenIds] = useState>([]);
75 | const [selected, setSelected] = useState>({});
76 | const [showActions, setShowActions] = useState(false);
77 | const [composedSquare, setComposedSquare] = useState([]);
78 | // const [showClear, setShowClear] = useState(false);
79 | const [isMinting, setIsMinting] = useState(false);
80 |
81 | const { entropyFacade } = useEntropy();
82 | const { addToast, removeAllToasts } = useToasts();
83 |
84 | const handleMint = async (): Promise => {
85 | if (entropyFacade) {
86 | setIsMinting(true);
87 | const _tokenIds: string[] = [];
88 | for (const item in selected) {
89 | if (selected[item]) {
90 | _tokenIds.push(tokenIds[item].tokenId);
91 | }
92 | }
93 | try {
94 | await entropyFacade.mintWithTokens(_tokenIds);
95 | } catch (e) {
96 | addToast(e, { appearance: 'error' });
97 | }
98 | setIsMinting(false);
99 | handleClear();
100 | refetchMyTokens();
101 | }
102 | }
103 |
104 | const handleClick = (index: number) => {
105 | const newSelected = { ...selected, [index]: !selected[index] };
106 | setSelected(newSelected)
107 | }
108 |
109 | const handleOperation = (op: Square.Operation): void => {
110 | const selectedTokens = [];
111 | for (const item in selected) {
112 |
113 | if (selected[item]) {
114 | selectedTokens.push(JSON.parse(JSON.stringify(tokens[item].mx)));
115 | }
116 | }
117 |
118 | setComposedSquare(Square.operate(selectedTokens, op));
119 | }
120 |
121 | const handleClear = () => {
122 | setComposedSquare([]);
123 | }
124 |
125 | useEffect(() => {
126 | let numberOfSelection = 0;
127 | for (const item in selected) {
128 |
129 | if (selected[item]) {
130 | numberOfSelection += 1;
131 | }
132 | }
133 | setShowActions(numberOfSelection > 1);
134 | setComposedSquare([]);
135 |
136 | }, [selected])
137 |
138 | const fetchMyTokens = useCallback(async () => {
139 | if (entropyFacade) {
140 | const rawTokens: any = [];
141 | const artTokens: any = [];
142 | const all = await entropyFacade.getMyTokens();
143 | all.forEach((num: string, index: number) => {
144 | const sq = Square.fromBytes(intToBuffer(num));
145 |
146 | artTokens.push({ id: index, mx: sq })
147 | rawTokens.push({ id: index, tokenId: num })
148 | })
149 | setTokens(artTokens);
150 | setTokenIds(rawTokens);
151 | }
152 |
153 | }, [entropyFacade])
154 |
155 | const { isPending: isTokensPending, reload: refetchMyTokens } = useAsync({
156 | promiseFn: fetchMyTokens,
157 | });
158 |
159 | useAsync({
160 | deferFn: handleMint,
161 | });
162 |
163 | return (
164 |
165 |
166 | Compose
167 | Select some of your tokens to mint a new one.
168 | start by selecting multiple tokens:
169 | {isTokensPending && Loading...}
170 | {!isTokensPending && tokens.length > 0 &&
171 |
172 | {tokens.map((token, index) => (
173 | handleClick(index)} isSelected={selected[index]} />
174 | ))}
175 |
176 | }
177 | {showActions &&
178 |
179 | Select one operation to see the result
180 |
181 |
182 |
185 |
188 |
191 |
192 |
193 | }
194 | {composedSquare.length > 0 && !isMinting &&
195 |
196 | }
197 | {isMinting &&
198 | minting in progress
199 | }
200 |
201 |
202 |
203 | )
204 | }
205 |
206 | export default Compose
207 |
--------------------------------------------------------------------------------
/packages/app/src/components/Pages/Create/Create.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import styled from 'styled-components'
3 | import * as Square from '../../../lib/square'
4 | import Matrix from '../../molecules/Matrix/Matrix'
5 |
6 | const Headline = styled.h1`
7 | font-size: 36px;
8 | font-weight: 700;
9 | text-align: center;
10 | margin-bottom: 10px;
11 | `
12 |
13 | const Subtitle = styled.h2`
14 | font-size: 18px;
15 | text-align: center;
16 | margin-bottom: 10px;
17 | `
18 |
19 | const mx1 = Square.fromText(`10000001
20 | 01000010
21 | 00111100
22 | 00100100
23 | 00100100
24 | 00111100
25 | 01000010
26 | 10000001`)
27 |
28 | const Create = () => {
29 | return (
30 |
31 | Entropy
32 | Collaboratively mine NFTs for generative arts
33 |
34 |
35 | )
36 | }
37 |
38 | export default Create
39 |
--------------------------------------------------------------------------------
/packages/app/src/components/Pages/Token/Token.tsx:
--------------------------------------------------------------------------------
1 | import { useWeb3React } from '@web3-react/core'
2 | import React, { useEffect, useState } from 'react'
3 | import { useParams } from 'react-router-dom'
4 | import { useToasts } from 'react-toast-notifications'
5 | import styled from 'styled-components'
6 | import Web3 from 'web3'
7 | import { useEntropy } from '../../../context/Entropy'
8 | import * as Square from '../../../lib/square'
9 | import Matrix from '../../molecules/Matrix/Matrix'
10 |
11 | const Headline = styled.h1`
12 | font-size: 36px;
13 | font-weight: 700;
14 | text-align: center;
15 | margin-bottom: 10px;
16 | `
17 |
18 | const Subtitle = styled.h2`
19 | font-size: 18px;
20 | text-align: center;
21 | margin-bottom: 10px;
22 | `
23 |
24 | const ImageWrapper = styled.div`
25 | display: grid;
26 | justify-content: center;
27 | `;
28 | const Image = styled.img`
29 | width: 400px;
30 | height: 400px;
31 | `;
32 |
33 |
34 | const Token = () => {
35 |
36 | const { activate } = useWeb3React();
37 | const { entropyFacade } = useEntropy();
38 | const { addToast, removeAllToasts } = useToasts();
39 |
40 | const { id } = useParams<{ id: string }>();
41 | const [bnId, setBnId] = useState();
42 | const [mx, setMx] = useState([]);
43 | const [metadata, setMetadata] = useState<{ fancy_image?: string, image?: string }>({});
44 | const [page, setPage] = useState(0);
45 |
46 | useEffect(() => {
47 | if (entropyFacade) {
48 | const square = Square.fromBytes(Buffer.from(id, 'hex'));
49 | const _bnId = entropyFacade.hexToBn(`0x${Square.toHex(square)}`);
50 | setBnId(_bnId);
51 | setMx(square);
52 | }
53 | }, [id, entropyFacade])
54 |
55 | useEffect(() => {
56 | if (bnId) {
57 | (async () => {
58 | console.log(id);
59 | //.replace('https://entropy-elmariachi.vercel.app', '')
60 | let _tokenUri;
61 | try {
62 | _tokenUri = await entropyFacade!.getTokenUri(bnId.toString());
63 | } catch (e) {
64 | _tokenUri = `https://entropy-elmariachi.vercel.app/token/0x${id}.json`
65 | }
66 |
67 | console.log(_tokenUri)
68 | const response = await fetch(_tokenUri)
69 | const _metadata = await response.json();
70 | console.log(_metadata);
71 | setMetadata(_metadata);
72 | })();
73 | }
74 | }, [bnId]);
75 |
76 |
77 | const toggle = () => {
78 | if (Object.keys(metadata).length) {
79 | const nextPage = page + 1
80 | setPage(nextPage % 3)
81 | }
82 | }
83 |
84 | return (
85 |
86 | Entropy 0x{id}
87 | click here to see the Entropy Art
88 | {bnId?.toString()}
89 | {page === 0 &&
90 |
91 | }
92 | {page === 1 &&
93 |
94 |
95 |
96 | }
97 | {page === 2 &&
98 |
99 |
100 |
101 | }
102 |
103 | )
104 | }
105 |
106 | export default Token
107 |
--------------------------------------------------------------------------------
/packages/app/src/components/atoms/ActivateWalletAlert.tsx:
--------------------------------------------------------------------------------
1 | import { injected } from '../../lib/connectors';
2 | import { ReactComponent as MetaMask } from '../../icons/mm-logo.svg'
3 | import Web3 from 'web3';
4 | import styled from 'styled-components';
5 | import { useWeb3React } from '@web3-react/core';
6 | import Link from './Link';
7 |
8 | const HeroAlert = styled.section`
9 | display: flex;
10 | margin: auto auto;
11 | border: 1px solid turquoise;
12 | color: turquoise;
13 | border-radius: 1rem;
14 | width: 80vw;
15 | min-height: 40vh;
16 | align-items: center;
17 | justify-content: center;
18 | flex-direction: column;
19 | `
20 | const ActivateWalletAlert = () => {
21 | const { activate } = useWeb3React();
22 |
23 | return
24 |
25 | Please activate(injected)}>connect to a wallet on the Rinkeby network.
26 |
27 | }
28 |
29 | export default ActivateWalletAlert;
--------------------------------------------------------------------------------
/packages/app/src/components/atoms/Button.tsx:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components'
2 |
3 | export const Button = styled.button`
4 | color: turquoise;
5 | border: 2px solid turquoise;
6 | padding: .5rem .75rem;
7 | border-radius: 1.5rem;
8 | cursor:pointer;
9 | background: #000;
10 | transition: all 700ms;
11 | &:hover {
12 | background: turquoise;
13 | color: #333;
14 | }
15 | `
--------------------------------------------------------------------------------
/packages/app/src/components/atoms/Link.tsx:
--------------------------------------------------------------------------------
1 | import styled from "styled-components";
2 |
3 | const Link = styled.a`
4 | color: turquoise;
5 | text-decoration: underline;
6 | cursor: pointer;
7 | &:hover {
8 | color: aqua;
9 | }
10 | `
11 |
12 | export default Link;
--------------------------------------------------------------------------------
/packages/app/src/components/atoms/MatrixDetails/MatrixDetails.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react'
2 | import * as Square from '../../../lib/square';
3 |
4 | interface Props {
5 | square: Square.Square
6 | }
7 |
8 | const MatrixDetails = ({square}: Props) => {
9 | const [hex, setHex] = useState();
10 | const [entropy, setEntropy] = useState();
11 |
12 | useEffect(
13 | () => {
14 | const bytes = Square.bitsToBytes(Square.toBinArray(square));
15 | setHex(bytes.toString('hex'));
16 | setEntropy(Square.entropy(square));
17 | },
18 | [square],
19 | )
20 |
21 | return (
22 |
23 |
{hex}
24 | symbols: {entropy?.symbolicEntropy}
25 | dir: {entropy?.sq.x} {entropy?.sq.y}
26 |
27 | )
28 | }
29 |
30 | export default MatrixDetails
31 |
--------------------------------------------------------------------------------
/packages/app/src/components/atoms/MatrixTile/MatrixTile.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react'
2 | import styled from 'styled-components'
3 | import { Howl } from 'howler'
4 |
5 | interface Props {
6 | on: boolean;
7 | onClick?: () => void;
8 | tune: Howl;
9 | sm: boolean;
10 | isSelectable: boolean;
11 | }
12 |
13 | const Tile = styled.div<{ on: boolean, sm: boolean }>`
14 | width: ${(props) => (props.sm ? '8px' : '40px')};
15 | height: ${(props) => (props.sm ? '8px' : '40px')};
16 | margin: ${(props) => (props.sm ? '2px' : '5px')};
17 | border-radius: 2px;
18 | color: ${(props) => (props.on ? '#333333' : '#DDDDDD')};
19 | background: ${(props) => (props.on ? '#47dcfc' : '#ffffff')};
20 | &:hover {
21 | background: #b6b6b6;
22 | }
23 | `
24 | const MatrixTile = ({ on, onClick, tune, sm, isSelectable }: Props) => {
25 | const playToggle = () => {
26 | if (isSelectable){
27 | if (!on) {
28 | tune?.play()
29 | } else {
30 | tune.stop();
31 | }
32 | }
33 | }
34 |
35 | const handleClick = () => {
36 | if (onClick) {
37 | playToggle();
38 | onClick();
39 | }
40 | }
41 |
42 | return (
43 |
44 | {on}
45 |
46 | )
47 | }
48 |
49 | const defaultProps = {
50 | sm: false,
51 | }
52 |
53 | MatrixTile.defaultProps = defaultProps;
54 |
55 | export default MatrixTile
56 |
--------------------------------------------------------------------------------
/packages/app/src/components/atoms/Toast/Toast.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import styled from 'styled-components'
3 |
4 | interface Props {
5 | appearance: any;
6 | children: any;
7 | }
8 |
9 | const Wrapper = styled.div<{ appearance: string }>`
10 | background: ${(props) => props?.appearance === 'error' ? '#8d4266' : '#42578d'};
11 | padding: 1rem;
12 | border-radius: 2px;
13 | }
14 | `
15 |
16 | const Toast = ({ appearance, children }: Props) => {
17 |
18 |
19 | return (
20 |
21 | {children}
22 |
23 | )
24 | }
25 |
26 | export default Toast
27 |
--------------------------------------------------------------------------------
/packages/app/src/components/molecules/Matrix/Matrix.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react'
2 | import styled from 'styled-components'
3 | import * as Square from '../../../lib/square'
4 | // import MatrixDetails from '../../atoms/MatrixDetails/MatrixDetails'
5 | import MatrixTile from '../../atoms/MatrixTile/MatrixTile'
6 | import { Howl } from 'howler'
7 | import { ReactComponent as Clear } from '../../../icons/close.svg'
8 | import { ReactComponent as Play } from '../../../icons/play.svg'
9 | import { ReactComponent as Mint } from '../../../icons/diamond.svg'
10 | import { ReactComponent as Pause } from '../../../icons/pause.svg'
11 | import tunes from '../../../dummyData/tunes'
12 |
13 | const Row = styled.div`
14 | display: flex;
15 | flex-direction: row;
16 | justify-content: center;
17 | `
18 |
19 | const Board = styled.div`
20 | display: grid;
21 | justify-content: center;
22 | grid-template-columns: 400px 40px;
23 | `;
24 |
25 | const Actions = styled.div`
26 | display: flex;
27 | flex-direction: column;
28 | align-items: flex-start;
29 | margin-left: 0.5rem;
30 | gap: 1rem;
31 | `;
32 |
33 | const Button = styled.button`
34 | display: flex;
35 | align-items: center;
36 | cursor: pointer;
37 | & span {
38 | display: none;
39 |
40 | }
41 |
42 | &:hover {
43 | & span {
44 | display: inline;
45 | margin-left: 5px;
46 | background: gray;
47 | padding: 2px;
48 | }
49 | }
50 |
51 | & svg {
52 | fill: white;
53 | }
54 | `;
55 |
56 |
57 | interface props {
58 | square: Square.Square;
59 | isMintable: boolean;
60 | isSelectable: boolean;
61 | onMint?: () => void;
62 | }
63 |
64 |
65 | const Matrix = ({ square, isSelectable, onMint, isMintable }: props) => {
66 | const [mySquare, setSquare] = useState(square)
67 | const [turnedOnTunes, setTurnedOnTunes] = useState([]);
68 | const [isPlaying, setIsPlaying] = useState(false);
69 |
70 | const toggle = (x: number, y: number) => {
71 | if (isSelectable) {
72 | const nw = [...mySquare]
73 | nw[y][x] = !mySquare[y][x]
74 | setSquare(nw)
75 | }
76 | }
77 |
78 | useEffect(() => {
79 | const _turnedOnTunes: Howl[] = [];
80 | mySquare.forEach((row, y) => {
81 | row.forEach((tile, x) => {
82 | if (tile) {
83 | _turnedOnTunes.push(tunes[x % 8][y % 8])
84 | }
85 | })
86 | })
87 | _turnedOnTunes.forEach(sound => sound.load())
88 | setTurnedOnTunes(_turnedOnTunes);
89 |
90 | }, [mySquare])
91 |
92 | useEffect(() => {
93 | setSquare(square);
94 | }, [square])
95 |
96 | const playAll = () => {
97 | if (turnedOnTunes.length && !isPlaying) {
98 | turnedOnTunes.forEach(sound => sound.play())
99 | setIsPlaying(true);
100 | }
101 | }
102 |
103 | const stopAll = () => {
104 | if (turnedOnTunes.length && isPlaying) {
105 | setIsPlaying(false);
106 | turnedOnTunes.forEach(sound => sound.stop())
107 | }
108 | }
109 |
110 | const clear = () => {
111 | setSquare(Square.empty(8))
112 | }
113 | return (
114 |
115 |
116 | {mySquare.map((row, y) => (
117 |
118 | {row.map((bit, x) => (
119 | toggle(x, y)} tune={tunes[x % 8][y % 8]} isSelectable={isSelectable}/>
120 | ))}
121 |
122 | ))}
123 |
124 |
125 | {/* */}
126 | {isSelectable &&
127 |
131 | }
132 | {isPlaying ?
133 |
137 | :
141 | }
142 | {isMintable &&
143 |
147 | }
148 |
149 |
150 |
151 | )
152 | }
153 |
154 | const defaultProps = {
155 | isSelectable: true,
156 | onMint: () => { }
157 | }
158 |
159 | Matrix.defaultProps = defaultProps;
160 |
161 | export default Matrix
162 |
--------------------------------------------------------------------------------
/packages/app/src/components/molecules/SimpleMatrix/SimpleMatrix.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react'
2 | import styled from 'styled-components'
3 | import * as Square from '../../../lib/square'
4 | // import MatrixDetails from '../../atoms/MatrixDetails/MatrixDetails'
5 | import MatrixTile from '../../atoms/MatrixTile/MatrixTile'
6 | import { Howl } from 'howler'
7 | import { ReactComponent as Play } from '../../../icons/play.svg'
8 | import { ReactComponent as Pause } from '../../../icons/pause.svg'
9 | import { ReactComponent as Eye } from '../../../icons/eye.svg'
10 | import tunes from '../../../dummyData/tunes'
11 | import { Link } from 'react-router-dom'
12 |
13 | const Row = styled.div`
14 | display: flex;
15 | flex-direction: row;
16 | justify-content: center;
17 | `
18 |
19 | const Board = styled.div`
20 | display: grid;
21 | justify-content: center;
22 | grid-template-columns: 100px;
23 | `;
24 |
25 | const MatrixWrapper = styled.div<{ isSelected: boolean }>`
26 | position: relative;
27 | border: ${(props) => props.isSelected ? 'solid 2px #27ffe2' : ''}
28 | `;
29 |
30 | const Actions = styled.div`
31 | display: flex;
32 | flex-direction: column;
33 | align-items: flex-start;
34 | margin-left: 0.5rem;
35 | gap: 1rem;
36 | `;
37 |
38 | const Button = styled.button`
39 | display: flex;
40 | align-items: center;
41 | cursor: pointer;
42 | opacity: 0.2;
43 | background: #1a5f4e;
44 | border-radius: 4px;
45 | transition: all 0.5 ease-in;
46 |
47 | &:hover {
48 | opacity: 1;
49 | animation: pulse-black 2s infinite;
50 | }
51 |
52 | & span {
53 | display: none;
54 | }
55 |
56 | & svg {
57 | margin: 2px;
58 | fill: white;
59 | width: 30px;
60 | height: 30px;
61 | }
62 |
63 | @keyframes pulse-black {
64 | 0% {
65 | transform: scale(0.95);
66 | box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.7);
67 | }
68 |
69 | 70% {
70 | transform: scale(1);
71 | box-shadow: 0 0 0 10px rgba(0, 0, 0, 0);
72 | }
73 |
74 | 100% {
75 | transform: scale(0.95);
76 | box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
77 | }
78 | }
79 | `;
80 |
81 | const CustomLink = styled(Link)`
82 | display: flex;
83 | align-items: center;
84 | cursor: pointer;
85 | opacity: 0.2;
86 | background: #1a5f4e;
87 | border-radius: 4px;
88 | transition: all 0.5 ease-in;
89 |
90 | &:hover {
91 | opacity: 1;
92 | animation: pulse-black 2s infinite;
93 | }
94 |
95 | & span {
96 | display: none;
97 | }
98 |
99 | & svg {
100 | margin: 2px;
101 | fill: white;
102 | width: 30px;
103 | height: 30px;
104 | }
105 |
106 | @keyframes pulse-black {
107 | 0% {
108 | transform: scale(0.95);
109 | box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.7);
110 | }
111 |
112 | 70% {
113 | transform: scale(1);
114 | box-shadow: 0 0 0 10px rgba(0, 0, 0, 0);
115 | }
116 |
117 | 100% {
118 | transform: scale(0.95);
119 | box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
120 | }
121 | }
122 | `;
123 |
124 | const PlayOverlay = styled.div`
125 | position: absolute;
126 | left: 20%;
127 | transform: translate(-20%, -20%);
128 | top: 20%;
129 | `;
130 |
131 | const DetailsOverlay = styled.div`
132 | position: absolute;
133 | left: 80%;
134 | transform: translate(-80%, -80%);
135 | top: 80%;
136 | `;
137 |
138 | interface props {
139 | onClick(): void;
140 | square: Square.Square;
141 | isSelected: boolean;
142 | }
143 |
144 | const SimpleMatrix = ({ square, onClick, isSelected }: props) => {
145 | const [mySquare, setSquare] = useState(square)
146 | const [turnedOnTunes, setTurnedOnTunes] = useState([]);
147 | const [isPlaying, setIsPlaying] = useState(false);
148 |
149 | useEffect(() => {
150 | const _turnedOnTunes: Howl[] = [];
151 | mySquare.forEach((row, y) => {
152 | row.forEach((tile, x) => {
153 | if (tile) {
154 | _turnedOnTunes.push(tunes[x % 8][y % 8])
155 | }
156 | })
157 | })
158 | setTurnedOnTunes(_turnedOnTunes);
159 |
160 | }, [mySquare])
161 |
162 | const playAll = () => {
163 | if (turnedOnTunes.length && !isPlaying) {
164 | turnedOnTunes.forEach(sound => {
165 | sound.on('end', () => setIsPlaying(false))
166 | sound.play()
167 | })
168 | setIsPlaying(true);
169 | }
170 | }
171 | const stopAll = () => {
172 | if (turnedOnTunes.length && isPlaying) {
173 | setIsPlaying(false);
174 | turnedOnTunes.forEach(sound => sound.stop())
175 | }
176 | }
177 |
178 | return (
179 |
180 |
181 | {mySquare.map((row, y) => (
182 |
183 | {row.map((bit, x) => (
184 |
185 | ))}
186 |
187 | ))}
188 |
189 | {isPlaying ?
190 |
194 | :
198 | }
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 | )
211 | }
212 |
213 | export default SimpleMatrix
214 |
--------------------------------------------------------------------------------
/packages/app/src/context/Entropy.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useContext, useEffect } from 'react';
2 | import EntopyFacade from '../lib/EntropyNFT';
3 | import { useWeb3React } from '@web3-react/core';
4 | import Web3 from 'web3';
5 |
6 | interface IEntropyFacade {
7 | entropyFacade: EntopyFacade | undefined;
8 | }
9 |
10 | const EntropyContext = React.createContext({
11 | entropyFacade: undefined,
12 | });
13 |
14 | const useEntropy = (): IEntropyFacade => useContext(EntropyContext);
15 |
16 | const EntropyProvider = ({ children }: { children: React.ReactNode }): React.ReactElement => {
17 |
18 | const [entropyFacade, setEntropyFacade] = useState();
19 | const { account, library } = useWeb3React();
20 |
21 | useEffect((): void => {
22 | if (account && library) {
23 | setEntropyFacade(
24 | new EntopyFacade(library, account, process.env.REACT_APP_CONTRACT_ADDRESS || ''),
25 | );
26 | }
27 | }, [account, library]);
28 |
29 | return {children};
30 | };
31 |
32 | export { EntropyProvider, useEntropy };
33 |
--------------------------------------------------------------------------------
/packages/app/src/dummyData/tunes.ts:
--------------------------------------------------------------------------------
1 | import { Howl } from 'howler'
2 |
3 | const wr = (name: string): Howl => new Howl({
4 | src: [`${process.env.REACT_APP_IPFS_GATEWAY}${process.env.REACT_APP_IPFS_TUNES_DIR}/Entropy_ ${name}.ogg`],
5 | });
6 |
7 | const tunes = [
8 | [wr('BASS 1'), wr('BASS 2'), wr('BASS 3'), wr('BASS 4'), wr('BASS 5'), wr('BASS 6'), wr('BASS 7'), wr('BASS 8'),],
9 | [wr('BASS 9'), wr('BASS 10'), wr('BASS 11'), wr('BASS 12'), wr('BASS 13'), wr('BASS 14'), wr('PERC 1'), wr('PERC 2'),],
10 | [wr('MELO 1'), wr('MELO 2'), wr('MELO 3'), wr('MELO 4'), wr('MELO 5'), wr('MELO 6'), wr('MELO 7'), wr('MELO 8'),],
11 | [wr('MELO 9'), wr('MELO 10'), wr('MELO 11'), wr('MELO 12'), wr('PERC 3'), wr('PERC 4'), wr('PERC 5'), wr('PERC 6'),],
12 | [wr('PAD 1'), wr('PAD 2'), wr('PAD 3'), wr('PAD 4'), wr('PAD 5'), wr('PAD 6'), wr('PAD 7'), wr('PAD 8'),],
13 | [wr('PAD 9'), wr('PAD 10'), wr('PAD 11'), wr('PAD 12'), wr('PAD 13'), wr('PAD 14'), wr('PAD 15'), wr('PAD 16'),],
14 | [wr('PAD 17'), wr('PAD 18'), wr('PAD 19'), wr('PAD 20'), wr('PAD 21'), wr('PAD 22'), wr('PAD 23'), wr('PAD 24'),],
15 | [wr('PERC 7'), wr('PAD 8'), wr('PAD 9'), wr('PAD 10'), wr('PAD 11'), wr('PAD 12'), wr('PAD 13'), wr('PAD 14'),],
16 | ]
17 |
18 |
19 | export default tunes;
--------------------------------------------------------------------------------
/packages/app/src/icons/and.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/app/src/icons/clear.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/app/src/icons/close.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/app/src/icons/diamond.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
60 |
--------------------------------------------------------------------------------
/packages/app/src/icons/eye.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/app/src/icons/mm-logo.svg:
--------------------------------------------------------------------------------
1 |
40 |
--------------------------------------------------------------------------------
/packages/app/src/icons/or.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/app/src/icons/pause.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/app/src/icons/play.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/app/src/icons/xor.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/app/src/index.scss:
--------------------------------------------------------------------------------
1 | @import './styles/index.scss';
2 |
--------------------------------------------------------------------------------
/packages/app/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom'
3 | import './index.scss'
4 | import App from './components/App'
5 | import { ApolloClient, ApolloProvider, InMemoryCache } from '@apollo/client'
6 | import { Web3ReactProvider } from '@web3-react/core'
7 | import Web3 from 'web3';
8 | import { EntropyProvider } from './context/Entropy'
9 | import { ToastProvider } from 'react-toast-notifications';
10 | import Toast from './components/atoms/Toast/Toast'
11 |
12 | const getLibrary = (provider:any) => {
13 | return new Web3(provider)
14 | }
15 |
16 | const subgraphUri = process.env.REACT_APP_SUBGRAPH_URL
17 |
18 | const client = new ApolloClient({
19 | uri: subgraphUri,
20 | cache: new InMemoryCache()
21 | });
22 |
23 | ReactDOM.render(
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | ,
35 | document.getElementById('root'),
36 | )
37 |
--------------------------------------------------------------------------------
/packages/app/src/lib/EntropyNFT.ts:
--------------------------------------------------------------------------------
1 | import Web3 from 'web3';
2 | import { Contract } from 'web3-eth-contract';
3 | import { AbiItem } from 'web3-utils';
4 | import EntropyJson from '../abi/EntropyNFT.json';
5 |
6 | class EntropyNFTFacade {
7 | public contract!: Contract;
8 |
9 | private readonly web3: Web3;
10 |
11 | private readonly account: string;
12 |
13 | constructor(web3: Web3, accountAddress: string, contractAddress: string) {
14 | this.web3 = web3;
15 | this.account = accountAddress;
16 | this.contract = this.contractInstance(
17 | contractAddress,
18 | );
19 | }
20 |
21 | private contractInstance( contractAddress: string): Contract {
22 | return new this.web3.eth.Contract(
23 | EntropyJson.abi as AbiItem[],
24 | contractAddress,
25 | {
26 | from: this.account,
27 | },
28 | );
29 | }
30 |
31 | public async mintWithTokens(tokens: string[]): Promise {
32 | let gasEstimate = 2500000;
33 | try {
34 | gasEstimate = await this.contract.methods.mintWithTokens(tokens).estimateGas();
35 | const a = this.contract.methods.mintWithTokens(tokens).send({
36 | gas: gasEstimate + 1
37 | });
38 | console.log(a);
39 | return a;
40 | } catch (e) {
41 | throw e.toString().split('\n')[0];
42 | }
43 |
44 | }
45 |
46 | public async getTokenUri(tokenid: string): Promise {
47 | return this.contract.methods.tokenURI(tokenid).call();
48 | }
49 |
50 |
51 | public async getAllTokens(): Promise {
52 | const tokens: string[] = [];
53 | const balance = await this.contract.methods.totalSupply().call();
54 | if (balance > 1){
55 |
56 | for (let index = 0; index < balance; index++) {
57 | tokens.push(await this.contract.methods.tokenByIndex(index).call());
58 | }
59 | }
60 | return tokens;
61 | }
62 |
63 | public async getMyTokens(): Promise {
64 | const tokens: string[] = [];
65 | const balance = await this.contract.methods.balanceOf(this.account).call();
66 | if (balance > 1){
67 | for (let index = 0; index < balance; index++) {
68 | tokens.push(await this.contract.methods.tokenOfOwnerByIndex(this.account, index).call());
69 | }
70 | }
71 | return tokens;
72 | }
73 |
74 | public hexToBn(hex: string) {
75 | return this.web3.utils.toBN(hex);
76 | }
77 |
78 | public idToBn(id: string) {
79 | return this.web3.utils.toBN(id);
80 | }
81 | }
82 |
83 | export default EntropyNFTFacade;
84 |
--------------------------------------------------------------------------------
/packages/app/src/lib/connectors.ts:
--------------------------------------------------------------------------------
1 | import { InjectedConnector } from "@web3-react/injected-connector";
2 |
3 | export const injected = new InjectedConnector({ supportedChainIds: [1, 3, 4, 5, 1337, 42] })
4 |
--------------------------------------------------------------------------------
/packages/app/src/lib/intToBuffer.ts:
--------------------------------------------------------------------------------
1 | import BN from 'bn.js'
2 |
3 | const toBuffer = (num: string) => {
4 | const bn = new BN(num, 10);
5 | let buf;
6 | try {
7 | buf = bn.toArrayLike(Buffer, 'be', 8);
8 | } catch {
9 | buf = bn.toArrayLike(Buffer, 'be', 16);
10 | }
11 | return buf;
12 | }
13 |
14 | export default toBuffer;
--------------------------------------------------------------------------------
/packages/app/src/lib/square.ts:
--------------------------------------------------------------------------------
1 | export type Square = Array>;
2 | export type Operation = (y: boolean, x: boolean) => boolean;
3 | export interface Entropy {
4 | x: number[];
5 | y: number[];
6 | s: { x: number, y: number };
7 | sq: { x: number, y: number };
8 | sym: Record;
9 | symbolicEntropy: number;
10 | }
11 |
12 | export function empty(size: number): Square {
13 | let square: Square = new Array>(size);
14 | for (let y = size; y-- > 0;) {
15 | square[y] = new Array(size);
16 | for (let x = size; x-- > 0;) {
17 | square[y][x] = false;
18 | }
19 | }
20 | return square;
21 | }
22 |
23 | export function entropy(square: Square): Entropy {
24 | let entropies = {
25 | x: new Array(square.length),
26 | y: new Array(square.length),
27 | s: { x: 0, y: 0 },
28 | sq: { x: 0, y: 0 },
29 | sym: {} as Record,
30 | symbolicEntropy: 0
31 | };
32 |
33 | for (let y = 0; y < square.length; y++) {
34 | let entropyX = 0;
35 | let entropyY = 0;
36 | for (let x = 0; x < square.length; x++) {
37 | if (x > 0) {
38 | entropyX += square[y][x] === square[y][x - 1] ? 0 : 1;
39 | entropyY += square[x][y] === square[x - 1][y] ? 0 : 1;
40 | }
41 | }
42 | entropies.x[y] = entropyX;
43 | entropies.y[y] = entropyY;
44 | }
45 |
46 |
47 | for (let i = 0; i < square.length; i++) {
48 | entropies.sym[i] = 0;
49 | }
50 | for (let i = 0; i < square.length; i++) {
51 | entropies.s.x += entropies.x[i] === 0 ? 0 : entropies.x[i] * Math.log2(entropies.x[i]);
52 | entropies.s.y += entropies.y[i] === 0 ? 0 : entropies.y[i] * Math.log2(entropies.y[i]);
53 | entropies.sq.x += entropies.x[i] * Math.sqrt(entropies.x[i]);
54 | entropies.sq.y += entropies.y[i] * Math.sqrt(entropies.y[i]);
55 | entropies.sym[entropies.x[i]]++;
56 | entropies.sym[entropies.y[i]]++;
57 | }
58 | let symbolicEntropy = 0;
59 | let q = 1;
60 | for (let i = 0; i < square.length; i++) {
61 | symbolicEntropy += entropies.sym[i] > 0 ? q++ * i : 0;
62 | }
63 | entropies.symbolicEntropy = symbolicEntropy;
64 | return entropies;
65 | }
66 |
67 | export function operate(squares: Square[], op: Operation): Square {
68 | const size = squares[0].length;
69 | const result = squares[0];
70 | for (let y = size; y-- > 0;) {
71 | for (let x = size; x-- > 0;) {
72 | for (let square of squares.slice(1)) {
73 | result[y][x] = op(result[y][x], square[y][x]);
74 | }
75 |
76 | }
77 | }
78 | return result;
79 | }
80 |
81 |
82 |
83 | export function fromBytes(id: Buffer): Square {
84 |
85 | let res = "";
86 | for (let byte of id) {
87 | res += byte2bin(byte);
88 | }
89 |
90 |
91 | const size = Math.floor(Math.sqrt(res.length));
92 | const square = new Array>(size);
93 | for (let y = 0; y < size; y++) {
94 | square[y] = new Array(size);
95 | for (let x = 0; x < size; x++) {
96 | square[y][x] = res[y * size + x] === '1' ? true : false;
97 | }
98 | }
99 | return square;
100 | }
101 |
102 | export function fromText(text: string): Square {
103 | const lines = text.trim().split("\n");
104 | const size = lines[0].length
105 | const square = empty(size);
106 | for (let y = 0; y < size; y++) {
107 | for (let x = 0; x < size; x++) {
108 | square[y][x] = lines[y].trim()[x] === "1";
109 | }
110 | }
111 | return square;
112 | }
113 |
114 | export const and: Operation = (y, x) => y && x;
115 | export const or: Operation = (y, x) => y || x;
116 | export const xor: Operation = (y, x) => x == y ? false : true;
117 |
118 | export function print(square: Square) {
119 | for (let y = 0; y < square.length; y++) {
120 | let row = '';
121 | for (let x = 0; x < square[y].length; x++) {
122 | row += (square[y][x] === true ? '█' : '_');
123 | }
124 | console.log(row);
125 | }
126 | }
127 |
128 | export function toBinArray(square: Square): number[] {
129 | const ret = [];
130 | for (let y = 0; y < square.length; y++) {
131 | for (let x = 0; x < square.length; x++) {
132 | ret.push(square[y][x] ? 1 : 0);
133 | }
134 | }
135 | return ret;
136 | }
137 |
138 | export function byte2bin(byte: number): string {
139 | const binary = (byte >>> 0).toString(2);
140 | const padded = String("0".repeat(8) + binary).slice(-8);
141 | return padded;
142 | }
143 |
144 | export function bitsToBytes(bits: number[]): Buffer {
145 | const byteLength = bits.length / 8;
146 |
147 | const ret = Buffer.alloc(byteLength);
148 | for (let b = 0; b < byteLength; b++) {
149 | let byte = 0x0;
150 | for (let bt = 0; bt < 8; bt++) {
151 | if (bits[8 * b + bt] === 1) {
152 | byte |= (128 >> bt);
153 | }
154 | }
155 | ret[b] = byte;
156 | }
157 | return ret;
158 | }
159 |
160 | export function toHex(square: Square) {
161 | const hex = Buffer.from(bitsToBytes(toBinArray(square))).toString('hex');
162 | return hex;
163 | }
--------------------------------------------------------------------------------
/packages/app/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/packages/app/src/styles/index.scss:
--------------------------------------------------------------------------------
1 | // mixins
2 | @import './reset.scss';
3 |
4 | body {
5 | margin: 0;
6 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
7 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
8 | sans-serif;
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 | background-color: black;
12 | color: white;
13 | }
14 |
15 | code {
16 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
17 | monospace;
18 | }
19 |
--------------------------------------------------------------------------------
/packages/app/src/styles/reset.scss:
--------------------------------------------------------------------------------
1 | html,
2 | body,
3 | div,
4 | span,
5 | applet,
6 | object,
7 | iframe,
8 | h1,
9 | h2,
10 | h3,
11 | h4,
12 | h5,
13 | h6,
14 | p,
15 | blockquote,
16 | pre,
17 | a,
18 | abbr,
19 | acronym,
20 | address,
21 | big,
22 | cite,
23 | code,
24 | del,
25 | dfn,
26 | em,
27 | img,
28 | ins,
29 | kbd,
30 | q,
31 | s,
32 | samp,
33 | small,
34 | strike,
35 | strong,
36 | sub,
37 | sup,
38 | tt,
39 | var,
40 | b,
41 | u,
42 | i,
43 | center,
44 | dl,
45 | dt,
46 | dd,
47 | ol,
48 | ul,
49 | li,
50 | fieldset,
51 | form,
52 | label,
53 | legend,
54 | table,
55 | caption,
56 | tbody,
57 | tfoot,
58 | thead,
59 | tr,
60 | th,
61 | td,
62 | article,
63 | aside,
64 | canvas,
65 | details,
66 | embed,
67 | figure,
68 | figcaption,
69 | footer,
70 | header,
71 | hgroup,
72 | menu,
73 | nav,
74 | output,
75 | ruby,
76 | section,
77 | summary,
78 | time,
79 | mark,
80 | audio,
81 | video {
82 | margin: 0;
83 | padding: 0;
84 | border: 0;
85 | font-size: 100%;
86 | font: inherit;
87 | vertical-align: baseline;
88 | }
89 |
90 | button {
91 | border: none;
92 | margin: 0;
93 | padding: 0;
94 | width: auto;
95 | overflow: visible;
96 |
97 | background: transparent;
98 |
99 | /* inherit font & color from ancestor */
100 | color: inherit;
101 | font: inherit;
102 |
103 | /* Normalize `line-height`. Cannot be changed from `normal` in Firefox 4+. */
104 | line-height: normal;
105 |
106 | /* Corrects font smoothing for webkit */
107 | -webkit-font-smoothing: inherit;
108 | -moz-osx-font-smoothing: inherit;
109 |
110 | /* Corrects inability to style clickable `input` types in iOS */
111 | -webkit-appearance: none;
112 | }
113 |
114 | /* HTML5 display-role reset for older browsers */
115 |
116 | article,
117 | aside,
118 | details,
119 | figcaption,
120 | figure,
121 | footer,
122 | header,
123 | hgroup,
124 | menu,
125 | nav,
126 | section {
127 | display: block;
128 | }
129 |
130 | body {
131 | line-height: 1;
132 | }
133 |
134 | a {
135 | text-decoration: none;
136 | color: inherit;
137 | }
138 | ol,
139 | ul {
140 | list-style: none;
141 | }
142 |
143 | blockquote,
144 | q {
145 | quotes: none;
146 | }
147 |
148 | blockquote {
149 | &:before,
150 | &:after {
151 | content: '';
152 | content: none;
153 | }
154 | }
155 |
156 | q {
157 | &:before,
158 | &:after {
159 | content: '';
160 | content: none;
161 | }
162 | }
163 |
164 | table {
165 | border-collapse: collapse;
166 | border-spacing: 0;
167 | }
168 |
--------------------------------------------------------------------------------
/packages/app/src/test/index.ts:
--------------------------------------------------------------------------------
1 | import * as Square from '../lib/square';
2 |
3 | const mx4=
4 | `00010000
5 | 00010000
6 | 00010000
7 | 00010000
8 | 00010000
9 | 00010000
10 | 00010000
11 | 00010000`
12 |
13 | const mx5=
14 | `10000000
15 | 00000000
16 | 00000000
17 | 00000000
18 | 00000000
19 | 00000000
20 | 00000000
21 | 0000000`
22 |
23 | const square0 = Square.fromBytes(Buffer.from("0000000200000004", 'hex'));
24 | Square.print(square0)
25 |
26 | // const sq4 = Square.fromText(mx4);
27 | // const sq5 = Square.fromText(mx5);
28 |
29 | // const combined = Square.operate([sq4, sq5], Square.or);
30 | // Square.print(combined)
31 |
32 | // const b4 = Square.bitsToBytes(Square.toBinArray(sq4));
33 | // const b5 = Square.bitsToBytes(Square.toBinArray(sq5));
34 | // const bc = Square.bitsToBytes(Square.toBinArray(combined));
35 |
36 | // console.log("4", b4.toString("hex"))
37 | // console.log("5", b5.toString("hex"))
38 | // console.log("c", bc.toString("hex"))
39 |
40 | // for (let i=0; i<10; i++) {
41 | // const field = 1 << i;
42 | // console.log(field);
43 | // }
44 |
45 | // const n1 = 0x10101010ff101010;
46 | // const n2 = 0x00000000ff000000;
47 | // const n3 = n1 || n2;
48 |
49 | // console.log("b", n3.toString(16));
--------------------------------------------------------------------------------
/packages/app/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "include": [
4 | "src"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/packages/contracts/.env:
--------------------------------------------------------------------------------
1 | PRIVATE_KEY=
2 | INFURA_ID=
3 | METADATA_BASEURL=http://localhost:3535/token/
--------------------------------------------------------------------------------
/packages/contracts/.env.production:
--------------------------------------------------------------------------------
1 | PRIVATE_KEY=
2 | INFURA_ID=
3 | METADATA_BASEURL=https://entropy-elmariachi.vercel.app/token/
--------------------------------------------------------------------------------
/packages/contracts/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | .env.local
3 |
--------------------------------------------------------------------------------
/packages/contracts/contracts/Entropy.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity >=0.6.0;
3 |
4 | import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
5 | import "@openzeppelin/contracts/access/Ownable.sol";
6 |
7 | contract EntropyNFT is ERC721, Ownable {
8 | bool initialized = false;
9 | string baseUri = "";
10 | bytes16 private constant alphabet = "0123456789abcdef";
11 |
12 | constructor() public ERC721("Entropy", "ENT") {}
13 |
14 | function _mintGenesis(
15 | uint256 bit,
16 | uint8 from,
17 | uint8 to
18 | ) internal {
19 | require(!initialized, "genesis has happened already");
20 | for (uint8 n = from; n < to; n++) {
21 | bit = bit * 2;
22 | _mint(msg.sender, bit);
23 | }
24 | }
25 |
26 | function updateBaseURI(string memory _baseUri) public onlyOwner {
27 | baseUri = _baseUri;
28 | }
29 |
30 | function baseURI() public view override returns (string memory) {
31 | return baseUri;
32 | }
33 |
34 | function genesis1() public onlyOwner {
35 | uint256 bit = uint256(1);
36 | _mint(msg.sender, bit);
37 | _mintGenesis(bit, 1, 32);
38 | }
39 |
40 | function genesis2() public onlyOwner {
41 | uint256 bit = (uint256(2)**32);
42 | _mintGenesis(bit, 32, 64);
43 | initialized = true;
44 | }
45 |
46 | function operateOr(uint256 tokenId1, uint256 tokenId2)
47 | public
48 | pure
49 | returns (uint256)
50 | {
51 | return tokenId1 | tokenId2;
52 | }
53 |
54 | function mintWithTokens(uint256[] memory tokenIds) public {
55 | require(
56 | tokenIds.length > 1 && tokenIds.length < 20,
57 | "we dont accept more than 20 seed tokens"
58 | );
59 | require(ownerOf(tokenIds[0]) == msg.sender, "You don't own that token");
60 | uint256 result = tokenIds[0];
61 | for (uint8 i = 1; i < tokenIds.length; i++) {
62 | require(
63 | ownerOf(tokenIds[i]) == msg.sender,
64 | "You don't own that token"
65 | );
66 | result = operateOr(result, tokenIds[i]);
67 | }
68 | _mint(msg.sender, result);
69 | }
70 |
71 | function tokenURI(uint256 tokenId)
72 | public
73 | view
74 | override
75 | returns (string memory)
76 | {
77 | require(
78 | _exists(tokenId),
79 | "ERC721Metadata: URI query for nonexistent token"
80 | );
81 |
82 | return
83 | string(
84 | abi.encodePacked(baseURI(), _toHexString(tokenId, 8), ".json")
85 | );
86 | }
87 |
88 | //https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol
89 | /**
90 | * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
91 | */
92 | function _toHexString(uint256 value, uint256 length)
93 | internal
94 | pure
95 | returns (string memory)
96 | {
97 | bytes memory buffer = new bytes(2 * length + 2);
98 | buffer[0] = "0";
99 | buffer[1] = "x";
100 | for (uint256 i = 2 * length + 1; i > 1; --i) {
101 | buffer[i] = alphabet[value & 0xf];
102 | value >>= 4;
103 | }
104 | require(value == 0, "Strings: hex length insufficient");
105 | return string(buffer);
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/packages/contracts/contracts/Migrations.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity >=0.4.22 <0.9.0;
3 |
4 | contract Migrations {
5 | address public owner = msg.sender;
6 | uint public last_completed_migration;
7 |
8 | modifier restricted() {
9 | require(
10 | msg.sender == owner,
11 | "This function is restricted to the contract's owner"
12 | );
13 | _;
14 | }
15 |
16 | function setCompleted(uint completed) public restricted {
17 | last_completed_migration = completed;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/packages/contracts/migrations/1_initial_migration.js:
--------------------------------------------------------------------------------
1 | const Migrations = artifacts.require("Migrations");
2 |
3 | module.exports = function (deployer) {
4 | deployer.deploy(Migrations);
5 | };
6 |
--------------------------------------------------------------------------------
/packages/contracts/migrations/2_entropy_nft.js:
--------------------------------------------------------------------------------
1 | require('dotenv-flow').config();
2 |
3 | const Entropy = artifacts.require("EntropyNFT");
4 |
5 | module.exports = async function (deployer) {
6 | await deployer.deploy(Entropy).then(async () => {
7 | const ent = await Entropy.deployed();
8 | await ent.genesis1();
9 | await ent.genesis2();
10 | });
11 | };
--------------------------------------------------------------------------------
/packages/contracts/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@entropy/contracts",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "license": "MIT",
6 | "devDependencies": {
7 | "ganache-cli": "^6.12.2",
8 | "truffle": "^5.2.4",
9 | "truffle-flattener": "^1.5.0"
10 | },
11 | "scripts": {
12 | "chain": "ganache-cli",
13 | "migrate": "truffle migrate"
14 | },
15 | "dependencies": {
16 | "@openzeppelin/contracts": "^3.4.1",
17 | "dotenv-flow": "^3.2.0",
18 | "truffle-privatekey-provider": "^1.5.0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/packages/contracts/test/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cod1ng-earth/entropy/3631e20eb805b07b01fc7ef0330ab5decec6c7fb/packages/contracts/test/.gitkeep
--------------------------------------------------------------------------------
/packages/contracts/test/entropy.js:
--------------------------------------------------------------------------------
1 | const Entropy = artifacts.require('EntropyNFT');
2 |
3 | contract('Entropy', (accounts) => {
4 | let entropy;
5 | before(async function () {
6 | entropy = await Entropy.deployed();
7 | await entropy.updateBaseURI("http://localhost:3000/token/");
8 | })
9 | it('has an initial supply', async () => {
10 | const supply = await entropy.totalSupply.call();
11 | assert.equal(
12 | supply.valueOf(), 64, 'bad initial supply',
13 | );
14 | });
15 |
16 | it('can create token uris', async function () {
17 | const tokenUri = await entropy.tokenURI("1024");
18 | assert.equal("http://localhost:3000/token/0x0000000000000400.json", tokenUri);
19 | })
20 |
21 | it('can convert token ids to hex', async function () {
22 | assert.equal(1 == 2)
23 | })
24 | });
25 |
--------------------------------------------------------------------------------
/packages/contracts/truffle-config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Use this file to configure your truffle project. It's seeded with some
3 | * common settings for different networks and features like migrations,
4 | * compilation and testing. Uncomment the ones you need or modify
5 | * them to suit your project as necessary.
6 | *
7 | * More information about configuration can be found at:
8 | *
9 | * trufflesuite.com/docs/advanced/configuration
10 | *
11 | * To deploy via Infura you'll need a wallet provider (like @truffle/hdwallet-provider)
12 | * to sign your transactions before they're sent to a remote public node. Infura accounts
13 | * are available for free at: infura.io/register.
14 | *
15 | * You'll also need a mnemonic - the twelve word phrase the wallet uses to generate
16 | * public/private key pairs. If you're publishing your code to GitHub make sure you load this
17 | * phrase from a file you've .gitignored so it doesn't accidentally become public.
18 | *
19 | */
20 |
21 | // const HDWalletProvider = require('@truffle/hdwallet-provider');
22 | // const infuraKey = "fj4jll3k.....";
23 | //
24 | // const fs = require('fs');
25 | // const mnemonic = fs.readFileSync(".secret").toString().trim();
26 | require('dotenv-flow').config();
27 |
28 | var PrivateKeyProvider = require("truffle-privatekey-provider");
29 |
30 | module.exports = {
31 | /**
32 | * Networks define how you connect to your ethereum client and let you set the
33 | * defaults web3 uses to send transactions. If you don't specify one truffle
34 | * will spin up a development blockchain for you on port 9545 when you
35 | * run `develop` or `test`. You can ask a truffle command to use a specific
36 | * network from the command line, e.g
37 | *
38 | * $ truffle test --network
39 | */
40 |
41 | networks: {
42 | // Useful for testing. The `development` name is special - truffle uses it by default
43 | // if it's defined here and no other network is specified at the command line.
44 | // You should run a client (like ganache-cli, geth or parity) in a separate terminal
45 | // tab if you use this network and you must also set the `host`, `port` and `network_id`
46 | // options below to some value.
47 | //
48 | development: {
49 | host: "127.0.0.1", // Localhost (default: none)
50 | port: 8545, // Standard Ethereum port (default: none)
51 | network_id: "*", // Any network (default: none)
52 | },
53 | // Another network with more advanced options...
54 | // advanced: {
55 | // port: 8777, // Custom port
56 | // network_id: 1342, // Custom network
57 | // gas: 8500000, // Gas sent with each transaction (default: ~6700000)
58 | // gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei)
59 | // from: , // Account to send txs from (default: accounts[0])
60 | // websocket: true // Enable EventEmitter interface for web3 (default: false)
61 | // },
62 | // Useful for deploying to a public network.
63 | // NB: It's important to wrap the provider as a function.
64 | rinkeby: {
65 | provider: () => new PrivateKeyProvider(process.env.PRIVATE_KEY, `https://rinkeby.infura.io/v3/${process.env.INFURA_ID}`),
66 | network_id: 4, // Ropsten's id
67 | gas: 5500000, // Ropsten has a lower block limit than mainnet
68 | confirmations: 2, // # of confs to wait between deployments. (default: 0)
69 | timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
70 | skipDryRun: true // Skip dry run before migrations? (default: false for public nets )
71 | },
72 | // Useful for private networks
73 | // private: {
74 | // provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
75 | // network_id: 2111, // This network is yours, in the cloud.
76 | // production: true // Treats this network as if it was a public net. (default: false)
77 | // }
78 | },
79 |
80 | // Set default mocha options here, use special reporters etc.
81 | mocha: {
82 | // timeout: 100000
83 | },
84 |
85 | // Configure your compilers
86 | compilers: {
87 | solc: {
88 | version: "0.6", // Fetch exact version from solc-bin (default: truffle's version)
89 | // docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
90 | // settings: { // See the solidity docs for advice about optimization and evmVersion
91 | // optimizer: {
92 | // enabled: false,
93 | // runs: 200
94 | // },
95 | // evmVersion: "byzantium"
96 | // }
97 | }
98 | },
99 |
100 | // Truffle DB is currently disabled by default; to enable it, change enabled: false to enabled: true
101 | //
102 | // Note: if you migrated your contracts prior to enabling this field in your Truffle project and want
103 | // those previously migrated contracts available in the .db directory, you will need to run the following:
104 | // $ truffle migrate --reset --compile-all
105 |
106 | db: {
107 | enabled: false
108 | }
109 | };
110 |
--------------------------------------------------------------------------------
/packages/metadata/.gitignore:
--------------------------------------------------------------------------------
1 | .vercel
2 |
--------------------------------------------------------------------------------
/packages/metadata/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@entropy/metadata",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "license": "MIT",
6 | "devDependencies": {
7 | "vercel": "^21.3.3"
8 | },
9 | "dependencies": {
10 | "canvas": "^2.7.0",
11 | "seedrandom": "^3.0.5",
12 | "tinycolor2": "^1.4.2"
13 | },
14 | "scripts": {
15 | "vercel-build": "yum install libuuid-devel libmount-devel zlib && cp /lib64/{libuuid,libmount,libblkid,libz}.so.1 node_modules/canvas/build/Release/"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/metadata/src/api/image.js:
--------------------------------------------------------------------------------
1 | const Square = require('../lib/square');
2 | const seedrandom = require('seedrandom');
3 | const { createCanvas } = require('canvas')
4 | const generators = require('../generators');
5 |
6 | module.exports = (req, res) => {
7 | const id = req.query.id;
8 |
9 | const square = Square.fromBytes(Buffer.from(id, 'hex'));
10 | const canvas = createCanvas(800, 800)
11 | const randomNess = seedrandom(id);
12 |
13 | const renderer = req.query.render ? generators[req.query.render] : generators.matrix;
14 |
15 | renderer(canvas, square, randomNess);
16 |
17 | canvas.toBuffer((err, buf) => {
18 | res.setHeader('content-type', 'image/png')
19 | res.send(buf);
20 | })
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/packages/metadata/src/api/token.js:
--------------------------------------------------------------------------------
1 | const Square = require('../lib/square');
2 |
3 | function erc721MetaData(tokenId) {
4 | //const square = Square.fromBytes(Buffer.from(id, 'hex'));
5 |
6 | return {
7 | "name": `Entropy Token #0x${tokenId}`,
8 | "description": "Entropy tokens let you own the seed for generative art",
9 | "external_url": `https://entropy.on.fleek.co/#/token/${tokenId}`,
10 | "image": `https://entropy-elmariachi.vercel.app/image/${tokenId}.png`,
11 | "fancy_image": `https://entropy-elmariachi.vercel.app/fancy/${tokenId}.png`,
12 | "attributes": [
13 | { "trait_type": "KIND", "key": "KIND", value: "Entropy" }
14 | ]
15 | }
16 | }
17 |
18 | module.exports = (req, res) => {
19 | const xTokenId = req.query.id;
20 | const tokenId = xTokenId.substr(2);
21 | const metaData = erc721MetaData(tokenId)
22 | res.json(metaData);
23 | }
--------------------------------------------------------------------------------
/packages/metadata/src/generators/emily.js:
--------------------------------------------------------------------------------
1 | /**
2 | * drawLineCluster function:
3 | * Draws a cluster of lines to the screen around a particular point.
4 | * Length, direction and color of lines are dictated by randomness.
5 | * Parameters:
6 | * strokeColoring controls the color palette of a line cluster, can be set to 1, 2, or 3
7 | * rand_line_dir_style controls the direction of lines, can be set to 1, 2, 3, or 4
8 | */
9 | function drawLineCluster(context, getRandomInt, center_x, center_y, strokeColoring, rand_line_dir_style, strokeLength = 150) {
10 | //First, a loop to control the number of lines in this cluster, so each cluster has a lot of lines in it
11 | for (let cycle_nums = 0; cycle_nums < 20; cycle_nums++) {
12 |
13 | //These variables control the color gradient for this cluster
14 | for (let i = 0; i < 6; i++) {
15 | for (let j = 0; j < 6; j++) {
16 |
17 | //Let's start drawing!
18 | context.beginPath();
19 |
20 | //Here we're shifting our center point for a bit of randomness
21 | switch (rand_line_dir_style) {
22 | case 1:
23 | //pompom
24 | context.moveTo(center_x, center_y);
25 | break;
26 | case 2:
27 | //Uni-directional
28 | context.moveTo(center_x + getRandomInt(strokeLength), center_y + getRandomInt(strokeLength));
29 | break;
30 | case 3:
31 | //Fountain splay down
32 | var plusOrMinus = getRandomInt(1) == 0 ? -1 : 1;
33 | context.moveTo(center_x + (plusOrMinus * getRandomInt(strokeLength)), center_y + getRandomInt(strokeLength));
34 | break;
35 | case 4:
36 | //Fountain v.2
37 | var plusOrMinusx = getRandomInt(1) == 0 ? -1 : 1;
38 | var plusOrMinusy = getRandomInt(1) == 0 ? -1 : 1;
39 | var randomLengthMax = getRandomInt(strokeLength);//make this number bigger for longer lines
40 | context.moveTo(center_x + (plusOrMinusx * getRandomInt(randomLengthMax)), center_y + (plusOrMinusy * getRandomInt(randomLengthMax)));
41 | break;
42 |
43 | default:
44 | //Just draw pompom
45 | context.moveTo(center_x, center_y);
46 | }
47 |
48 |
49 |
50 | //Use random number to generate length of line
51 | var length = getRandomInt(strokeLength);
52 | //Use another random number to get the angle of the line
53 | var angle = getRandomInt(360);
54 |
55 | //Finding an end point on a perimeter around the point
56 | plusOrMinus = getRandomInt(1) == 0 ? -1 : 1;
57 | var new_x = center_x + (length * Math.cos(angle));
58 | var new_y = center_y + plusOrMinus * (length * Math.sin(angle));
59 |
60 | //Finally draw that line – phew!
61 | context.lineTo(new_x, new_y);
62 |
63 | //Let's stroke it with a color gradient, also random, just playing with 4 different
64 | //hard coded color gradients here but of course we could make randomness drive those color gradiants
65 | switch (strokeColoring) {
66 | case 1:
67 | //Turquoise
68 | context.strokeStyle = `rgb(0,${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)})`; break;
69 | case 2:
70 |
71 | //Black and white
72 | context.strokeStyle = `rgb(${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * i)})`;
73 |
74 | break;
75 | case 3:
76 | //Purples
77 | context.strokeStyle = `rgb(${Math.floor(255 - 42.5 * i)},0,${Math.floor(255 - 42.5 * j)})`;
78 | break;
79 | case 4:
80 | //Not sure what color comes of this
81 | context.strokeStyle = `rgb(200, ${Math.floor(255 - 42.5 * i)}, ${Math.floor(255 - 42.5 * j)})`;
82 | break;
83 | default:
84 | //Black and white by default
85 | context.strokeStyle = `rgb(${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * i)})`;
86 | }
87 | context.stroke();
88 | }
89 | }
90 | }
91 | }
92 |
93 | module.exports = (canvas, square, randomNess) => {
94 |
95 | function getRandomInt(max) {
96 | return Math.floor(randomNess() * Math.floor(max));
97 | //return
98 | }
99 |
100 | const context = canvas.getContext('2d');
101 | context.fillStyle = "black";
102 | context.fillRect(0, 0, canvas.width, canvas.height);
103 |
104 | // const center_x = canvas.width / 2;
105 | // const center_y = canvas.height / 2;
106 |
107 | //Pull together a grid of points that represent our matrix
108 | const tile_rows = 8;
109 | var tile_cols = 8;
110 | const tile_width = canvas.width / tile_cols;
111 | const tile_height = canvas.height / tile_rows;
112 |
113 | for (let row = 0; row < tile_rows; row++) {
114 | for (let col = 0; col < tile_cols; col++) {
115 | const pnt_x = (tile_width * col) + (tile_width / 2);
116 | const pnt_y = (tile_height * row) + (tile_height / 2);
117 |
118 | //Setting NUMBER OF COLORS with rand_stroke_color parameter - can be 1,2,3 or 4
119 | //one color:
120 | //var rand_stroke_color =3;
121 | //two colors:
122 | //var rand_stroke_color =getRandomInt(2)+1;
123 | //three colors:
124 | const rand_stroke_color = getRandomInt(3) + 1;
125 |
126 | //Setting LINE DIRECTION with rand_line_dir_style parameter - can be 1,2,3 or 4
127 | const rand_line_dir_style = getRandomInt(4) + 1;
128 | //Calling our line cluster function for each of our tiles!
129 | drawLineCluster(context, getRandomInt, pnt_x, pnt_y, rand_stroke_color, rand_line_dir_style, 100);
130 | }
131 | }
132 |
133 | }
134 |
135 |
136 |
137 |
138 |
139 |
--------------------------------------------------------------------------------
/packages/metadata/src/generators/geometric.js:
--------------------------------------------------------------------------------
1 | const tinycolor = require("tinycolor2");
2 | const extract = require('../lib/extractParameters')
3 |
4 | /**
5 | * @param {CanvasRenderingContext2D} canvas
6 | * @param {boolean[][]} square
7 | * @param {Function} randomNess
8 | */
9 | module.exports = function (canvas, square, randomNess) {
10 |
11 | const bytes = extract.bytes8(square);
12 | const bgColorTone = (360 / 16) * (bytes[0] & 0xF0) >> 4;
13 | const bgColorSat = 25 + (70 / 16) * (bytes[0] & 0x0F);
14 | const radius = (50 / 16) * ((bytes[1] & 0xF0) >> 4);
15 | const radiusVariance = (2 / 16) * ((bytes[1] & 0x0F));
16 | const shape = ((bytes[2] & 0xF0) >> 4) & 0x01 ? 'circle' : 'rect';
17 | const iterations = 10 + ((bytes[2] & 0x0F) << 2)
18 |
19 | console.log(bgColorTone, bgColorSat, radius, radiusVariance, shape, iterations);
20 |
21 | const bgColor = tinycolor(`hsl(${bgColorTone}, ${bgColorSat}%, 75%`);
22 | const fgColor = bgColor.clone().spin(135);
23 | const strokeColor = fgColor.clone().spin(135);
24 | const ctx = canvas.getContext('2d')
25 | ctx.fillStyle = bgColor.toHexString();
26 | ctx.fillRect(0, 0, 800, 800)
27 |
28 | for (let i = 0; i < iterations; i++) {
29 | const x = Math.floor(800 * randomNess());
30 | const y = Math.floor(800 * randomNess());
31 | const size = radius + (10 * ((randomNess() * 10) ^ radiusVariance));
32 | ctx.fillStyle = fgColor.toHexString();
33 | ctx.strokeStyle = strokeColor.toHexString();
34 | ctx.lineWidth = 4;
35 | if (shape == "circle") {
36 | ctx.beginPath()
37 | ctx.ellipse(x, y, size, size, 0, Math.PI * 2, 0, 1);
38 | } else {
39 | ctx.fillRect(x, y, size, size);
40 | ctx.strokeRect(x, y, size, size);
41 | }
42 |
43 | ctx.fill()
44 | ctx.stroke();
45 | }
46 | return canvas;
47 | }
--------------------------------------------------------------------------------
/packages/metadata/src/generators/index.js:
--------------------------------------------------------------------------------
1 | const emily = require('./emily');
2 | const matrix = require('./matrix');
3 | const geometric = require('./geometric');
4 |
5 | module.exports = {
6 | emily,
7 | matrix,
8 | geometric,
9 | }
--------------------------------------------------------------------------------
/packages/metadata/src/generators/matrix.js:
--------------------------------------------------------------------------------
1 | module.exports = (canvas, square) => {
2 | const ctx = canvas.getContext('2d')
3 | ctx.fillStyle = 'black';
4 | ctx.fillRect(0, 0, 800, 800)
5 | const pad = 15;
6 | for (let y = 0; y < square.length; y++) {
7 | for (let x = 0; x < square.length; x++) {
8 | ctx.fillStyle = square[y][x] ? '#47dcfc' : 'white'
9 | ctx.fillRect(x * 100 + pad, y * 100 + pad, 100 - pad, 100 - pad);
10 | }
11 | }
12 |
13 | return canvas;
14 | }
--------------------------------------------------------------------------------
/packages/metadata/src/lib/extractParameters.js:
--------------------------------------------------------------------------------
1 | const Square = require('./square');
2 |
3 | /**
4 | * @param {boolean[][]} square
5 | */
6 | module.exports = {
7 | bytes8: function (square) {
8 | return square.map(row => {
9 | return Square.bitsToByte(row)
10 | });
11 | }
12 | }
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/packages/metadata/src/lib/square.js:
--------------------------------------------------------------------------------
1 | export function byte2bin(byte) {
2 | const binary = (byte >>> 0).toString(2);
3 | const padded = String("0".repeat(8) + binary).slice(-8);
4 | return padded;
5 | }
6 |
7 | export function fromBytes(id) {
8 | let res = "";
9 | for (let byte of id) {
10 | res += byte2bin(byte);
11 | }
12 |
13 | const size = Math.sqrt(res.length);
14 | const square = new Array(size);
15 | for (let y = 0; y < size; y++) {
16 | square[y] = new Array(size);
17 | for (let x = 0; x < size; x++) {
18 | square[y][x] = res[y * size + x] === '1' ? true : false;
19 | }
20 | }
21 | return square;
22 | }
23 |
24 | /**
25 | * @param {boolean[]} bits
26 | * @returns number
27 | */
28 | export function bitsToByte(bits) {
29 |
30 | let byte = 0x0;
31 | for (let bt = 0; bt < bits.length; bt++) {
32 | if (bits[bt] == true) {
33 | byte |= (128 >> bt);
34 | }
35 | }
36 | return byte;
37 | }
38 |
--------------------------------------------------------------------------------
/packages/metadata/src/vercel.json:
--------------------------------------------------------------------------------
1 | {
2 | "rewrites": [
3 | {
4 | "source": "/image/:id*.png",
5 | "destination": "/api/image?id=:id*"
6 | },
7 | {
8 | "source": "/geometric/:id*.png",
9 | "destination": "/api/image?render=geometric&id=:id*"
10 | },
11 | {
12 | "source": "/fancy/:id*.png",
13 | "destination": "/api/image?render=emily&id=:id*"
14 | },
15 | {
16 | "source": "/token/:id*.json",
17 | "destination": "/api/token?id=:id*"
18 | }
19 | ],
20 | "headers": [
21 | {
22 | "source": "/(.*)",
23 | "headers": [
24 | {
25 | "key": "access-control-allow-origin",
26 | "value": "*"
27 | }
28 | ]
29 | }
30 | ]
31 | }
--------------------------------------------------------------------------------
/packages/metadata/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@sindresorhus/is@^0.14.0":
6 | version "0.14.0"
7 | resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
8 | integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
9 |
10 | "@szmarczak/http-timer@^1.1.2":
11 | version "1.1.2"
12 | resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
13 | integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==
14 | dependencies:
15 | defer-to-connect "^1.0.1"
16 |
17 | "@types/node@*":
18 | version "14.14.35"
19 | resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.35.tgz#42c953a4e2b18ab931f72477e7012172f4ffa313"
20 | integrity sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag==
21 |
22 | "@vercel/build-utils@2.10.1":
23 | version "2.10.1"
24 | resolved "https://registry.yarnpkg.com/@vercel/build-utils/-/build-utils-2.10.1.tgz#5b175fc66639a82f8beeb19e85983fe955f27875"
25 | integrity sha512-K5xaXoZnysKXxuc5YuR9NZxzBaS9UZYI+TGQCrpx+n1jFJMnVKcXTIlcGtsbNzVI1PR8Fx7YgjtAChSoIyBznQ==
26 |
27 | "@vercel/go@1.2.2":
28 | version "1.2.2"
29 | resolved "https://registry.yarnpkg.com/@vercel/go/-/go-1.2.2.tgz#47686fc8f381767428d855bdd846b66efe2f742f"
30 | integrity sha512-Oo1lXjXmDrSqdF3LKCWXJGU9DInq5aMe6weQSoWnKRvSZ6v4at2x19ltHYvgUO95y4tbdzqPLRKFNUSQEJVdjQ==
31 |
32 | "@vercel/node@1.9.1":
33 | version "1.9.1"
34 | resolved "https://registry.yarnpkg.com/@vercel/node/-/node-1.9.1.tgz#55c079a469208560fd3f9f186cb68a504c4a10a1"
35 | integrity sha512-sZIEk6UtJhbW4qRSCTnTWnGOT7UR6ZrhhSvK6z9AAS/BRc+Jz1/nbwPlYjT7HjZySo32VAwpeq2VHOd3hyxKGw==
36 | dependencies:
37 | "@types/node" "*"
38 | ts-node "8.9.1"
39 | typescript "3.9.3"
40 |
41 | "@vercel/python@2.0.1":
42 | version "2.0.1"
43 | resolved "https://registry.yarnpkg.com/@vercel/python/-/python-2.0.1.tgz#5a94438762e8e2d39015a2655625779fa3300b5c"
44 | integrity sha512-qrb6y1VYLq0x0uziW3/w6UZ1GNvNpeoM3aTfjFayr2CMZJ665J9lUaqbZhdH2/q4qw6VrBrlw3FYjr5HUpAFrw==
45 |
46 | "@vercel/ruby@1.2.6":
47 | version "1.2.6"
48 | resolved "https://registry.yarnpkg.com/@vercel/ruby/-/ruby-1.2.6.tgz#d3472c32705f0ef64d3f0bd07bae1b0990cc35ca"
49 | integrity sha512-ZLDMxMvOL0xd7FBHXQJ9EJxPohw+qzpgwulaNhXGgPuFUfnS9mboUEyj0sU9A9F7lMJFPJ6gs8UfVxBY2eNnGA==
50 |
51 | abbrev@1:
52 | version "1.1.1"
53 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
54 | integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
55 |
56 | ansi-align@^3.0.0:
57 | version "3.0.0"
58 | resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb"
59 | integrity sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==
60 | dependencies:
61 | string-width "^3.0.0"
62 |
63 | ansi-regex@^2.0.0:
64 | version "2.1.1"
65 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
66 | integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
67 |
68 | ansi-regex@^3.0.0:
69 | version "3.0.0"
70 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
71 | integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
72 |
73 | ansi-regex@^4.1.0:
74 | version "4.1.0"
75 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
76 | integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
77 |
78 | ansi-regex@^5.0.0:
79 | version "5.0.0"
80 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
81 | integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
82 |
83 | ansi-styles@^4.1.0:
84 | version "4.3.0"
85 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
86 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
87 | dependencies:
88 | color-convert "^2.0.1"
89 |
90 | aproba@^1.0.3:
91 | version "1.2.0"
92 | resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
93 | integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
94 |
95 | are-we-there-yet@~1.1.2:
96 | version "1.1.5"
97 | resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21"
98 | integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==
99 | dependencies:
100 | delegates "^1.0.0"
101 | readable-stream "^2.0.6"
102 |
103 | arg@^4.1.0:
104 | version "4.1.3"
105 | resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
106 | integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
107 |
108 | balanced-match@^1.0.0:
109 | version "1.0.0"
110 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
111 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
112 |
113 | boxen@^4.2.0:
114 | version "4.2.0"
115 | resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64"
116 | integrity sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==
117 | dependencies:
118 | ansi-align "^3.0.0"
119 | camelcase "^5.3.1"
120 | chalk "^3.0.0"
121 | cli-boxes "^2.2.0"
122 | string-width "^4.1.0"
123 | term-size "^2.1.0"
124 | type-fest "^0.8.1"
125 | widest-line "^3.1.0"
126 |
127 | brace-expansion@^1.1.7:
128 | version "1.1.11"
129 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
130 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
131 | dependencies:
132 | balanced-match "^1.0.0"
133 | concat-map "0.0.1"
134 |
135 | buffer-from@^1.0.0:
136 | version "1.1.1"
137 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
138 | integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
139 |
140 | cacheable-request@^6.0.0:
141 | version "6.1.0"
142 | resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912"
143 | integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==
144 | dependencies:
145 | clone-response "^1.0.2"
146 | get-stream "^5.1.0"
147 | http-cache-semantics "^4.0.0"
148 | keyv "^3.0.0"
149 | lowercase-keys "^2.0.0"
150 | normalize-url "^4.1.0"
151 | responselike "^1.0.2"
152 |
153 | camelcase@^5.3.1:
154 | version "5.3.1"
155 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
156 | integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
157 |
158 | canvas@^2.7.0:
159 | version "2.7.0"
160 | resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.7.0.tgz#3ce3fe30c69595ccd2bd1232967e681c026be61e"
161 | integrity sha512-pzCxtkHb+5su5MQjTtepMDlIOtaXo277x0C0u3nMOxtkhTyQ+h2yNKhlROAaDllWgRyePAUitC08sXw26Eb6aw==
162 | dependencies:
163 | nan "^2.14.0"
164 | node-pre-gyp "^0.15.0"
165 | simple-get "^3.0.3"
166 |
167 | chalk@^3.0.0:
168 | version "3.0.0"
169 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4"
170 | integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==
171 | dependencies:
172 | ansi-styles "^4.1.0"
173 | supports-color "^7.1.0"
174 |
175 | chownr@^1.1.1:
176 | version "1.1.4"
177 | resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
178 | integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
179 |
180 | ci-info@^2.0.0:
181 | version "2.0.0"
182 | resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
183 | integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==
184 |
185 | cli-boxes@^2.2.0:
186 | version "2.2.1"
187 | resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f"
188 | integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==
189 |
190 | clone-response@^1.0.2:
191 | version "1.0.2"
192 | resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
193 | integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=
194 | dependencies:
195 | mimic-response "^1.0.0"
196 |
197 | code-point-at@^1.0.0:
198 | version "1.1.0"
199 | resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
200 | integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
201 |
202 | color-convert@^2.0.1:
203 | version "2.0.1"
204 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
205 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
206 | dependencies:
207 | color-name "~1.1.4"
208 |
209 | color-name@~1.1.4:
210 | version "1.1.4"
211 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
212 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
213 |
214 | concat-map@0.0.1:
215 | version "0.0.1"
216 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
217 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
218 |
219 | configstore@^5.0.1:
220 | version "5.0.1"
221 | resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96"
222 | integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==
223 | dependencies:
224 | dot-prop "^5.2.0"
225 | graceful-fs "^4.1.2"
226 | make-dir "^3.0.0"
227 | unique-string "^2.0.0"
228 | write-file-atomic "^3.0.0"
229 | xdg-basedir "^4.0.0"
230 |
231 | console-control-strings@^1.0.0, console-control-strings@~1.1.0:
232 | version "1.1.0"
233 | resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
234 | integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
235 |
236 | core-util-is@~1.0.0:
237 | version "1.0.2"
238 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
239 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
240 |
241 | crypto-random-string@^2.0.0:
242 | version "2.0.0"
243 | resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5"
244 | integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==
245 |
246 | debug@^3.2.6:
247 | version "3.2.7"
248 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
249 | integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
250 | dependencies:
251 | ms "^2.1.1"
252 |
253 | decompress-response@^3.3.0:
254 | version "3.3.0"
255 | resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
256 | integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=
257 | dependencies:
258 | mimic-response "^1.0.0"
259 |
260 | decompress-response@^4.2.0:
261 | version "4.2.1"
262 | resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986"
263 | integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==
264 | dependencies:
265 | mimic-response "^2.0.0"
266 |
267 | deep-extend@^0.6.0:
268 | version "0.6.0"
269 | resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
270 | integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
271 |
272 | defer-to-connect@^1.0.1:
273 | version "1.1.3"
274 | resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591"
275 | integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==
276 |
277 | delegates@^1.0.0:
278 | version "1.0.0"
279 | resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
280 | integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=
281 |
282 | detect-libc@^1.0.2:
283 | version "1.0.3"
284 | resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
285 | integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
286 |
287 | diff@^4.0.1:
288 | version "4.0.2"
289 | resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
290 | integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
291 |
292 | dot-prop@^5.2.0:
293 | version "5.3.0"
294 | resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88"
295 | integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==
296 | dependencies:
297 | is-obj "^2.0.0"
298 |
299 | duplexer3@^0.1.4:
300 | version "0.1.4"
301 | resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
302 | integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
303 |
304 | emoji-regex@^7.0.1:
305 | version "7.0.3"
306 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
307 | integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
308 |
309 | emoji-regex@^8.0.0:
310 | version "8.0.0"
311 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
312 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
313 |
314 | end-of-stream@^1.1.0:
315 | version "1.4.4"
316 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
317 | integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
318 | dependencies:
319 | once "^1.4.0"
320 |
321 | escape-goat@^2.0.0:
322 | version "2.1.1"
323 | resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675"
324 | integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==
325 |
326 | fs-minipass@^1.2.5:
327 | version "1.2.7"
328 | resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7"
329 | integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==
330 | dependencies:
331 | minipass "^2.6.0"
332 |
333 | fs.realpath@^1.0.0:
334 | version "1.0.0"
335 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
336 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
337 |
338 | gauge@~2.7.3:
339 | version "2.7.4"
340 | resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
341 | integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=
342 | dependencies:
343 | aproba "^1.0.3"
344 | console-control-strings "^1.0.0"
345 | has-unicode "^2.0.0"
346 | object-assign "^4.1.0"
347 | signal-exit "^3.0.0"
348 | string-width "^1.0.1"
349 | strip-ansi "^3.0.1"
350 | wide-align "^1.1.0"
351 |
352 | get-stream@^4.1.0:
353 | version "4.1.0"
354 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
355 | integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
356 | dependencies:
357 | pump "^3.0.0"
358 |
359 | get-stream@^5.1.0:
360 | version "5.2.0"
361 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
362 | integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
363 | dependencies:
364 | pump "^3.0.0"
365 |
366 | glob@^7.1.3:
367 | version "7.1.6"
368 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
369 | integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
370 | dependencies:
371 | fs.realpath "^1.0.0"
372 | inflight "^1.0.4"
373 | inherits "2"
374 | minimatch "^3.0.4"
375 | once "^1.3.0"
376 | path-is-absolute "^1.0.0"
377 |
378 | global-dirs@^2.0.1:
379 | version "2.1.0"
380 | resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.1.0.tgz#e9046a49c806ff04d6c1825e196c8f0091e8df4d"
381 | integrity sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==
382 | dependencies:
383 | ini "1.3.7"
384 |
385 | got@^9.6.0:
386 | version "9.6.0"
387 | resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85"
388 | integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==
389 | dependencies:
390 | "@sindresorhus/is" "^0.14.0"
391 | "@szmarczak/http-timer" "^1.1.2"
392 | cacheable-request "^6.0.0"
393 | decompress-response "^3.3.0"
394 | duplexer3 "^0.1.4"
395 | get-stream "^4.1.0"
396 | lowercase-keys "^1.0.1"
397 | mimic-response "^1.0.1"
398 | p-cancelable "^1.0.0"
399 | to-readable-stream "^1.0.0"
400 | url-parse-lax "^3.0.0"
401 |
402 | graceful-fs@^4.1.2:
403 | version "4.2.6"
404 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
405 | integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
406 |
407 | has-flag@^4.0.0:
408 | version "4.0.0"
409 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
410 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
411 |
412 | has-unicode@^2.0.0:
413 | version "2.0.1"
414 | resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
415 | integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=
416 |
417 | has-yarn@^2.1.0:
418 | version "2.1.0"
419 | resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77"
420 | integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==
421 |
422 | http-cache-semantics@^4.0.0:
423 | version "4.1.0"
424 | resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
425 | integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==
426 |
427 | iconv-lite@^0.4.4:
428 | version "0.4.24"
429 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
430 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
431 | dependencies:
432 | safer-buffer ">= 2.1.2 < 3"
433 |
434 | ignore-walk@^3.0.1:
435 | version "3.0.3"
436 | resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37"
437 | integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==
438 | dependencies:
439 | minimatch "^3.0.4"
440 |
441 | import-lazy@^2.1.0:
442 | version "2.1.0"
443 | resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43"
444 | integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=
445 |
446 | imurmurhash@^0.1.4:
447 | version "0.1.4"
448 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
449 | integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
450 |
451 | inflight@^1.0.4:
452 | version "1.0.6"
453 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
454 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
455 | dependencies:
456 | once "^1.3.0"
457 | wrappy "1"
458 |
459 | inherits@2, inherits@~2.0.3:
460 | version "2.0.4"
461 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
462 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
463 |
464 | ini@1.3.7:
465 | version "1.3.7"
466 | resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84"
467 | integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==
468 |
469 | ini@~1.3.0:
470 | version "1.3.8"
471 | resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
472 | integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
473 |
474 | is-ci@^2.0.0:
475 | version "2.0.0"
476 | resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c"
477 | integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==
478 | dependencies:
479 | ci-info "^2.0.0"
480 |
481 | is-fullwidth-code-point@^1.0.0:
482 | version "1.0.0"
483 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
484 | integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs=
485 | dependencies:
486 | number-is-nan "^1.0.0"
487 |
488 | is-fullwidth-code-point@^2.0.0:
489 | version "2.0.0"
490 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
491 | integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
492 |
493 | is-fullwidth-code-point@^3.0.0:
494 | version "3.0.0"
495 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
496 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
497 |
498 | is-installed-globally@^0.3.1:
499 | version "0.3.2"
500 | resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141"
501 | integrity sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==
502 | dependencies:
503 | global-dirs "^2.0.1"
504 | is-path-inside "^3.0.1"
505 |
506 | is-npm@^4.0.0:
507 | version "4.0.0"
508 | resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d"
509 | integrity sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==
510 |
511 | is-obj@^2.0.0:
512 | version "2.0.0"
513 | resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982"
514 | integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==
515 |
516 | is-path-inside@^3.0.1:
517 | version "3.0.3"
518 | resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
519 | integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
520 |
521 | is-typedarray@^1.0.0:
522 | version "1.0.0"
523 | resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
524 | integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
525 |
526 | is-yarn-global@^0.3.0:
527 | version "0.3.0"
528 | resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232"
529 | integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==
530 |
531 | isarray@~1.0.0:
532 | version "1.0.0"
533 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
534 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
535 |
536 | json-buffer@3.0.0:
537 | version "3.0.0"
538 | resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
539 | integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=
540 |
541 | keyv@^3.0.0:
542 | version "3.1.0"
543 | resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9"
544 | integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==
545 | dependencies:
546 | json-buffer "3.0.0"
547 |
548 | latest-version@^5.0.0:
549 | version "5.1.0"
550 | resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face"
551 | integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==
552 | dependencies:
553 | package-json "^6.3.0"
554 |
555 | lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
556 | version "1.0.1"
557 | resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
558 | integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==
559 |
560 | lowercase-keys@^2.0.0:
561 | version "2.0.0"
562 | resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
563 | integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
564 |
565 | make-dir@^3.0.0:
566 | version "3.1.0"
567 | resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
568 | integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==
569 | dependencies:
570 | semver "^6.0.0"
571 |
572 | make-error@^1.1.1:
573 | version "1.3.6"
574 | resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
575 | integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
576 |
577 | mimic-response@^1.0.0, mimic-response@^1.0.1:
578 | version "1.0.1"
579 | resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
580 | integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
581 |
582 | mimic-response@^2.0.0:
583 | version "2.1.0"
584 | resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43"
585 | integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==
586 |
587 | minimatch@^3.0.4:
588 | version "3.0.4"
589 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
590 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
591 | dependencies:
592 | brace-expansion "^1.1.7"
593 |
594 | minimist@^1.2.0, minimist@^1.2.5:
595 | version "1.2.5"
596 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
597 | integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
598 |
599 | minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0:
600 | version "2.9.0"
601 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6"
602 | integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==
603 | dependencies:
604 | safe-buffer "^5.1.2"
605 | yallist "^3.0.0"
606 |
607 | minizlib@^1.2.1:
608 | version "1.3.3"
609 | resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d"
610 | integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==
611 | dependencies:
612 | minipass "^2.9.0"
613 |
614 | mkdirp@^0.5.0, mkdirp@^0.5.3:
615 | version "0.5.5"
616 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
617 | integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
618 | dependencies:
619 | minimist "^1.2.5"
620 |
621 | ms@^2.1.1:
622 | version "2.1.3"
623 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
624 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
625 |
626 | nan@^2.14.0:
627 | version "2.14.2"
628 | resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
629 | integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==
630 |
631 | needle@^2.5.0:
632 | version "2.6.0"
633 | resolved "https://registry.yarnpkg.com/needle/-/needle-2.6.0.tgz#24dbb55f2509e2324b4a99d61f413982013ccdbe"
634 | integrity sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==
635 | dependencies:
636 | debug "^3.2.6"
637 | iconv-lite "^0.4.4"
638 | sax "^1.2.4"
639 |
640 | node-pre-gyp@^0.15.0:
641 | version "0.15.0"
642 | resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.15.0.tgz#c2fc383276b74c7ffa842925241553e8b40f1087"
643 | integrity sha512-7QcZa8/fpaU/BKenjcaeFF9hLz2+7S9AqyXFhlH/rilsQ/hPZKK32RtR5EQHJElgu+q5RfbJ34KriI79UWaorA==
644 | dependencies:
645 | detect-libc "^1.0.2"
646 | mkdirp "^0.5.3"
647 | needle "^2.5.0"
648 | nopt "^4.0.1"
649 | npm-packlist "^1.1.6"
650 | npmlog "^4.0.2"
651 | rc "^1.2.7"
652 | rimraf "^2.6.1"
653 | semver "^5.3.0"
654 | tar "^4.4.2"
655 |
656 | nopt@^4.0.1:
657 | version "4.0.3"
658 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48"
659 | integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==
660 | dependencies:
661 | abbrev "1"
662 | osenv "^0.1.4"
663 |
664 | normalize-url@^4.1.0:
665 | version "4.5.0"
666 | resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129"
667 | integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==
668 |
669 | npm-bundled@^1.0.1:
670 | version "1.1.1"
671 | resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b"
672 | integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==
673 | dependencies:
674 | npm-normalize-package-bin "^1.0.1"
675 |
676 | npm-normalize-package-bin@^1.0.1:
677 | version "1.0.1"
678 | resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2"
679 | integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==
680 |
681 | npm-packlist@^1.1.6:
682 | version "1.4.8"
683 | resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e"
684 | integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==
685 | dependencies:
686 | ignore-walk "^3.0.1"
687 | npm-bundled "^1.0.1"
688 | npm-normalize-package-bin "^1.0.1"
689 |
690 | npmlog@^4.0.2:
691 | version "4.1.2"
692 | resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
693 | integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
694 | dependencies:
695 | are-we-there-yet "~1.1.2"
696 | console-control-strings "~1.1.0"
697 | gauge "~2.7.3"
698 | set-blocking "~2.0.0"
699 |
700 | number-is-nan@^1.0.0:
701 | version "1.0.1"
702 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
703 | integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
704 |
705 | object-assign@^4.1.0:
706 | version "4.1.1"
707 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
708 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
709 |
710 | once@^1.3.0, once@^1.3.1, once@^1.4.0:
711 | version "1.4.0"
712 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
713 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
714 | dependencies:
715 | wrappy "1"
716 |
717 | os-homedir@^1.0.0:
718 | version "1.0.2"
719 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
720 | integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
721 |
722 | os-tmpdir@^1.0.0:
723 | version "1.0.2"
724 | resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
725 | integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
726 |
727 | osenv@^0.1.4:
728 | version "0.1.5"
729 | resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410"
730 | integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==
731 | dependencies:
732 | os-homedir "^1.0.0"
733 | os-tmpdir "^1.0.0"
734 |
735 | p-cancelable@^1.0.0:
736 | version "1.1.0"
737 | resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc"
738 | integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==
739 |
740 | package-json@^6.3.0:
741 | version "6.5.0"
742 | resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0"
743 | integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==
744 | dependencies:
745 | got "^9.6.0"
746 | registry-auth-token "^4.0.0"
747 | registry-url "^5.0.0"
748 | semver "^6.2.0"
749 |
750 | path-is-absolute@^1.0.0:
751 | version "1.0.1"
752 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
753 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
754 |
755 | prepend-http@^2.0.0:
756 | version "2.0.0"
757 | resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
758 | integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
759 |
760 | process-nextick-args@~2.0.0:
761 | version "2.0.1"
762 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
763 | integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
764 |
765 | pump@^3.0.0:
766 | version "3.0.0"
767 | resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
768 | integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
769 | dependencies:
770 | end-of-stream "^1.1.0"
771 | once "^1.3.1"
772 |
773 | pupa@^2.0.1:
774 | version "2.1.1"
775 | resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62"
776 | integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==
777 | dependencies:
778 | escape-goat "^2.0.0"
779 |
780 | rc@^1.2.7, rc@^1.2.8:
781 | version "1.2.8"
782 | resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
783 | integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
784 | dependencies:
785 | deep-extend "^0.6.0"
786 | ini "~1.3.0"
787 | minimist "^1.2.0"
788 | strip-json-comments "~2.0.1"
789 |
790 | readable-stream@^2.0.6:
791 | version "2.3.7"
792 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
793 | integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
794 | dependencies:
795 | core-util-is "~1.0.0"
796 | inherits "~2.0.3"
797 | isarray "~1.0.0"
798 | process-nextick-args "~2.0.0"
799 | safe-buffer "~5.1.1"
800 | string_decoder "~1.1.1"
801 | util-deprecate "~1.0.1"
802 |
803 | registry-auth-token@^4.0.0:
804 | version "4.2.1"
805 | resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250"
806 | integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==
807 | dependencies:
808 | rc "^1.2.8"
809 |
810 | registry-url@^5.0.0:
811 | version "5.1.0"
812 | resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009"
813 | integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==
814 | dependencies:
815 | rc "^1.2.8"
816 |
817 | responselike@^1.0.2:
818 | version "1.0.2"
819 | resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7"
820 | integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=
821 | dependencies:
822 | lowercase-keys "^1.0.0"
823 |
824 | rimraf@^2.6.1:
825 | version "2.7.1"
826 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
827 | integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
828 | dependencies:
829 | glob "^7.1.3"
830 |
831 | safe-buffer@^5.1.2:
832 | version "5.2.1"
833 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
834 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
835 |
836 | safe-buffer@~5.1.0, safe-buffer@~5.1.1:
837 | version "5.1.2"
838 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
839 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
840 |
841 | "safer-buffer@>= 2.1.2 < 3":
842 | version "2.1.2"
843 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
844 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
845 |
846 | sax@^1.2.4:
847 | version "1.2.4"
848 | resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
849 | integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
850 |
851 | seedrandom@^3.0.5:
852 | version "3.0.5"
853 | resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7"
854 | integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==
855 |
856 | semver-diff@^3.1.1:
857 | version "3.1.1"
858 | resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b"
859 | integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==
860 | dependencies:
861 | semver "^6.3.0"
862 |
863 | semver@^5.3.0:
864 | version "5.7.1"
865 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
866 | integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
867 |
868 | semver@^6.0.0, semver@^6.2.0, semver@^6.3.0:
869 | version "6.3.0"
870 | resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
871 | integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
872 |
873 | set-blocking@~2.0.0:
874 | version "2.0.0"
875 | resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
876 | integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
877 |
878 | signal-exit@^3.0.0, signal-exit@^3.0.2:
879 | version "3.0.3"
880 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
881 | integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
882 |
883 | simple-concat@^1.0.0:
884 | version "1.0.1"
885 | resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f"
886 | integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==
887 |
888 | simple-get@^3.0.3:
889 | version "3.1.0"
890 | resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.0.tgz#b45be062435e50d159540b576202ceec40b9c6b3"
891 | integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==
892 | dependencies:
893 | decompress-response "^4.2.0"
894 | once "^1.3.1"
895 | simple-concat "^1.0.0"
896 |
897 | source-map-support@^0.5.17:
898 | version "0.5.19"
899 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
900 | integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
901 | dependencies:
902 | buffer-from "^1.0.0"
903 | source-map "^0.6.0"
904 |
905 | source-map@^0.6.0:
906 | version "0.6.1"
907 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
908 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
909 |
910 | string-width@^1.0.1:
911 | version "1.0.2"
912 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
913 | integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=
914 | dependencies:
915 | code-point-at "^1.0.0"
916 | is-fullwidth-code-point "^1.0.0"
917 | strip-ansi "^3.0.0"
918 |
919 | "string-width@^1.0.2 || 2":
920 | version "2.1.1"
921 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
922 | integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
923 | dependencies:
924 | is-fullwidth-code-point "^2.0.0"
925 | strip-ansi "^4.0.0"
926 |
927 | string-width@^3.0.0:
928 | version "3.1.0"
929 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
930 | integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==
931 | dependencies:
932 | emoji-regex "^7.0.1"
933 | is-fullwidth-code-point "^2.0.0"
934 | strip-ansi "^5.1.0"
935 |
936 | string-width@^4.0.0, string-width@^4.1.0:
937 | version "4.2.2"
938 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5"
939 | integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==
940 | dependencies:
941 | emoji-regex "^8.0.0"
942 | is-fullwidth-code-point "^3.0.0"
943 | strip-ansi "^6.0.0"
944 |
945 | string_decoder@~1.1.1:
946 | version "1.1.1"
947 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
948 | integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
949 | dependencies:
950 | safe-buffer "~5.1.0"
951 |
952 | strip-ansi@^3.0.0, strip-ansi@^3.0.1:
953 | version "3.0.1"
954 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
955 | integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
956 | dependencies:
957 | ansi-regex "^2.0.0"
958 |
959 | strip-ansi@^4.0.0:
960 | version "4.0.0"
961 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
962 | integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8=
963 | dependencies:
964 | ansi-regex "^3.0.0"
965 |
966 | strip-ansi@^5.1.0:
967 | version "5.2.0"
968 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
969 | integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
970 | dependencies:
971 | ansi-regex "^4.1.0"
972 |
973 | strip-ansi@^6.0.0:
974 | version "6.0.0"
975 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
976 | integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==
977 | dependencies:
978 | ansi-regex "^5.0.0"
979 |
980 | strip-json-comments@~2.0.1:
981 | version "2.0.1"
982 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
983 | integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
984 |
985 | supports-color@^7.1.0:
986 | version "7.2.0"
987 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
988 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
989 | dependencies:
990 | has-flag "^4.0.0"
991 |
992 | tar@^4.4.2:
993 | version "4.4.13"
994 | resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
995 | integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==
996 | dependencies:
997 | chownr "^1.1.1"
998 | fs-minipass "^1.2.5"
999 | minipass "^2.8.6"
1000 | minizlib "^1.2.1"
1001 | mkdirp "^0.5.0"
1002 | safe-buffer "^5.1.2"
1003 | yallist "^3.0.3"
1004 |
1005 | term-size@^2.1.0:
1006 | version "2.2.1"
1007 | resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54"
1008 | integrity sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==
1009 |
1010 | tinycolor2@^1.4.2:
1011 | version "1.4.2"
1012 | resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803"
1013 | integrity sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==
1014 |
1015 | to-readable-stream@^1.0.0:
1016 | version "1.0.0"
1017 | resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771"
1018 | integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==
1019 |
1020 | ts-node@8.9.1:
1021 | version "8.9.1"
1022 | resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.9.1.tgz#2f857f46c47e91dcd28a14e052482eb14cfd65a5"
1023 | integrity sha512-yrq6ODsxEFTLz0R3BX2myf0WBCSQh9A+py8PBo1dCzWIOcvisbyH6akNKqDHMgXePF2kir5mm5JXJTH3OUJYOQ==
1024 | dependencies:
1025 | arg "^4.1.0"
1026 | diff "^4.0.1"
1027 | make-error "^1.1.1"
1028 | source-map-support "^0.5.17"
1029 | yn "3.1.1"
1030 |
1031 | type-fest@^0.8.1:
1032 | version "0.8.1"
1033 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
1034 | integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
1035 |
1036 | typedarray-to-buffer@^3.1.5:
1037 | version "3.1.5"
1038 | resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
1039 | integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==
1040 | dependencies:
1041 | is-typedarray "^1.0.0"
1042 |
1043 | typescript@3.9.3:
1044 | version "3.9.3"
1045 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.3.tgz#d3ac8883a97c26139e42df5e93eeece33d610b8a"
1046 | integrity sha512-D/wqnB2xzNFIcoBG9FG8cXRDjiqSTbG2wd8DMZeQyJlP1vfTkIxH4GKveWaEBYySKIg+USu+E+EDIR47SqnaMQ==
1047 |
1048 | unique-string@^2.0.0:
1049 | version "2.0.0"
1050 | resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d"
1051 | integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==
1052 | dependencies:
1053 | crypto-random-string "^2.0.0"
1054 |
1055 | update-notifier@4.1.0:
1056 | version "4.1.0"
1057 | resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.0.tgz#4866b98c3bc5b5473c020b1250583628f9a328f3"
1058 | integrity sha512-w3doE1qtI0/ZmgeoDoARmI5fjDoT93IfKgEGqm26dGUOh8oNpaSTsGNdYRN/SjOuo10jcJGwkEL3mroKzktkew==
1059 | dependencies:
1060 | boxen "^4.2.0"
1061 | chalk "^3.0.0"
1062 | configstore "^5.0.1"
1063 | has-yarn "^2.1.0"
1064 | import-lazy "^2.1.0"
1065 | is-ci "^2.0.0"
1066 | is-installed-globally "^0.3.1"
1067 | is-npm "^4.0.0"
1068 | is-yarn-global "^0.3.0"
1069 | latest-version "^5.0.0"
1070 | pupa "^2.0.1"
1071 | semver-diff "^3.1.1"
1072 | xdg-basedir "^4.0.0"
1073 |
1074 | url-parse-lax@^3.0.0:
1075 | version "3.0.0"
1076 | resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c"
1077 | integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=
1078 | dependencies:
1079 | prepend-http "^2.0.0"
1080 |
1081 | util-deprecate@~1.0.1:
1082 | version "1.0.2"
1083 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
1084 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
1085 |
1086 | vercel@^21.3.3:
1087 | version "21.3.3"
1088 | resolved "https://registry.yarnpkg.com/vercel/-/vercel-21.3.3.tgz#22af77308cf612699c652ad49ecedc60eaa0b38f"
1089 | integrity sha512-NhxhAmpUoymKQp2WT0PR+NgFPcoVRuhYJ7HSSPKP+S0UCQtZNhy9YCeMkbBzooAw9rrb8gEH+ODEbhK0u5YlFg==
1090 | dependencies:
1091 | "@vercel/build-utils" "2.10.1"
1092 | "@vercel/go" "1.2.2"
1093 | "@vercel/node" "1.9.1"
1094 | "@vercel/python" "2.0.1"
1095 | "@vercel/ruby" "1.2.6"
1096 | update-notifier "4.1.0"
1097 |
1098 | wide-align@^1.1.0:
1099 | version "1.1.3"
1100 | resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"
1101 | integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==
1102 | dependencies:
1103 | string-width "^1.0.2 || 2"
1104 |
1105 | widest-line@^3.1.0:
1106 | version "3.1.0"
1107 | resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca"
1108 | integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==
1109 | dependencies:
1110 | string-width "^4.0.0"
1111 |
1112 | wrappy@1:
1113 | version "1.0.2"
1114 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
1115 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
1116 |
1117 | write-file-atomic@^3.0.0:
1118 | version "3.0.3"
1119 | resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8"
1120 | integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==
1121 | dependencies:
1122 | imurmurhash "^0.1.4"
1123 | is-typedarray "^1.0.0"
1124 | signal-exit "^3.0.2"
1125 | typedarray-to-buffer "^3.1.5"
1126 |
1127 | xdg-basedir@^4.0.0:
1128 | version "4.0.0"
1129 | resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"
1130 | integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==
1131 |
1132 | yallist@^3.0.0, yallist@^3.0.3:
1133 | version "3.1.1"
1134 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
1135 | integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
1136 |
1137 | yn@3.1.1:
1138 | version "3.1.1"
1139 | resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
1140 | integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
1141 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "downlevelIteration": true,
10 | "allowJs": true,
11 | "skipLibCheck": true,
12 | "esModuleInterop": true,
13 | "allowSyntheticDefaultImports": true,
14 | "strict": true,
15 | "forceConsistentCasingInFileNames": true,
16 | "noFallthroughCasesInSwitch": true,
17 | "module": "esnext",
18 | "moduleResolution": "node",
19 | "resolveJsonModule": true,
20 | "isolatedModules": true,
21 | "noEmit": true,
22 | "jsx": "react-jsx"
23 | }
24 | }
--------------------------------------------------------------------------------