Implement docusaurus build, deployment and CI hooks (#129)
* Implement docs build, deployment and CI hooks * Fixup travis config * Update references to final domain choice
69
.travis.yml
|
@ -1,34 +1,51 @@
|
|||
dist: bionic
|
||||
sudo: required
|
||||
language: rust
|
||||
services:
|
||||
- docker
|
||||
cache:
|
||||
cargo: true
|
||||
directories:
|
||||
- "~/.npm"
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
install:
|
||||
- cargo --version
|
||||
- rustup install nightly
|
||||
- rustup component add clippy --toolchain nightly
|
||||
- docker --version
|
||||
- wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
||||
- sudo apt-add-repository "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main"
|
||||
- sudo apt-get update
|
||||
- sudo apt-get install -y clang-7 --allow-unauthenticated
|
||||
- sudo apt-get install -y openssl --allow-unauthenticated
|
||||
- sudo apt-get install -y libssl-dev --allow-unauthenticated
|
||||
- sudo apt-get install -y libssl1.1 --allow-unauthenticated
|
||||
- clang-7 --version
|
||||
- nvm install node
|
||||
- node --version
|
||||
cache:
|
||||
cargo: true
|
||||
directories:
|
||||
- "~/.npm"
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- stage: "Test Programs"
|
||||
script: ./ci/memo.sh
|
||||
- script: ./ci/token-swap.sh
|
||||
- script: ./ci/token.sh
|
||||
- name: "Test Memo"
|
||||
language: rust
|
||||
install:
|
||||
source .travis/install-program-deps.sh
|
||||
script:
|
||||
./ci/memo.sh
|
||||
|
||||
- name: "Test Token-Swap"
|
||||
language: rust
|
||||
install:
|
||||
source .travis/install-program-deps.sh
|
||||
script:
|
||||
./ci/token-swap.sh
|
||||
|
||||
- name: "Test Token Program"
|
||||
language: rust
|
||||
install:
|
||||
source .travis/install-program-deps.sh
|
||||
script:
|
||||
./ci/token.sh
|
||||
|
||||
|
||||
# docs pull request or commit to master
|
||||
- name: "Build Docs"
|
||||
if: type IN (push, pull_request) AND branch = master
|
||||
language: node_js
|
||||
node_js:
|
||||
- "node"
|
||||
|
||||
before_install:
|
||||
- .travis/affects.sh docs/ .travis || travis_terminate 0
|
||||
- cd docs/
|
||||
- source .travis/before_install.sh
|
||||
script:
|
||||
- source .travis/script.sh
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Check if files in the commit range match one or more prefixes
|
||||
#
|
||||
|
||||
(
|
||||
set -x
|
||||
git diff --name-only "$TRAVIS_COMMIT_RANGE"
|
||||
)
|
||||
|
||||
for file in $(git diff --name-only "$TRAVIS_COMMIT_RANGE"); do
|
||||
for prefix in "$@"; do
|
||||
if [[ $file =~ ^"$prefix" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
echo "No modifications to $*"
|
||||
exit 1
|
|
@ -0,0 +1,16 @@
|
|||
# |source| this file
|
||||
|
||||
cargo --version
|
||||
rustup install nightly
|
||||
rustup component add clippy --toolchain nightly
|
||||
docker --version
|
||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
||||
sudo apt-add-repository "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main"
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y clang-7 --allow-unauthenticated
|
||||
sudo apt-get install -y openssl --allow-unauthenticated
|
||||
sudo apt-get install -y libssl-dev --allow-unauthenticated
|
||||
sudo apt-get install -y libssl1.1 --allow-unauthenticated
|
||||
clang-7 --version
|
||||
nvm install node
|
||||
node --version
|
|
@ -0,0 +1,92 @@
|
|||
#
|
||||
# Normalized CI environment variables
|
||||
#
|
||||
# |source| me
|
||||
#
|
||||
|
||||
if [[ -n $CI ]]; then
|
||||
export CI=1
|
||||
if [[ -n $TRAVIS ]]; then
|
||||
export CI_BRANCH=$TRAVIS_BRANCH
|
||||
export CI_BASE_BRANCH=$TRAVIS_BRANCH
|
||||
export CI_BUILD_ID=$TRAVIS_BUILD_ID
|
||||
export CI_COMMIT=$TRAVIS_COMMIT
|
||||
export CI_JOB_ID=$TRAVIS_JOB_ID
|
||||
if [[ $TRAVIS_PULL_REQUEST != false ]]; then
|
||||
export CI_PULL_REQUEST=true
|
||||
else
|
||||
export CI_PULL_REQUEST=
|
||||
fi
|
||||
export CI_OS_NAME=$TRAVIS_OS_NAME
|
||||
export CI_REPO_SLUG=$TRAVIS_REPO_SLUG
|
||||
export CI_TAG=$TRAVIS_TAG
|
||||
elif [[ -n $BUILDKITE ]]; then
|
||||
export CI_BRANCH=$BUILDKITE_BRANCH
|
||||
export CI_BUILD_ID=$BUILDKITE_BUILD_ID
|
||||
export CI_COMMIT=$BUILDKITE_COMMIT
|
||||
export CI_JOB_ID=$BUILDKITE_JOB_ID
|
||||
# The standard BUILDKITE_PULL_REQUEST environment variable is always "false" due
|
||||
# to how solana-ci-gate is used to trigger PR builds rather than using the
|
||||
# standard Buildkite PR trigger.
|
||||
if [[ $CI_BRANCH =~ pull/* ]]; then
|
||||
export CI_BASE_BRANCH=$BUILDKITE_PULL_REQUEST_BASE_BRANCH
|
||||
export CI_PULL_REQUEST=true
|
||||
else
|
||||
export CI_BASE_BRANCH=$BUILDKITE_BRANCH
|
||||
export CI_PULL_REQUEST=
|
||||
fi
|
||||
export CI_OS_NAME=linux
|
||||
if [[ -n $BUILDKITE_TRIGGERED_FROM_BUILD_PIPELINE_SLUG ]]; then
|
||||
# The solana-secondary pipeline should use the slug of the pipeline that
|
||||
# triggered it
|
||||
export CI_REPO_SLUG=$BUILDKITE_ORGANIZATION_SLUG/$BUILDKITE_TRIGGERED_FROM_BUILD_PIPELINE_SLUG
|
||||
else
|
||||
export CI_REPO_SLUG=$BUILDKITE_ORGANIZATION_SLUG/$BUILDKITE_PIPELINE_SLUG
|
||||
fi
|
||||
# TRIGGERED_BUILDKITE_TAG is a workaround to propagate BUILDKITE_TAG into
|
||||
# the solana-secondary pipeline
|
||||
if [[ -n $TRIGGERED_BUILDKITE_TAG ]]; then
|
||||
export CI_TAG=$TRIGGERED_BUILDKITE_TAG
|
||||
else
|
||||
export CI_TAG=$BUILDKITE_TAG
|
||||
fi
|
||||
elif [[ -n $APPVEYOR ]]; then
|
||||
export CI_BRANCH=$APPVEYOR_REPO_BRANCH
|
||||
export CI_BUILD_ID=$APPVEYOR_BUILD_ID
|
||||
export CI_COMMIT=$APPVEYOR_REPO_COMMIT
|
||||
export CI_JOB_ID=$APPVEYOR_JOB_ID
|
||||
if [[ -n $APPVEYOR_PULL_REQUEST_NUMBER ]]; then
|
||||
export CI_PULL_REQUEST=true
|
||||
else
|
||||
export CI_PULL_REQUEST=
|
||||
fi
|
||||
if [[ $CI_LINUX = True ]]; then
|
||||
export CI_OS_NAME=linux
|
||||
else
|
||||
export CI_OS_NAME=windows
|
||||
fi
|
||||
export CI_REPO_SLUG=$APPVEYOR_REPO_NAME
|
||||
export CI_TAG=$APPVEYOR_REPO_TAG_NAME
|
||||
fi
|
||||
else
|
||||
export CI=
|
||||
export CI_BRANCH=
|
||||
export CI_BUILD_ID=
|
||||
export CI_COMMIT=
|
||||
export CI_JOB_ID=
|
||||
export CI_OS_NAME=
|
||||
export CI_PULL_REQUEST=
|
||||
export CI_REPO_SLUG=
|
||||
export CI_TAG=
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
CI=$CI
|
||||
CI_BRANCH=$CI_BRANCH
|
||||
CI_BUILD_ID=$CI_BUILD_ID
|
||||
CI_COMMIT=$CI_COMMIT
|
||||
CI_JOB_ID=$CI_JOB_ID
|
||||
CI_OS_NAME=$CI_OS_NAME
|
||||
CI_PULL_REQUEST=$CI_PULL_REQUEST
|
||||
CI_TAG=$CI_TAG
|
||||
EOF
|
|
@ -0,0 +1,22 @@
|
|||
# Dependencies
|
||||
/node_modules
|
||||
|
||||
# Production
|
||||
/build
|
||||
|
||||
# Generated files
|
||||
.docusaurus
|
||||
.cache-loader
|
||||
.vercel
|
||||
vercel.json
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
|
@ -0,0 +1,9 @@
|
|||
# |source| this file
|
||||
|
||||
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
|
||||
sudo apt install -y nodejs
|
||||
|
||||
npm install --global docusaurus-init
|
||||
docusaurus-init
|
||||
|
||||
npm install --global vercel
|
|
@ -0,0 +1,4 @@
|
|||
# |source| this file
|
||||
|
||||
set -ex
|
||||
./build.sh
|
|
@ -0,0 +1,36 @@
|
|||
# Docs Readme
|
||||
|
||||
SPL Docs are built using [Docusaurus 2](https://v2.docusaurus.io/) with `npm`.
|
||||
Static content delivery is handled using `vercel`.
|
||||
|
||||
### Installing Docusaurus
|
||||
|
||||
```
|
||||
$ npm install
|
||||
```
|
||||
|
||||
### Local Development
|
||||
|
||||
This command starts a local development server and open up a browser window.
|
||||
Most changes are reflected live without having to restart the server.
|
||||
|
||||
```
|
||||
$ npm run start
|
||||
```
|
||||
|
||||
### Build Locally
|
||||
|
||||
This command generates static content into the `build` directory and can be
|
||||
served using any static contents hosting service.
|
||||
|
||||
```
|
||||
$ docs/build.sh
|
||||
```
|
||||
|
||||
### CI Build Flow
|
||||
The docs are built and published in Travis CI with the `docs/build.sh` script.
|
||||
On each PR, the docs are built, but not published.
|
||||
|
||||
In each post-commit build, docs are built and published using `vercel`.
|
||||
|
||||
Documentation is published to spl.solana.com
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
presets: [require.resolve("@docusaurus/core/lib/babel/preset")],
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
# shellcheck source=ci/env.sh
|
||||
source ../ci/env.sh
|
||||
|
||||
# Build from /src into /build
|
||||
npm run build
|
||||
|
||||
# Publish only from merge commits and release tags
|
||||
if [[ -n $CI ]]; then
|
||||
if [[ -z $CI_PULL_REQUEST ]]; then
|
||||
./publish-docs.sh
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,67 @@
|
|||
module.exports = {
|
||||
title: "Solana Program Library Docs",
|
||||
tagline:
|
||||
"Solana is an open source project implementing a new, high-performance, permissionless blockchain.",
|
||||
url: "https://spl.docs.solana.com",
|
||||
baseUrl: "/",
|
||||
favicon: "img/favicon.ico",
|
||||
organizationName: "solana-labs", // Usually your GitHub org/user name.
|
||||
projectName: "solana-program-library", // Usually your repo name.
|
||||
themeConfig: {
|
||||
navbar: {
|
||||
logo: {
|
||||
alt: "Solana Logo",
|
||||
src: "img/logo-horizontal.svg",
|
||||
srcDark: "img/logo-horizontal-dark.svg",
|
||||
},
|
||||
},
|
||||
footer: {
|
||||
style: "dark",
|
||||
links: [
|
||||
{
|
||||
title: "Community",
|
||||
items: [
|
||||
{
|
||||
label: "Discord",
|
||||
href: "https://discordapp.com/invite/pquxPsq",
|
||||
},
|
||||
{
|
||||
label: "Twitter",
|
||||
href: "https://twitter.com/solana",
|
||||
},
|
||||
{
|
||||
label: "Forums",
|
||||
href: "https://forums.solana.com",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "More",
|
||||
items: [
|
||||
{
|
||||
label: "GitHub",
|
||||
href: "https://github.com/solana-labs/solana-program-library",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
copyright: `Copyright © ${new Date().getFullYear()} Solana Foundation`,
|
||||
},
|
||||
},
|
||||
presets: [
|
||||
[
|
||||
"@docusaurus/preset-classic",
|
||||
{
|
||||
docs: {
|
||||
path: "src",
|
||||
routeBasePath: "/",
|
||||
homePageId: 'introduction',
|
||||
sidebarPath: require.resolve("./sidebars.js"),
|
||||
},
|
||||
theme: {
|
||||
customCss: require.resolve("./src/css/custom.css"),
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"name": "solana-spl-docs",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "docusaurus start",
|
||||
"build": "docusaurus build",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
"deploy": "docusaurus deploy",
|
||||
"format": "prettier --check \"**/*.{js,jsx,json,md,scss}\"",
|
||||
"format:fix": "prettier --write \"**/*.{js,jsx,json,md,scss}\"",
|
||||
"lint": "set -ex; eslint .",
|
||||
"lint:fix": "npm run lint -- --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "^2.0.0-alpha.58",
|
||||
"@docusaurus/preset-classic": "^2.0.0-alpha.58",
|
||||
"@docusaurus/theme-search-algolia": "^2.0.0-alpha.32",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"clsx": "^1.1.1",
|
||||
"eslint": "^7.3.1",
|
||||
"eslint-plugin-react": "^7.20.0",
|
||||
"prettier": "^2.0.5",
|
||||
"react": "^16.8.4",
|
||||
"react-dom": "^16.8.4"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -ex
|
||||
|
||||
if [[ -d .vercel ]]; then
|
||||
rm -r .vercel
|
||||
fi
|
||||
|
||||
CONFIG_FILE=vercel.json
|
||||
PROJECT_NAME=spl-solana-com
|
||||
|
||||
PRODUCTION=
|
||||
if [[ -n "$CI" ]]; then
|
||||
PRODUCTION=--prod
|
||||
fi
|
||||
|
||||
cat > "$CONFIG_FILE" <<EOF
|
||||
{
|
||||
"name": "$PROJECT_NAME",
|
||||
"scope": "solana-labs"
|
||||
}
|
||||
EOF
|
||||
|
||||
[[ -n $VERCEL_TOKEN ]] || {
|
||||
echo "VERCEL_TOKEN is undefined. Needed for Vercel authentication."
|
||||
exit 1
|
||||
}
|
||||
vercel deploy . --local-config="$CONFIG_FILE" --confirm --token "$VERCEL_TOKEN" "$PRODUCTION"
|
|
@ -0,0 +1,10 @@
|
|||
module.exports = {
|
||||
docs: {
|
||||
"Introduction": ["introduction"],
|
||||
"Programs": [
|
||||
"token",
|
||||
"token-swap",
|
||||
"memo",
|
||||
],
|
||||
},
|
||||
};
|
|
@ -0,0 +1,69 @@
|
|||
/* stylelint-disable docusaurus/copyright-header */
|
||||
/**
|
||||
* Any CSS included here will be global. The classic template
|
||||
* bundles Infima by default. Infima is a CSS framework designed to
|
||||
* work well for content-centric websites.
|
||||
*/
|
||||
|
||||
/* You can override the default Infima variables here. */
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=Roboto');
|
||||
|
||||
:root {
|
||||
--ifm-color-primary: #25c2a0;
|
||||
--ifm-color-primary-dark: #409088;
|
||||
--ifm-color-primary-darker: #387462;
|
||||
--ifm-color-primary-darkest: #1b4e3f;
|
||||
--ifm-color-primary-light: #42ba96;
|
||||
--ifm-color-primary-lighter: #86b8b6;
|
||||
--ifm-color-primary-lightest: #abd5c6;
|
||||
--ifm-code-font-size: 95%;
|
||||
--ifm-spacing-horizontal: 1em;
|
||||
--ifm-font-family-base: "Roboto", system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
|
||||
--ifm-footer-background-color: #232323;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@keyframes fadeInUp {
|
||||
0% { opacity: 0; transform: translateY(1.5rem); }
|
||||
}
|
||||
|
||||
main {
|
||||
margin: 1rem 0 5rem 0;
|
||||
}
|
||||
|
||||
.docusaurus-highlight-code-line {
|
||||
background-color: rgb(72, 77, 91);
|
||||
display: block;
|
||||
margin: 0 calc(-1 * var(--ifm-pre-padding));
|
||||
padding: 0 var(--ifm-pre-padding);
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 1rem;
|
||||
margin-top: 2rem;
|
||||
animation: fadeInUp 400ms backwards;
|
||||
animation-delay: 150ms;
|
||||
transition-property: all;
|
||||
transition-duration: 200ms;
|
||||
box-shadow: 0 8px 28px 4px rgba(86,91,115,0.15);
|
||||
}
|
||||
|
||||
|
||||
.card a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translate(0px, -5px);
|
||||
}
|
||||
|
||||
.footer--dark {
|
||||
background-color: #232323 !important;
|
||||
}
|
||||
|
||||
footer .text--center {
|
||||
padding: 2rem 0 0 0;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
title: Solana Program Library
|
||||
---
|
||||
|
||||
The Solana Program Library (SPL) is a collection of on-chain programs targeting
|
||||
the [Sealevel parallel runtime](https://medium.com/solana-labs/sealevel-parallel-processing-thousands-of-smart-contracts-d814b378192).
|
||||
These programs are tested against Solana's implementation
|
||||
of Sealevel, solana-runtime, and deployed to its mainnet. As others implement
|
||||
Sealevel, we will graciously accept patches to ensure the programs here are
|
||||
portable across all implementations.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: Memo Program
|
||||
---
|
||||
|
||||
A simple program that accepts a string of encoded characters and verifies that
|
||||
it parses. Currently handles UTF-8.
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
title: Token-Swap Program
|
||||
---
|
||||
|
||||
An Uniswap-like exchange for the Token program on the Solana blockchain.
|
||||
|
||||
The project comprises:
|
||||
|
||||
* The Rust on-chain program
|
||||
* A JavaScript library to interact with the on-chain program
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
title: Token Program
|
||||
---
|
||||
|
||||
An ERC20-like Token program on the Solana blockchain.
|
||||
|
||||
The project comprises:
|
||||
|
||||
* The Rust on-chain program
|
||||
* A JavaScript library to interact with the on-chain program
|
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 6.5 KiB |
After Width: | Height: | Size: 2.0 KiB |
|
@ -0,0 +1,5 @@
|
|||
<svg width="353" height="286" viewBox="0 0 353 286" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M302.21 67.6045C300.092 69.7497 297.22 70.9548 294.225 70.9548H11.3146C1.31552 70.9548 -3.74985 58.7613 3.24069 51.519L49.6464 3.44179C51.7709 1.24078 54.6815 6.10352e-05 57.7203 6.10352e-05H341.685C351.745 6.10352e-05 356.784 12.3212 349.67 19.5273L302.21 67.6045Z" fill="currentColor"/>
|
||||
<path d="M302.21 282.326C300.092 284.418 297.22 285.593 294.225 285.593H11.3146C1.31552 285.593 -3.74985 273.704 3.24069 266.643L49.6464 219.768C51.7709 217.622 54.6815 216.412 57.7203 216.412H341.685C351.745 216.412 356.784 228.425 349.67 235.451L302.21 282.326Z" fill="currentColor"/>
|
||||
<path d="M302.21 111.473C300.092 109.381 297.22 108.206 294.225 108.206L11.3146 108.206C1.31552 108.206 -3.74979 120.095 3.24072 127.156L49.6464 174.031C51.7709 176.177 54.6815 177.387 57.7203 177.387L341.685 177.387C351.745 177.387 356.784 165.374 349.67 158.348L302.21 111.473Z" fill="currentColor"/>
|
||||
</svg>
|
After Width: | Height: | Size: 995 B |
After Width: | Height: | Size: 204 B |
After Width: | Height: | Size: 319 B |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 13 KiB |
|
@ -0,0 +1,6 @@
|
|||
<svg width="643" height="643" viewBox="0 0 643 643" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="643" height="643" fill="#00FFAD"/>
|
||||
<path d="M447.21 246.604C445.092 248.75 442.22 249.955 439.225 249.955H156.315C146.316 249.955 141.25 237.761 148.241 230.519L194.646 182.442C196.771 180.241 199.681 179 202.72 179H486.685C496.745 179 501.784 191.321 494.67 198.527L447.21 246.604Z" fill="black"/>
|
||||
<path d="M447.21 461.326C445.092 463.418 442.22 464.593 439.225 464.593H156.315C146.316 464.593 141.25 452.704 148.241 445.643L194.646 398.768C196.771 396.622 199.681 395.412 202.72 395.412H486.685C496.745 395.412 501.784 407.425 494.67 414.451L447.21 461.326Z" fill="black"/>
|
||||
<path d="M447.21 290.473C445.092 288.381 442.22 287.206 439.225 287.206L156.315 287.206C146.316 287.206 141.25 299.095 148.241 306.156L194.646 353.031C196.771 355.177 199.681 356.387 202.72 356.387L486.685 356.387C496.745 356.387 501.784 344.374 494.67 337.348L447.21 290.473Z" fill="black"/>
|
||||
</svg>
|
After Width: | Height: | Size: 989 B |