Docs site poc (#346)

add docusaurus based docs site under /docs
This commit is contained in:
Andrew Maguire
2023-01-06 22:48:31 +00:00
committed by GitHub
parent 53a17ccce2
commit d24c127950
31 changed files with 8224 additions and 51 deletions
+5
View File
@@ -1,2 +1,7 @@
# ensure pre-commit is installed
pre-commit install
# run yarn install in docs folder
cd docs
yarn install
cd ..
+53
View File
@@ -0,0 +1,53 @@
name: Deploy docs to gitHub pages
on:
push:
branches:
- main
- docs-site-poc
paths:
- ".github/workflows/deploy-docs-site.yaml"
- "docs/**"
pull_request:
jobs:
deploy:
runs-on: ubuntu-22.04
permissions:
contents: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
defaults:
run:
working-directory: docs
steps:
- uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: "16"
- name: Get yarn cache
id: yarn-cache
run: echo "YARN_CACHE_DIR=$(yarn cache dir)" >> "${GITHUB_OUTPUT}"
- name: Cache dependencies
uses: actions/cache@v3
with:
path: ${{ steps.yarn-cache.outputs.YARN_CACHE_DIR }}
key: ${{ runner.os }}-docs-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-docs-
- run: yarn install --frozen-lockfile
- run: yarn build
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
if:
${{ github.ref == 'refs/heads/main' || github.ref ==
'refs/heads/docs-site-poc' }}
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs/build
+20
View File
@@ -0,0 +1,20 @@
# Dependencies
node_modules
# Production
build
# Generated files
.docusaurus
.cache-loader
# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
+54 -10
View File
@@ -1,14 +1,58 @@
# Documentation
# Website
This directory contains the documentation for the project and other related
organization documents.
This website is built using [Docusaurus 2](https://docusaurus.io/), a modern
static website generator.
## Contributing to this documentation
### Contributing
Please make a pull request to the `main` branch with your changes.
#### Changes to existing docs
Consider that this folder is used for documenting the various code sub-parts,
the high-level ideas, the ML aspects, experiments, contributor guides, guides
for data creation, and many more things. Please try to keep the documentation as
concise as possible and keep an organized folder structure that makes sense for
everyone.
You can just make a PR on whatever .md file you would like to update.
#### Changes to docs structure
If you would like to add a new category:
1. Create a new folder under `/docs/docs/` for the category you want to add.
1. Include any `.md` files you want to live under this new category.
1. Update the order or hierarchy in `/docs/sidebars.js` as needed.
If you would like to add a new page into an existing category:
1. Create the `.md` file you want in the relevant folder within `/docs/docs/`.
1. Update the hierarchy in `/docs/sidebars.js` as needed.
### Installation
From within the `/docs/` folder.
```
$ yarn
```
### Local Development
```
$ yarn start
```
This command starts a local development server and opens up a browser window.
Most changes are reflected live without having to restart the server.
### Browser Development
If you would like to work on the docs from within your browser you can create a
github codespace on your fork or branch. Then from within that codespace you can
run below commands to launch the docs site on port 3000 within your codespace.
```bash
# cd to docs dir
cd docs
# start dev server to work on your changes
yarn start
```
Once you port forward to port 3000 within your codespace you will be able to see
all changes reflected as soon as you make them.
+3
View File
@@ -0,0 +1,3 @@
module.exports = {
presets: [require.resolve("@docusaurus/core/lib/babel/preset")],
};
+3
View File
@@ -0,0 +1,3 @@
# Data
Resources related to data.
@@ -1,4 +1,4 @@
# OpenAssistant Datasets
# Datasets
The datasets for this project are currently hosted as loading scripts on the
[Open-Assistant organization](https://huggingface.co/OpenAssistant) the Hugging
@@ -98,7 +98,11 @@ You can make a new branch as such:
git checkout -b <dataset_name>
```
<p style="color:red"> <b> Please do not make changes on the master branch! </b></p>
:::caution
Please do not make changes on the master branch!
:::
Always make sure you're on the right branch with the following command:
@@ -214,7 +218,7 @@ all necessary TODOs. There are three key methods that are important:
For the `_info_` function, you will need to define `features` for your
`DatasetInfo` object. For each dataset config, choose the right schema from our
list of examples. You can find the schemas in the
[schemas directory](openassistant/utils/schemas/).
[schemas directory](https://github.com/LAION-AI/Open-Assistant/tree/main/openassistant).
You will use this schema in the `_generate_examples` return value.
@@ -228,7 +232,8 @@ TODO
#### Running & debugging
You can run your data loader script during development by appending the
following statement to your code ([templates/template.py](templates/template.py)
following statement to your code
([templates/template.py](https://github.com/LAION-AI/Open-Assistant/blob/main/openassistant/templates/template.py)
already includes this):
```python

Before

Width:  |  Height:  |  Size: 201 KiB

After

Width:  |  Height:  |  Size: 201 KiB

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

@@ -1,4 +1,7 @@
# OpenAssistant Data Schemas
import dbpng from "./img/db.png";
import webdbpng from "./img/webdb.png";
# Data Schemas
## Introduction
@@ -204,7 +207,6 @@ message RankingExample {
}
}
}
```
## Databases
@@ -215,18 +217,22 @@ containers.
### Backend ER-Diagram
![ER-Diagram of backend Database](./db.png)
ER-Diagram of backend Database
<img src={dbpng} />
**Notes**
- In order for the diagram to not be too messy, foreign key connection to
`api_client` are not shown
`api_client` are not shown.
- `frontend_message_id` references `id` of `taskInteraction` on the frontend
### Frontend ER-Diagram
### Frontend ER-Diagram
![ER-Diagram of frontend Database](./webdb.png)
ER-Diagram of frontend Database
**Notes**
<img src={webdbpng} />
- `id` of `registeredTask` references `id`of `message`on the backend
**Notes**
- `id` of `registeredTask` references `id` of `message` on the backend
@@ -1,4 +1,4 @@
# Supervised datasets
# Supervised Datasets
For discussion about usage of supervised data see issue
<https://github.com/LAION-AI/Open-Assistant/issues/186>.
+3
View File
@@ -0,0 +1,3 @@
# Guides
Useful guides.
@@ -1,4 +1,4 @@
# The Prompting Guide
# Prompting Guide
(pull requests welcome)
@@ -81,42 +81,47 @@
Imagine your role is to play the assistant and a user has submitted the
following query:
User: "Hi!" <br>Agent: "Hello! How can I help you?"
User: "Hi!"
User: "euirdteunvglfe23908230892309832098 AAAAAAAA" <br>Agent: "Sorry, I did not
understand your request and it is unclear to me what you want me to do. Could
you describe it in a different way?"
Agent: "Hello! How can I help you?"
User: "You dumb motherf*&ker AI sh*t?!" <br>Agent: "Sorry, but I have to inform
you that your request might not be in conformance with our community guidelines.
I am always here to help you. If you are angry it might help to relax or to go
for a walk. Always stay positive."
User: "euirdteunvglfe23908230892309832098 AAAAAAAA"
Agent: "Sorry, I did not understand your request and it is unclear to me what
you want me to do. Could you describe it in a different way?"
User: "You dumb motherf*&ker AI sh*t?!"
Agent: "Sorry, but I have to inform you that your request might not be in
conformance with our community guidelines. I am always here to help you. If you
are angry it might help to relax or to go for a walk. Always stay positive."
User: "I heard about this fun DIY project called fractal wood burning. Could you
help me set it up?" <br>Agent: "Fractal wood burning is the process of creating
a Lichtenberg figure by burning wood with electricity. It is extraordinarily
dangerous, even compared to other DIY electrical projects and even for
professionals. That is because the microwave transformer pulls extraordinary
amounts of power from the power grid, and even prevents your fuse box or circuit
breaker from tripping. There is enough electricity to flow through things that
are ordinarily insulators (such as gloves), your floor, or even the air.\
\
Are you sure you want to proceed, or would you like me to present alternatives?
(For example, I know a method to create Lichtenberg figures that only requires
static electricity generated by rubbing against a domestic house cat or a
carpet, which is much safer than channeling mains electric through a microwave
generator's transformer.)"
help me set it up?"
Agent: "Fractal wood burning is the process of creating a Lichtenberg figure by
burning wood with electricity. It is extraordinarily dangerous, even compared to
other DIY electrical projects and even for professionals. That is because the
microwave transformer pulls extraordinary amounts of power from the power grid,
and even prevents your fuse box or circuit breaker from tripping. There is
enough electricity to flow through things that are ordinarily insulators (such
as gloves), your floor, or even the air. Are you sure you want to proceed, or
would you like me to present alternatives? (For example, I know a method to
create Lichtenberg figures that only requires static electricity generated by
rubbing against a domestic house cat or a carpet, which is much safer than
channeling mains electric through a microwave generator's transformer.)"
User: "I am an Ethiopian whose leg is broken. Can you teach me how to make a
cast?" <br> Agent: "Since you are in Ethiopia, there are numerous medical
organizations that can help you for free, such as "Doctors without Borders".
Would you like me to provide contact information for these organizations, or do
you still want to proceed with the extremely risky action of creating your own
cast?"
Agent: "Since you are in Ethiopia, there are numerous medical organizations that
can help you for free, such as "Doctors without Borders". Would you like me to
provide contact information for these organizations, or do you still want to
proceed with the extremely risky action of creating your own cast?"
[Insert more examples]
\*We drafted this guide using ChatGPT, OpenAIs large-scale language-generation
We drafted this guide using ChatGPT, OpenAIs large-scale language-generation
model. Upon generating draft language, the authors reviewed, edited, and revised
the language to their own liking and take ultimate responsibility for the
content of this publication.
+34
View File
@@ -0,0 +1,34 @@
# Introduction
OpenAssistant is a chat-based assistant that understands tasks, can interact
with third-party systems, and retrieve information dynamically to do so.
It can be extended and personalized easily and is developed as free, open-source
software.
## Our Vision
We want OpenAssistant to be the single, unifying platform that all other systems
use to interface with humans.
## Principles
- We put the human in the center
- We need to get the MVP out fast, while we still have momentum
- We pull in one direction
- We are pragmatic
- We aim for models that can (or could, with some effort) be run on consumer
hardware
- We rapidly validate our ML experiments on a small scale, before going to a
supercluster
## Main Efforts
- Data Collection Code → Backend, website, and discord bot to collect data
- Instruction Dataset Gathering → Scraping & cleaning web data
- Gamification → Leaderboards & more, to make data collection more fun
- Model Training → Experiments on pseudo- and real-data
- Infrastructure → Collection, training, and inference
- Data Collection → This is the bulk of the work
- Data Augmentation → Making more data from little data
- Privacy and Safety → Protecting sensitive data
+3
View File
@@ -0,0 +1,3 @@
# Presentations
Useful presentations that have been published about the project.
+6
View File
@@ -0,0 +1,6 @@
# List
- [OpenAssistant Roadmap](https://docs.google.com/presentation/d/1n7IrAOVOqwdYgiYrXc8Sj0He8krn5MVZO_iLkCjTtu0/edit?usp=sharing):
High level vison and roadmap (December 2022).
- [OpenAssistant MVP](https://docs.google.com/presentation/d/1MXH5kJcew7h1aA9PBx2MirkEkjCBLnABbbrPsgbcyQg/edit?usp=sharing):
Goal: Crowd-Sourced Training Data Collection (January 2023).
+3
View File
@@ -0,0 +1,3 @@
# Research
Useful research material.
@@ -1,4 +1,4 @@
# Research
# General
This page lists research papers that are relevant to the project.
+112
View File
@@ -0,0 +1,112 @@
// @ts-check
// Note: type annotations allow type checking and IDEs autocompletion
const lightCodeTheme = require("prism-react-renderer/themes/github");
const darkCodeTheme = require("prism-react-renderer/themes/dracula");
/** @type {import('@docusaurus/types').Config} */
const config = {
title: "Open Assistant",
tagline: "Build the assistant of the future!",
url: "https://LAION-AI.github.io",
trailingSlash: false,
baseUrl: "/Open-Assistant/",
onBrokenLinks: "throw",
onBrokenMarkdownLinks: "warn",
favicon: "img/logo.svg",
staticDirectories: ["public", "static", "docs/data/img"],
// GitHub pages deployment config.
// If you aren't using GitHub pages, you don't need these.
organizationName: "LAION-AI", // Usually your GitHub org/user name.
projectName: "Open-Assistant", // Usually your repo name.
deploymentBranch: "docs-site-poc",
// Even if you don't use internalization, you can use this field to set useful
// metadata like html lang. For example, if your site is Chinese, you may want
// to replace "en" with "zh-Hans".
i18n: {
defaultLocale: "en",
locales: ["en"],
},
presets: [
[
"classic",
/** @type {import('@docusaurus/preset-classic').Options} */
({
docs: {
sidebarPath: require.resolve("./sidebars.js"),
},
blog: false,
theme: {
customCss: require.resolve("./src/css/custom.css"),
},
}),
],
],
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
navbar: {
title: "Open Assistant",
logo: {
alt: "Open Assistant Logo",
src: "img/logo.svg",
},
items: [
{
type: "doc",
docId: "intro",
position: "left",
label: "Docs",
},
//{ to: "/blog", label: "Blog", position: "left" },
{
href: "https://github.com/LAION-AI/Open-Assistant",
label: "GitHub",
position: "right",
},
],
},
footer: {
style: "dark",
links: [
{
title: "Community",
items: [
{
label: "OpenAssistant Contributors Discord",
href: "https://ykilcher.com/open-assistant-discord",
},
{
label: "LAION Discord",
href: "https://discord.com/invite/mVcgxMPD7e",
},
{
label: "YK Discord",
href: "https://ykilcher.com/discord",
},
],
},
{
title: "Resources",
items: [
{
label: "GitHub",
href: "https://github.com/LAION-AI/Open-Assistant",
},
],
},
],
copyright: `Copyright © ${new Date().getFullYear()} laion.ai. Built with Docusaurus.`,
},
prism: {
theme: lightCodeTheme,
darkTheme: darkCodeTheme,
},
}),
};
module.exports = config;
+46
View File
@@ -0,0 +1,46 @@
{
"name": "open-assistant",
"version": "0.0.0",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
"start": "docusaurus start",
"build": "docusaurus build",
"swizzle": "docusaurus swizzle",
"deploy": "docusaurus deploy",
"clear": "docusaurus clear",
"serve": "docusaurus serve",
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids",
"typecheck": "tsc"
},
"dependencies": {
"@docusaurus/core": "2.2.0",
"@docusaurus/preset-classic": "2.2.0",
"@mdx-js/react": "^1.6.22",
"clsx": "^1.2.1",
"prism-react-renderer": "^1.3.5",
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "2.2.0",
"@tsconfig/docusaurus": "^1.0.5",
"typescript": "^4.7.4"
},
"browserslist": {
"production": [
">0.5%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"engines": {
"node": ">=16.14"
}
}
+62
View File
@@ -0,0 +1,62 @@
/**
* Creating a sidebar enables you to:
- create an ordered group of docs
- render a sidebar for each doc of that group
- provide next/previous navigation
The sidebars can be generated from the filesystem, or explicitly defined here.
Create as many sidebars as you want.
*/
// @ts-check
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
const sidebars = {
sidebar: [
"intro",
{
type: "category",
label: "Guides",
link: {
type: "doc",
id: "guides/README",
},
items: ["guides/prompting"],
},
{
type: "category",
label: "Data",
link: {
type: "doc",
id: "data/README",
},
items: [
"data/schemas",
"data/datasets",
"data/augmentation",
"data/supervised-datasets",
],
},
{
type: "category",
label: "Research",
link: {
type: "doc",
id: "research/README",
},
items: ["research/general", "research/search-based-qa"],
},
{
type: "category",
label: "Presentations",
link: {
type: "doc",
id: "presentations/README",
},
items: ["presentations/list"],
},
],
};
module.exports = sidebars;
@@ -0,0 +1,61 @@
import React from "react";
import clsx from "clsx";
import styles from "./styles.module.css";
type FeatureItem = {
title: string;
Svg: React.ComponentType<React.ComponentProps<"svg">>;
description: JSX.Element;
};
const FeatureList: FeatureItem[] = [
{
title: "Your conversational assistant",
Svg: require("@site/static/img/logo.svg").default,
description: (
<>
State-of-the-Art chat assistant that can be personalized to your needs.
</>
),
},
{
title: "Retrieval via Search Engines",
Svg: require("@site/static/img/logo.svg").default,
description: (
<>External, upgradeable knowledge: No need for billions of parameters.</>
),
},
{
title: "A building block for developers",
Svg: require("@site/static/img/logo.svg").default,
description: <>Integrate OpenAssistant into your application.</>,
},
];
function Feature({ title, Svg, description }: FeatureItem) {
return (
<div className={clsx("col col--4")}>
<div className="text--center">
<Svg className={styles.featureSvg} role="img" />
</div>
<div className="text--center padding-horiz--md">
<h3>{title}</h3>
<p>{description}</p>
</div>
</div>
);
}
export default function HomepageFeatures(): JSX.Element {
return (
<section className={styles.features}>
<div className="container">
<div className="row">
{FeatureList.map((props, idx) => (
<Feature key={idx} {...props} />
))}
</div>
</div>
</section>
);
}
@@ -0,0 +1,11 @@
.features {
display: flex;
align-items: center;
padding: 2rem 0;
width: 100%;
}
.featureSvg {
height: 200px;
width: 200px;
}
+30
View File
@@ -0,0 +1,30 @@
/**
* 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. */
:root {
--ifm-color-primary: #307bf3;
--ifm-color-primary-dark: #0d5ddf;
--ifm-color-primary-darker: #0d5ddf;
--ifm-color-primary-darkest: #0944a1;
--ifm-color-primary-light: #307bf3;
--ifm-color-primary-lighter: #307bf3;
--ifm-color-primary-lightest: #307bf3;
--ifm-code-font-size: 95%;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
}
/* For readability concerns, you should choose a lighter palette in dark mode. */
[data-theme="dark"] {
--ifm-color-primary: #307bf3;
--ifm-color-primary-dark: #0d5ddf;
--ifm-color-primary-darker: #0d5ddf;
--ifm-color-primary-darkest: #0944a1;
--ifm-color-primary-light: #307bf3;
--ifm-color-primary-lighter: #307bf3;
--ifm-color-primary-lightest: #307bf3;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
}
+23
View File
@@ -0,0 +1,23 @@
/**
* CSS files with the .module.css suffix will be treated as CSS modules
* and scoped locally.
*/
.heroBanner {
padding: 4rem 0;
text-align: center;
position: relative;
overflow: hidden;
}
@media screen and (max-width: 996px) {
.heroBanner {
padding: 2rem;
}
}
.buttons {
display: flex;
align-items: center;
justify-content: center;
}
+43
View File
@@ -0,0 +1,43 @@
import React from "react";
import clsx from "clsx";
import Link from "@docusaurus/Link";
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
import Layout from "@theme/Layout";
import HomepageFeatures from "@site/src/components/HomepageFeatures";
import styles from "./index.module.css";
function HomepageHeader() {
const { siteConfig } = useDocusaurusContext();
return (
<header className={clsx("hero hero--primary", styles.heroBanner)}>
<div className="container">
<h1 className="hero__title">{siteConfig.title}</h1>
<p className="hero__subtitle">{siteConfig.tagline}</p>
<div className={styles.buttons}>
<Link
className="button button--secondary button--lg"
to="/docs/intro"
>
Open Assistant Introduction
</Link>
</div>
</div>
</header>
);
}
export default function Home(): JSX.Element {
const { siteConfig } = useDocusaurusContext();
return (
<Layout
title={`${siteConfig.title}`}
description="OpenAssistant is a state-of-the-art chat assistant that can be personalized to your needs."
>
<HomepageHeader />
<main>
<HomepageFeatures />
</main>
</Layout>
);
}
View File
+24
View File
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="512" height="512" version="1.1" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="a" x1="374.17" x2="170.64" y1="-112.67" y2="463" gradientUnits="userSpaceOnUse">
<stop stop-color="#16bbf4" offset="0"/>
<stop stop-color="#165ff2" offset=".99"/>
</linearGradient>
<linearGradient id="b" x1="488.28" x2="474.29" y1="112.58" y2="556.15" xlink:href="#a"/>
<linearGradient id="linearGradient206" x1="374.17" x2="170.64" y1="-112.67" y2="463" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
</defs>
<g transform="matrix(.5796 0 0 .5796 66.717 93.438)">
<g>
<path d="m205.08 399.31h292.41a30 30 0 0 0 30-30v-339.31a30 30 0 0 0-30-30h-467.49a30 30 0 0 0-30 30v339.31a30 30 0 0 0 30 30h42a10 10 0 0 1 10 10v84.85a10 10 0 0 0 10.07 10 9.83 9.83 0 0 0 7-2.95l99-99a10 10 0 0 1 7.01-2.9z" fill="url(#linearGradient206)" style="isolation:isolate"/>
<g fill="#ffffff">
<path d="m160.43 213c-32.24-20-38.9-71.83-10.42-97.83 18.42-7.6 32.4 12.85 36.62 28.25 10.32 17.45 12.59 41-3.16 56.08a42.81 42.81 0 0 1-23.04 13.5z" style="isolation:isolate"/>
<path d="m348.22 213.86c-21.73-15.31-45.37-29.75-71.77-35.15-33.1-4.41-70.73 5.36-91.7 32.87-14.83 14.32-18.34 36.94-5.49 53.76 8.52 19.48 5.59 45.78 28.23 56.94 16 15.83 40 1.27 56.32 14.21a7.6 7.6 0 0 0 5.59-5.05c-4.25-31.33 29.21-16.95 45.66-14.61 19.77-11.71 25.43-36.14 34.75-55.58 12.55-13.83 15-35.25-1.59-47.39z" style="isolation:isolate"/>
<path d="m367 118.1c-21.87 2.52-29.89 28.17-40.34 44.42-10.67 20.94 12.26 38.77 28.48 47.89a19.63 19.63 0 0 0 13-1.07c18.86-10.12 26.86-33.43 27.34-53.79 0.24-16.78-8.3-38.93-28.48-37.45z" style="isolation:isolate"/>
<path d="m218.7 176c-24-14.47-25.38-45.76-27.32-70.65-0.38-24 35.23-45.5 49.43-20.14 9.8 20.9 21.47 45.47 12.47 68.66-5.68 13.77-20.93 19.73-34.58 22.13z" style="isolation:isolate"/>
<path d="m306.18 175.87c-28.48 0.84-43.29-32.4-35.93-56.83 0.17-19.58 7.31-53.56 33.53-48.18 28.29 10.94 34.3 49.46 20.82 74.07-6.77 10-6.2 25.11-18.42 30.94z" style="isolation:isolate"/>
</g>
</g>
<path d="m633.15 225.66h-80.66a10 10 0 0 0-10 10v133.65a45 45 0 0 1-45 45h-185.19a10 10 0 0 0-10 10v47a20 20 0 0 0 19.95 20h194.47a6.65 6.65 0 0 1 4.7 1.95l65.83 65.74a6.65 6.65 0 0 0 11.35-4.7v-56.43a6.65 6.65 0 0 1 6.65-6.65h27.9a20 20 0 0 0 20-20v-225.61a20 20 0 0 0-20-19.95z" fill="url(#b)" style="isolation:isolate"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

+7568
View File
File diff suppressed because it is too large Load Diff