Merge pull request #1249 from bakkenbaeck/dev-tools-pages

Dev tools pages
This commit is contained in:
Fabio B 2019-01-09 16:22:59 +01:00 committed by GitHub
commit 08d0ff48c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
86 changed files with 5708 additions and 1277 deletions

View File

@ -4,7 +4,7 @@ jobs:
build: build:
resource_class: medium+ resource_class: medium+
docker: docker:
- image: circleci/node:9 - image: circleci/node:9-browsers
environment: environment:
CONTRACTS_COMMIT_HASH: '9ed05f5' CONTRACTS_COMMIT_HASH: '9ed05f5'
working_directory: ~/repo working_directory: ~/repo
@ -16,7 +16,7 @@ jobs:
command: sudo npm install --global yarn@1.9.4 command: sudo npm install --global yarn@1.9.4
- run: - run:
name: yarn name: yarn
command: yarn --frozen-lockfile install || yarn --frozen-lockfile install command: yarn --frozen-lockfile --ignore-engines install || yarn --frozen-lockfile --ignore-engines install
- run: yarn build:ci:no_website - run: yarn build:ci:no_website
- run: yarn build:ts - run: yarn build:ts
- save_cache: - save_cache:
@ -26,7 +26,7 @@ jobs:
build-website: build-website:
resource_class: medium+ resource_class: medium+
docker: docker:
- image: circleci/node:9 - image: circleci/node:9-browsers
working_directory: ~/repo working_directory: ~/repo
steps: steps:
- restore_cache: - restore_cache:
@ -35,7 +35,7 @@ jobs:
- run: cd packages/website && yarn build:prod - run: cd packages/website && yarn build:prod
test-contracts-ganache: test-contracts-ganache:
docker: docker:
- image: circleci/node:9 - image: circleci/node:9-browsers
working_directory: ~/repo working_directory: ~/repo
steps: steps:
- restore_cache: - restore_cache:
@ -49,7 +49,7 @@ jobs:
- run: yarn wsrun test:circleci @0x/contracts-protocol - run: yarn wsrun test:circleci @0x/contracts-protocol
test-contracts-geth: test-contracts-geth:
docker: docker:
- image: circleci/node:9 - image: circleci/node:9-browsers
- image: 0xorg/devnet - image: 0xorg/devnet
working_directory: ~/repo working_directory: ~/repo
steps: steps:
@ -67,7 +67,7 @@ jobs:
test-publish: test-publish:
resource_class: medium+ resource_class: medium+
docker: docker:
- image: circleci/node:9 - image: circleci/node:9-browsers
- image: 0xorg/verdaccio - image: 0xorg/verdaccio
working_directory: ~/repo working_directory: ~/repo
steps: steps:
@ -77,7 +77,7 @@ jobs:
- run: yarn test:publish:circleci - run: yarn test:publish:circleci
test-doc-generation: test-doc-generation:
docker: docker:
- image: circleci/node:9 - image: circleci/node:9-browsers
working_directory: ~/repo working_directory: ~/repo
steps: steps:
- restore_cache: - restore_cache:
@ -100,7 +100,7 @@ jobs:
- ~/repo/packages/pipeline/coverage/lcov.info - ~/repo/packages/pipeline/coverage/lcov.info
test-rest: test-rest:
docker: docker:
- image: circleci/node:9 - image: circleci/node:9-browsers
working_directory: ~/repo working_directory: ~/repo
steps: steps:
- restore_cache: - restore_cache:
@ -283,7 +283,7 @@ jobs:
static-tests: static-tests:
working_directory: ~/repo working_directory: ~/repo
docker: docker:
- image: circleci/node:9 - image: circleci/node:9-browsers
steps: steps:
- restore_cache: - restore_cache:
keys: keys:
@ -294,7 +294,7 @@ jobs:
- run: yarn bundlewatch - run: yarn bundlewatch
submit-coverage: submit-coverage:
docker: docker:
- image: circleci/node:9 - image: circleci/node:9-browsers
working_directory: ~/repo working_directory: ~/repo
steps: steps:
- restore_cache: - restore_cache:

View File

@ -24,6 +24,7 @@ lib
/packages/metacoin/src/contract_wrappers /packages/metacoin/src/contract_wrappers
/packages/metacoin/artifacts /packages/metacoin/artifacts
/packages/sra-spec/public/ /packages/sra-spec/public/
/packages/dev-tools-pages/ts/**/data.json
package.json package.json
scripts/postpublish_utils.js scripts/postpublish_utils.js
packages/sol-cov/test/fixtures/artifacts packages/sol-cov/test/fixtures/artifacts

View File

@ -62,6 +62,9 @@
"repoBranchBase": "development" "repoBranchBase": "development"
} }
}, },
"resolutions": {
"graceful-fs": "4.1.15"
},
"devDependencies": { "devDependencies": {
"@0x-lerna-fork/lerna": "3.0.0-beta.26", "@0x-lerna-fork/lerna": "3.0.0-beta.26",
"@0xproject/npm-cli-login": "^0.0.11", "@0xproject/npm-cli-login": "^0.0.11",

3
packages/dev-tools-pages/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
public
assets/fonts/*.woff
assets/fonts/*.woff2

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<ul>
<li><a href="/compiler">Compiler</a></li>
<li><a href="/cov">Cov</a></li>
<li><a href="/profiler">Profiler</a></li>
<li><a href="/trace">Trace</a></li>
</ul>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="preload" href="/fonts/MaisonNeue-Book-subset.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/fonts/MaisonNeue-Bold-subset.woff2" as="font" type="font/woff2" crossorigin>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<div id="app"></div>
</body>
</html>

View File

@ -7,7 +7,7 @@
"private": true, "private": true,
"description": "0x Dev tools pages", "description": "0x Dev tools pages",
"scripts": { "scripts": {
"build": "node --max_old_space_size=8192 ../../node_modules/.bin/webpack --mode production", "build": "node --max_old_space_size=8192 ../../node_modules/.bin/webpack --mode production && react-snap",
"build:ci": "yarn build", "build:ci": "yarn build",
"build:dev": "../../node_modules/.bin/webpack --mode development", "build:dev": "../../node_modules/.bin/webpack --mode development",
"clean": "shx rm -f public/bundle*", "clean": "shx rm -f public/bundle*",
@ -19,30 +19,40 @@
"@0x/react-shared": "^1.1.0", "@0x/react-shared": "^1.1.0",
"basscss": "^8.0.3", "basscss": "^8.0.3",
"bowser": "^1.9.3", "bowser": "^1.9.3",
"highlight.js": "^9.13.1",
"less": "^2.7.2", "less": "^2.7.2",
"lodash": "^4.17.5",
"polished": "^1.9.2", "polished": "^1.9.2",
"react": "^16.4.2", "react": "^16.5.2",
"react-document-title": "^2.0.3", "react-dom": "^16.5.2",
"react-dom": "^16.4.2", "react-loadable": "^5.5.0",
"react-helmet": "^5.2.0", "react-lottie": "^1.2.3",
"styled-components": "^3.3.0" "react-tabs": "^2.3.0",
"styled-components": "^4.1.1",
"styled-normalize": "^8.0.1"
}, },
"devDependencies": { "devDependencies": {
"@types/highlight.js": "^9.12.3",
"@types/lodash": "4.14.104", "@types/lodash": "4.14.104",
"@types/node": "*", "@types/node": "*",
"@types/react": "^16.4.2", "@types/react": "^16.4.2",
"@types/react-dom": "^16.0.7", "@types/react-dom": "^16.0.7",
"@types/react-helmet": "^5.0.6", "@types/react-loadable": "^5.4.1",
"@types/react-lottie": "^1.2.0",
"@types/react-router-dom": "^4.0.4", "@types/react-router-dom": "^4.0.4",
"@types/react-tabs": "^2.3.0",
"@types/react-tap-event-plugin": "0.0.30", "@types/react-tap-event-plugin": "0.0.30",
"@types/styled-components": "^4.0.0", "@types/styled-components": "4.1.1",
"awesome-typescript-loader": "^5.2.1", "awesome-typescript-loader": "^5.2.1",
"clean-webpack-plugin": "^0.1.19",
"copy-webpack-plugin": "^4.5.4",
"copyfiles": "^2.0.0", "copyfiles": "^2.0.0",
"css-loader": "0.23.x", "css-loader": "0.23.x",
"html-webpack-plugin": "^3.2.0",
"less-loader": "^4.1.0", "less-loader": "^4.1.0",
"make-promises-safe": "^1.1.0", "make-promises-safe": "^1.1.0",
"raw-loader": "^0.5.1", "raw-loader": "^0.5.1",
"react-snap": "^1.19.0",
"react-svg-loader": "^2.1.0",
"shx": "^0.2.2", "shx": "^0.2.2",
"source-map-loader": "^0.2.4", "source-map-loader": "^0.2.4",
"style-loader": "0.23.x", "style-loader": "0.23.x",
@ -52,7 +62,15 @@
"typescript": "3.0.1", "typescript": "3.0.1",
"uglifyjs-webpack-plugin": "^2.0.1", "uglifyjs-webpack-plugin": "^2.0.1",
"webpack": "^4.20.2", "webpack": "^4.20.2",
"webpack-bundle-analyzer": "^3.0.3",
"webpack-cli": "3.1.2", "webpack-cli": "3.1.2",
"webpack-dev-server": "^3.1.9" "webpack-dev-server": "^3.1.9"
},
"reactSnap": {
"source": "public",
"puppeteerArgs": [
"--no-sandbox",
"--disable-setuid-sandbox"
]
} }
} }

View File

@ -0,0 +1,72 @@
const pages = [
{
title: 'sol-compiler',
filename: 'compiler/index.html',
template: 'assets/index.html',
chunks: ['compiler'],
favicon: 'assets/favicons/compiler.ico',
minify: true,
meta: {
description: 'Solidity compilation that just works',
'og-title': { property: 'og:title', content: 'sol-compiler' },
'og-description': { property: 'og:description', content: 'Solidity compilation that just works' },
'og-type': { property: 'og:type', content: 'website' },
'og-image': { property: 'og:image', content: '/images/og-compiler' },
'twitter:site': '@0xproject',
'twitter:image': '/images/og-compiler',
},
},
{
title: 'sol-cov',
filename: 'cov/index.html',
template: 'assets/index.html',
chunks: ['cov'],
favicon: 'assets/favicons/cov.ico',
minify: true,
meta: {
description: 'Solidity code coverage',
'og-title': { property: 'og:title', content: 'sol-cov' },
'og-description': { property: 'og:description', content: 'Solidity code coverage' },
'og-type': { property: 'og:type', content: 'website' },
'og-image': { property: 'og:image', content: '/images/og-cov' },
'twitter:site': '@0xproject',
'twitter:image': '/images/og-cov',
},
},
{
title: 'sol-profiler',
filename: 'profiler/index.html',
template: 'assets/index.html',
chunks: ['profiler'],
favicon: 'assets/favicons/profiler.ico',
minify: true,
meta: {
description: 'Gas profiling for Solidity',
'og-title': { property: 'og:title', content: 'sol-profiler' },
'og-description': { property: 'og:description', content: 'Gas profiling for Solidity' },
'og-type': { property: 'og:type', content: 'website' },
'og-image': { property: 'og:image', content: '/images/og-profiler' },
'twitter:site': '@0xproject',
'twitter:image': '/images/og-profiler',
},
},
{
title: 'sol-trace',
filename: 'trace/index.html',
template: 'assets/index.html',
chunks: ['trace'],
favicon: 'assets/favicons/trace.ico',
minify: true,
meta: {
description: 'Human-readable stack traces',
'og-title': { property: 'og:title', content: 'sol-trace' },
'og-description': { property: 'og:description', content: 'Human-readable stack traces' },
'og-type': { property: 'og:type', content: 'website' },
'og-image': { property: 'og:image', content: '/images/og-trace' },
'twitter:site': '@0xproject',
'twitter:image': '/images/og-trace',
},
},
];
module.exports = pages;

View File

@ -1,85 +0,0 @@
/* Custom Basscss Responsive Utilities */
@media (max-width: 52em) {
.sm-center {
text-align: center;
}
.sm-align-middle {
vertical-align: middle;
}
.sm-align-top {
vertical-align: top;
}
.sm-left-align {
text-align: left;
}
.sm-right-align {
text-align: right;
}
.sm-table-cell {
display: table-cell;
}
.sm-mx-auto {
margin-left: auto;
margin-right: auto;
}
.sm-right {
float: right;
}
}
@media (min-width: 52em) {
.md-center {
text-align: center;
}
.md-align-middle {
vertical-align: middle;
}
.md-align-top {
vertical-align: top;
}
.md-left-align {
text-align: left;
}
.md-right-align {
text-align: right;
}
.md-table-cell {
display: table-cell;
}
.md-mx-auto {
margin-left: auto;
margin-right: auto;
}
.md-right {
float: right;
}
}
@media (min-width: 64em) {
.lg-center {
text-align: center;
}
.lg-align-middle {
vertical-align: middle;
}
.lg-align-top {
vertical-align: top;
}
.lg-left-align {
text-align: left;
}
.lg-right-align {
text-align: right;
}
.lg-table-cell {
display: table-cell;
}
.lg-mx-auto {
margin-left: auto;
margin-right: auto;
}
.lg-right {
float: right;
}
}

View File

@ -1,453 +0,0 @@
/* Basscss Responsive Margin */
@media (max-width: 52em) {
/* Modified by Fabio Berger to max-width from min-width */
.sm-m0 {
margin: 0;
}
.sm-mt0 {
margin-top: 0;
}
.sm-mr0 {
margin-right: 0;
}
.sm-mb0 {
margin-bottom: 0;
}
.sm-ml0 {
margin-left: 0;
}
.sm-mx0 {
margin-left: 0;
margin-right: 0;
}
.sm-my0 {
margin-top: 0;
margin-bottom: 0;
}
.sm-m1 {
margin: 0.5rem;
}
.sm-mt1 {
margin-top: 0.5rem;
}
.sm-mr1 {
margin-right: 0.5rem;
}
.sm-mb1 {
margin-bottom: 0.5rem;
}
.sm-ml1 {
margin-left: 0.5rem;
}
.sm-mx1 {
margin-left: 0.5rem;
margin-right: 0.5rem;
}
.sm-my1 {
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}
.sm-m2 {
margin: 1rem;
}
.sm-mt2 {
margin-top: 1rem;
}
.sm-mr2 {
margin-right: 1rem;
}
.sm-mb2 {
margin-bottom: 1rem;
}
.sm-ml2 {
margin-left: 1rem;
}
.sm-mx2 {
margin-left: 1rem;
margin-right: 1rem;
}
.sm-my2 {
margin-top: 1rem;
margin-bottom: 1rem;
}
.sm-m3 {
margin: 2rem;
}
.sm-mt3 {
margin-top: 2rem;
}
.sm-mr3 {
margin-right: 2rem;
}
.sm-mb3 {
margin-bottom: 2rem;
}
.sm-ml3 {
margin-left: 2rem;
}
.sm-mx3 {
margin-left: 2rem;
margin-right: 2rem;
}
.sm-my3 {
margin-top: 2rem;
margin-bottom: 2rem;
}
.sm-m4 {
margin: 4rem;
}
.sm-mt4 {
margin-top: 4rem;
}
.sm-mr4 {
margin-right: 4rem;
}
.sm-mb4 {
margin-bottom: 4rem;
}
.sm-ml4 {
margin-left: 4rem;
}
.sm-mx4 {
margin-left: 4rem;
margin-right: 4rem;
}
.sm-my4 {
margin-top: 4rem;
margin-bottom: 4rem;
}
.sm-mxn1 {
margin-left: -0.5rem;
margin-right: -0.5rem;
}
.sm-mxn2 {
margin-left: -1rem;
margin-right: -1rem;
}
.sm-mxn3 {
margin-left: -2rem;
margin-right: -2rem;
}
.sm-mxn4 {
margin-left: -4rem;
margin-right: -4rem;
}
.sm-ml-auto {
margin-left: auto;
}
.sm-mr-auto {
margin-right: auto;
}
.sm-mx-auto {
margin-left: auto;
margin-right: auto;
}
}
@media (min-width: 52em) {
.md-m0 {
margin: 0;
}
.md-mt0 {
margin-top: 0;
}
.md-mr0 {
margin-right: 0;
}
.md-mb0 {
margin-bottom: 0;
}
.md-ml0 {
margin-left: 0;
}
.md-mx0 {
margin-left: 0;
margin-right: 0;
}
.md-my0 {
margin-top: 0;
margin-bottom: 0;
}
.md-m1 {
margin: 0.5rem;
}
.md-mt1 {
margin-top: 0.5rem;
}
.md-mr1 {
margin-right: 0.5rem;
}
.md-mb1 {
margin-bottom: 0.5rem;
}
.md-ml1 {
margin-left: 0.5rem;
}
.md-mx1 {
margin-left: 0.5rem;
margin-right: 0.5rem;
}
.md-my1 {
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}
.md-m2 {
margin: 1rem;
}
.md-mt2 {
margin-top: 1rem;
}
.md-mr2 {
margin-right: 1rem;
}
.md-mb2 {
margin-bottom: 1rem;
}
.md-ml2 {
margin-left: 1rem;
}
.md-mx2 {
margin-left: 1rem;
margin-right: 1rem;
}
.md-my2 {
margin-top: 1rem;
margin-bottom: 1rem;
}
.md-m3 {
margin: 2rem;
}
.md-mt3 {
margin-top: 2rem;
}
.md-mr3 {
margin-right: 2rem;
}
.md-mb3 {
margin-bottom: 2rem;
}
.md-ml3 {
margin-left: 2rem;
}
.md-mx3 {
margin-left: 2rem;
margin-right: 2rem;
}
.md-my3 {
margin-top: 2rem;
margin-bottom: 2rem;
}
.md-m4 {
margin: 4rem;
}
.md-mt4 {
margin-top: 4rem;
}
.md-mr4 {
margin-right: 4rem;
}
.md-mb4 {
margin-bottom: 4rem;
}
.md-ml4 {
margin-left: 4rem;
}
.md-mx4 {
margin-left: 4rem;
margin-right: 4rem;
}
.md-my4 {
margin-top: 4rem;
margin-bottom: 4rem;
}
.md-mxn1 {
margin-left: -0.5rem;
margin-right: -0.5rem;
}
.md-mxn2 {
margin-left: -1rem;
margin-right: -1rem;
}
.md-mxn3 {
margin-left: -2rem;
margin-right: -2rem;
}
.md-mxn4 {
margin-left: -4rem;
margin-right: -4rem;
}
.md-ml-auto {
margin-left: auto;
}
.md-mr-auto {
margin-right: auto;
}
.md-mx-auto {
margin-left: auto;
margin-right: auto;
}
}
@media (min-width: 64em) {
.lg-m0 {
margin: 0;
}
.lg-mt0 {
margin-top: 0;
}
.lg-mr0 {
margin-right: 0;
}
.lg-mb0 {
margin-bottom: 0;
}
.lg-ml0 {
margin-left: 0;
}
.lg-mx0 {
margin-left: 0;
margin-right: 0;
}
.lg-my0 {
margin-top: 0;
margin-bottom: 0;
}
.lg-m1 {
margin: 0.5rem;
}
.lg-mt1 {
margin-top: 0.5rem;
}
.lg-mr1 {
margin-right: 0.5rem;
}
.lg-mb1 {
margin-bottom: 0.5rem;
}
.lg-ml1 {
margin-left: 0.5rem;
}
.lg-mx1 {
margin-left: 0.5rem;
margin-right: 0.5rem;
}
.lg-my1 {
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}
.lg-m2 {
margin: 1rem;
}
.lg-mt2 {
margin-top: 1rem;
}
.lg-mr2 {
margin-right: 1rem;
}
.lg-mb2 {
margin-bottom: 1rem;
}
.lg-ml2 {
margin-left: 1rem;
}
.lg-mx2 {
margin-left: 1rem;
margin-right: 1rem;
}
.lg-my2 {
margin-top: 1rem;
margin-bottom: 1rem;
}
.lg-m3 {
margin: 2rem;
}
.lg-mt3 {
margin-top: 2rem;
}
.lg-mr3 {
margin-right: 2rem;
}
.lg-mb3 {
margin-bottom: 2rem;
}
.lg-ml3 {
margin-left: 2rem;
}
.lg-mx3 {
margin-left: 2rem;
margin-right: 2rem;
}
.lg-my3 {
margin-top: 2rem;
margin-bottom: 2rem;
}
.lg-m4 {
margin: 4rem;
}
.lg-mt4 {
margin-top: 4rem;
}
.lg-mr4 {
margin-right: 4rem;
}
.lg-mb4 {
margin-bottom: 4rem;
}
.lg-ml4 {
margin-left: 4rem;
}
.lg-mx4 {
margin-left: 4rem;
margin-right: 4rem;
}
.lg-my4 {
margin-top: 4rem;
margin-bottom: 4rem;
}
.lg-mxn1 {
margin-left: -0.5rem;
margin-right: -0.5rem;
}
.lg-mxn2 {
margin-left: -1rem;
margin-right: -1rem;
}
.lg-mxn3 {
margin-left: -2rem;
margin-right: -2rem;
}
.lg-mxn4 {
margin-left: -4rem;
margin-right: -4rem;
}
.lg-ml-auto {
margin-left: auto;
}
.lg-mr-auto {
margin-right: auto;
}
.lg-mx-auto {
margin-left: auto;
margin-right: auto;
}
}

View File

@ -1,134 +0,0 @@
/* Basscss Responsive Padding */
/* Modified by Fabio Berger to include xs prefix */
@media (max-width: 52em) { /* Modified by Fabio Berger to max-width from min-width */
.sm-p0 { padding: 0 }
.sm-pt0 { padding-top: 0 }
.sm-pr0 { padding-right: 0 }
.sm-pb0 { padding-bottom: 0 }
.sm-pl0 { padding-left: 0 }
.sm-px0 { padding-left: 0; padding-right: 0 }
.sm-py0 { padding-top: 0; padding-bottom: 0 }
.sm-p1 { padding: .5rem }
.sm-pt1 { padding-top: .5rem }
.sm-pr1 { padding-right: .5rem }
.sm-pb1 { padding-bottom: .5rem }
.sm-pl1 { padding-left: .5rem }
.sm-px1 { padding-left: .5rem; padding-right: .5rem }
.sm-py1 { padding-top: .5rem; padding-bottom: .5rem }
.sm-p2 { padding: 1rem }
.sm-pt2 { padding-top: 1rem }
.sm-pr2 { padding-right: 1rem }
.sm-pb2 { padding-bottom: 1rem }
.sm-pl2 { padding-left: 1rem }
.sm-px2 { padding-left: 1rem; padding-right: 1rem }
.sm-py2 { padding-top: 1rem; padding-bottom: 1rem }
.sm-p3 { padding: 2rem }
.sm-pt3 { padding-top: 2rem }
.sm-pr3 { padding-right: 2rem }
.sm-pb3 { padding-bottom: 2rem }
.sm-pl3 { padding-left: 2rem }
.sm-px3 { padding-left: 2rem; padding-right: 2rem }
.sm-py3 { padding-top: 2rem; padding-bottom: 2rem }
.sm-p4 { padding: 4rem }
.sm-pt4 { padding-top: 4rem }
.sm-pr4 { padding-right: 4rem }
.sm-pb4 { padding-bottom: 4rem }
.sm-pl4 { padding-left: 4rem }
.sm-px4 { padding-left: 4rem; padding-right: 4rem }
.sm-py4 { padding-top: 4rem; padding-bottom: 4rem }
}
@media (min-width: 52em) {
.md-p0 { padding: 0 }
.md-pt0 { padding-top: 0 }
.md-pr0 { padding-right: 0 }
.md-pb0 { padding-bottom: 0 }
.md-pl0 { padding-left: 0 }
.md-px0 { padding-left: 0; padding-right: 0 }
.md-py0 { padding-top: 0; padding-bottom: 0 }
.md-p1 { padding: .5rem }
.md-pt1 { padding-top: .5rem }
.md-pr1 { padding-right: .5rem }
.md-pb1 { padding-bottom: .5rem }
.md-pl1 { padding-left: .5rem }
.md-px1 { padding-left: .5rem; padding-right: .5rem }
.md-py1 { padding-top: .5rem; padding-bottom: .5rem }
.md-p2 { padding: 1rem }
.md-pt2 { padding-top: 1rem }
.md-pr2 { padding-right: 1rem }
.md-pb2 { padding-bottom: 1rem }
.md-pl2 { padding-left: 1rem }
.md-px2 { padding-left: 1rem; padding-right: 1rem }
.md-py2 { padding-top: 1rem; padding-bottom: 1rem }
.md-p3 { padding: 2rem }
.md-pt3 { padding-top: 2rem }
.md-pr3 { padding-right: 2rem }
.md-pb3 { padding-bottom: 2rem }
.md-pl3 { padding-left: 2rem }
.md-px3 { padding-left: 2rem; padding-right: 2rem }
.md-py3 { padding-top: 2rem; padding-bottom: 2rem }
.md-p4 { padding: 4rem }
.md-pt4 { padding-top: 4rem }
.md-pr4 { padding-right: 4rem }
.md-pb4 { padding-bottom: 4rem }
.md-pl4 { padding-left: 4rem }
.md-px4 { padding-left: 4rem; padding-right: 4rem }
.md-py4 { padding-top: 4rem; padding-bottom: 4rem }
}
@media (min-width: 64em) {
.lg-p0 { padding: 0 }
.lg-pt0 { padding-top: 0 }
.lg-pr0 { padding-right: 0 }
.lg-pb0 { padding-bottom: 0 }
.lg-pl0 { padding-left: 0 }
.lg-px0 { padding-left: 0; padding-right: 0 }
.lg-py0 { padding-top: 0; padding-bottom: 0 }
.lg-p1 { padding: .5rem }
.lg-pt1 { padding-top: .5rem }
.lg-pr1 { padding-right: .5rem }
.lg-pb1 { padding-bottom: .5rem }
.lg-pl1 { padding-left: .5rem }
.lg-px1 { padding-left: .5rem; padding-right: .5rem }
.lg-py1 { padding-top: .5rem; padding-bottom: .5rem }
.lg-p2 { padding: 1rem }
.lg-pt2 { padding-top: 1rem }
.lg-pr2 { padding-right: 1rem }
.lg-pb2 { padding-bottom: 1rem }
.lg-pl2 { padding-left: 1rem }
.lg-px2 { padding-left: 1rem; padding-right: 1rem }
.lg-py2 { padding-top: 1rem; padding-bottom: 1rem }
.lg-p3 { padding: 2rem }
.lg-pt3 { padding-top: 2rem }
.lg-pr3 { padding-right: 2rem }
.lg-pb3 { padding-bottom: 2rem }
.lg-pl3 { padding-left: 2rem }
.lg-px3 { padding-left: 2rem; padding-right: 2rem }
.lg-py3 { padding-top: 2rem; padding-bottom: 2rem }
.lg-p4 { padding: 4rem }
.lg-pt4 { padding-top: 4rem }
.lg-pr4 { padding-right: 4rem }
.lg-pb4 { padding-bottom: 4rem }
.lg-pl4 { padding-left: 4rem }
.lg-px4 { padding-left: 4rem; padding-right: 4rem }
.lg-py4 { padding-top: 4rem; padding-bottom: 4rem }
}

View File

@ -1,35 +0,0 @@
/* Basscss Responsive Type Scale */
/* Modified by Fabio Berger to include xs prefix */
@media (max-width: 52em) { /* Modified by Fabio Berger to max-width from min-width */
.sm-h00 { font-size: 4rem }
.sm-h0 { font-size: 3rem }
.sm-h1 { font-size: 2rem }
.sm-h2 { font-size: 1.5rem }
.sm-h3 { font-size: 1.25rem }
.sm-h4 { font-size: 1rem }
.sm-h5 { font-size: .875rem }
.sm-h6 { font-size: .75rem }
}
@media (min-width: 52em) {
.md-h00 { font-size: 4rem }
.md-h0 { font-size: 3rem }
.md-h1 { font-size: 2rem }
.md-h2 { font-size: 1.5rem }
.md-h3 { font-size: 1.25rem }
.md-h4 { font-size: 1rem }
.md-h5 { font-size: .875rem }
.md-h6 { font-size: .75rem }
}
@media (min-width: 64em) {
.lg-h00 { font-size: 4rem }
.lg-h0 { font-size: 3rem }
.lg-h1 { font-size: 2rem }
.lg-h2 { font-size: 1.5rem }
.lg-h3 { font-size: 1.25rem }
.lg-h4 { font-size: 1rem }
.lg-h5 { font-size: .875rem }
.lg-h6 { font-size: .75rem }
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 684 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -1,26 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="" />
<meta property="og:type" content="website" />
<meta property="og:title" content="0x" />
<meta property="og:description" content="" />
<meta property="og:image" content="/images/og_image.png" />
<title>0x: The Protocol for Trading Tokens</title>
<link rel="icon" type="image/png" href="/images/favicon/favicon-2-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="/images/favicon/favicon-2-16x16.png" sizes="16x16" />
<link rel="stylesheet" href="/css/basscss_responsive_custom.css">
<link rel="stylesheet" href="/css/basscss_responsive_padding.css">
<link rel="stylesheet" href="/css/basscss_responsive_margin.css">
<link rel="stylesheet" href="/css/basscss_responsive_type_scale.css">
</head>
<body style="margin: 0px; min-width: 355px;">
<div id="app"></div>
<script type="text/javascript" crossorigin="anonymous" src="/bundle.js" charset="utf-8"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,11 @@
import * as React from 'react';
import { BaseAnimation } from '../index';
import * as animationData from './data.json';
const CompilerAnimation: React.StatelessComponent<{}> = () => (
<BaseAnimation animationData={animationData} width={2150} height={700} />
);
export { CompilerAnimation };

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,11 @@
import * as React from 'react';
import { BaseAnimation } from '../index';
import * as animationData from './data.json';
const CovAnimation: React.StatelessComponent<{}> = () => (
<BaseAnimation animationData={animationData} width={1981} height={660} />
);
export { CovAnimation };

View File

@ -0,0 +1,96 @@
import * as React from 'react';
import Lottie from 'react-lottie';
import styled from 'styled-components';
import { media } from 'ts/variables';
interface AnimationProps {
animationData: object;
width: number;
height: number;
}
interface AnimationState {
width?: number | undefined;
height?: number | undefined;
}
class BaseAnimation extends React.PureComponent<AnimationProps, AnimationState> {
public state: AnimationState = {
height: undefined,
width: undefined,
};
private _timeout = undefined as number;
public componentDidMount(): void {
this._updateAnimationSize();
window.addEventListener('resize', this._handleResize.bind(this));
}
public componentWillUnmount(): void {
window.removeEventListener('resize', this._handleResize.bind(this));
}
public render(): React.ReactNode {
const { animationData } = this.props;
const height = this.state.height || this.props.height;
const width = this.state.width || this.props.width;
return (
<Container height={height}>
<InnerContainer>
<Lottie
width={width}
height={height}
options={{
loop: true,
autoplay: true,
animationData,
}}
/>
</InnerContainer>
</Container>
);
}
private _handleResize(): void {
clearTimeout(this._timeout);
this._timeout = window.setTimeout(this._updateAnimationSize.bind(this), 50);
}
private _updateAnimationSize(): void {
const windowWidth = window.innerWidth;
let width;
let height;
if (windowWidth <= 1000) {
const maxWidth = windowWidth + 250;
const ratio = maxWidth / this.props.width;
height = Math.round(this.props.height * ratio);
width = Math.round(this.props.width * ratio);
}
this.setState({ width, height });
}
}
const Container =
styled.div <
AnimationProps >
`
width: 100%;
height: ${props => props.height}px;
position: absolute;
top: 40%;
left: 0;
z-index: -1;
overflow: hidden;
${media.large`
top: 100%;
transform: translateY(-50%);
`};
`;
const InnerContainer = styled.div`
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
`;
export { BaseAnimation };

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,11 @@
import * as React from 'react';
import { BaseAnimation } from '../index';
import * as animationData from './data.json';
const ProfilerAnimation: React.StatelessComponent<{}> = () => (
<BaseAnimation animationData={animationData} width={1985} height={657} />
);
export { ProfilerAnimation };

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,11 @@
import * as React from 'react';
import { BaseAnimation } from '../index';
import * as animationData from './data.json';
const TraceAnimation: React.StatelessComponent<{}> = () => (
<BaseAnimation animationData={animationData} width={2241} height={610} />
);
export { TraceAnimation };

View File

@ -0,0 +1,26 @@
import * as React from 'react';
import { ThemeProvider } from 'styled-components';
import { Footer } from 'ts/components/footer';
import { Header } from 'ts/components/header';
import { ThemeContext } from 'ts/context';
import { GlobalStyles } from 'ts/globalStyles';
interface BaseProps {
context: any;
}
const Base: React.StatelessComponent<BaseProps> = props => (
<ThemeContext.Provider value={props.context}>
<ThemeProvider theme={props.context}>
<React.Fragment>
<GlobalStyles colors={props.context.colors} />
<Header />
{props.children}
<Footer />
</React.Fragment>
</ThemeProvider>
</ThemeContext.Provider>
);
export { Base };

View File

@ -0,0 +1,12 @@
import styled from 'styled-components';
import { media } from 'ts/variables';
const Breakout = styled.div`
${media.small`
margin-left: -2.5rem;
width: calc(100% + 5rem);
`};
`;
export { Breakout };

View File

@ -0,0 +1,55 @@
import styled from 'styled-components';
import { colors, media } from 'ts/variables';
interface ButtonProps {
large?: boolean;
}
const Button =
styled.button <
ButtonProps >
`
font-family: inherit;
line-height: 1;
font-weight: 500;
white-space: nowrap;
vertical-align: middle;
background-color: ${props => props.theme.colors.secondary};
color: ${colors.black};
border: 0;
border-radius: 5rem;
display: inline-flex;
justify-content: space-between;
align-items: center;
${props =>
props.large
? `
font-size: 1rem;
padding: 1.1875rem 2.375rem 1.0625rem;
`
: `
font-size: .875rem;
padding: .5625rem 1.25rem;
`}
:hover, :focus {
background-color: ${props => props.theme.colors.secondary_alt};
outline: 0;
}
${media.small`
font-size: .875rem;
padding: .5625rem 1.25rem;
`}
${props =>
props.large &&
media.small`
font-size: 1rem;
padding: 1rem 1.5rem .75rem;
`}
`;
export { Button };

View File

@ -0,0 +1,204 @@
import * as _ from 'lodash';
import * as React from 'react';
import styled from 'styled-components';
import { colors } from 'ts/variables';
import { Button as BaseButton } from './button';
const isTouch = Boolean(
'ontouchstart' in window ||
(window as any).navigator.maxTouchPoints > 0 ||
(window as any).navigator.msMaxTouchPoints > 0,
);
interface CodeProps {
language?: string;
isLight?: boolean;
isDiff?: boolean;
gutter?: Array<number | undefined>;
gutterLength?: number;
canCopy?: boolean;
isEtc?: boolean;
}
interface CodeState {
hlCode?: string;
didCopy?: boolean;
}
const Button = styled(BaseButton)`
opacity: ${isTouch ? '1' : '0'};
position: absolute;
top: 1rem;
right: 1rem;
transition: opacity 0.2s;
:focus {
opacity: 1;
}
`;
const Container = styled.div`
position: relative;
&:hover ${Button} {
opacity: 1;
}
`;
const Base =
styled.div <
CodeProps >
`
font-size: .875rem;
color: ${props => (_.isUndefined(props.language) ? colors.white : 'inherit')};
background-color: ${props =>
props.isLight ? 'rgba(255,255,255,.15)' : _.isUndefined(props.language) ? colors.black : '#F1F4F5'};
white-space: ${props => (_.isUndefined(props.language) ? 'nowrap' : '')};
position: relative;
${props =>
props.isDiff
? `
background-color: #E9ECED;
display: flex;
padding-top: 1.5rem;
padding-bottom: 1.5rem;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
`
: ``}
`;
const CodeDiff: React.StatelessComponent<any> = ({ gutterLength, ...props }) => <code {...props} />;
const StyledCodeDiff = styled(CodeDiff)`
::before {
content: '';
width: calc(0.75rem + ${props => props.gutterLength}ch);
background-color: #e2e5e6;
position: absolute;
top: 0;
left: 0;
bottom: 0;
}
[class^='line-'] {
display: inline-block;
width: 100%;
position: relative;
padding-right: 1.5rem;
padding-left: calc(2.25rem + ${props => props.gutterLength}ch);
::before {
content: attr(data-gutter);
width: ${props => props.gutterLength};
padding-left: 0.375rem;
padding-right: 0.375rem;
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
z-index: 1;
}
}
.line-addition {
background-color: rgba(0, 202, 105, 0.1);
}
.line-deletion {
background-color: rgba(255, 0, 0, 0.07);
}
`;
const StyledPre =
styled.pre <
CodeProps >
`
margin: 0;
${props =>
!props.isDiff
? `
padding: 1.5rem;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
`
: ``};
`;
const StyledCopyInput = styled.textarea`
opacity: 0;
height: 0;
position: absolute;
top: 0;
right: 0;
z-index: -1;
`;
class Code extends React.Component<CodeProps, CodeState> {
public state: CodeState = {};
private readonly _code = React.createRef<HTMLTextAreaElement>();
public componentDidMount(): void {
// _onMountAsync is only setting state, so no point in handling the promise
// tslint:disable-next-line:no-floating-promises
this._onMountAsync();
}
public render(): React.ReactNode {
const { language, isLight, isDiff, children, gutterLength, canCopy } = this.props;
const { hlCode } = this.state;
return (
<Container>
<Base language={language} isDiff={isDiff} isLight={isLight}>
<StyledPre isDiff={isDiff}>
{_.isUndefined(hlCode) ? (
<code>{children}</code>
) : (
<StyledCodeDiff
gutterLength={gutterLength}
dangerouslySetInnerHTML={hlCode ? { __html: this.state.hlCode } : null}
/>
)}
</StyledPre>
{!('clipboard' in navigator) ? (
<StyledCopyInput readOnly={true} aria-hidden="true" ref={this._code} value={children} />
) : null}
</Base>
{navigator.userAgent !== 'ReactSnap' && canCopy ? (
<Button onClick={this._handleCopyAsync.bind(this)}>{this.state.didCopy ? 'Copied' : 'Copy'}</Button>
) : null}
</Container>
);
}
private async _onMountAsync(): Promise<void> {
const { language, children, isDiff, gutter, isEtc } = this.props;
const code = children as string;
if (language !== undefined) {
const { highlight } = await System.import(/* webpackChunkName: 'highlightjs' */ 'ts/highlight');
this.setState({
hlCode: highlight({ language, code, isDiff, gutter, isEtc }),
});
}
}
private async _handleCopyAsync(): Promise<void> {
try {
if ('clipboard' in navigator) {
await (navigator as any).clipboard.writeText(this.props.children);
this.setState({ didCopy: true });
} else {
const lastActive = document.activeElement as HTMLElement;
this._code.current.focus();
this._code.current.select();
document.execCommand('copy');
lastActive.focus();
this.setState({ didCopy: true });
}
} catch (error) {
this.setState({ didCopy: false });
}
}
}
export { Code };

View File

@ -0,0 +1,90 @@
import * as _ from 'lodash';
import * as React from 'react';
import styled from 'styled-components';
import { colors, media } from 'ts/variables';
import { Breakout } from './breakout';
import { Container } from './container';
import { InlineCode } from './inline-code';
const Cards = styled.dl`
column-count: 3;
column-gap: 1.25rem;
${media.medium`
column-count: 1;
`};
`;
const Card = styled.div`
background-color: ${colors.lightGray};
padding: 3.125rem;
padding-bottom: 2.5rem;
display: inline-block;
margin-bottom: 1.25rem;
width: 100%;
${media.medium`
padding: 1.875rem;
`};
`;
const Dt = styled.dt`
font-weight: 500;
display: inline;
::after {
content: '. ';
}
`;
const Dd = styled.dd`
display: inline;
margin-left: 0;
`;
const cards = [
{
title: 'A Project-centric',
body: (
<React.Fragment>
Compiles an entire project instead of only individual <InlineCode isAlt={true}>.sol</InlineCode> files.
</React.Fragment>
),
},
{
title: 'Incremental builds',
body: 'Recompiles your smart contracts after they have changed',
},
{
title: 'Customizable artifacts',
body:
'Stores only the required compiler output in your artifacts, so you can have complete control over your bundle size.',
},
{
title: 'Seamless',
body: 'Fetches and caches the required compiler binaries.',
},
{
title: 'Versioning',
body:
'Compiles each contract with the version specified at the top of its file (sol-compiler even supports version ranges!).',
},
];
const Compiler: React.StatelessComponent<{}> = () => (
<Container>
<Breakout>
<Cards>
{_.map(cards, card => (
<Card key={card.title.split(' ').join('-')}>
<Dt>{card.title}</Dt>
<Dd>{card.body}</Dd>
</Card>
))}
</Cards>
</Breakout>
</Container>
);
export { Compiler };

View File

@ -0,0 +1,16 @@
import styled from 'styled-components';
interface ContainerProps {
wide?: boolean;
}
const Container =
styled.div <
ContainerProps >
`
max-width: 77.5rem;
margin: 0 auto;
width: ${props => (props.wide ? '100%' : 'calc(100% - 5rem)')};
`;
export { Container };

View File

@ -0,0 +1,78 @@
import * as _ from 'lodash';
import * as React from 'react';
import styled from 'styled-components';
import { ContextInterface } from 'ts/context';
import { media } from 'ts/variables';
import { Alpha, Beta } from './typography';
const Base = styled.div`
display: flex;
align-items: flex-start;
justify-content: space-between;
:not(:last-of-type) {
margin-bottom: 6.25rem;
}
${Beta} {
margin-bottom: 2.5rem;
}
${media.small`
display: block;
:not(:last-of-type) {
margin-bottom: 3.125rem;
}
`};
`;
const Content = styled.div`
width: 66.693548387%;
${media.small`
width: 100%;
`};
`;
const Item = styled.div`
p {
max-width: 31.25rem;
}
&:not(:last-of-type) {
margin-bottom: 2.5rem;
${media.small`
margin-bottom: 1.875rem;
`};
}
`;
const StyledTitle = styled(Alpha)`
color: ${props => props.color};
${media.small`
& + div {
margin-top: 1.5rem;
}
`};
`;
interface ContentBlockProps extends ContextInterface {
title: string;
main?: boolean;
children?: React.ReactNode;
}
const ContentBlock: React.StatelessComponent<ContentBlockProps> = props => {
const children = React.Children.map(props.children, child => {
return <Item>{child}</Item>;
});
const Title = props.main ? StyledTitle : Beta;
return (
<Base>
<Title color={props.colors}>{props.title}</Title>
{_.isUndefined(children) ? null : <Content>{children}</Content>}
</Base>
);
};
export { ContentBlock };

View File

@ -0,0 +1,34 @@
import * as React from 'react';
import styled from 'styled-components';
import { Container } from './container';
const StyledMain =
styled.div <
MainProps >
`
padding-top: 6.25rem;
padding-bottom: 6.25rem;
${props =>
props.dark
? `
background-color: #000;
color: #fff;
p:not([class]) {
color: #CCC;
}
`
: ''};
`;
interface MainProps {
dark?: boolean;
}
const Content: React.StatelessComponent<MainProps> = props => (
<StyledMain dark={props.dark}>
<Container>{props.children}</Container>
</StyledMain>
);
export { Content };

View File

@ -0,0 +1,133 @@
import * as _ from 'lodash';
import * as React from 'react';
import styled from 'styled-components';
import { context as compiler } from 'ts/context/compiler';
import { context as cov } from 'ts/context/cov';
import { context as profiler } from 'ts/context/profiler';
import { context as trace } from 'ts/context/trace';
import MainIcon from 'ts/icons/logos/0x.svg';
import { media } from 'ts/variables';
import { Container } from './container';
import { Alpha, Beta } from './typography';
const tools = [trace, cov, compiler, profiler];
const Footer: React.StatelessComponent<{}> = () => (
<StyledFooter>
<Container>
<Top>
<Alpha>Other tools by 0x</Alpha>
<List>
{_.map(tools, ({ title, subtitle, icon }) => (
<ListItem key={title}>
<ListLink href="#">
<Icon as={icon as 'svg'} />
<div>
<Beta>{title}</Beta>
<p>{subtitle}</p>
</div>
</ListLink>
</ListItem>
))}
</List>
</Top>
<Media as="aside">
<Icon as={MainIcon} />
<Small>
0x is an open, permissionless protocol allowing for tokens to be traded on the Ethereum blockchain.
</Small>
</Media>
</Container>
</StyledFooter>
);
const StyledFooter = styled.footer`
background-color: ${props => props.theme.colors.secondary};
padding-top: 6.25rem;
padding-bottom: 5.4375rem;
${media.small`padding-top: 2.5rem;`};
`;
const Top = styled.div`
display: flex;
justify-content: space-between;
margin-bottom: 9.375rem;
${media.medium`
display: block;
margin-bottom: 5.3125rem;
`};
${Alpha} {
${media.medium`margin-bottom: 3.8125rem;`};
}
`;
const Icon = styled.div`
margin-right: 1.3125rem;
flex-shrink: 0;
${media.small`margin-right: 0.9375rem`};
`;
const Media = styled.div`
display: flex;
align-items: center;
${Icon} {
margin-top: 0.5rem;
align-self: flex-start;
}
`;
const List = styled.ul`
list-style: none;
margin: 0;
padding: 0;
width: 66.693548387%;
display: flex;
flex-wrap: wrap;
${media.medium`
width: 100%;
`};
${media.small`
display: block;
`};
`;
const ListItem = styled.li`
margin-bottom: 3.3125rem;
padding-right: 1rem;
flex-basis: 50%;
:nth-last-of-type(-n + 2) {
margin-bottom: 0;
${media.small`margin-bottom: 1.875rem`};
}
${media.small`
margin-bottom: 1.875rem
:last-of-type {
margin-bottom: 0;
}
`};
`;
const ListLink = styled.a`
display: flex;
align-items: center;
:hover {
color: ${props => props.theme.colors.dark};
}
`;
const Small = styled.small`
font-size: 1em;
max-width: 37.5rem;
`;
export { Footer };

View File

@ -0,0 +1,76 @@
import * as React from 'react';
import styled from 'styled-components';
import { ContextInterface, ThemeContext } from 'ts/context';
import { media } from 'ts/variables';
import { Container } from './container';
import { Small } from './typography';
const Header: React.StatelessComponent<{}> = () => (
<ThemeContext.Consumer>
{({ icon, title }: ContextInterface) => (
<StyledHeader>
<Container>
<LogoMark>
<Logo as={icon as 'svg'} />
<Title>{title}</Title>
</LogoMark>
<Link as="a" href="https://0xproject.com/">
Built by 0x
</Link>
</Container>
</StyledHeader>
)}
</ThemeContext.Consumer>
);
const StyledHeader = styled.header`
padding-top: 3.75rem;
padding-bottom: 0.875rem;
width: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 2;
${Container} {
display: flex;
justify-content: space-between;
align-items: center;
}
${media.small`padding-top: 2.125rem;`};
`;
const LogoMark = styled.div`
position: relative;
height: 1.75rem;
display: flex;
align-items: center;
`;
const Logo = styled.div`
color: ${props => props.theme.colors.main};
width: 1.75rem;
height: 100%;
`;
const Title = styled.h1`
font-size: 1.5rem;
line-height: 1;
white-space: nowrap;
margin-top: 2px;
margin-bottom: 0;
margin-left: 0.8125rem;
${media.small`font-size: 1.25rem;`};
`;
const Link = styled(Small)`
:hover {
text-decoration: underline;
}
`;
export { Header };

View File

@ -0,0 +1,63 @@
import * as React from 'react';
import styled from 'styled-components';
import { ContextInterface, ThemeContext } from 'ts/context';
import { media } from 'ts/variables';
import { Button } from './button';
import { Beta } from './typography';
const Hero: React.StatelessComponent<ContextInterface> = ({ children }) => (
<ThemeContext.Consumer>
{({ subtitle, tagline }: ContextInterface) => (
<StyledHero>
<HeroContainer>
<Subtitle>{subtitle}</Subtitle>
<Tagline as="p">{tagline}</Tagline>
<Button as="a" href="#" large={true}>
Read the Docs
</Button>
</HeroContainer>
{navigator.userAgent !== 'ReactSnap' ? children : null}
</StyledHero>
)}
</ThemeContext.Consumer>
);
const StyledHero = styled.section`
text-align: center;
padding-top: 9.375rem;
padding-bottom: 2rem;
padding-left: 2.5rem;
padding-right: 2.5rem;
min-height: min-content;
max-height: 37.5rem;
height: 80vh;
position: relative;
`;
const HeroContainer = styled.div`
margin: 0 auto;
max-width: 590px;
`;
const Subtitle = styled.h2`
font-size: 3.75rem;
line-height: 1.16;
margin-bottom: 1.5rem;
${media.small`
font-size: 2.25rem;
line-height: 1.1;
margin-bottom: 1.375rem;
`};
`;
const Tagline = styled(Beta)`
margin-bottom: 2rem;
${media.small`
margin-bottom: 1.25rem;
`};
`;
export { Hero };

View File

@ -0,0 +1,20 @@
import * as React from 'react';
import styled from 'styled-components';
import { colors } from '../variables';
interface InlineCodeProps {
isAlt?: boolean;
children: React.ReactNode;
}
const Code: React.StatelessComponent<InlineCodeProps> = ({ isAlt, children, ...props }) => (
<code {...props}>{children}</code>
);
const InlineCode = styled(Code)`
background-color: ${props => (props.isAlt ? '#E5E8E9' : colors.blueGray)};
padding: 0.3125rem;
`;
export { InlineCode };

View File

@ -0,0 +1,70 @@
import * as React from 'react';
import styled from 'styled-components';
import { colors, media } from 'ts/variables';
import { Breakout } from './breakout';
import { Container } from './container';
import { Alpha, Lead } from './typography';
const Main = styled.div`
background-color: ${colors.lightGray};
padding: 6.25rem;
display: flex;
justify-content: space-between;
${media.large`
padding: 2.5rem;
`};
${media.medium`
display: block;
`};
`;
const Title = styled(Alpha)`
margin-bottom: 2.5rem;
${media.medium`margin-bottom: 2.25rem;`};
`;
const StyledIntroLead = styled(Lead)`
max-width: 25.9375rem;
margin-right: 2rem;
${media.medium`
max-width: 100%;
margin-bottom: 1.5625rem;
`};
`;
const StyledIntroAside = styled.div`
max-width: 32.5rem;
position: relative;
${media.medium`
max-width: 100%;
`};
`;
interface IntroLeadProps {
title: string;
}
const IntroLead: React.StatelessComponent<IntroLeadProps> = props => (
<StyledIntroLead as="div">
<Title>{props.title}</Title>
{props.children}
</StyledIntroLead>
);
const IntroAside: React.StatelessComponent<{}> = props => (
<Breakout>
<StyledIntroAside>{props.children}</StyledIntroAside>
</Breakout>
);
const Intro: React.StatelessComponent<{}> = props => (
<Container wide={true}>
<Main>{props.children}</Main>
</Container>
);
export { IntroLead, IntroAside, Intro };

View File

@ -0,0 +1,50 @@
import * as _ from 'lodash';
import * as React from 'react';
import styled from 'styled-components';
import { media } from 'ts/variables';
const StyledList = styled.ul`
list-style-type: none;
margin: 0;
padding: 0;
position: relative;
`;
const StyledItem = styled.li`
position: relative;
padding-left: 1.625rem;
:before {
content: '';
border: 1px solid black;
width: 0.625rem;
height: 0.625rem;
display: inline-block;
position: absolute;
margin-top: 2px;
top: 0.3125rem;
left: 0;
transform: rotate(45deg);
}
:not(:last-child) {
margin-bottom: 0.5625rem;
${media.small`
margin-bottom: 0.375rem;
`};
}
`;
interface ListProps {
items?: [];
}
const List: React.StatelessComponent<ListProps> = props => (
<StyledList>
{props.children !== undefined
? props.children
: _.map(props.items, (bullet, index) => <StyledItem key={index}>{bullet}</StyledItem>)}
</StyledList>
);
export { List, StyledItem as ListItem };

View File

@ -1,25 +0,0 @@
import * as React from 'react';
import { Helmet } from 'react-helmet';
export interface MetaTagsProps {
title: string;
description: string;
imgSrc?: string;
}
export const MetaTags: React.StatelessComponent<MetaTagsProps> = ({ title, description, imgSrc }) => (
<Helmet>
<title>{title}</title>
<meta name="description" content={description} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:type" content="website" />
<meta property="og:image" content={imgSrc} />
<meta name="twitter:site" content="@0xproject" />
<meta name="twitter:image" content={imgSrc} />
</Helmet>
);
MetaTags.defaultProps = {
imgSrc: '/images/og_image.png',
};

View File

@ -0,0 +1,64 @@
import * as React from 'react';
import { Tab, TabList, TabPanel, Tabs as ReactTabs } from 'react-tabs';
import styled from 'styled-components';
import { colors } from 'ts/variables';
import { Breakout } from './breakout';
const StyledTabList = styled(TabList)`
text-transform: uppercase;
list-style: none;
margin: 0;
padding: 0;
overflow: hidden;
`;
const StyledTab = styled(Tab)`
background-color: ${props => props.theme.colors.secondary};
height: 2.5rem;
padding-left: 1rem;
padding-right: 1rem;
display: flex;
justify-content: space-around;
align-items: center;
float: left;
&:not(:first-of-type) {
margin-left: 0.25rem;
}
&[aria-selected='true'] {
background-color: ${colors.gray};
}
&[aria-selected='false']:focus,
&[aria-selected='false']:hover {
background-color: ${props => props.theme.colors.secondary_alt};
cursor: pointer;
}
`;
const Tabs: React.StatelessComponent<{}> = props => (
<Breakout>
<ReactTabs>
<StyledTabList>
{React.Children.map(props.children, child => {
const { title } = React.cloneElement(child as React.ReactElement<any>).props;
return <StyledTab>{title}</StyledTab>;
})}
</StyledTabList>
{React.Children.map(props.children, child => <TabPanel>{child}</TabPanel>)}
</ReactTabs>
</Breakout>
);
interface TabBlockProps {
title: string;
}
const TabBlock: React.StatelessComponent<TabBlockProps> = props => <React.Fragment>{props.children}</React.Fragment>;
const ContextTabs = Tabs;
export { ContextTabs as Tabs, TabBlock };

View File

@ -0,0 +1,223 @@
import * as React from 'react';
import styled from 'styled-components';
import { ContextInterface, ThemeContext } from 'ts/context';
import ExactLocation from 'ts/icons/exact-location.svg';
import NoLocation from 'ts/icons/no-location.svg';
import TimeConsuming from 'ts/icons/time-consuming.svg';
import TimeSaving from 'ts/icons/time-saving.svg';
import { colors, media } from 'ts/variables';
import { Breakout } from './breakout';
import { Code } from './code';
import { Container } from './container';
import { Alpha, Gamma, Lead } from './typography';
const Trace: React.StatelessComponent<{}> = () => (
<ThemeContext.Consumer>
{(props: ContextInterface) => (
<StyledSection background={props.colors.secondary}>
<Wrapper>
<Block>
<Alpha>The Issue</Alpha>
<MainCopy>
Every time an Ethereum transaction fails, it's extremely hard to trace down the
troublemaking line of code. The only hint you'll get is a generic error.
</MainCopy>
<Breakout>
<Code isLight={true}>Error: VM Exception while processing transaction: rever</Code>
</Breakout>
<List>
<Item>
<Copy dark={true}>
<Gamma as="h3">No location</Gamma>
<p>
The error basically says "anything could have gone wrong here", which keeps you
completely in the dark about its exact location.
</p>
</Copy>
<Icon as={NoLocation} />
</Item>
<Item>
<Copy dark={true}>
<Gamma as="h3">Time-consuming</Gamma>
<p>
Working with a large code-base that contains hundreds of smart contracts,
finding the failing line of code quickly becomes a daunting task.
</p>
</Copy>
<Icon as={TimeConsuming} />
</Item>
</List>
</Block>
<Block background={props.colors.secondary}>
<Alpha>The Fix</Alpha>
<MainCopy>
Sol-trace will give you full stack traces, including contract names, line numbers and code
snippets, every time you encounter an error.
</MainCopy>
<Breakout>
<Code isLight={true} language="javascript">
{`contracts/src/2.0.0/protocol/Exchange/MixinSignatureValidator.sol:51:8
require(
isValidSignature(
hash,
signerAddress,
signature
),
"INVALID_SIGNATURE"
)`}
</Code>
</Breakout>
<List>
<Item>
<Copy>
<Gamma as="h3">Exact location</Gamma>
<p>
It shows you the exact location of the specific code linen and where it was
called from.
</p>
</Copy>
<Icon as={ExactLocation} />
</Item>
<Item>
<Copy>
<Gamma as="h3">Time-saving</Gamma>
<p>
Turning "Your code failed somewhere, good luck debugging it" into "Your code
failed on line X of contract Y", it drastically improves the developer
experience.
</p>
</Copy>
<Icon as={TimeSaving} />
</Item>
</List>
</Block>
</Wrapper>
</StyledSection>
)}
</ThemeContext.Consumer>
);
interface TraceProps {
background?: string;
}
const StyledSection =
styled.section <
TraceProps >
`
max-width: 90rem;
margin: 0 auto;
background: linear-gradient(to right, ${colors.black} 50%, ${props => props.background} 50%);
overflow: hidden;
${media.large`
background: none
padding-top: 0;
padding-bottom: 0;
`};
`;
const Wrapper = styled(Container)`
display: flex;
${Alpha} {
padding-bottom: 2.5rem;
${media.small`padding-bottom: 1.875rem;`};
}
${media.large`
display: block;
width: 100%;
`};
`;
const Block =
styled.div <
TraceProps >
`
width: 50%;
background: ${props => (props.background ? props.background : colors.black)};
color: ${props => (props.background ? 'inherit' : colors.white)};
padding-top: 6.25rem;
padding-bottom: 5.25rem;
:first-of-type {
padding-right: 6.25rem;
}
:last-of-type {
padding-left: 6.25rem;
}
${media.xlarge`
:first-of-type {
padding-right: 2.5rem;
}
:last-of-type {
padding-left: 2.5rem;
}
`}
${media.large`
width: 100%;
padding: 2.5rem;
`}
${media.small`
padding-left: 1.875rem;
padding-right: 1.875rem;
`};
`;
const MainCopy = styled(Lead)`
margin-bottom: 3.1875rem;
${media.small`
margin-bottom: 1.125rem;
`};
`;
const List = styled.ul`
margin-top: 6.25rem;
margin-bottom: 0;
padding: 0;
${media.small`margin-top: 3.4375rem;`};
`;
const Item = styled.li`
display: flex;
align-items: center;
:not(:last-child) {
margin-bottom: 4.4375rem;
${media.small`margin-bottom: 3.4375rem;`};
}
`;
const Copy =
styled.div <
{ dark: boolean } >
`
margin-right: 5.875rem;
${props =>
props.dark &&
`
p {
color: #ccc;
}
`}
${media.small`margin-right: 2.0625rem;`};
`;
const Icon = styled.div`
flex-shrink: 0;
`;
export { Trace };

View File

@ -0,0 +1,33 @@
import styled from 'styled-components';
import { media } from '../variables';
const Alpha = styled.h2`
font-size: 1.75rem;
line-height: 1;
${media.small`font-size: 1.5rem;`};
`;
const Beta = styled.h3`
font-size: 1.25rem;
line-height: 1.65;
`;
const Gamma = styled.h4`
font-size: 1rem;
${media.small`font-size: 0.875rem;`};
`;
const Lead = styled.p`
font-size: 1.25rem;
line-height: 1.6;
${media.small`font-size: 1rem;`};
`;
const Small = styled.p`
font-size: 0.875rem;
`;
export { Alpha, Beta, Gamma, Lead, Small };

View File

@ -1,59 +0,0 @@
import { darken, saturate } from 'polished';
import * as React from 'react';
import styled from 'styled-components';
/**
* AN EXAMPLE OF HOW TO CREATE A STYLED COMPONENT USING STYLED-COMPONENTS
* SEE: https://www.styled-components.com/docs/basics#coming-from-css
*/
export interface ButtonProps {
backgroundColor?: string;
borderColor?: string;
width?: string;
padding?: string;
type?: string;
isDisabled?: boolean;
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
className?: string;
}
const PlainButton: React.StatelessComponent<ButtonProps> = ({ children, isDisabled, onClick, type, className }) => (
<button type={type} className={className} onClick={isDisabled ? undefined : onClick} disabled={isDisabled}>
{children}
</button>
);
const darkenOnHoverAmount = 0.1;
const darkenOnActiveAmount = 0.2;
const saturateOnFocusAmount = 0.2;
export const Button = styled(PlainButton)`
cursor: ${props => (props.isDisabled ? 'default' : 'pointer')};
transition: background-color, opacity 0.5s ease;
padding: ${props => props.padding};
border-radius: 3px;
outline: none;
width: ${props => props.width};
background-color: ${props => (props.backgroundColor ? props.backgroundColor : 'none')};
border: ${props => (props.borderColor ? `1px solid ${props.backgroundColor}` : 'none')};
&:hover {
background-color: ${props =>
!props.isDisabled ? darken(darkenOnHoverAmount, props.backgroundColor) : ''} !important;
}
&:active {
background-color: ${props => (!props.isDisabled ? darken(darkenOnActiveAmount, props.backgroundColor) : '')};
}
&:disabled {
opacity: 0.5;
}
&:focus {
background-color: ${props => saturate(saturateOnFocusAmount, props.backgroundColor)};
}
`;
Button.defaultProps = {
backgroundColor: 'red',
width: 'auto',
isDisabled: false,
padding: '1em 2.2em',
};
Button.displayName = 'Button';

View File

@ -1,55 +0,0 @@
import * as React from 'react';
type StringOrNum = string | number;
export type ContainerTag = 'div' | 'span';
export interface ContainerProps {
marginTop?: StringOrNum;
marginBottom?: StringOrNum;
marginRight?: StringOrNum;
marginLeft?: StringOrNum;
padding?: StringOrNum;
paddingTop?: StringOrNum;
paddingBottom?: StringOrNum;
paddingRight?: StringOrNum;
paddingLeft?: StringOrNum;
backgroundColor?: string;
borderRadius?: StringOrNum;
maxWidth?: StringOrNum;
maxHeight?: StringOrNum;
width?: StringOrNum;
height?: StringOrNum;
minWidth?: StringOrNum;
minHeight?: StringOrNum;
isHidden?: boolean;
className?: string;
position?: 'absolute' | 'fixed' | 'relative' | 'unset';
display?: 'inline-block' | 'block' | 'inline-flex' | 'inline';
top?: string;
left?: string;
right?: string;
bottom?: string;
zIndex?: number;
Tag?: ContainerTag;
cursor?: string;
id?: string;
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
overflowX?: 'scroll' | 'hidden' | 'auto' | 'visible';
}
export const Container: React.StatelessComponent<ContainerProps> = props => {
const { children, className, Tag, isHidden, id, onClick, ...style } = props;
const visibility = isHidden ? 'hidden' : undefined;
return (
<Tag id={id} style={{ ...style, visibility }} className={className} onClick={onClick}>
{children}
</Tag>
);
};
Container.defaultProps = {
Tag: 'div',
};
Container.displayName = 'Container';

View File

@ -1,74 +0,0 @@
import { colors } from '@0x/react-shared';
import { darken } from 'polished';
import * as React from 'react';
import styled from 'styled-components';
export type TextTag = 'p' | 'div' | 'span' | 'label' | 'h1' | 'h2' | 'h3' | 'h4' | 'i';
export interface TextProps {
className?: string;
Tag?: TextTag;
fontSize?: string;
fontFamily?: string;
fontStyle?: string;
fontColor?: string;
lineHeight?: string;
minHeight?: string;
center?: boolean;
fontWeight?: number | string;
textDecorationLine?: string;
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
hoverColor?: string;
noWrap?: boolean;
display?: string;
}
const PlainText: React.StatelessComponent<TextProps> = ({ children, className, onClick, Tag }) => (
<Tag className={className} onClick={onClick}>
{children}
</Tag>
);
export const Text = styled(PlainText)`
font-family: ${props => props.fontFamily};
font-style: ${props => props.fontStyle};
font-weight: ${props => props.fontWeight};
font-size: ${props => props.fontSize};
text-decoration-line: ${props => props.textDecorationLine};
${props => (props.lineHeight ? `line-height: ${props.lineHeight}` : '')};
${props => (props.center ? 'text-align: center' : '')};
color: ${props => props.fontColor};
${props => (props.minHeight ? `min-height: ${props.minHeight}` : '')};
${props => (props.onClick ? 'cursor: pointer' : '')};
transition: color 0.5s ease;
${props => (props.noWrap ? 'white-space: nowrap' : '')};
${props => (props.display ? `display: ${props.display}` : '')};
&:hover {
${props => (props.onClick ? `color: ${props.hoverColor || darken(0.3, props.fontColor || 'black')}` : '')};
}
`;
Text.defaultProps = {
fontFamily: 'Roboto',
fontStyle: 'normal',
fontWeight: 400,
fontColor: colors.black,
fontSize: '15px',
lineHeight: '1.5em',
textDecorationLine: 'none',
Tag: 'div',
noWrap: false,
};
Text.displayName = 'Text';
export const Title: React.StatelessComponent<TextProps> = props => <Text {...props} />;
Title.defaultProps = {
Tag: 'h2',
fontSize: '20px',
fontWeight: 600,
fontColor: colors.black,
};
Title.displayName = 'Title';

View File

@ -0,0 +1,19 @@
import Icon from 'ts/icons/logos/compiler.svg';
import { ContextInterface } from './index';
export const context: ContextInterface = {
title: 'sol-compiler',
name: 'compiler',
subtitle: 'Solidity compilation that just works',
tagline: 'Seamlessly compile an entire solidity project and generate customisable artifacts',
icon: Icon,
colors: {
main: '#1EADCD',
secondary: '#D1F4FC',
secondary_alt: '#C4F2FC',
type: '#30C3E3',
type_alt: '#16A9C9',
dark: '#4B818D',
},
};

View File

@ -0,0 +1,19 @@
import Icon from 'ts/icons/logos/cov.svg';
import { ContextInterface } from './index';
export const context: ContextInterface = {
title: 'sol-cov',
name: 'cov',
subtitle: 'Solidity code coverage',
tagline: 'Measure Solidity code coverage',
icon: Icon,
colors: {
main: '#BB9200',
secondary: '#F1DB8D',
secondary_alt: '#F1D882',
type: '#D7AE1B',
type_alt: '#BD9406',
dark: '#817033',
},
};

View File

@ -0,0 +1,21 @@
import { createContext } from 'react';
interface ContextInterface {
title?: string;
name?: string;
subtitle?: string;
tagline?: string;
icon?: React.ReactNode;
colors?: {
main: string;
secondary: string;
secondary_alt: string;
type: string;
type_alt: string;
dark: string;
};
}
const ThemeContext = createContext({});
export { ThemeContext, ContextInterface };

View File

@ -0,0 +1,19 @@
import Icon from 'ts/icons/logos/profiler.svg';
import { ContextInterface } from './index';
export const context: ContextInterface = {
title: 'sol-profiler',
name: 'profiler',
subtitle: 'Gas profiling for Solidity',
tagline: "Implement data-guided optimizations by profiling your contract's gas usage",
icon: Icon,
colors: {
main: '#FF7144',
secondary: '#FED7CB',
secondary_alt: '#FECEBE',
type: '#EB8666',
type_alt: '#D16745',
dark: '#985C49',
},
};

View File

@ -0,0 +1,19 @@
import Icon from 'ts/icons/logos/trace.svg';
import { ContextInterface } from './index';
export const context: ContextInterface = {
title: 'sol-trace',
name: 'trace',
subtitle: 'Human-readable stack traces',
tagline: 'Immediately locate Solidity errors and rapidly debug failed transactions',
icon: Icon,
colors: {
main: '#4F76FF',
secondary: '#CDD8FF',
secondary_alt: '#BFCDFF',
type: '#7090FF',
type_alt: '#355CE5',
dark: '#2A4ABC',
},
};

View File

@ -0,0 +1,90 @@
import hljsStyles from 'highlight.js/styles/github-gist.css';
import { createGlobalStyle } from 'styled-components';
import styledNormalize from 'styled-normalize';
import { ContextInterface } from 'ts/context';
import { media } from 'ts/variables';
const GlobalStyles =
createGlobalStyle <
ContextInterface >
`
${styledNormalize}
${hljsStyles}
@font-face {
font-family: "Maison Neue";
src: url("/fonts/MaisonNeue-Book-subset.woff2") format("woff2"), url("/fonts/MaisonNeue-Book-subset.woff") format("woff");
font-weight: 300;
font-display: swap;
unicode-range: U+20-7E;
}
@font-face {
font-family: "Maison Neue";
src: url("/fonts/MaisonNeue-Bold-subset.woff2") format("woff2"), url("/fonts/MaisonNeue-Bold-subset.woff") format("woff");
font-weight: 500;
font-display: swap;
unicode-range: U+20-7E;
}
@font-face {
font-family: "Maison Neue Mono";
src: url("/fonts/MaisonNeue-Mono-subset.woff2") format("woff2"), url("/fonts/MaisonNeue-Mono-subset.woff") format("woff");
font-weight: 300;
font-display: optional;
unicode-range: U+20-7E;
}
html {
font-size: 100%;
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
}
body {
font-family: "Maison Neue", system-ui, sans-serif;
font-weight: 300;
font-size: 1rem;
line-height: 1.8;
${media.small`font-size: 0.875rem;`};
}
a {
color: inherit;
text-decoration: none;
}
a:not([class]) {
color: ${props => props.colors.type_alt};
text-decoration: none;
&:hover {
color: ${props => props.colors.type_alt};
}
}
h1, h2, h3, h4 {
font-weight: 500;
margin: 0;
}
p {
margin-top: 0;
margin-bottom: 1em;
&:not([class]):last-of-type {
margin-bottom: 0;
}
}
code {
font-family: "Maison Neue Mono", monospace;
${media.small`
font-size: .75rem;
`}
}
`;
export { GlobalStyles };

View File

@ -1,5 +1,10 @@
declare module 'whatwg-fetch'; declare module 'whatwg-fetch';
declare module 'react-document-title'; declare module 'react-document-title';
declare module 'highlight.js/lib/highlight';
declare module 'highlight.js/lib/languages/javascript';
declare module 'highlight.js/lib/languages/json';
declare var System: any;
declare module '*.json' { declare module '*.json' {
const json: any; const json: any;
@ -7,3 +12,13 @@ declare module '*.json' {
export default json; export default json;
/* tslint:enable */ /* tslint:enable */
} }
declare module '*.css' {
const css: any;
export default css;
}
declare module '*.svg' {
const svg: any;
export default svg;
}

View File

@ -0,0 +1,67 @@
import * as hljs from 'highlight.js/lib/highlight';
import * as javascript from 'highlight.js/lib/languages/javascript';
import * as json from 'highlight.js/lib/languages/json';
import * as _ from 'lodash';
hljs.registerLanguage('javascript', javascript);
hljs.registerLanguage('json', json);
interface PatchInterface {
[key: string]: string;
}
const PATCH_TYPES: PatchInterface = {
'+': 'addition',
'-': 'deletion',
'!': 'change',
};
function diffHighlight(language: string, code: any, gutter: any): string {
return _.map(code.split(/\r?\n/g), (line: string, index: number) => {
let type;
let currentLine = line;
if (/^-{3} [^-]+ -{4}$|^\*{3} [^*]+ \*{4}$|^@@ [^@]+ @@$/.test(currentLine)) {
type = 'chunk';
} else if (/^Index: |^[+\-*]{3}|^[*=]{5,}$/.test(currentLine)) {
type = 'header';
} else {
type = PATCH_TYPES[currentLine[0]] || 'null';
currentLine = currentLine.replace(/^[+\-! ]/, '');
}
const g = gutter[index];
return `<span data-gutter="${g !== undefined ? `${g}x` : ''}" class="line-${type}">${
hljs.highlight(language, currentLine).value
}</span>`;
}).join('\n');
}
interface HighlightProps {
language: string;
code: string;
isDiff?: boolean;
gutter?: [];
isEtc?: boolean;
}
function highlight({ language, code, isDiff, gutter, isEtc }: HighlightProps): string {
if (isDiff) {
return diffHighlight(language, code, gutter);
}
const hlCode = hljs.highlight(language, code).value;
if (!isEtc) {
return hlCode;
}
const hc = hlCode.split(/\r?\n/g);
hc.splice(1, 0, ' ...');
hc.splice(hc.length - 1, 0, ' ...');
return hc.join('\n');
}
export { highlight };

View File

@ -0,0 +1 @@
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M80 33.6772c0 5.1116-1.8855 10.4454-4.7935 15.617-2.9036 5.1637-6.7886 10.0987-10.6962 14.3941-3.9047 4.2922-7.8128 7.9248-10.746 10.4851-1.4659 1.2795-2.6866 2.2897-3.5393 2.9788-.2841.2296-.5273.4235-.725.5798-.1977-.1563-.4409-.3502-.725-.5798-.8527-.6891-2.0734-1.6993-3.5393-2.9788-2.9332-2.5603-6.8413-6.1929-10.746-10.4851-3.9076-4.2954-7.7926-9.2304-10.6962-14.3941C20.8855 44.1226 19 38.7888 19 33.6772 19 16.7294 32.6606 3 49.5 3 66.3394 3 80 16.7294 80 33.6772z" stroke="#fff" stroke-width="2"/><path d="M50 98V55M27.5 77H73" stroke="#000" stroke-width="2"/><circle cx="50" cy="34" r="10" stroke="#fff" stroke-width="2"/></svg>

After

Width:  |  Height:  |  Size: 746 B

View File

@ -0,0 +1 @@
<svg width="37" height="37" viewBox="0 0 37 37" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><path d="M9.20465 34.4904c2.38415 1.3926 5.13725 2.2736 8.08905 2.4725 4.0871.2558 7.9188-.8242 11.1261-2.8704 1.5894-1.0232 3.0085-2.2737 4.229-3.7231-.9934-1.3926-2.0719-2.842-3.2072-4.3199-.3123-.3979-.6245-.7958-.9367-1.1937-1.1921 1.9042-2.9518 3.4389-4.9953 4.4052l-3.1789-3.0978-11.12605 8.3272zM2.44955 9.30988C1.08718 11.6972.235696 14.3971.0370167 17.3244-.218428 21.417.860116 25.2821 2.90368 28.4652c1.02177 1.5916 2.27062 3.0126 3.71814 4.2347 1.39075-.9947 2.83827-2.0747 4.31418-3.2115.3974-.3127.7947-.6253 1.1921-.9379-1.9017-1.2221-3.43434-2.9841-4.39936-5.0304l3.12206-3.1831L2.44955 9.30988zM27.7954 2.51741C25.4112 1.12481 22.6581.243776 19.7063.0448336 15.6192-.23937 11.7591.840605 8.55184 2.91529 6.96241 3.93843 5.54327 5.18893 4.32281 6.63837c.9934 1.3926 2.07194 2.84204 3.20725 4.31993.31221.3979.62442.7957.93663 1.1936 1.22046-1.9041 2.95181-3.43884 5.02371-4.40514l2.9802 2.87044 11.3248-8.09979zM34.5788 27.6126c1.334-2.3589 2.1855-5.0304 2.3842-7.9293.2554-4.0925-.8231-7.9293-2.8667-11.14077-1.0218-1.59154-2.2706-3.01256-3.7181-4.23464-1.3908.99472-2.8383 2.07469-4.3142 3.21151-.3974.31262-.7947.62525-1.1921.93787 1.9301 1.22208 3.4627 2.98413 4.4277 5.03043l.0284.0568-3.0085 3.1263 8.2593 10.9418z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,3 @@
<svg width="28" height="28" viewBox="0 0 28 28" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 28V15V0H15H28V15V28H15H0ZM26 13V2H15V13H26ZM15 15H26V26H15V15ZM13 13V2H2V13H13ZM2 15H13V26H2V15Z" />
</svg>

After

Width:  |  Height:  |  Size: 264 B

View File

@ -0,0 +1,3 @@
<svg width="28" height="28" viewBox="0 0 28 28" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 0H28V28H0V0ZM2 2V26H26V16H12V2H2ZM14 2V14H26V2H14Z"/>
</svg>

After

Width:  |  Height:  |  Size: 217 B

View File

@ -0,0 +1,3 @@
<svg width="28" height="28" viewBox="0 0 28 28" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 2H26V9H2V2ZM2 11V26H26V11H2ZM0 0H2H26H28V2V26V28H26H2H0V26V2V0Z" />
</svg>

After

Width:  |  Height:  |  Size: 231 B

View File

@ -0,0 +1 @@
<svg width="28" height="28" viewBox="0 0 28 28" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10 15H2V2h24v13H10zm0 2H2v9h8v-9zm2 9h14v-9H12v9zm-2 2H0V0h28v28H10z"/></svg>

After

Width:  |  Height:  |  Size: 230 B

View File

@ -0,0 +1 @@
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"><path opacity=".5" d="M88.2609 41.4937c0 6.4322-2.3631 13.1253-5.9866 19.5928-3.6191 6.4597-8.4581 12.6276-13.3196 17.9909-4.8586 5.3602-9.7205 9.8958-13.3691 13.0921-1.8236 1.5975-3.3423 2.8589-4.4037 3.7198-.4285.3475-.7823.6297-1.0515.8423-.2692-.2126-.623-.4948-1.0514-.8423-1.0614-.8609-2.5802-2.1223-4.4038-3.7198-3.6486-3.1963-8.5105-7.7319-13.3691-13.0921-4.8614-5.3633-9.7004-11.5312-13.3196-17.9909C14.363 54.619 12 47.9259 12 41.4937 12 20.2255 29.0803 3 50.1304 3c21.0502 0 38.1305 17.2255 38.1305 38.4937z" stroke="#CDD8FF" stroke-width="2"/><circle opacity=".5" cx="50" cy="42" r="18" stroke="#CDD8FF" stroke-width="2"/><path d="M22.5 69.5L78 14" stroke="#fff" stroke-width="2"/></svg>

After

Width:  |  Height:  |  Size: 798 B

View File

@ -0,0 +1 @@
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"><circle opacity=".5" cx="50" cy="50" r="42" stroke="#CDD8FF" stroke-width="2"/><path opacity=".5" d="M34.6621 79.4343c6.9918 3.5363 15.2613 4.61 23.4252 2.4225 8.1639-2.1875 14.7886-7.2521 19.0755-13.8105M33.8711 58c2.9454 5.9269 9.0615 10 16.129 10 1.5538 0 3.0617-.1969 4.5-.5671M30 25.0185C35.4784 20.6269 42.4324 18 50 18c13.4295 0 24.9268 8.2727 29.6739 20" stroke="#CDD8FF" stroke-width="2"/><path d="M35 64l17.5-12.5L37.5 9" stroke="#fff" stroke-width="2"/></svg>

After

Width:  |  Height:  |  Size: 569 B

View File

@ -0,0 +1 @@
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="49.9092" cy="49.7499" r="40.4824" transform="rotate(45 49.9092 49.7499)" stroke="#fff" stroke-width="2"/><path d="M21.5991 79.4236l8.5269-8.5269M71.3965 29.6267l8.5268-8.5268M69.6914 70.8967l8.5269 8.5269M20.5761 21.7819l9.2091 9.2091M9.01002 50.4736H21.0688M79.4334 50.4736h12.0588M49.0449 78.45v12.0588M49.0449 8.99112V22.0146" stroke="#fff" stroke-width="2"/><path d="M35.584 36.789l14.3252 14.3252 30.0146-30.0146" stroke="#000" stroke-width="2"/></svg>

After

Width:  |  Height:  |  Size: 568 B

View File

@ -1,17 +0,0 @@
import * as React from 'react';
import { render } from 'react-dom';
import { MetaTags } from 'ts/components/meta_tags';
import { Landing } from 'ts/pages/landing';
import 'basscss/css/basscss.css';
const DOCUMENT_TITLE = '';
const DOCUMENT_DESCRIPTION = '';
render(
<div>
<MetaTags title={DOCUMENT_TITLE} description={DOCUMENT_DESCRIPTION} />
<Landing />
</div>,
document.getElementById('app'),
);

View File

@ -0,0 +1,170 @@
import * as React from 'react';
import { hydrate, render } from 'react-dom';
import * as Loadable from 'react-loadable';
import { context } from 'ts/context/compiler';
import { Base } from 'ts/components/base';
import { Breakout } from 'ts/components/breakout';
import { Code } from 'ts/components/code';
import { Compiler as CompilerComponent } from 'ts/components/compiler';
import { Content } from 'ts/components/content';
import { ContentBlock } from 'ts/components/content-block';
import { Hero } from 'ts/components/hero';
import { InlineCode } from 'ts/components/inline-code';
import { Lead } from 'ts/components/typography';
const Animation = Loadable({
loader: () => System.import(/* webpackChunkName: 'compiler-animation' */ 'ts/components/animations/compiler'),
loading: () => <div />,
delay: 1000,
render(loadable: { CompilerAnimation: any }): React.ReactNode {
const Component = loadable.CompilerAnimation;
return <Component />;
},
});
const Compiler: React.StatelessComponent<{}> = () => (
<Base context={context}>
<Hero>
<Animation />
</Hero>
<CompilerComponent />
<Content>
<ContentBlock main={true} title="Get started" />
<ContentBlock title="Install">
<Breakout>
<Code canCopy={true}>npm install @0x/sol-compiler --g</Code>
</Breakout>
</ContentBlock>
<ContentBlock title="Run">
<Breakout>
<Code>cd /your_project_dir && sol-compiler</Code>
</Breakout>
</ContentBlock>
<ContentBlock title="Configure">
<p>
Configure via a <InlineCode>compiler.json</InlineCode> file.
</p>
<Breakout>
<Code>mkdir compiler.json</Code>
</Breakout>
<p>Example of settings:</p>
<Breakout>
<Code language="json">
{`{
"contractsDir": "contracts",
"artifactsDir": "artifacts",
"contracts": "*",
"compilerSettings": {
"optimizer": { "enabled": false },
"outputSelection": {
"*": {
"*": ["abi", "evm.bytecode.object"]
}
}
}
}`}
</Code>
</Breakout>
</ContentBlock>
</Content>
<Content dark={true}>
<ContentBlock main={true} title="Artifacts">
<Lead>
Sol compiler uses solidity standard JSON output format for the artifacts. This way, you can define
which parts of the artifact you need.
</Lead>
</ContentBlock>
<ContentBlock title="Production">
<p>
Sol compiler uses solidity standard JSON output format for the artifacts. This way, you can define
which parts of the artifact you need.
</p>
<Breakout>
<Code isLight={true} language="json" isEtc={true}>
{`{
"compilerSettings": {
"outputSelection": {
"*": {
"*": ["abi"]
}
}
}
}`}
</Code>
</Breakout>
<Breakout>
<Code isLight={true} language="json" isEtc={true}>
{`{
"compilerOutput": {
"abi": [...],
},
}`}
</Code>
</Breakout>
</ContentBlock>
<ContentBlock title="Development">
<p>
Sometimes you need to use some debuggers or other dev tools and youll need more info in the
artifact.
</p>
<Breakout>
<Code isLight={true} language="json" isEtc={true}>
{`{
"compilerSettings": {
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode.object",
"evm.bytecode.sourceMap",
"evm.deployedBytecode.object",
"evm.deployedBytecode.sourceMap"
]
}
}
}
}`}
</Code>
</Breakout>
<Breakout>
<Code isLight={true} language="json" isEtc={true}>
{`{
"compilerOutput": {
"abi": [...],
"evm": {
"bytecode": {
"object": "0xdeadbeef",
"sourceMap": "26:480:..."
},
"deployedBytecode": {
"object": "0xdeadbeef",
"sourceMap": "26:480:0..."
}
}
}
"sources": {
"Migrations.sol": {
"id": 0
}
},
}`}
</Code>
</Breakout>
</ContentBlock>
</Content>
</Base>
);
const root = document.getElementById('app');
if (root.hasChildNodes()) {
hydrate(<Compiler />, root);
} else {
render(<Compiler />, root);
}

View File

@ -0,0 +1,149 @@
import * as React from 'react';
import { hydrate, render } from 'react-dom';
import * as Loadable from 'react-loadable';
import { context } from 'ts/context/cov';
import { Base } from 'ts/components/base';
import { Breakout } from 'ts/components/breakout';
import { Code } from 'ts/components/code';
import { Content } from 'ts/components/content';
import { ContentBlock } from 'ts/components/content-block';
import { Hero } from 'ts/components/hero';
import { InlineCode } from 'ts/components/inline-code';
import { Intro, IntroAside, IntroLead } from 'ts/components/intro';
import { List, ListItem } from 'ts/components/list';
import { TabBlock, Tabs } from 'ts/components/tabs';
const Animation = Loadable({
loader: () => System.import(/* webpackChunkName: 'cov-animation' */ 'ts/components/animations/cov'),
loading: () => <div />,
delay: 1000,
render(loadable: { CovAnimation: any }): React.ReactNode {
const Component = loadable.CovAnimation;
return <Component />;
},
});
const Cov: React.StatelessComponent<{}> = () => (
<Base context={context}>
<Hero>
<Animation />
</Hero>
<Intro>
<IntroLead title="Measure your tests">
<p>
When it comes to writing smart contracts, testing is one of the most important steps of the process.
In order to quantify the robustness of your Solidity testing suite, you need to measure its code
coverage.
</p>
</IntroLead>
<IntroAside>
<Code
language="javascript"
isDiff={true}
gutterLength={2}
gutter={[4, undefined, 4, 4, 4, undefined, 4, 2, 2, 2]}
>
{`+function executeTransaction(uint transactionId)
public
+ notExecuted(transactionId)
+ fullyConfirmed(transactionId)
+ pastTimeLock(transactionId)
{
+ Transaction storage tx = transactions[transactionId]
+ tx.executed = true
+ if (tx.destination.call.value(tx.value)(tx.data))
+ Execution(transactionId)
else {
- ExecutionFailure(transactionId)
- tx.executed = false
}
}`}
</Code>
</IntroAside>
</Intro>
<Content>
<ContentBlock main={true} title="Get started" />
<ContentBlock title="Prerequisites">
<List>
<ListItem>
Use <a href="#">ganache-cli</a> as a backing node.
</ListItem>
<ListItem>
Understand and use <a href="#">web3-provider-engine</a>.
</ListItem>
</List>
</ContentBlock>
<ContentBlock title="Installation">
<Breakout>
<Code>npm install @0x/sol-cov --save</Code>
</Breakout>
<p>
Sol-cov is a subprovider that needs to be prepended to your <a href="#">provider engine</a>.
Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-cov ships with
the <InlineCode>SolCompilerArtifactAdapter</InlineCode> for use with <a href="#">Sol-compiler</a>{' '}
and <InlineCode>TruffleArtifactAdapter</InlineCode> for use with the{' '}
<a href="#">Truffle framework</a>. You can also write your own and support any artifact format.
</p>
<Tabs>
<TabBlock title="Sol-compiler">
<Code language="javascript">
{`import { SolCompilerArtifactAdapter } from '@0x/sol-trace';
// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in
const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDir);`}
</Code>
</TabBlock>
<TabBlock title="Truffle">
<Code language="javascript">
{`import { TruffleArtifactAdapter } from '@0x/sol-trace';
const projectRoot = '.';
const solcVersion = '0.4.24';
const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion);`}
</Code>
</TabBlock>
<TabBlock title="Custom">
<Code language="javascript">
{`import { AbstractArtifactAdapter } from '@0x/sol-trace';
class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...};
const artifactAdapter = new YourCustomArtifactsAdapter(...);`}
</Code>
</TabBlock>
</Tabs>
<p>
Now that we have an <InlineCode>artifactAdapter</InlineCode>, we can create a{' '}
<InlineCode>RevertTraceSubprovider</InlineCode> and append it to our provider engine.
</p>
<Breakout>
<Code language="javascript">
{`import { ProviderEngine, RpcSubprovider } from 'web3-provider-engine';
import { RevertTraceSubprovider } from '@0x/sol-cov';
const defaultFromAddress = "..."; // Some ethereum address with test funds
const revertTraceSubprovider = new RevertTraceSubprovider(artifactAdapter, defaultFromAddress);
const providerEngine = new ProviderEngine();
providerEngine.addProvider(revertTraceSubprovider);
providerEngine.addProvider(new RpcSubprovider({rpcUrl: 'http://localhost:8545'}));
providerEngine.start();`}
</Code>
</Breakout>
</ContentBlock>
</Content>
</Base>
);
const root = document.getElementById('app');
if (root.hasChildNodes()) {
hydrate(<Cov />, root);
} else {
render(<Cov />, root);
}

View File

@ -1,27 +0,0 @@
import * as _ from 'lodash';
import * as React from 'react';
import { Button } from '../components/ui/button';
import { Container } from '../components/ui/container';
import { Text } from '../components/ui/text';
interface LandingProps {}
interface LandingState {}
export class Landing extends React.Component<LandingProps, LandingState> {
constructor(props: LandingProps) {
super(props);
}
public render(): React.ReactNode {
return (
<Container id="landing" className="clearfix">
<Container className="mx-auto p4" width="200px">
<Button>
<Text fontColor="white">Click me!</Text>
</Button>
</Container>
</Container>
);
}
}

View File

@ -0,0 +1,146 @@
import * as React from 'react';
import { hydrate, render } from 'react-dom';
import * as Loadable from 'react-loadable';
import { context } from 'ts/context/profiler';
import { Base } from 'ts/components/base';
import { Breakout } from 'ts/components/breakout';
import { Code } from 'ts/components/code';
import { Content } from 'ts/components/content';
import { ContentBlock } from 'ts/components/content-block';
import { Hero } from 'ts/components/hero';
import { InlineCode } from 'ts/components/inline-code';
import { Intro, IntroAside, IntroLead } from 'ts/components/intro';
import { List, ListItem } from 'ts/components/list';
import { TabBlock, Tabs } from 'ts/components/tabs';
const Animation = Loadable({
loader: () => System.import(/* webpackChunkName: 'profiler-animation' */ 'ts/components/animations/profiler'),
loading: () => <div />,
delay: 1000,
render(loadable: { ProfilerAnimation: any }): React.ReactNode {
const Component = loadable.ProfilerAnimation;
return <Component />;
},
});
const Profiler: React.StatelessComponent<{}> = () => (
<Base context={context}>
<Hero>
<Animation />
</Hero>
<Intro>
<IntroLead title="Outline gas usage">
<p>
Sol-profiler gathers line-by-line gas usage for any transaction submitted through your provider.
This will help you find unexpected inefficiencies in parts of your smart contract, and take a
data-driven approach to optimizing it.
</p>
</IntroLead>
<IntroAside>
<Code
language="javascript"
isDiff={true}
gutterLength={6}
gutter={[15, 15, undefined, 21747, 20303, 1435]}
>
{`+function() public payable {
+ deposit();
}
+function deposit() public payabble {
+ balanceOf[msg.sender] += msg.value;
+ Deposit(msg.sender, msg.value);
}
-function withdraw(uint wad) public {
- require(balanceOf[msg.sender] >= wad);
- balanceOf[msg.sender] -= wad;
- msg.sender.transfer(wad);
- Withdrawal(msg.sender, wad);
}`}
</Code>
</IntroAside>
</Intro>
<Content>
<ContentBlock main={true} title="Get started" />
<ContentBlock title="Prerequisites">
<List>
<ListItem>
Use <a href="#">ganache-cli</a> as a backing node.
</ListItem>
<ListItem>
Understand and use <a href="#">web3-provider-engine</a>.
</ListItem>
</List>
</ContentBlock>
<ContentBlock title="Installation">
<Breakout>
<Code>npm install @0x/sol-trace --save</Code>
</Breakout>
<p>
Sol-trace is a subprovider that needs to be prepended to your <a href="#">provider engine</a>.
Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-trace ships
with the <InlineCode>SolCompilerArtifactAdapter</InlineCode> for use with{' '}
<a href="#">Sol-compiler</a> and <InlineCode>TruffleArtifactAdapter</InlineCode> for use with the{' '}
<a href="#">Truffle framework</a>. You can also write your own and support any artifact format.
</p>
<Tabs>
<TabBlock title="Sol-compiler">
<Code language="javascript">
{`import { SolCompilerArtifactAdapter } from '@0x/sol-trace';
// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in
const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDir);`}
</Code>
</TabBlock>
<TabBlock title="Truffle">
<Code language="javascript">
{`import { TruffleArtifactAdapter } from '@0x/sol-trace';
const projectRoot = '.';
const solcVersion = '0.4.24';
const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion);`}
</Code>
</TabBlock>
<TabBlock title="Custom">
<Code language="javascript">
{`import { AbstractArtifactAdapter } from '@0x/sol-trace';
class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...};
const artifactAdapter = new YourCustomArtifactsAdapter(...);`}
</Code>
</TabBlock>
</Tabs>
<p>
Now that we have an <InlineCode>artifactAdapter</InlineCode>, we can create a{' '}
<InlineCode>RevertTraceSubprovider</InlineCode> and append it to our provider engine.
</p>
<Breakout>
<Code language="javascript">
{`import { ProviderEngine, RpcSubprovider } from 'web3-provider-engine';
import { RevertTraceSubprovider } from '@0x/sol-cov';
const defaultFromAddress = "..."; // Some ethereum address with test funds
const revertTraceSubprovider = new RevertTraceSubprovider(artifactAdapter, defaultFromAddress);
const providerEngine = new ProviderEngine();
providerEngine.addProvider(revertTraceSubprovider);
providerEngine.addProvider(new RpcSubprovider({rpcUrl: 'http://localhost:8545'}));
providerEngine.start();`}
</Code>
</Breakout>
</ContentBlock>
</Content>
</Base>
);
const root = document.getElementById('app');
if (root.hasChildNodes()) {
hydrate(<Profiler />, root);
} else {
render(<Profiler />, root);
}

View File

@ -0,0 +1,116 @@
import * as React from 'react';
import { hydrate, render } from 'react-dom';
import * as Loadable from 'react-loadable';
import { context } from 'ts/context/trace';
import { Base } from 'ts/components/base';
import { Breakout } from 'ts/components/breakout';
import { Code } from 'ts/components/code';
import { Content } from 'ts/components/content';
import { ContentBlock } from 'ts/components/content-block';
import { Hero } from 'ts/components/hero';
import { InlineCode } from 'ts/components/inline-code';
import { List, ListItem } from 'ts/components/list';
import { TabBlock, Tabs } from 'ts/components/tabs';
import { Trace as TraceComponent } from 'ts/components/trace';
const Animation = Loadable({
loader: () => System.import(/* webpackChunkName: 'trace-animation' */ 'ts/components/animations/trace'),
loading: () => <div />,
delay: 1000,
render(loadable: { TraceAnimation: any }): React.ReactNode {
const Component = loadable.TraceAnimation;
return <Component />;
},
});
const Trace: React.StatelessComponent<{}> = () => (
<Base context={context}>
<Hero>
<Animation />
</Hero>
<TraceComponent />
<Content>
<ContentBlock main={true} title="Get started" />
<ContentBlock title="Prerequisites">
<List>
<ListItem>
Use <a href="#">ganache-cli</a> as a backing node.
</ListItem>
<ListItem>
Understand and use <a href="#">web3-provider-engine</a>.
</ListItem>
</List>
</ContentBlock>
<ContentBlock title="Installation">
<Breakout>
<Code>npm install @0x/sol-trace --save</Code>
</Breakout>
<p>
Sol-trace is a subprovider that needs to be prepended to your <a href="#">provider engine</a>.
Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-trace ships
with the <InlineCode>SolCompilerArtifactAdapter</InlineCode> for use with{' '}
<a href="#">Sol-compiler</a> and <InlineCode>TruffleArtifactAdapter</InlineCode> for use with the{' '}
<a href="#">Truffle framework</a>. You can also write your own and support any artifact format.
</p>
<Tabs>
<TabBlock title="Sol-compiler">
<Code language="javascript">
{`import { SolCompilerArtifactAdapter } from '@0x/sol-trace';
// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in
const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDir);`}
</Code>
</TabBlock>
<TabBlock title="Truffle">
<Code language="javascript">
{`import { TruffleArtifactAdapter } from '@0x/sol-trace';
const projectRoot = '.';
const solcVersion = '0.4.24';
const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion);`}
</Code>
</TabBlock>
<TabBlock title="Custom">
<Code language="javascript">
{`import { AbstractArtifactAdapter } from '@0x/sol-trace';
class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...};
const artifactAdapter = new YourCustomArtifactsAdapter(...);`}
</Code>
</TabBlock>
</Tabs>
<p>
Now that we have an <InlineCode>artifactAdapter</InlineCode>, we can create a{' '}
<InlineCode>RevertTraceSubprovider</InlineCode> and append it to our provider engine.
</p>
<Breakout>
<Code language="javascript">
{`import { ProviderEngine, RpcSubprovider } from 'web3-provider-engine';
import { RevertTraceSubprovider } from '@0x/sol-cov';
const defaultFromAddress = "..."; // Some ethereum address with test funds
const revertTraceSubprovider = new RevertTraceSubprovider(artifactAdapter, defaultFromAddress);
const providerEngine = new ProviderEngine();
providerEngine.addProvider(revertTraceSubprovider);
providerEngine.addProvider(new RpcSubprovider({rpcUrl: 'http://localhost:8545'}));
providerEngine.start();`}
</Code>
</Breakout>
</ContentBlock>
</Content>
</Base>
);
const root = document.getElementById('app');
if (root.hasChildNodes()) {
hydrate(<Trace />, root);
} else {
render(<Trace />, root);
}

View File

@ -1,32 +0,0 @@
import * as bowser from 'bowser';
import * as _ from 'lodash';
export const utils = {
getColSize(items: number): number {
const bassCssGridSize = 12; // Source: http://basscss.com/#basscss-grid
const colSize = bassCssGridSize / items;
if (!_.isInteger(colSize)) {
throw new Error(`Number of cols must be divisible by ${bassCssGridSize}`);
}
return colSize;
},
getCurrentBaseUrl(): string {
const port = window.location.port;
const hasPort = !_.isUndefined(port);
const baseUrl = `https://${window.location.hostname}${hasPort ? `:${port}` : ''}`;
return baseUrl;
},
onPageLoadPromise: new Promise<void>((resolve, _reject) => {
if (document.readyState === 'complete') {
resolve();
return;
}
window.onload = () => resolve();
}),
openUrl(url: string): void {
window.open(url, '_blank');
},
isMobileOperatingSystem(): boolean {
return bowser.mobile;
},
};

View File

@ -0,0 +1,34 @@
import { css } from 'styled-components';
const colors = {
black: '#000000',
white: '#FFFFFF',
lightGray: '#F1F4F5',
gray: '#F1F2F7',
darkGray: '#E9ECED',
darkestGray: '#E2E5E6',
blueGray: '#ECEFF9',
};
interface SizesInterface {
[key: string]: number;
}
const sizes: SizesInterface = {
xlarge: 1420,
large: 1000,
medium: 900,
small: 650,
};
const media = Object.keys(sizes).reduce((acc: any, label: string) => {
acc[label] = (args: any) => css`
@media (max-width: ${sizes[label] / 16}em) {
${css(args)};
}
`;
return acc;
}, {});
export { colors, media };

View File

@ -1,13 +1,24 @@
const path = require('path'); const path = require('path');
const webpack = require('webpack'); const webpack = require('webpack');
const TerserPlugin = require('terser-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const HtmlWebpackPlugin = require('html-webpack-plugin');
const childProcess = require('child_process'); const childProcess = require('child_process');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const pages = require('./pages');
const config = { const config = {
entry: ['./ts/index.tsx'], entry: {
compiler: './ts/pages/compiler.tsx',
cov: './ts/pages/cov.tsx',
profiler: './ts/pages/profiler.tsx',
trace: './ts/pages/trace.tsx',
},
output: { output: {
path: path.join(__dirname, '/public'), path: path.join(__dirname, '/public'),
filename: 'bundle.js', filename: 'bundle-[name].js',
chunkFilename: 'bundle-[name].js', chunkFilename: 'bundle-[name].js',
publicPath: '/', publicPath: '/',
}, },
@ -48,6 +59,10 @@ const config = {
test: /\.css$/, test: /\.css$/,
loaders: ['style-loader', 'css-loader'], loaders: ['style-loader', 'css-loader'],
}, },
{
test: /\.svg$/,
loaders: ['react-svg-loader'],
},
], ],
}, },
optimization: { optimization: {
@ -60,21 +75,36 @@ const config = {
devServer: { devServer: {
port: 3572, port: 3572,
disableHostCheck: true, disableHostCheck: true,
overlay: true,
historyApiFallback: true,
}, },
}; };
module.exports = (_env, argv) => { module.exports = (_env, argv) => {
let plugins = []; let plugins = [
new CleanWebpackPlugin('public'),
...pages.map(p => new HtmlWebpackPlugin(p)),
new CopyWebpackPlugin([
{ from: 'assets/crawl.html', to: 'index.html' },
{ from: 'assets/fonts', to: 'fonts' },
{ from: 'assets/images', to: 'images' },
]),
];
if (argv.mode === 'development') { if (argv.mode === 'development') {
config.mode = 'development'; config.mode = 'development';
} else { } else {
config.mode = 'production'; config.mode = 'production';
config.output.filename = 'bundle-[name].[chunkhash].js';
config.output.chunkFilename = 'bundle-[name].[chunkhash].js';
plugins = plugins.concat([ plugins = plugins.concat([
new webpack.DefinePlugin({ new webpack.DefinePlugin({
'process.env': { 'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV), NODE_ENV: JSON.stringify(process.env.NODE_ENV || config.mode),
}, },
}), }),
// commented out to check the bundle when needed
//new BundleAnalyzerPlugin(),
]); ]);
} }
console.log('i 「atl」: Mode: ', config.mode); console.log('i 「atl」: Mode: ', config.mode);

View File

@ -76,7 +76,7 @@
"@types/react-dom": "^16.0.8", "@types/react-dom": "^16.0.8",
"@types/react-redux": "^6.0.9", "@types/react-redux": "^6.0.9",
"@types/redux": "^3.6.0", "@types/redux": "^3.6.0",
"@types/styled-components": "^4.0.1", "@types/styled-components": "4.0.1",
"awesome-typescript-loader": "^5.2.1", "awesome-typescript-loader": "^5.2.1",
"dotenv-cli": "^1.4.0", "dotenv-cli": "^1.4.0",
"enzyme": "^3.6.0", "enzyme": "^3.6.0",

View File

@ -27,7 +27,7 @@
"@0x/dev-utils": "^1.0.22", "@0x/dev-utils": "^1.0.22",
"@0x/tslint-config": "^2.0.0", "@0x/tslint-config": "^2.0.0",
"@types/compare-versions": "^3.0.0", "@types/compare-versions": "^3.0.0",
"@types/styled-components": "^4.0.0", "@types/styled-components": "4.0.0",
"make-promises-safe": "^1.1.0", "make-promises-safe": "^1.1.0",
"shx": "^0.2.2", "shx": "^0.2.2",
"tslint": "^5.9.1", "tslint": "^5.9.1",

View File

@ -43,7 +43,7 @@
"@types/react-dom": "*", "@types/react-dom": "*",
"@types/react-router-dom": "^4.0.4", "@types/react-router-dom": "^4.0.4",
"@types/react-scroll": "1.5.3", "@types/react-scroll": "1.5.3",
"@types/styled-components": "^4.0.0", "@types/styled-components": "4.0.0",
"@types/valid-url": "^1.0.2", "@types/valid-url": "^1.0.2",
"basscss": "^8.0.3", "basscss": "^8.0.3",
"change-case": "^3.0.2", "change-case": "^3.0.2",

View File

@ -36,7 +36,7 @@
"@types/react-lazyload": "^2.3.1", "@types/react-lazyload": "^2.3.1",
"@types/react-loadable": "^5.4.2", "@types/react-loadable": "^5.4.2",
"@types/react-syntax-highlighter": "^0.0.8", "@types/react-syntax-highlighter": "^0.0.8",
"@types/styled-components": "^4.1.1", "@types/styled-components": "4.1.1",
"accounting": "^0.4.1", "accounting": "^0.4.1",
"basscss": "^8.0.3", "basscss": "^8.0.3",
"blockies": "^0.0.2", "blockies": "^0.0.2",

3458
yarn.lock

File diff suppressed because it is too large Load Diff