Create desktop applications based on oxygen-ui

This commit is contained in:
2024-03-14 16:56:42 +08:00
commit 2265ba7407
229 changed files with 33099 additions and 0 deletions

75
src/main/index.ts Normal file
View File

@@ -0,0 +1,75 @@
import { app, shell, BrowserWindow, ipcMain } from 'electron'
import { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/logo.ico?asset'
function createWindow(): void {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 900,
height: 670,
show: false,
autoHideMenuBar: true,
icon,
webPreferences: {
preload: join(__dirname, '../preload/index.js'),
sandbox: false,
nodeIntegrationInSubFrames: true
}
})
mainWindow.on('ready-to-show', () => {
mainWindow.show()
})
mainWindow.webContents.setWindowOpenHandler((details) => {
void shell.openExternal(details.url)
return { action: 'deny' }
})
// HMR for renderer base on electron-vite cli.
// Load the remote URL for development or the local html file for production.
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
void mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
} else {
void mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
}
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
void app.whenReady().then(() => {
// Set app user model id for windows
electronApp.setAppUserModelId('top.fatweb')
// Default open or close DevTools by F12 in development
// and ignore CommandOrControl + R in production.
// see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
app.on('browser-window-created', (_, window) => {
optimizer.watchWindowShortcuts(window)
})
// IPC test
ipcMain.on('ping', () => console.log('pong'))
createWindow()
app.on('activate', function () {
// On macOS, it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

8
src/preload/index.d.ts vendored Normal file
View File

@@ -0,0 +1,8 @@
import { ElectronAPI } from '@electron-toolkit/preload'
declare global {
interface Window {
electron: ElectronAPI
api: unknown
}
}

25
src/preload/index.ts Normal file
View File

@@ -0,0 +1,25 @@
import { contextBridge, Notification } from 'electron'
import { electronAPI } from '@electron-toolkit/preload'
// Custom APIs for renderer
const api = {}
// Use `contextBridge` APIs to expose Electron APIs to
// renderer only if context isolation is enabled, otherwise
// just add to the DOM global.
if (process.contextIsolated) {
try {
contextBridge.exposeInMainWorld('electron', electronAPI)
contextBridge.exposeInMainWorld('api', api)
contextBridge.exposeInMainWorld('notification', Notification)
} catch (error) {
console.error(error)
}
} else {
// @ts-expect-error (define in dts)
window.electron = electronAPI
// @ts-expect-error (define in dts)
window.api = api
// @ts-expect-error (define in dts)
window.Notification = Notification
}

12
src/renderer/index.html Normal file
View File

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Oxygen Toolbox</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

28
src/renderer/src/App.tsx Normal file
View File

@@ -0,0 +1,28 @@
import { getRouter } from '@/router'
import FullscreenLoadingMask from '@/components/common/FullscreenLoadingMask'
export const AppContext = createContext<{ refreshRouter: () => void }>({
refreshRouter: () => undefined
})
const App = () => {
const [routerState, setRouterState] = useState(getRouter)
return (
<>
<AppContext.Provider
value={{
refreshRouter: () => {
setRouterState(getRouter())
}
}}
>
<Suspense fallback={<FullscreenLoadingMask />}>
<RouterProvider router={routerState} />
</Suspense>
</AppContext.Provider>
</>
)
}
export default App

View File

@@ -0,0 +1,58 @@
import { PRODUCTION_NAME } from '@/constants/common.constants'
import { getRedirectUrl } from '@/util/route'
import { getLoginStatus, getVerifyStatus_async } from '@/util/auth'
const AuthRoute = () => {
const [searchParams] = useSearchParams()
const matches = useMatches()
const lastMatch = matches.reduce((_, second) => second)
const handle = lastMatch.handle as RouteHandle
const location = useLocation()
const outlet = useOutlet()
const isLogin = getLoginStatus()
const isVerify = getVerifyStatus_async()
return useMemo(() => {
document.title = `${handle?.titlePrefix ?? ''}${
handle?.title ? handle?.title : PRODUCTION_NAME
}${handle?.titlePostfix ?? ''}`
if (matches.some(({ handle }) => (handle as RouteHandle)?.auth)) {
if (!isLogin) {
return (
<Navigate
replace
to={getRedirectUrl('/login', `${lastMatch.pathname}${location.search}`)}
/>
)
}
if (isVerify === false && lastMatch.pathname !== '/verify') {
return <Navigate to={'/verify'} />
}
}
if (isLogin && ['/login', '/forget'].includes(lastMatch.pathname)) {
if (searchParams.has('redirect')) {
return <Navigate to={searchParams.get('redirect') ?? '/'} />
} else {
return <Navigate to={'/'} />
}
}
if (location.pathname.length > 1 && location.pathname.endsWith('/')) {
return <Navigate to={location.pathname.substring(0, location.pathname.length - 1)} />
}
return outlet
}, [
handle?.title,
handle?.titlePostfix,
handle?.titlePrefix,
isLogin,
lastMatch.pathname,
location.search,
matches,
outlet
])
}
export default AuthRoute

29
src/renderer/src/ant-design.d.ts vendored Normal file
View File

@@ -0,0 +1,29 @@
import { ComponentType, ForwardRefExoticComponent, Key, SVGProps } from 'react'
import { CustomIconComponentProps } from '@ant-design/icons/es/components/Icon'
import { GetProp, TablePaginationConfig, UploadProps } from 'antd/lib'
import { ColumnsType, FilterValue, SorterResult, SortOrder } from 'antd/es/table/interface'
import { CheckboxChangeEvent } from 'antd/es/checkbox'
import type { DataNode } from 'antd/es/tree'
declare global {
type IconComponent =
| ComponentType<CustomIconComponentProps | SVGProps<SVGSVGElement>>
| ForwardRefExoticComponent<CustomIconComponentProps>
type _TablePaginationConfig = TablePaginationConfig
type _ColumnsType<T> = ColumnsType<T>
type _FilterValue = FilterValue
type _SorterResult<T> = SorterResult<T>
type _SortOrder = SortOrder
type _CheckboxChangeEvent = CheckboxChangeEvent
interface _DataNode extends DataNode {
value: Key
fullTitle?: string
parentId?: number
children?: _DataNode[]
}
type _UploadProps = UploadProps
type _GetProp<T, PropName> = GetProp<T, PropName>
}

View File

@@ -0,0 +1,22 @@
@mixin keyframes($animationName) {
@-webkit-keyframes #{$animationName} {
@content
}
@-moz-keyframes #{$animationName} {
@content
}
@-o-keyframes #{$animationName} {
@content
}
@keyframes #{$animationName} {
@content
}
}
@mixin unique-keyframes {
$animationName: unique-id();
animation-name: $animationName;
@include keyframes($animationName) {
@content
}
}

View File

@@ -0,0 +1,63 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
em,
i {
font-style: normal
}
li {
list-style: none
}
img {
border: 0;
vertical-align: middle
}
button {
cursor: pointer
}
a {
color: #666;
text-decoration: none
}
button,
input {
font-family: Microsoft YaHei, Heiti SC, tahoma, arial, Hiragino Sans GB, "\5B8B\4F53", sans-serif;
border: 0;
outline: none;
}
body {
-webkit-font-smoothing: antialiased;
background-color: #fff;
font: 12px/1.5 Microsoft YaHei, Heiti SC, tahoma, arial, Hiragino Sans GB, "\5B8B\4F53", sans-serif;
color: #666
}
.hide,
.none {
display: none
}
.clearfix:after {
visibility: hidden;
clear: both;
display: block;
content: ".";
height: 0
}
.clearfix {
*zoom: 1
}

View File

@@ -0,0 +1,118 @@
@use '@/assets/css/constants' as constants;
#root {
height: 100vh;
width: 100vw;
}
.body {
background-color: constants.$background-color;
color: constants.$font-main-color;
user-select: none;
min-width: 900px;
min-height: 400px;
}
.fill {
height: 100%;
width: 100%;
}
.fill-with {
width: 100%;
}
.fill-height {
height: 100%;
}
.background-origin {
background-color: constants.$origin-color;
}
.center-box {
display: flex;
justify-content: center;
align-items: center;
}
.vertical-center-box {
display: flex;
align-items: center;
}
.horizontal-center-box {
display: flex;
justify-content: center;
}
.icon-size-xs {
width: 16px;
height: 16px;
> use {
width: 16px;
height: 16px;
}
}
.icon-size-sm {
width: 20px;
height: 20px;
> use {
width: 20px;
height: 20px;
}
}
.icon-size-md {
width: 24px;
height: 24px;
> use {
width: 24px;
height: 24px;
}
}
.icon-size-lg {
width: 32px;
height: 32px;
> use {
width: 32px;
height: 32px;
}
}
.icon-size-xl {
width: 64px;
height: 64px;
> use {
width: 64px;
height: 64px;
}
}
.icon-size-menu {
width: 23px;
height: 23px;
> use {
width: 23px;
height: 23px;
}
}
.flex-horizontal {
display: flex;
flex-direction: row;
}
.flex-vertical {
display: flex;
flex-direction: column;
}

View File

@@ -0,0 +1,8 @@
@use '@/assets/css/constants' as constants;
.card-box {
background-color: constants.$origin-color;
border-radius: 8px;
overflow: hidden;
box-shadow: 5px 5px 15px 0 rgba(0,0,0,0.1);
}

View File

@@ -0,0 +1,7 @@
.fit-center {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}

View File

@@ -0,0 +1,5 @@
.fit-fullscreen {
position: relative;
width: 100%;
height: 100vh;
}

View File

@@ -0,0 +1,5 @@
.flex-box {
> * {
flex: 1;
}
}

View File

@@ -0,0 +1,10 @@
.fullscreen-loading-mask {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
z-index: 100;
background-color: rgba(200, 200, 200, 0.2);
}

View File

@@ -0,0 +1,93 @@
@use '@/assets/css/constants' as constants;
@use '@/assets/css/mixins' as mixins;
.hide-scrollbar-mask {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
.hide-scrollbar-selection {
position: relative;
overflow: scroll;
scrollbar-width: none;
-ms-overflow-style: none;
.hide-scrollbar-content {
display: inline-block;
width: 100%;
}
}
::-webkit-scrollbar {
display: none;
}
.scrollbar {
position: absolute;
z-index: 1000;
opacity: .5;
touch-action: none;
.box {
position: relative;
width: 100%;
height: 100%;
border-radius: 8px;
overflow: hidden;
.block {
position: absolute;
width: 100%;
height: 100%;
border-radius: 8px;
background-color: constants.$font-secondary-color;
transition: background-color .2s;
}
:hover {
background-color: constants.$font-main-color;
}
}
&.hide {
display: block;
opacity: 0;
animation: 0.4s linear;
@include mixins.unique-keyframes {
0% {
opacity: 0.5;
}
100% {
opacity: 0;
}
}
}
}
.vertical-scrollbar {
padding: 12px 2px;
height: 100%;
left: 100%;
top: 0;
transform: translateX(-100%);
.box {
width: 6px;
}
}
.horizontal-scrollbar {
padding: 4px 12px;
width: 100%;
left: 0;
top: 100%;
transform: translateY(-100%);
.box {
height: 8px;
}
}
}

View File

@@ -0,0 +1,34 @@
@use '@/assets/css/constants' as constants;
.dot-list {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
.item {
flex: auto;
cursor: pointer;
.dot {
width: 10px;
height: 10px;
border-radius: 50%;
border: {
width: 2px;
color: constants.$font-secondary-color;
style: solid;
};
transition: all .2s;
}
:hover {
background-color: constants.$focus-color;
}
}
.active > * {
background-color: constants.$font-secondary-color !important;
}
}

View File

@@ -0,0 +1,8 @@
.loading-mask {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
z-index: 100;
}

View File

@@ -0,0 +1,322 @@
@use "@/assets/css/constants" as constants;
@use "@/assets/css/mixins" as mixins;
.sidebar {
display: flex;
flex-direction: column;
height: 100%;
user-select: none;
transition: all .3s;
white-space: nowrap;
.title {
display: flex;
align-items: center;
font-weight: bold;
padding: 10px 14px;
color: constants.$main-color;
overflow: hidden;
.icon-box {
display: flex;
justify-content: center;
align-items: center;
padding: 10px;
width: 40px;
height: 40px;
font-size: constants.$SIZE_ICON_SM;
border-radius: 8px;
cursor: pointer;
span {
transform: rotateZ(180deg);
transition: all .3s;
}
&:hover {
background-color: constants.$background-color;
}
}
.text {
flex: 1;
font-size: 2em;
text-align: center;
letter-spacing: 0.2em;
transform: translateX(0.1em);
}
}
.content, .bottom-fixed {
display: flex;
min-height: 0;
flex-direction: column;
flex: 1;
.scroll {
min-height: 0;
flex: 1;
}
ul {
> li {
&.item {
position: relative;
margin: 4px 14px;
font-size: 1.4em;
>.menu-bt {
border-radius: 8px;
overflow: hidden;
height: 40px;
.icon-box {
display: flex;
justify-content: center;
align-items: center;
padding: 0 10px;
width: 40px;
height: 40px;
font-size: constants.$SIZE_ICON_SM;
cursor: pointer;
}
a {
display: flex;
align-items: center;
height: 100%;
width: 100%;
transition: all 0.2s;
.text {
flex: 1;
padding-left: 8px;
}
&.active {
color: constants.$origin-color;
background-color: constants.$main-color !important;
}
}
}
.submenu {
visibility: hidden;
position: fixed;
padding-left: 20px;
z-index: 10000;
animation: 0.1s ease forwards;
@include mixins.unique-keyframes {
0% {
transform: translateX(0);
opacity: 1;
}
100% {
transform: translateX(-10px);
opacity: 0;
}
}
.content {
display: flex;
flex-direction: column;
gap: 2px;
padding: 10px 10px;
background-color: constants.$origin-color;
border-radius: 8px;
.item {
border-radius: 8px;
white-space: nowrap;
overflow: hidden;
a {
display: block;
padding: 8px 16px;
transition: all 0.2s;
&.active {
color: constants.$origin-color;
background-color: constants.$main-color !important;
}
}
&:hover a {
background-color: constants.$background-color;
}
}
}
}
&:hover {
>.menu-bt {
a {
background-color: constants.$background-color;
}
}
.submenu {
visibility: visible;
animation: 0.3s ease;
@include mixins.unique-keyframes {
0% {
transform: translateX(-10px);
opacity: 0;
}
100% {
transform: translateX(0);
opacity: 1;
}
}
}
}
}
}
}
}
.separate {
height: 0;
margin: 10px 5px;
border: {
width: 1px;
color: constants.$font-secondary-color;
style: solid;
};
opacity: 0.4;
}
.footer {
display: flex;
align-items: center;
font-weight: bold;
padding: 8px 14px;
color: constants.$main-color;
.icon-user {
display: flex;
justify-content: center;
align-items: center;
flex: 0 0 auto;
margin-left: 4px;
width: 36px;
height: 36px;
font-size: constants.$SIZE_ICON_XS;
border: 2px constants.$font-secondary-color solid;
color: constants.$font-secondary-color;
border-radius: 50%;
overflow: hidden;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
}
.text {
flex: 1;
padding-left: 10px;
font-size: 1.4em;
color: constants.$font-main-color;
user-select: text;
overflow: hidden;
text-overflow: ellipsis;
a{
color: constants.$main-color;
text-decoration: underline;
}
}
.icon-exit {
font-size: constants.$SIZE_ICON_XS;
color: constants.$error-color;
padding: 6px 10px;
cursor: pointer;
&:hover {
border-radius: 8px;
background-color: constants.$background-color;
}
}
}
&.hide {
width: 68px !important;
.title {
.icon-box {
span {
transform: rotateZ(360deg);
transition: all .3s;
}
}
.text {
display: none;
}
}
.menu-bt {
.text {
display: none;
}
}
.submenu {
.menu-bt {
.text {
display: block;
}
}
}
.footer {
position: relative;
.text {
display: none;
}
.submenu-exit {
display: none;
position: absolute;
padding-left: 6px;
left: 100%;
z-index: 1000;
box-shadow: 5px 5px 15px 0 rgba(0,0,0,0.1);
.content {
padding: 8px;
border-radius: 8px;
background-color: constants.$origin-color;
.icon-exit {
padding: 4px 8px;
&:hover {
border-radius: 8px;
background-color: constants.$background-color;
}
}
}
&.hide {
display: none!important;
}
}
&:hover .submenu-exit {
display: block;
animation: 0.3s ease;
@include mixins.unique-keyframes {
0% {
transform: translateX(-10px);
opacity: 0;
}
100% {
transform: translateX(0);
opacity: 1;
}
}
}
}
}
}

View File

@@ -0,0 +1,22 @@
$origin-color: white;
$production-color: #4E47BB;
$main-color: $production-color;
$secondary-color: #BAB8E5;
$error-color: #FF4D4F;
$error-secondary-color: #FF7875;
$blue-color: #1677FF;
$active-color: #EBECFD;
$background-color: #F5F5F5;
$font-main-color: #4D4D4D;
$font-secondary-color: #9E9E9E;
$focus-color: #DDDDDD;
$divide-color: rgba(204, 204, 204, 0.66);
$border-color: rgba(204, 204, 204, 0.33);
$url-color: rgba(102, 102, 102, .8);
$url-active-color: #ccc;
$SIZE_ICON_XS: 16px;
$SIZE_ICON_SM: 20px;
$SIZE_ICON_MD: 24px;
$SIZE_ICON_LG: 32px;
$SIZE_ICON_XL: 64px;
$SIZE_ICON_XXL: 96px;

View File

@@ -0,0 +1,149 @@
@use "@/assets/css/mixins" as mixins;
@use "@/assets/css/constants" as constants;
[data-component=sign] {
background-color: #D2D0DD;
user-select: none;
a {
cursor: pointer;
}
a:hover {
color: constants.$production-color;
}
.sign-box {
position: relative;
background-color: constants.$origin-color;
width: 900px;
height: 600px;
overflow: hidden;
border-radius: 12px;
.left, .right {
opacity: 1;
transition: all 1s ease;
> * {
width: 100%;
height: 100%;
}
&.hidden {
opacity: 0;
}
> * {
.title {
margin-bottom: 20px;
transform: translateY(-10px);
.primary {
font-size: 2.4em;
font-weight: bolder;
color: constants.$production-color;
}
.secondary {
font-size: 1.2em;
}
}
.form {
width: 300px;
font-size: 14px;
button {
font-weight: bolder;
}
.addition {
justify-content: space-between;
margin-bottom: 14px;
> * {
flex: 0 0 auto;
}
}
.footer {
text-align: center;
a {
color: constants.$production-color;
}
}
}
}
.verify {
a {
color: constants.$production-color;
font-weight: bolder;
}
}
.sign-up, .sign-in, .forget {
.footer {
a {
font-weight: bolder;
}
}
}
.sign-up, .forget {
.retry, .success {
margin-bottom: 16px;
a {
font-weight: bolder;
}
}
}
}
.cover {
position: absolute;
height: 100%;
width: 50%;
background-color: #F3F4F8;
transition: all 0.8s ease;
.ball-box {
position: relative;
overflow: hidden;
background-color: #F1F2F7;
.ball {
position: absolute;
width: 128px;
height: 128px;
background-color: constants.$production-color;
border-radius: 50%;
bottom: 0;
left: 50%;
transform: translateX(-50%) translateY(50%);
}
}
.mask {
transform: rotateZ(180deg);
filter: blur(12px);
.ball {
width: 140px;
height: 140px;
}
}
}
&.switch {
.cover {
transform: translateX(100%);
transition: all 0.8s ease;
}
}
}
}

View File

@@ -0,0 +1,14 @@
@use "@/assets/css/constants" as constants;
@use "@/assets/css/mixins" as mixins;
[data-component=system-framework] {
.left-panel {
background-color: constants.$origin-color;
}
.right-panel {
flex: 1;
width: 0;
background-color: constants.$background-color;
}
}

View File

@@ -0,0 +1,41 @@
@use '@/assets/css/constants' as constants;
[data-component=system] {
.root-content {
padding: 30px;
gap: 20px;
flex-wrap: wrap;
justify-content: flex-start;
> .card-box {
width: 200px;
height: 360px;
flex: 0 0 auto;
overflow: hidden !important;
cursor: pointer;
.common-card {
width: 100%;
height: 100%;
margin-top: 100px;
text-align: center;
gap: 42px;
> * {
flex: 0 0 auto;
display: block;
}
.icon {
color: constants.$production-color;
font-size: constants.$SIZE_ICON_XL;
}
.text {
font-weight: bolder;
font-size: 2em;
}
}
}
}
}

View File

@@ -0,0 +1,46 @@
@use '@/assets/css/constants' as constants;
[data-component=system-settings] {
.root-content {
padding: 30px;
gap: 20px;
.root-col {
gap: 20px;
> * {
flex: 0 0 auto;
}
.settings-card {
padding: 20px;
gap: 20px;
color: constants.$main-color;
> .head {
align-items: center;
gap: 5px;
.icon {
font-size: constants.$SIZE_ICON_MD;
flex: 0 0 auto;
}
.title {
display: flex;
font-size: 1.2em;
}
:nth-child(n+3) {
flex: 0 0 auto;
color: constants.$font-main-color;
}
.bt-save {
color: constants.$main-color;
}
}
}
}
}
}

View File

@@ -0,0 +1,90 @@
@use '@/assets/css/constants' as constants;
[data-component=system-statistics] {
.root-content {
padding: 30px;
gap: 20px;
flex-wrap: wrap;
justify-content: center;
> .card-box {
width: 48%;
flex: 0 0 auto;
.common-card {
padding: 20px;
gap: 20px;
> .head {
align-items: center;
gap: 5px;
color: constants.$main-color;
.icon {
font-size: constants.$SIZE_ICON_MD;
flex: 0 0 auto;
}
.title {
display: flex;
font-size: 1.2em;
}
:nth-child(n+3) {
flex: 0 0 auto;
color: constants.$font-main-color;
}
}
.card-content {
font-size: 1.1em;
padding: 0 10px;
gap: 10px;
.key, .value-percent {
flex: 0 0 auto;
color: constants.$font-main-color;
}
.value {
color: constants.$font-secondary-color;
overflow: hidden;
> * {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.value-chart {
justify-content: space-around;
width: 0;
> div {
max-height: 12px;
height: 12px;
> * {
transform: translateY(1px);
}
}
}
.value-percent {
text-align: right;
}
.big-chart {
width: 0;
height: 400px;
}
> * {
gap: 5px;
}
}
}
}
}
}

View File

@@ -0,0 +1,42 @@
@use '@/assets/css/constants' as constants;
[data-component=system-tools-base] {
.root-content {
padding: 30px;
gap: 10px;
height: 100%;
width: 100%;
.has-edited::after {
content: '*';
color: constants.$font-secondary-color;
}
>*:first-child {
height: fit-content;
}
> *:nth-child(2) {
position: sticky;
top: 20px;
height: calc(100vh - 60px);
}
.close-editor-btn {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 10px;
right: 10px;
background-color: constants.$font-secondary-color;
width: 32px;
height: 32px;
border-radius: 50%;
color: white;
opacity: 0.6;
box-shadow: 2px 2px 10px 0 rgba(0,0,0,0.2);
cursor: pointer;
}
}
}

View File

@@ -0,0 +1,20 @@
[data-component=system-tools-code] {
padding: 30px;
.card-box {
width: 100%;
height: 100%;
}
.draggable-content {
position: fixed;
inset-inline-end: 48px;
inset-block-end: 48px;
> * {
position: relative;
inset-inline-end: 0;
inset-block-end: 0;
}
}
}

View File

@@ -0,0 +1,8 @@
[data-component=system-tools-execute] {
padding: 30px;
.card-box {
width: 100%;
height: 100%;
}
}

View File

@@ -0,0 +1,14 @@
@use "@/assets/css/constants" as constants;
@use "@/assets/css/mixins" as mixins;
[data-component=tools-framework] {
.left-panel {
background-color: constants.$origin-color;
}
.right-panel {
flex: 1;
width: 0;
background-color: constants.$background-color;
}
}

View File

@@ -0,0 +1,48 @@
@use "@/assets/css/mixins" as mixins;
@use "@/assets/css/constants" as constants;
[data-component=tools-create] {
.root-content {
padding: 20px;
gap: 20px;
height: 100%;
width: 100%;
> * {
gap: 10px;
width: 0;
.title {
flex: 0 0 auto;
height: 40px;
> * {
height: 100%;
width: 100%;
justify-content: center;
align-items: center;
font-size: 1.6em;
color: constants.$production-color;
font-weight: bolder;
}
}
.config {
.config-content {
padding: 20px;
.help {
margin-left: 6px;
color: constants.$font-main-color;
font-size: 0.8em;
}
.create-bt {
width: 100%;
font-weight: bold;
}
}
}
}
}
}

View File

@@ -0,0 +1,28 @@
[data-component=tools-edit] {
.root-content {
width: 100%;
height: 100%;
> * {
width: 0;
}
.draggable-mask {
position: absolute;
width: 100%;
height: 100%;
}
}
.draggable-content {
position: fixed;
inset-inline-end: 32px;
inset-block-end: 48px;
> * {
position: relative;
inset-inline-end: 0;
inset-block-end: 0;
}
}
}

View File

@@ -0,0 +1,115 @@
@use "@/assets/css/mixins" as mixins;
@use '@/assets/css/constants' as constants;
[data-component=tools] {
.root-content {
padding: 30px;
gap: 20px;
flex-wrap: wrap;
justify-content: flex-start;
> .card-box {
width: 180px;
height: 290px;
flex: 0 0 auto;
.common-card {
width: 100%;
height: 100%;
text-align: center;
align-items: center;
> * {
display: block;
flex: 0 0 auto;
}
.version-select {
position: absolute;
top: 10px;
left: 10px;
width: 8em;
}
.upgrade-bt {
position: absolute;
top: 10px;
right: 10px;
font-size: 1.8em;
}
.icon {
display: flex;
padding-top: 50px;
padding-bottom: 20px;
color: constants.$production-color;
font-size: constants.$SIZE_ICON_XL;
justify-content: center;
img {
width: constants.$SIZE_ICON_XL;
}
}
.tool-name {
font-weight: bolder;
font-size: 1.6em;
}
}
}
& > :first-child {
cursor: pointer;
.info {
padding-top: 50px;
}
}
& > :not(:first-child) {
.info {
transform: translateY(40px);
transition: all 0.1s ease;
}
.operation {
display: flex;
flex: 1;
justify-content: center;
padding-bottom: 20px;
gap: 4px;
width: 70%;
flex-direction: column;
align-items: center;
visibility: hidden;
opacity: 0;
> *, .edit > * {
width: 100%;
}
.edit {
> * {
> :first-child {
flex: 1;
}
}
}
}
}
& > :not(:first-child):hover {
.info {
transform: translateY(-10px);
transition: all 0.2s ease;
}
.operation {
visibility: visible;
opacity: 1;
transition: all 0.4s ease;
}
}
}
}

View File

@@ -0,0 +1,8 @@
[data-component=tools-source] {
padding: 30px;
.card-box {
width: 100%;
height: 100%;
}
}

View File

@@ -0,0 +1,144 @@
@use '@/assets/css/constants' as constants;
[data-component=tools-store] {
.search {
display: flex;
position: sticky;
width: 100%;
margin-top: 20px;
top: 20px;
z-index: 10;
justify-content: center;
transition: all 0.3s ease;
> * {
width: 80%;
}
&.hide {
transform: translateY(-60px);
}
}
.root-content {
padding: 30px;
gap: 20px;
flex-wrap: wrap;
justify-content: center;
> .card-box {
width: 180px;
height: 290px;
flex: 0 0 auto;
cursor: pointer;
.common-card {
width: 100%;
height: 100%;
text-align: center;
align-items: center;
> * {
display: block;
flex: 0 0 auto;
}
.icon {
display: flex;
padding-top: 40px;
padding-bottom: 20px;
color: constants.$production-color;
font-size: constants.$SIZE_ICON_XL;
justify-content: center;
img {
width: constants.$SIZE_ICON_XL;
}
}
.version {
position: absolute;
left: 10px;
top: 10px;
}
.info {
padding-top: 20px;
.tool-name {
font-weight: bolder;
font-size: 1.6em;
}
.tool-desc {
margin-top: 10px;
color: constants.$font-secondary-color;
}
}
.author {
display: flex;
margin-top: auto;
flex-direction: row;
justify-content: end;
padding-bottom: 10px;
gap: 10px;
.avatar {
> * {
width: 24px;
height: 24px;
}
}
.author-name {
display: flex;
align-items: center;
}
}
.operation {
position: absolute;
top: 6px;
right: 12px;
font-size: 1.6em;
> *:hover {
color: constants.$font-secondary-color;
}
}
}
.load-more-card {
width: 100%;
height: 100%;
text-align: center;
align-items: center;
.icon {
display: flex;
font-size: constants.$SIZE_ICON_XXL;
color: constants.$production-color;
align-items: center;
transform: translateY(-20px);
}
.text {
position: absolute;
top: 60%;
font-size: 1.2em;
font-weight: bolder;
}
}
}
.no-tool {
display: flex;
justify-content: center;
font-size: 1.4em;
font-weight: bolder;
color: constants.$font-secondary-color;
}
}
}

View File

@@ -0,0 +1,188 @@
@use '@/assets/css/constants' as constants;
[data-component=tools-store-user] .root-content {
padding: {
top: 80px;
left: 30px;
right: 30px;
bottom: 30px;
};
.root-box {
width: 100%;
height: 100%;
overflow: visible;
align-items: center;
min-width: 900px;
padding-bottom: 20px;
> .info {
margin-left: 40px;
transform: translateY(-40px);
> * {
flex: 0 0 auto;
}
.avatar-box {
background-color: white;
padding: 4px;
border-radius: 50%;
box-shadow: 5px 5px 15px 0 rgba(0, 0, 0, 0.1);
.avatar {
background-color: transparent !important;
}
}
.info-name {
margin: {
top: 20px;
left: 24px;
};
justify-content: center;
> * {
flex: 0 0 auto;
}
.nickname {
font-size: 2.4em;
font-weight: bolder;
color: constants.$production-color;
}
.url {
cursor: pointer;
> span {
margin-left: 8px;
}
}
}
}
.tools {
padding: 20px;
gap: 20px;
flex-wrap: wrap;
justify-content: center;
> .card-box {
width: 180px;
height: 290px;
flex: 0 0 auto;
cursor: pointer;
.common-card {
width: 100%;
height: 100%;
text-align: center;
align-items: center;
> * {
display: block;
flex: 0 0 auto;
}
.icon {
display: flex;
padding-top: 40px;
padding-bottom: 20px;
color: constants.$production-color;
font-size: constants.$SIZE_ICON_XL;
justify-content: center;
img {
width: constants.$SIZE_ICON_XL;
}
}
.version {
position: absolute;
left: 10px;
top: 10px;
}
.info {
padding-top: 20px;
.tool-name {
font-weight: bolder;
font-size: 1.6em;
}
.tool-desc {
margin-top: 10px;
color: constants.$font-secondary-color;
}
}
.author {
display: flex;
margin-top: auto;
flex-direction: row;
justify-content: end;
padding-bottom: 10px;
gap: 10px;
.avatar {
> * {
width: 24px;
height: 24px;
}
}
.author-name {
display: flex;
align-items: center;
}
}
.operation {
position: absolute;
top: 6px;
right: 12px;
font-size: 1.6em;
> *:hover {
color: constants.$font-secondary-color;
}
}
}
.load-more-card {
width: 100%;
height: 100%;
text-align: center;
align-items: center;
.icon {
display: flex;
font-size: constants.$SIZE_ICON_XXL;
color: constants.$production-color;
align-items: center;
transform: translateY(-20px);
}
.text {
position: absolute;
top: 60%;
font-size: 1.2em;
font-weight: bolder;
}
}
}
.no-tool {
display: flex;
justify-content: center;
margin-bottom: 20px;
font-size: 1.2em;
font-weight: bolder;
color: constants.$font-secondary-color;
}
}
}
}

View File

@@ -0,0 +1,8 @@
[data-component=tools-view] {
padding: 30px;
.card-box {
height: 100%;
width: 100%;
}
}

View File

@@ -0,0 +1,14 @@
@use "@/assets/css/constants" as constants;
@use "@/assets/css/mixins" as mixins;
[data-component=user-framework] {
.left-panel {
background-color: constants.$origin-color;
}
.right-panel {
flex: 1;
width: 0;
background-color: constants.$background-color;
}
}

View File

@@ -0,0 +1,135 @@
@use '@/assets/css/constants' as constants;
[data-component=user] .root-content {
padding: {
top: 80px;
left: 30px;
right: 30px;
bottom: 30px;
};
.card-box {
width: 100%;
height: 100%;
overflow: visible;
align-items: center;
min-width: 900px;
padding-bottom: 20px;
> :not(:first-child) {
padding: {
left: 60px;
right: 60px;
};
}
.divide {
height: 1px;
width: calc(100% - 120px);
background-color: constants.$divide-color;
margin: {
left: 60px;
right: 60px;
};
}
.info {
margin-left: 40px;
transform: translateY(-40px);
> * {
flex: 0 0 auto;
}
.avatar-box {
background-color: white;
padding: 4px;
border-radius: 50%;
box-shadow: 5px 5px 15px 0 rgba(0, 0, 0, 0.1);
.avatar {
background-color: transparent !important;
}
}
.info-name {
margin: {
top: 20px;
left: 24px;
};
justify-content: center;
> * {
flex: 0 0 auto;
}
.nickname {
font-size: 2.4em;
font-weight: bolder;
color: constants.$production-color;
}
.url {
> span {
margin-left: 8px;
}
}
}
}
.title {
align-items: center;
.content {
padding: {
bottom: 30px;
};
justify-content: space-between;
align-items: center;
width: 100%;
> * {
flex: 0 0 auto;
}
.text {
font-size: 1.6em;
font-weight: bolder;
}
.operation {
gap: 10px;
}
}
}
.table {
gap: 24px;
padding: {
top: 30px;
bottom: 20px;
};
.row {
> * {
flex: 0 0 auto;
}
.label {
font-size: 1.4em;
font-weight: bolder;
width: 400px;
}
.input {
width: 400px;
> * {
width: 100%;
}
}
}
}
}
}

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1080 1024"><path d="M265.216 920.348444a41.472 41.472 0 0 1-41.415111-42.211555v-215.608889a42.154667 42.154667 0 1 1 83.512889 0v215.608889a42.097778 42.097778 0 0 1-42.097778 42.211555z m207.701333 0a41.472 41.472 0 0 1-41.358222-42.211555V536.689778a42.097778 42.097778 0 0 1 83.512889 0v340.764444a42.097778 42.097778 0 0 1-42.097778 42.894222z m207.758223 0a41.472 41.472 0 0 1-41.358223-42.211555V728.177778a42.097778 42.097778 0 0 1 83.512889 0v149.959111a42.097778 42.097778 0 0 1-42.097778 42.211555z m207.758222 0a41.472 41.472 0 0 1-41.415111-42.211555v-276.48a42.154667 42.154667 0 1 1 83.569777 0v279.950222a42.097778 42.097778 0 0 1-42.097777 38.684445zM210.659556 502.101333a41.415111 41.415111 0 0 1-33.792-16.554666 42.211556 42.211556 0 0 1 10.353777-58.766223l300.202667-231.537777a42.723556 42.723556 0 0 1 51.768889 0l138.069333 112.64 222.947556-185.969778a41.756444 41.756444 0 0 1 53.816889 63.601778l-247.808 208.782222a41.358222 41.358222 0 0 1-53.134223 0L515.072 280.917333 238.933333 493.112889a42.723556 42.723556 0 0 1-28.273777 8.988444z" /><path d="M927.118222 336.896a42.097778 42.097778 0 0 1-42.097778-41.472V179.313778h-117.361777a42.154667 42.154667 0 0 1 0-83.626667h159.459555a42.097778 42.097778 0 0 1 42.097778 41.415111v158.321778a42.097778 42.097778 0 0 1-42.097778 41.528889z" /></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M471.893333 149.333333a42.666667 42.666667 0 0 0-73.258666-29.781333l-343.893334 352.981333a42.666667 42.666667 0 0 0-0.768 58.709334l343.893334 372.352a42.666667 42.666667 0 0 0 73.984-28.928v-190.677334c56.917333-5.248 116.821333-1.365333 179.882666 11.989334 65.834667 13.994667 150.528 76.032 253.909334 202.24a42.666667 42.666667 0 0 0 75.477333-31.36c-15.445333-152.32-73.984-281.301333-176.170667-384.853334-92.757333-93.994667-204.373333-146.432-333.098666-156.586666V149.333333z" /></svg>

After

Width:  |  Height:  |  Size: 570 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M1001.472 608.768l-473.088-216.576c-5.12-2.048-10.752-3.584-15.872-3.584s-10.752 1.024-15.872 3.584L22.528 608.768c-13.824 6.656-22.528 19.968-22.528 35.328 0 15.36 8.704 28.672 23.04 35.328l473.088 212.992c10.24 4.608 21.504 4.608 31.744 0l473.088-212.992c14.336-6.144 23.04-19.968 23.04-35.328 0-15.36-8.704-28.672-22.528-35.328z" /><path d="M23.04 435.2l125.952 56.32c12.8 5.632 27.648 0 33.28-12.288 5.632-12.8 0-27.648-12.288-33.28l-103.424-46.08 445.44-203.776 445.952 204.288-102.912 46.08c-12.8 5.632-18.432 20.48-12.288 33.28s20.48 18.432 33.28 12.288L1000.96 435.2c14.336-6.144 23.04-19.968 23.04-35.328 0-15.36-8.704-29.184-22.528-35.328L527.872 148.48c-5.12-2.048-10.752-3.584-15.872-3.584s-10.752 1.024-15.872 3.584L22.528 365.056C8.704 371.2 0 385.024 0 400.384s8.704 28.672 23.04 34.816z" /><path d="M23.04 433.152l125.952 56.32c12.8 5.632 27.648 0 33.28-12.288 5.632-12.8 0-27.648-12.288-33.28l-103.424-46.08 445.44-204.288 445.952 204.288-102.912 46.592c-12.8 5.632-18.432 20.48-12.288 33.28s20.48 18.432 33.28 12.288l125.44-56.832c14.336-6.144 23.04-19.968 23.04-35.328 0-15.36-8.704-29.184-22.528-35.328l-473.088-216.576c-5.12-2.048-10.752-3.584-15.872-3.584s-10.752 1.024-15.872 3.584L22.528 362.496C8.704 369.152 0 382.464 0 397.824c0 15.36 8.704 29.184 23.04 35.328z" /></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M128 426.666667H85.333333V170.794667C85.333333 147.157333 104.746667 128 127.658667 128h768.682666A42.24 42.24 0 0 1 938.666667 170.794667V426.666667h-42.666667v426.709333a42.496 42.496 0 0 1-42.368 42.624H170.368A42.453333 42.453333 0 0 1 128 853.376V426.666667z m682.666667 0H213.333333v384h597.333334v-384zM170.666667 213.333333v128h682.666666V213.333333H170.666667z m213.333333 298.666667h256v85.333333H384v-85.333333z" /></svg>

After

Width:  |  Height:  |  Size: 505 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M1000 768c13.2 0 24 10.8 24 24v80c0 13.2-10.8 24-24 24H24c-13.2 0-24-10.8-24-24V152c0-13.2 10.8-24 24-24h80c13.2 0 24 10.8 24 24v616h872zM745.4 319L576 432l-170.6-227.4c-10.2-13.6-31-12.6-39.8 2L192 496v208h768l-179.8-375.6c-6.4-13-22.8-17.4-34.8-9.4z" /></svg>

After

Width:  |  Height:  |  Size: 334 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1028 1024"><path d="M646.4 512l345.6-345.6c38.4-38.4 38.4-96 0-134.4-38.4-38.4-96-38.4-134.4 0L512 377.6 166.4 32C128-6.4 70.4-6.4 32 32c-38.4 38.4-38.4 96 0 134.4L377.6 512l-345.6 345.6c-38.4 38.4-38.4 96 0 134.4 19.2 19.2 44.8 25.6 70.4 25.6s51.2-6.4 70.4-25.6L512 646.4l345.6 345.6c19.2 19.2 44.8 25.6 70.4 25.6s51.2-6.4 70.4-25.6c38.4-38.4 38.4-96 0-134.4L646.4 512z" /></svg>

After

Width:  |  Height:  |  Size: 433 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M305.6 225.6c-17.6-17.6-43.2-17.6-59.2 0L19.2 460.8c-25.6 30.4-25.6 72 0 97.6l225.6 235.2c8 8 20.8 12.8 30.4 12.8s20.8-4.8 30.4-12.8c17.6-17.6 17.6-43.2 0-59.2L88 512l217.6-225.6c17.6-17.6 17.6-43.2 0-60.8zM1001.6 460.8L774.4 225.6c-17.6-17.6-43.2-17.6-59.2 0s-17.6 43.2 0 59.2L932.8 512 715.2 737.6c-17.6 17.6-17.6 43.2 0 59.2 8 8 17.6 12.8 30.4 12.8 12.8 0 20.8-4.8 30.4-12.8l225.6-235.2c28.8-28.8 28.8-70.4 0-100.8zM612.8 230.4c-20.8-8-46.4 4.8-56 25.6L382.4 742.4c-8 20.8 4.8 46.4 25.6 56 4.8 0 8 4.8 12.8 4.8 17.6 0 33.6-12.8 38.4-30.4l179.2-491.2c8-20.8-4.8-46.4-25.6-51.2z" /></svg>

After

Width:  |  Height:  |  Size: 662 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M672 832 224 832c-52.928 0-96-43.072-96-96L128 160c0-52.928 43.072-96 96-96l448 0c52.928 0 96 43.072 96 96l0 576C768 788.928 724.928 832 672 832zM224 128C206.368 128 192 142.368 192 160l0 576c0 17.664 14.368 32 32 32l448 0c17.664 0 32-14.336 32-32L704 160c0-17.632-14.336-32-32-32L224 128z" /><path d="M800 960 320 960c-17.664 0-32-14.304-32-32s14.336-32 32-32l480 0c17.664 0 32-14.336 32-32L832 256c0-17.664 14.304-32 32-32s32 14.336 32 32l0 608C896 916.928 852.928 960 800 960z" /><path d="M544 320 288 320c-17.664 0-32-14.336-32-32s14.336-32 32-32l256 0c17.696 0 32 14.336 32 32S561.696 320 544 320z" /><path d="M608 480 288.032 480c-17.664 0-32-14.336-32-32s14.336-32 32-32L608 416c17.696 0 32 14.336 32 32S625.696 480 608 480z" /><path d="M608 640 288 640c-17.664 0-32-14.304-32-32s14.336-32 32-32l320 0c17.696 0 32 14.304 32 32S625.696 640 608 640z" /></svg>

After

Width:  |  Height:  |  Size: 937 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M256 768h512V256H256v512z m341.3 85.3H426.6v85.3h-85.3v-85.3h-128a42.7 42.7 0 0 1-42.7-42.7v-128H85.3v-85.3h85.3V426.6H85.3v-85.3h85.3v-128a42.7 42.7 0 0 1 42.7-42.7h128V85.3h85.3v85.3h170.7V85.3h85.3v85.3h128a42.7 42.7 0 0 1 42.7 42.7v128h85.3v85.3h-85.3v170.7h85.3v85.3h-85.3v128a42.7 42.7 0 0 1-42.7 42.7h-128v85.3h-85.3v-85.3z m-256-512h341.3v341.3H341.3V341.3z" /></svg>

After

Width:  |  Height:  |  Size: 448 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" version="1.1"><path d="M885.333333 266.666667H768v-64C768 149.738667 725.290667 106.666667 672.746667 106.666667H352A96.106667 96.106667 0 0 0 256 202.666667v64H138.666667c-17.706667 0-32 14.293333-32 32s14.293333 32 32 32h746.666666c17.706667 0 32-14.293333 32-32s-14.293333-32-32-32zM320 202.666667c0-17.621333 14.378667-32 32-32h320.746667C690.24 170.666667 704 184.725333 704 202.666667v64H320v-64zM736.128 917.333333H288.064a96.128 96.128 0 0 1-96-96l1.194667-384a32 32 0 0 1 64 0l-1.194667 384c0 17.664 14.378667 32 32 32h448.064a32 32 0 0 0 32-32l-0.234667-384a32 32 0 1 1 64 0l0.234667 384c0 52.928-43.072 96-96 96z" /><path d="M384 469.333333m32 0l0 0q32 0 32 32l0 192q0 32-32 32l0 0q-32 0-32-32l0-192q0-32 32-32Z" /><path d="M576 469.333333m32 0l0 0q32 0 32 32l0 192q0 32-32 32l0 0q-32 0-32-32l0-192q0-32 32-32Z" /></svg>

After

Width:  |  Height:  |  Size: 895 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M960 736c0 41.27-33.4 74.66-74.67 74.66H138.67C97.4 810.66 64 777.27 64 736V586.67C64 545.4 97.4 512 138.67 512h746.67c41.26 0 74.66 33.4 74.66 74.67V736zM138.67 462.38c-13.84 0-35.31 4.29-47.95 9.54l150.05-225.19c12.17-18.37 40.08-33.39 62.02-33.39h417.7c22.19 0 49.86 14.79 62.26 33.39L932.8 471.92c-15.27-5.73-31.49-9.06-47.71-9.54H138.67z m472.8 198.96c0 27.43 22.19 49.86 49.86 49.86 27.43 0 49.86-22.18 49.86-49.86 0-27.43-22.42-49.86-49.86-49.86-27.43 0.24-49.86 22.43-49.86 49.86z m149.34 0c0 27.43 22.19 49.86 49.86 49.86 27.43 0 49.86-22.18 49.86-49.86 0-27.43-22.42-49.86-49.86-49.86-27.44 0.24-49.86 22.43-49.86 49.86z" /></svg>

After

Width:  |  Height:  |  Size: 713 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M958.577476 311.180252c0 15.286148-5.878894 29.522384-16.564257 40.166815L551.623951 741.043556c-1.39272 1.425466-2.577708 2.537799-3.846608 3.449565l-2.905166 2.304486c-11.416004 11.362792-24.848944 16.945951-39.068807 16.945951-14.475689 0-28.010961-5.708002-38.110993-16.056698L79.475588 355.310332c-10.467399-10.613732-16.236799-24.786523-16.236799-39.893592 0-14.772448 5.599532-28.726252 15.753799-39.286772 10.18599-10.497075 24.390503-16.539698 38.95215-16.539698 14.382569 0 28.009937 5.723352 38.366819 16.142655l350.169241 353.968777 359.428116-358.485651c10.30981-10.248412 23.781636-15.909341 37.994336-15.909341 14.889105 0 28.859281 6.05081 39.333844 16.999163C953.126324 282.725176 958.577476 296.556183 958.577476 311.180252z" /></svg>

After

Width:  |  Height:  |  Size: 825 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M926.47619 355.644952V780.190476a73.142857 73.142857 0 0 1-73.142857 73.142857H170.666667a73.142857 73.142857 0 0 1-73.142857-73.142857V355.644952l304.103619 257.828572a170.666667 170.666667 0 0 0 220.745142 0L926.47619 355.644952zM853.333333 170.666667a74.044952 74.044952 0 0 1 26.087619 4.778666 72.704 72.704 0 0 1 30.622477 22.186667 73.508571 73.508571 0 0 1 10.678857 17.67619c3.169524 7.509333 5.12 15.652571 5.607619 24.210286L926.47619 243.809524v24.380952L559.469714 581.241905a73.142857 73.142857 0 0 1-91.306666 2.901333l-3.632762-2.925714L97.52381 268.190476v-24.380952a72.899048 72.899048 0 0 1 40.155428-65.292191A72.97219 72.97219 0 0 1 170.666667 170.666667h682.666666z" /></svg>

After

Width:  |  Height:  |  Size: 770 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M750.912 505.216L256 198.016c-27.712-17.024-64 4.288-64 36.288v614.4c0 32 36.288 53.312 64 36.288l492.8-307.2c29.888-14.976 29.888-57.6 2.112-72.576z" /></svg>

After

Width:  |  Height:  |  Size: 232 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M835.669333 554.666667h-473.173333A42.453333 42.453333 0 0 1 320 512a42.666667 42.666667 0 0 1 42.474667-42.666667h473.173333l-161.813333-161.834666a42.666667 42.666667 0 0 1 60.330666-60.330667l234.666667 234.666667a42.666667 42.666667 0 0 1 0 60.330666l-234.666667 234.666667a42.666667 42.666667 0 0 1-60.330666-60.330667L835.669333 554.666667zM554.666667 42.666667a42.666667 42.666667 0 1 1 0 85.333333H149.525333C137.578667 128 128 137.578667 128 149.482667v725.034666C128 886.4 137.6 896 149.525333 896H554.666667a42.666667 42.666667 0 1 1 0 85.333333H149.525333A106.816 106.816 0 0 1 42.666667 874.517333V149.482667A106.773333 106.773333 0 0 1 149.525333 42.666667H554.666667z" /></svg>

After

Width:  |  Height:  |  Size: 765 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1028 1024"><path d="M8.533333 192c0-25.6 17.066667-42.666667 34.133334-42.666667h490.666666c21.333333 0 34.133333 17.066667 34.133334 42.666667 0 21.333333-17.066667 42.666667-34.133334 42.666667h-490.666666c-21.333333 0-34.133333-21.333333-34.133334-42.666667z m550.4 213.333333c0 25.6-21.333333 42.666667-46.933333 42.666667h-465.066667c-25.6 0-46.933333-17.066667-46.933333-42.666667 0-21.333333 21.333333-42.666667 46.933333-42.666666h465.066667c25.6 0 46.933333 17.066667 46.933333 42.666666z m-507.733333 256c-25.6 0-46.933333-17.066667-46.933333-42.666666s21.333333-42.666667 46.933333-42.666667h465.066667c25.6 0 46.933333 17.066667 46.933333 42.666667 0 21.333333-21.333333 42.666667-46.933333 42.666666h-465.066667z m507.733333 170.666667c0 25.6-21.333333 42.666667-51.2 42.666667h-452.266666c-29.866667 0-51.2-17.066667-51.2-42.666667s21.333333-42.666667 51.2-42.666667h452.266666c29.866667 0 51.2 17.066667 51.2 42.666667z m140.8-85.333333l221.866667-238.933334-221.866667-238.933333c-17.066667-17.066667-17.066667-51.2 0-68.266667 17.066667-17.066667 46.933333-17.066667 64 0l251.733334 273.066667c17.066667 17.066667 17.066667 51.2 0 68.266667l-251.733334 273.066666c-17.066667 17.066667-46.933333 17.066667-64 0-17.066667-17.066667-17.066667-46.933333 0-68.266666z" /></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1152 1024"><path d="M576 288a221.88 221.88 0 0 0-62.48 10 110.8 110.8 0 0 1 14.48 54 112 112 0 0 1-112 112 110.8 110.8 0 0 1-54-14.48A223.42 223.42 0 1 0 576 288z m569.04 194.8C1036.58 271.18 821.86 128 576 128S115.36 271.28 6.96 482.82a64.7 64.7 0 0 0 0 58.38C115.42 752.82 330.14 896 576 896s460.64-143.28 569.04-354.82a64.7 64.7 0 0 0 0-58.38zM576 800c-197.3 0-378.18-110-475.86-288C197.82 334 378.68 224 576 224s378.18 110 475.86 288C954.2 690 773.32 800 576 800z" /></svg>

After

Width:  |  Height:  |  Size: 530 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z" /></svg>

After

Width:  |  Height:  |  Size: 650 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M620.8 611.2c67.2-38.4 115.2-112 115.2-195.2 0-124.8-99.2-224-224-224s-224 99.2-224 224c0 83.2 44.8 156.8 115.2 195.2-89.6 35.2-156.8 115.2-179.2 211.2-3.2 16 6.4 35.2 25.6 38.4H256c16 0 28.8-9.6 32-25.6 22.4-105.6 115.2-182.4 224-182.4s201.6 76.8 224 182.4c3.2 16 19.2 28.8 38.4 25.6 16-3.2 28.8-19.2 25.6-38.4-22.4-96-89.6-176-179.2-211.2zM352 416c0-89.6 70.4-160 160-160s160 70.4 160 160-70.4 160-160 160-160-70.4-160-160zM992 630.4c-12.8-64-54.4-115.2-118.4-144 35.2-32 54.4-76.8 54.4-128C928 265.6 857.6 192 768 192c-19.2 0-32 12.8-32 32s12.8 32 32 32c54.4 0 96 44.8 96 102.4 0 51.2-28.8 89.6-73.6 99.2-16 3.2-28.8 22.4-22.4 38.4 0 16 9.6 28.8 25.6 28.8 70.4 12.8 118.4 54.4 131.2 115.2 3.2 16 16 25.6 32 25.6h6.4c19.2 0 32-16 28.8-35.2zM252.8 499.2c6.4-19.2-6.4-35.2-22.4-41.6C188.8 448 160 409.6 160 358.4 163.2 300.8 201.6 256 256 256c19.2 0 32-12.8 32-32s-16-32-32-32c-89.6 0-156.8 70.4-156.8 166.4 0 51.2 19.2 96 51.2 128-60.8 28.8-105.6 80-118.4 144-3.2 16 6.4 35.2 25.6 38.4H64c16 0 28.8-9.6 32-25.6 12.8-60.8 60.8-102.4 131.2-115.2 16 0 25.6-12.8 25.6-28.8z" /></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M981.333333 533.333333H42.666667l151.68-303.36A85.226667 85.226667 0 0 1 275.626667 170.666667h472.746666c37.12 0 69.973333 23.893333 81.28 59.306666L981.333333 533.333333zM42.666667 597.333333v170.666667c0 47.146667 38.186667 85.333333 85.333333 85.333333h768c47.146667 0 85.333333-38.186667 85.333333-85.333333v-170.666667H42.666667z m778.666666 170.666667h-106.666666c-17.706667 0-32-14.293333-32-32s14.293333-32 32-32h106.666666c17.706667 0 32 14.293333 32 32s-14.293333 32-32 32z" /></svg>

After

Width:  |  Height:  |  Size: 567 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M1024 512c0 282.624-229.376 512-512 512S0 794.624 0 512 229.376 0 512 0s512 229.376 512 512z m-510.464 209.408c-23.552 0-43.008 19.456-43.008 43.008v9.728c0 23.552 19.456 42.496 43.008 42.496 23.552 0 43.008-18.944 43.008-42.496v-9.728c0-23.552-19.456-43.008-43.008-43.008z m10.24-481.792c-56.32-1.024-99.84 13.312-129.536 42.496-32.256 31.744-48.64 81.408-48.64 147.456v0.512c1.024 10.752 10.752 30.72 37.376 30.72 26.624 0 35.328-20.48 35.84-31.232-1.024-40.96 8.192-71.168 27.136-89.6 17.92-17.408 45.568-25.6 81.92-23.552 49.664 5.632 74.752 32.768 76.8 82.944-3.584 22.528-23.04 52.224-57.344 88.576C500.224 536.576 476.16 580.608 476.16 619.52v39.424c1.536 9.728 10.752 27.648 35.328 27.648 24.064 0 33.792-17.92 35.328-27.648v-27.648c0-29.696 22.016-66.56 66.048-108.544 48.128-44.032 72.192-85.504 72.192-123.392-4.608-101.888-58.368-155.648-161.28-159.744z" /></svg>

After

Width:  |  Height:  |  Size: 948 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M116.707556 631.751111a56.888889 56.888889 0 1 1 113.777777 0V910.222222h539.704889V512a56.888889 56.888889 0 1 1 113.777778 0v398.222222a113.777778 113.777778 0 0 1-113.777778 113.777778H230.485333a113.777778 113.777778 0 0 1-113.777777-113.777778v-278.471111z" /><path d="M98.929778 573.070222a56.888889 56.888889 0 0 1-84.081778-76.629333L412.700444 59.904A113.777778 113.777778 0 0 1 578.019556 56.888889l429.710222 438.044444a56.888889 56.888889 0 0 1-81.237334 79.644445L496.810667 136.533333 98.929778 573.098667z" /></svg>

After

Width:  |  Height:  |  Size: 603 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M564 96c44.864 105.888-160.864 170.752-180 259.008-17.504 80.992 121.888 176 122.016 176-21.28-33.504-36.768-61.76-58.016-114.016C412 328.736 667.36 249.12 564 96z m136 147.008s-179.872 11.36-188.992 128.992c-4.16 52.384 47.488 79.872 48.992 118.016 1.28 31.104-31.008 56.96-31.008 56.96s57.888-10.464 76-57.984c20-52.736-38.976-88.736-32.992-131.008 5.76-40.352 128-114.976 128-114.976z m44 270.976c-18.88-0.864-40.128 6.144-59.008 20 37.248-8.224 69.024 15.136 69.024 42.016 0 60.256-86.016 116.992-86.016 116.992s132.992-14.88 132.992-113.984c0-40.896-25.6-63.52-56.992-65.024z m-352.992 1.024c-46.4 1.6-139.008 9.248-139.008 44.992 0 49.76 215.744 53.632 370.016 23.008 0 0 41.984-29.248 52.992-40-101.12 20.992-332 24.256-332 5.984 0-16.736 73.984-33.984 73.984-33.984s-10.496-0.512-25.984 0z m-14.016 92c-25.376 0-63.008 19.744-63.008 38.976 0 38.752 191.04 68.512 332.032 12l-49.024-29.984c-95.616 31.264-272.256 20.864-220-20.992z m24 86.976c-34.624 0-56.992 21.888-56.992 38.016 0 49.6 206.88 54.496 288.992 4l-52-34.016c-61.248 26.4-215.36 30.272-180-8z m-116 45.024C228.512 737.888 192 763.488 192 784.96c0 114.368 579.008 108.896 579.008-8 0-19.36-22.88-28.608-31.008-32.992 47.264 111.744-472.992 103.008-472.992 36.992 0-14.976 38.496-29.984 73.984-22.976l-29.984-17.024a190.784 190.784 0 0 0-26.016-1.984zM832 816c-88 85.12-310.72 115.616-535.008 63.008 224.256 93.76 533.888 41.6 535.008-63.008z" /></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M487.1 425c-1.4-11.2-19-23.1-28.2-31.9-5.1-5-29-23.1-30.4-29.9-1.4-6.6 9.7-21.5 13.3-28.9 5.1-10.7 8.8-23.7 11.3-32.6 18.8-66.1 20.7-156.9-6.2-211.2-10.2-20.6-38.6-49-56.4-62.5-42-31.7-119.6-35.3-170.1-16.6-14.1 5.2-27.8 9.8-40.1 17.1-33.1 19.4-68.3 32.5-78.1 71.6-24.2 10.8-31.5 41.8-30.3 77.8.2 7 4.1 15.8 2.7 22.4-.7 3.3-5.2 7.6-6.1 9.8-11.6 27.7-2.3 64 11.1 83.7 8.1 11.9 21.5 22.4 39.2 25.2.7 10.6 3.3 19.7 8.2 30.4 3.1 6.8 14.7 19 10.4 27.7-2.2 4.4-21 13.8-27.3 17.6C89 407.2 73.7 415 54.2 429c-12.6 9-32.3 10.2-29.2 31.1 2.1 14.1 10.1 31.6 14.7 45.8.7 2 1.4 4.1 2.1 6h422c4.9-15.3 9.7-30.9 14.6-47.2 3.4-11.4 10.2-27.8 8.7-39.7zM205.9 33.7c1.8-.5 3.4.7 4.9 2.4-.2 5.2-5.4 5.1-8.9 6.8-5.4 6.7-13.4 9.8-20 17.2-6.8 7.5-14.4 27.7-23.4 30-4.5 1.1-9.7-.8-13.6-.5-10.4.7-17.7 6-28.3 7.5 13.6-29.9 56.1-54 89.3-63.4zm-104.8 93.6c13.5-14.9 32.1-24.1 54.8-25.9 11.7 29.7-8.4 65-.9 97.6 2.3 9.9 10.2 25.4-2.4 25.7.3-28.3-34.8-46.3-61.3-29.6-1.8-21.5-4.9-51.7 9.8-67.8zm36.7 200.2c-1-4.1-2.7-12.9-2.3-15.1 1.6-8.7 17.1-12.5 11-24.7-11.3-.1-13.8 10.2-24.1 11.3-26.7 2.6-45.6-35.4-44.4-58.4 1-19.5 17.6-38.2 40.1-35.8 16 1.8 21.4 19.2 24.5 34.7 9.2.5 22.5-.4 26.9-7.6-.6-17.5-8.8-31.6-8.2-47.7 1-30.3 17.5-57.6 4.8-87.4 13.6-30.9 53.5-55.3 83.1-70 36.6-18.3 94.9-3.7 129.3 15.8 19.7 11.1 34.4 32.7 48.3 50.7-19.5-5.8-36.1 4.2-33.1 20.3 16.3-14.9 44.2-.2 52.5 16.4 7.9 15.8 7.8 39.3 9 62.8 2.9 57-10.4 115.9-39.1 157.1-7.7 11-14.1 23-24.9 30.6-26 18.2-65.4 34.7-99.2 23.4-44.7-15-65-44.8-89.5-78.8.7 18.7 13.8 34.1 26.8 48.4 11.3 12.5 25 26.6 39.7 32.4-12.3-2.9-31.1-3.8-36.2 7.2-28.6-1.9-55.1-4.8-68.7-24.2-10.6-15.4-21.4-41.4-26.3-61.4zm222 124.1c4.1-3 11.1-2.9 17.4-3.6-5.4-2.7-13-3.7-19.3-2.2-.1-4.2-2-6.8-3.2-10.2 10.6-3.8 35.5-28.5 49.6-20.3 6.7 3.9 9.5 26.2 10.1 37 .4 9-.8 18-4.5 22.8-18.8-.6-35.8-2.8-50.7-7 .9-6.1-1-12.1.6-16.5zm-17.2-20c-16.8.8-26-1.2-38.3-10.8.2-.8 1.4-.5 1.5-1.4 18 8 40.8-3.3 59-4.9-7.9 5.1-14.6 11.6-22.2 17.1zm-12.1 33.2c-1.6-9.4-3.5-12-2.8-20.2 25-16.6 29.7 28.6 2.8 20.2zM226 438.6c-11.6-.7-48.1-14-38.5-23.7 9.4 6.5 27.5 4.9 41.3 7.3.8 4.4-2.8 10.2-2.8 16.4zM57.7 497.1c-4.3-12.7-9.2-25.1-14.8-36.9 30.8-23.8 65.3-48.9 102.2-63.5 2.8-1.1 23.2 25.4 26.2 27.6 16.5 11.7 37 21 56.2 30.2 1.2 8.8 3.9 20.2 8.7 35.5.7 2.3 1.4 4.7 2.2 7.2H57.7zm240.6 5.7h-.8c.3-.2.5-.4.8-.5v.5zm7.5-5.7c2.1-1.4 4.3-2.8 6.4-4.3 1.1 1.4 2.2 2.8 3.2 4.3h-9.6zm15.1-24.7c-10.8 7.3-20.6 18.3-33.3 25.2-6 3.3-27 11.7-33.4 10.2-3.6-.8-3.9-5.3-5.4-9.5-3.1-9-10.1-23.4-10.8-37-.8-17.2-2.5-46 16-42.4 14.9 2.9 32.3 9.7 43.9 16.1 7.1 3.9 11.1 8.6 21.9 9.5-.1 1.4-.1 2.8-.2 4.3-5.9 3.9-15.3 3.8-21.8 7.1 9.5.4 17 2.7 23.5 5.9-.1 3.4-.3 7-.4 10.6zm53.4 24.7h-14c-.1-3.2-2.8-5.8-6.1-5.8s-5.9 2.6-6.1 5.8h-17.4c-2.8-4.4-5.7-8.6-8.9-12.5 2.1-2.2 4-4.7 6-6.9 9 3.7 14.8-4.9 21.7-4.2 7.9.8 14.2 11.7 25.4 11l-.6 12.6zm8.7 0c.2-4 .4-7.8.6-11.5 15.6-7.3 29 1.3 35.7 11.5H383zm83.4-37c-2.3 11.2-5.8 24-9.9 37.1-.2-.1-.4-.1-.6-.1H428c.6-1.1 1.2-2.2 1.9-3.3-2.6-6.1-9-8.7-10.9-15.5 12.1-22.7 6.5-93.4-24.2-78.5 4.3-6.3 15.6-11.5 20.8-19.3 13 10.4 20.8 20.3 33.2 31.4 6.8 6 20 13.3 21.4 23.1.8 5.5-2.6 18.9-3.8 25.1zM222.2 130.5c5.4-14.9 27.2-34.7 45-32 7.7 1.2 18 8.2 12.2 17.7-30.2-7-45.2 12.6-54.4 33.1-8.1-2-4.9-13.1-2.8-18.8zm184.1 63.1c8.2-3.6 22.4-.7 29.6-5.3-4.2-11.5-10.3-21.4-9.3-37.7.5 0 1 0 1.4.1 6.8 14.2 12.7 29.2 21.4 41.7-5.7 13.5-43.6 25.4-43.1 1.2zm20.4-43zm-117.2 45.7c-6.8-10.9-19-32.5-14.5-45.3 6.5 11.9 8.6 24.4 17.8 33.3 4.1 4 12.2 9 8.2 20.2-.9 2.7-7.8 8.6-11.7 9.7-14.4 4.3-47.9.9-36.6-17.1 11.9.7 27.9 7.8 36.8-.8zm27.3 70c3.8 6.6 1.4 18.7 12.1 20.6 20.2 3.4 43.6-12.3 58.1-17.8 9-15.2-.8-20.7-8.9-30.5-16.6-20-38.8-44.8-38-74.7 6.7-4.9 7.3 7.4 8.2 9.7 8.7 20.3 30.4 46.2 46.3 63.5 3.9 4.3 10.3 8.4 11 11.2 2.1 8.2-5.4 18-4.5 23.5-21.7 13.9-45.8 29.1-81.4 25.6-7.4-6.7-10.3-21.4-2.9-31.1zm-201.3-9.2c-6.8-3.9-8.4-21-16.4-21.4-11.4-.7-9.3 22.2-9.3 35.5-7.8-7.1-9.2-29.1-3.5-40.3-6.6-3.2-9.5 3.6-13.1 5.9 4.7-34.1 49.8-15.8 42.3 20.3zm299.6 28.8c-10.1 19.2-24.4 40.4-54 41-.6-6.2-1.1-15.6 0-19.4 22.7-2.2 36.6-13.7 54-21.6zm-141.9 12.4c18.9 9.9 53.6 11 79.3 10.2 1.4 5.6 1.3 12.6 1.4 19.4-33 1.8-72-6.4-80.7-29.6zm92.2 46.7c-1.7 4.3-5.3 9.3-9.8 11.1-12.1 4.9-45.6 8.7-62.4-.3-10.7-5.7-17.5-18.5-23.4-26-2.8-3.6-16.9-12.9-.2-12.9 13.1 32.7 58 29 95.8 28.1z" /></svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 0 0-94.3-139.9 437.71 437.71 0 0 0-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3 0.1 19.9-16 36-35.9 36z" /></svg>

After

Width:  |  Height:  |  Size: 402 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M512 725.333333c46.933333 0 85.333333-38.4 85.333333-85.333333s-38.4-85.333333-85.333333-85.333333-85.333333 38.4-85.333333 85.333333 38.4 85.333333 85.333333 85.333333z m256-384h-42.666667v-85.333333c0-117.76-95.573333-213.333333-213.333333-213.333333S298.666667 138.24 298.666667 256v85.333333h-42.666667c-46.933333 0-85.333333 38.4-85.333333 85.333334v426.666666c0 46.933333 38.4 85.333333 85.333333 85.333334h512c46.933333 0 85.333333-38.4 85.333333-85.333334V426.666667c0-46.933333-38.4-85.333333-85.333333-85.333334z m-388.266667-85.333333c0-72.96 59.306667-132.266667 132.266667-132.266667s132.266667 59.306667 132.266667 132.266667v85.333333H379.733333v-85.333333zM768 853.333333H256V426.666667h512v426.666666z" /></svg>

After

Width:  |  Height:  |  Size: 802 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M298.666667 298.666667c17.066667 0 32-14.933333 32-32v-128c0-17.066667-14.933333-32-32-32s-32 14.933333-32 32v128c0 17.066667 14.933333 32 32 32zM576 298.666667c17.066667 0 32-14.933333 32-32v-128c0-17.066667-14.933333-32-32-32s-32 14.933333-32 32v128c0 17.066667 14.933333 32 32 32z" /><path d="M469.333333 725.333333c0-104.533333 64-196.266667 153.6-234.666666H224c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h405.333333c17.066667 0 32 14.933333 32 32 0 8.533333-4.266667 14.933333-8.533333 21.333333 23.466667-6.4 46.933333-10.666667 72.533333-10.666667 6.4 0 14.933333 0 21.333334 2.133334V277.333333c0-46.933333-38.4-85.333333-85.333334-85.333333v74.666667c0 53.333333-42.666667 96-96 96S469.333333 320 469.333333 266.666667V192h-85.333333v74.666667c0 53.333333-42.666667 96-96 96S192 320 192 266.666667V192c-46.933333 0-85.333333 38.4-85.333333 85.333333v554.666667c0 46.933333 38.4 85.333333 85.333333 85.333333h364.8c-53.333333-46.933333-87.466667-115.2-87.466667-192z m-53.333333 21.333334h-192c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h192c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32z m0-128h-192c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h192c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32z" /><path d="M725.333333 533.333333c-106.666667 0-192 87.466667-192 192s87.466667 192 192 192 192-87.466667 192-192-85.333333-192-192-192z m74.666667 256h-106.666667c-17.066667 0-32-14.933333-32-32v-128c0-17.066667 14.933333-32 32-32s32 14.933333 32 32V725.333333h74.666667c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32z" /></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 911.75 898.91"><path d="M828.52,831.72c-216,259.7-774.46,115.85-765.17-319.5-19-292.76,370.82-602.09,704.81-367.11,44.53,48.2,81.39,32.52,121.28,46.67,28.28,14.3,21.36,42.61,52.36,142.6,31.6,101.09,60.92,133.92-17.45,182.4-28,11.34-46.6-2.34-117.82-25.31-92-29.65-109-22.33-132.66-48-27.26-29.62-14.42-50.13-41.31-80.13C507.2,259.81,336.39,351,290.74,489.72c-7,26.59-20.37,92.15,8.72,162.38,25.72,62.11,71.11,95.23,99.93,115.7C554.85,878.2,781.33,840.41,828.52,831.72Zm50.11-584.95c-15.4,5.93.73,47,16,40.82C910.07,281.66,893.94,240.63,878.63,246.77Zm-152,180.06c-4.34,15.92,35.73,26.64,39.92,10.68C770.9,421.58,730.83,410.86,726.63,426.83Z" transform="translate(-62.68 -62.16)"/></svg>

After

Width:  |  Height:  |  Size: 739 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 1024"><path d="M1280 261.88V192c0-35.34-28.66-64-64-64H64C28.66 128 0 156.66 0 192v69.88c37.2 13.22 64 48.38 64 90.12s-26.8 76.9-64 90.12V640h1280v-197.88c-37.2-13.22-64-48.38-64-90.12s26.8-76.9 64-90.12zM448 512h-128V256h128v256z m256 0h-128V256h128v256z m256 0h-128V256h128v256zM0 896h128v-53.34c0-17.68 14.32-32 32-32s32 14.32 32 32V896h256v-53.34c0-17.68 14.32-32 32-32s32 14.32 32 32V896h256v-53.34c0-17.68 14.32-32 32-32s32 14.32 32 32V896h256v-53.34c0-17.68 14.32-32 32-32s32 14.32 32 32V896h128v-192H0v192z" /></svg>

After

Width:  |  Height:  |  Size: 582 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M950.784 768v72.704q0 15.36-10.24 25.6t-26.624 11.264H110.08q-15.36 0-25.6-11.264t-11.264-25.6V768q0-15.36 11.264-25.6t25.6-11.264h803.84q15.36 0 26.624 11.264t10.24 25.6z m0-292.864v73.728q0 14.336-10.24 25.6t-26.624 10.24H110.08q-15.36 0-25.6-10.24t-11.264-25.6v-73.728q0-14.336 11.264-25.6t25.6-10.24h803.84q15.36 0 26.624 10.24t10.24 25.6z m0-291.84V256q0 14.336-10.24 25.6t-26.624 11.264H110.08q-15.36 0-25.6-11.264T73.216 256V183.296q0-15.36 11.264-26.624t25.6-10.24h803.84q15.36 0 26.624 10.24t10.24 26.624z" /></svg>

After

Width:  |  Height:  |  Size: 597 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M243.2 512m-83.2 0a1.3 1.3 0 1 0 166.4 0 1.3 1.3 0 1 0-166.4 0Z" /><path d="M512 512m-83.2 0a1.3 1.3 0 1 0 166.4 0 1.3 1.3 0 1 0-166.4 0Z" /><path d="M780.8 512m-83.2 0a1.3 1.3 0 1 0 166.4 0 1.3 1.3 0 1 0-166.4 0Z" /></svg>

After

Width:  |  Height:  |  Size: 296 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M899.5 288.4L528 74c-9.9-5.7-22.1-5.7-32 0L140.3 278.9c-10 5.6-16.1 16.2-16.2 27.6l-0.1 410.6c0 11.4 6.1 22 16 27.7L512 959v0.1c20-11.4 32-32.5 32-55.3l-0.1-372.6 323.7-187.3c19.7-11.5 31.9-32.6 31.9-55.5zM188 698.7V362.4l292 168.7v335.7L188 698.7z m323.8-223L220.4 306.9 512 138.7 803.6 307 511.8 475.7z" /><path d="M928 672H800V544c0-17.7-14.3-32-32-32s-32 14.3-32 32v128H608c-17.7 0-32 14.3-32 32s14.3 32 32 32h128v128c0 17.7 14.3 32 32 32s32-14.3 32-32V736h128c17.7 0 32-14.3 32-32s-14.3-32-32-32z" /></svg>

After

Width:  |  Height:  |  Size: 584 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M739.584 575.561143A365.824 365.824 0 0 0 513.828571 950.857143H73.142857c0-242.358857 196.498286-438.857143 438.857143-438.857143 83.346286 0 161.243429 23.222857 227.584 63.561143zM512 512a219.428571 219.428571 0 1 1 0-438.857143 219.428571 219.428571 0 0 1 0 438.857143z m182.857143 146.285714h256v73.142857h-256v-73.142857z m-73.142857 109.714286h329.142857v73.142857h-329.142857v-73.142857z m-36.571429 109.714286h365.714286v73.142857H585.142857v-73.142857z" /></svg>

After

Width:  |  Height:  |  Size: 545 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M810.666667 384a128 128 0 0 0-120.32 85.333333H128a42.666667 42.666667 0 0 0 0 85.333334h562.346667A128 128 0 1 0 810.666667 384zM128 298.666667h50.346667a128 128 0 0 0 240.64 0H896a42.666667 42.666667 0 0 0 0-85.333334H418.986667a128 128 0 0 0-240.64 0H128a42.666667 42.666667 0 0 0 0 85.333334zM896 725.333333h-306.346667a128 128 0 0 0-240.64 0H128a42.666667 42.666667 0 0 0 0 85.333334h221.013333a128 128 0 0 0 240.64 0H896a42.666667 42.666667 0 0 0 0-85.333334z" /></svg>

After

Width:  |  Height:  |  Size: 548 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M768 426.666667V341.333333A256 256 0 0 0 256 341.333333v85.333334a85.333333 85.333333 0 0 0-85.333333 85.333333v341.333333a85.333333 85.333333 0 0 0 85.333333 85.333334h512a85.333333 85.333333 0 0 0 85.333333-85.333334v-341.333333a85.333333 85.333333 0 0 0-85.333333-85.333333zM341.333333 341.333333a170.666667 170.666667 0 0 1 341.333334 0v85.333334H341.333333z m298.666667 320a21.333333 21.333333 0 0 1 21.333333-21.333333h42.666667a21.333333 21.333333 0 0 1 21.333333 21.333333v42.666667a21.333333 21.333333 0 0 1-21.333333 21.333333h-42.666667a21.333333 21.333333 0 0 1-21.333333-21.333333z m-170.666667 0a21.333333 21.333333 0 0 1 21.333334-21.333333h42.666666a21.333333 21.333333 0 0 1 21.333334 21.333333v42.666667a21.333333 21.333333 0 0 1-21.333334 21.333333h-42.666666a21.333333 21.333333 0 0 1-21.333334-21.333333z m-170.666666 42.666667v-42.666667a21.333333 21.333333 0 0 1 21.333333-21.333333h42.666667a21.333333 21.333333 0 0 1 21.333333 21.333333v42.666667a21.333333 21.333333 0 0 1-21.333333 21.333333h-42.666667a21.333333 21.333333 0 0 1-21.333333-21.333333z" /></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M853.333333 554.666667 554.666667 554.666667l0 298.666667c0 23.466667-19.2 42.666667-42.666667 42.666667s-42.666667-19.2-42.666667-42.666667L469.333333 554.666667 170.666667 554.666667c-23.466667 0-42.666667-19.2-42.666667-42.666667 0-23.466667 19.2-42.666667 42.666667-42.666667l298.666667 0L469.333333 170.666667c0-23.466667 19.2-42.666667 42.666667-42.666667s42.666667 19.2 42.666667 42.666667l0 298.666667 298.666667 0c23.466667 0 42.666667 19.2 42.666667 42.666667C896 535.466667 876.8 554.666667 853.333333 554.666667z" /></svg>

After

Width:  |  Height:  |  Size: 607 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M955.136 551.488a64 64 0 0 1-13.888 69.76l-128 128A63.829333 63.829333 0 0 1 768 768a63.829333 63.829333 0 0 1-45.248-18.752l-128-128a64.106667 64.106667 0 0 1-13.888-69.76A64.042667 64.042667 0 0 1 640 512h64c0-141.376-114.624-256-256-256S192 370.624 192 512s114.624 256 256 256c33.344 0 64.896-6.784 94.144-18.368l96.512 95.36A381.802667 381.802667 0 0 1 448 896c-212.032 0-384-171.968-384-384S235.968 128 448 128s384 171.968 384 384h64c25.856 0 49.28 15.616 59.136 39.488z" /></svg>

After

Width:  |  Height:  |  Size: 558 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M721.8 326.1c0-124.4-100.8-225.2-225.2-225.2S271.3 201.7 271.3 326.1c0 82.2 44 154.1 109.8 193.4-14.1 4.2-28.1 9.2-41.8 15-46.9 19.8-89.1 48.3-125.3 84.4s-64.6 78.3-84.4 125.3c-20.6 48.6-31 100.2-31 153.4 0 13.3 10.7 24 24 24s24-10.7 24-24c0-190.8 155.3-346.1 346.1-346.1 1 0 1.9-0.1 2.9-0.2h1c124.3 0.1 225.2-100.8 225.2-225.2z m-402.5 0c0-47.3 18.4-91.9 51.9-125.3 33.5-33.5 78-51.9 125.3-51.9s91.9 18.4 125.3 51.9c33.5 33.5 51.9 78 51.9 125.3s-18.4 91.9-51.9 125.3-78 51.9-125.3 51.9-91.9-18.4-125.3-51.9c-33.5-33.4-51.9-77.9-51.9-125.3zM905.3 679.7h-32.2v-18c0-76.6-62.4-139-139-139s-139 62.4-139 139v18h-23.8c-13.3 0-24 10.7-24 24v144.5c0 41.1 33.4 74.5 74.5 74.5h233c41.1 0 74.5-33.4 74.5-74.5V703.7c0-13.3-10.7-24-24-24z m-262.2-18c0-50.2 40.8-91 91-91s91 40.8 91 91v18h-182v-18z m238.2 186.4c0 14.6-11.9 26.5-26.5 26.5h-233c-14.6 0-26.5-11.9-26.5-26.5V727.7h286v120.4z" /><path d="M782.3 754.1h-88c-8.3 0-15 6.7-15 15s6.7 15 15 15h29v48.4c0 8.3 6.7 15 15 15s15-6.7 15-15v-48.4h29c8.3 0 15-6.7 15-15s-6.7-15-15-15z" /></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M512 78.869333l21.162667 12.096c69.717333 39.829333 150.677333 65.344 215.466666 80.874667 32.149333 7.722667 59.776 12.864 79.274667 16.064a824.981333 824.981333 0 0 0 28.437333 4.16l1.386667 0.170667 0.32 0.021333L896 196.48v361.728l-0.576 3.477333L853.333333 554.666667c42.090667 7.018667 42.069333 7.04 42.069334 7.061333v0.064l-0.021334 0.106667-0.064 0.32-0.170666 0.917333-0.554667 2.922667c-0.490667 2.410667-1.216 5.76-2.218667 9.898666-2.026667 8.277333-5.226667 19.861333-10.005333 33.856a495.445333 495.445333 0 0 1-51.797333 106.666667c-52.736 82.112-146.069333 174.869333-306.773334 221.098667l-11.797333 3.413333-11.797333-3.413333c-160.704-46.229333-254.037333-138.986667-306.773334-221.12a495.573333 495.573333 0 0 1-51.797333-106.645334 394.709333 394.709333 0 0 1-10.005333-33.856 262.250667 262.250667 0 0 1-2.773334-12.8l-0.192-0.938666-0.042666-0.32-0.021334-0.106667v-0.064c0-0.021333 0-0.042667 42.069334-7.061333l-42.090667 7.018666L128 558.208V196.48l37.952-4.224 0.32-0.021333 1.386667-0.170667 5.824-0.768c5.184-0.704 12.864-1.813333 22.613333-3.413333 19.498667-3.2 47.146667-8.32 79.274667-16.042667 64.768-15.530667 145.749333-41.045333 215.466666-80.874667L512 78.869333z m-298.666667 192.661334v278.976a310.4 310.4 0 0 0 9.045334 31.701333c7.765333 22.72 21.056 54.186667 42.858666 88.149333 42.026667 65.408 116.16 141.013333 246.762667 181.696 130.602667-40.661333 204.757333-116.288 246.762667-181.696a410.304 410.304 0 0 0 42.88-88.149333A309.76 309.76 0 0 0 810.666667 550.506667V271.530667c-20.906667-3.477333-49.28-8.853333-81.962667-16.704C666.154667 239.786667 586.026667 215.338667 512 176.618667c-74.026667 38.72-154.176 63.189333-216.704 78.208-32.704 7.850667-61.077333 13.226667-81.962667 16.704z m517.098667 146.154666L486.933333 661.184 328.746667 503.04l60.352-60.330667 97.834666 97.813334 183.146667-183.146667 60.352 60.330667z" /></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" ><path d="M931.882 259.882l-167.764-167.764A96 96 0 0 0 696.236 64H160C106.98 64 64 106.98 64 160v704c0 53.02 42.98 96 96 96h704c53.02 0 96-42.98 96-96V327.764a96 96 0 0 0-28.118-67.882zM512 832c-70.692 0-128-57.308-128-128 0-70.692 57.308-128 128-128s128 57.308 128 128c0 70.692-57.308 128-128 128z m192-609.04V424c0 13.254-10.746 24-24 24H216c-13.254 0-24-10.746-24-24V216c0-13.254 10.746-24 24-24h457.04c6.366 0 12.47 2.528 16.97 7.03l6.96 6.96A23.992 23.992 0 0 1 704 222.96z" /></svg>

After

Width:  |  Height:  |  Size: 553 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M962.56 972.8L61.44 972.8C30.72 972.8 0 942.08 0 911.36c0-40.96 30.72-61.44 61.44-61.44l51.2-1e-8 235.52-665.59999999c20.47999999-81.92 102.4-143.36 194.56-122.88 61.44000001 10.24 112.64 61.44 122.88 122.88l235.52 665.59999999 51.2 1e-8c40.96 0 71.68 20.47999999 71.68 61.44 0 30.72-30.72 61.44-61.44 61.44zM512 819.2c30.72 0 61.44-20.47999999 61.44-61.44 0-30.72-30.72-61.44-61.44-71.68-30.72 0-61.44 30.72-61.44 61.44 0 40.96 20.47999999 61.44 61.44 71.68z m0-512c-40.96 0-61.44 20.47999999-61.44000001 51.2l1e-8 30.72S481.28 614.4 512 604.15999999c20.48 10.24 61.44-215.04 61.44-215.03999999L573.44000001 358.4c0-40.96-30.72-61.44-61.44000001-51.2z" /></svg>

After

Width:  |  Height:  |  Size: 735 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M512.571429 373.257143c-34.171429 0-66.171429 13.257143-90.4 37.485714-24.114286 24.228571-37.485714 56.228571-37.485715 90.4 0 34.171429 13.371429 66.171429 37.485715 90.4 24.228571 24.114286 56.228571 37.485714 90.4 37.485714 34.171429 0 66.171429-13.371429 90.4-37.485714 24.114286-24.228571 37.485714-56.228571 37.485714-90.4 0-34.171429-13.371429-66.171429-37.485714-90.4a126.811429 126.811429 0 0 0-90.4-37.485714z m471.2 269.142857l-74.742858-63.885714c3.542857-21.714286 5.371429-43.885714 5.371429-65.942857s-1.828571-44.342857-5.371429-65.942858l74.742858-63.885714a36.605714 36.605714 0 0 0 10.628571-40.228571l-1.028571-2.971429a505.714286 505.714286 0 0 0-90.971429-157.371428l-2.057143-2.4a36.708571 36.708571 0 0 0-40.114286-10.857143l-92.8 33.028571c-34.285714-28.114286-72.457143-50.285714-113.828571-65.714286l-17.942857-97.028571a36.628571 36.628571 0 0 0-29.485714-29.371429l-3.085715-0.571428c-59.428571-10.742857-122.057143-10.742857-181.485714 0l-3.085714 0.571428a36.628571 36.628571 0 0 0-29.485715 29.371429l-18.057142 97.485714a403.931429 403.931429 0 0 0-113.028572 65.485715l-93.485714-33.257143a36.571429 36.571429 0 0 0-40.114286 10.857143l-2.057143 2.4a509.634286 509.634286 0 0 0-90.971428 157.371428l-1.028572 2.971429c-5.142857 14.285714-0.914286 30.285714 10.628572 40.228571l75.657143 64.571429c-3.542857 21.485714-5.257143 43.428571-5.257143 65.142857 0 21.942857 1.714286 43.885714 5.257143 65.142857l-75.428572 64.571429a36.605714 36.605714 0 0 0-10.628571 40.228571l1.028571 2.971429c20.685714 57.485714 51.2 110.628571 90.971429 157.371428l2.057143 2.4a36.708571 36.708571 0 0 0 40.114285 10.857143l93.485715-33.257143c34.057143 28 72 50.171429 113.028571 65.485714l18.057143 97.485715a36.628571 36.628571 0 0 0 29.485714 29.371428l3.085714 0.571429a512.308571 512.308571 0 0 0 181.485715 0l3.085714-0.571429a36.628571 36.628571 0 0 0 29.485714-29.371428l17.942857-97.028572c41.371429-15.542857 79.542857-37.6 113.828572-65.714285l92.8 33.028571a36.571429 36.571429 0 0 0 40.114286-10.857143l2.057142-2.4c39.771429-46.971429 70.285714-99.885714 90.971429-157.371428l1.028571-2.971429c4.914286-14.171429 0.685714-30.057143-10.857142-40z m-471.2 59.657143c-110.971429 0-200.914286-89.942857-200.914286-200.914286s89.942857-200.914286 200.914286-200.914286 200.914286 89.942857 200.914285 200.914286-89.942857 200.914286-200.914285 200.914286z" /></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M1001.627381 394.106435a44.521739 44.521739 0 1 1-88.598261 0V208.228174l-398.914783 398.914783a54.049391 54.049391 0 1 1-76.577391-76.310261l397.579131-397.490087h-182.984348a44.78887 44.78887 0 1 1 0-89.043479h298.740869c1.335652 0 2.226087 0.534261 3.561739 0.623305s1.78087-0.623304 2.671305-0.623305a40.069565 40.069565 0 0 1 27.158261 11.620174c1.157565 0.667826 2.226087 1.513739 3.116521 2.448696 0.890435 0.979478 1.78087 2.092522 2.671305 3.161043a41.360696 41.360696 0 0 1 11.575652 27.158261c0 0.979478-0.445217 1.825391-0.445218 2.80487s0.445217 2.359652 0.445218 3.650783v298.963478zM111.192598 934.956522h712.347826v-400.695652h89.043479v400.695652a89.043478 89.043478 0 0 1-89.043479 89.043478H111.192598a89.043478 89.043478 0 0 1-89.043478-89.043478V222.608696a89.043478 89.043478 0 0 1 89.043478-89.043479h400.695652v89.043479H111.192598v712.347826z" /></svg>

After

Width:  |  Height:  |  Size: 950 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M832 106.666667H192C144.853333 106.666667 106.666667 144.853333 106.666667 192v128h810.666666V192c0-47.146667-38.186667-85.333333-85.333333-85.333333zM106.666667 384v448c0 47.146667 38.186667 85.333333 85.333333 85.333333h640c47.146667 0 85.333333-38.186667 85.333333-85.333333V384H106.666667z m278.613333 338.986667c12.586667 12.586667 12.586667 32.853333 0 45.226666-12.586667 12.586667-32.853333 12.586667-45.226667 0l-105.6-105.6a31.786667 31.786667 0 0 1 0-45.226666l105.6-105.6a31.786667 31.786667 0 0 1 45.226667 0c12.586667 12.586667 12.586667 32.853333 0 45.226666L302.293333 640l82.986667 82.986667z m186.88-212.053334l-57.6 271.36c-3.626667 17.28-20.693333 28.373333-37.973333 24.746667-17.28-3.626667-28.373333-20.693333-24.746667-37.973333l57.6-271.36c3.626667-17.28 20.693333-28.373333 37.973333-24.746667 17.28 3.84 28.373333 20.693333 24.746667 37.973333z m217.386667 151.68l-105.6 105.6c-12.586667 12.586667-32.853333 12.586667-45.226667 0a31.786667 31.786667 0 0 1 0-45.226666L721.706667 640l-82.986667-82.986667a31.786667 31.786667 0 0 1 0-45.226666 31.786667 31.786667 0 0 1 45.226667 0l105.6 105.6c12.586667 12.586667 12.586667 32.64 0 45.226666z" /></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M42.666667 149.482667A106.752 106.752 0 0 1 149.482667 42.666667h725.034666A106.752 106.752 0 0 1 981.333333 149.482667v725.034666A106.752 106.752 0 0 1 874.517333 981.333333H149.482667A106.752 106.752 0 0 1 42.666667 874.517333V149.482667z m85.333333 0v725.034666C128 886.421333 137.578667 896 149.482667 896h725.034666c11.904 0 21.482667-9.578667 21.482667-21.482667V149.482667C896 137.578667 886.421333 128 874.517333 128H149.482667C137.578667 128 128 137.578667 128 149.482667zM661.333333 213.333333a42.666667 42.666667 0 1 1 85.333334 0v106.666667c0 129.536-105.088 234.666667-234.666667 234.666667-129.536 0-234.666667-105.216-234.666667-234.666667v-106.666667a42.666667 42.666667 0 1 1 85.333334 0v106.666667c0 82.346667 66.944 149.333333 149.333333 149.333333 82.453333 0 149.333333-66.922667 149.333333-149.333333v-106.666667z" /></svg>

After

Width:  |  Height:  |  Size: 918 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M846.208 435.498667A260.565333 260.565333 0 0 0 781.098667 426.666667V377.429333a21.333333 21.333333 0 0 0-21.333334-21.333333H260.181333a21.333333 21.333333 0 0 0-21.333333 21.333333v306.346667a21.333333 21.333333 0 0 0 21.333333 21.333333h275.072c4.437333 22.229333 12.16 43.349333 22.698667 62.890667H213.333333a42.666667 42.666667 0 0 1-42.666666-42.666667V256a42.666667 42.666667 0 0 1 42.666666-42.666667h590.208a42.666667 42.666667 0 0 1 42.666667 42.666667v179.498667zM274.261333 315.733333c19.882667 0 36.010667-15.274667 36.010667-34.133333 0-18.858667-16.128-34.133333-36.010667-34.133333-19.925333 0-36.053333 15.274667-36.053333 34.133333 0 18.858667 16.128 34.133333 36.053333 34.133333z m112.597334 0c19.882667 0 36.010667-15.274667 36.010666-34.133333 0-18.858667-16.128-34.133333-36.010666-34.133333-19.925333 0-36.053333 15.274667-36.053334 34.133333 0 18.858667 16.128 34.133333 36.053334 34.133333z m589.653333 307.242667c2.901333 12.202667 3.84 25.386667 4.821333 38.570667 0 12.202667-0.981333 24.405333-3.84 38.528v0.938666a26.325333 26.325333 0 0 1-12.586666 14.08c-0.938667 0.981333-0.938667 0.981333-1.92 0.981334-17.365333 4.693333-31.829333 15.018667-39.552 28.16a63.573333 63.573333 0 0 0-5.802667 49.877333c2.901333 7.509333 0 16.896-6.741333 20.650667-18.346667 15.061333-39.594667 27.306667-64.682667 37.632-1.92 0.938667-4.821333 0.938667-6.741333 0.938666-4.821333 0-9.642667-2.816-13.525334-6.570666-13.482667-13.184-28.928-20.693333-45.354666-20.693334a59.733333 59.733333 0 0 0-45.354667 19.754667 22.4 22.4 0 0 1-15.445333 6.570667h-2.901334c-1.92 0-2.858667-0.938667-3.84-0.938667a178.346667 178.346667 0 0 1-66.56-38.570667c-6.826667-5.632-8.704-14.08-5.845333-20.650666a56.021333 56.021333 0 0 0-5.76-47.957334c-9.642667-16-22.186667-25.386667-39.594667-29.141333h-0.938666a18.048 18.048 0 0 1-14.506667-16 160.64 160.64 0 0 1-3.84-37.589333c0-12.245333 0.981333-24.448 3.84-38.570667v-0.938667a26.325333 26.325333 0 0 1 12.586667-14.08c0.938667-0.981333 0.938667-0.981333 1.92-0.981333 17.365333-4.693333 31.829333-15.018667 39.552-28.16a63.573333 63.573333 0 0 0 5.802666-49.877333 17.578667 17.578667 0 0 1 6.741334-20.650667c18.346667-15.061333 39.594667-27.306667 64.682666-37.632a19.370667 19.370667 0 0 1 21.205334 4.693333c13.525333 13.184 28.970667 20.693333 45.354666 20.693334 18.346667 0 34.773333-6.570667 45.354667-19.754667 6.784-6.570667 14.506667-8.448 21.248-5.632a182.144 182.144 0 0 1 65.621333 38.570667c6.784 5.632 8.704 14.08 5.802667 20.650666-5.802667 16-2.901333 33.877333 5.802667 47.957334 9.642667 16 22.186667 25.386667 39.552 29.141333h0.981333a18.048 18.048 0 0 1 14.464 16zM778.666667 725.333333c37.632 0 67.541333-28.330667 67.541333-64s-29.866667-64-67.541333-64c-37.632 0-67.541333 28.330667-67.541334 64s29.866667 64 67.541334 64z" /></svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M832 96H192c-52.935 0-96 43.065-96 96v640c0 52.935 43.065 96 96 96h640c52.935 0 96-43.065 96-96V192c0-52.935-43.065-96-96-96z m-640 64h640c17.645 0 32 14.355 32 32v160H160V192c0-17.645 14.355-32 32-32z m-32 672V416h192v448H192c-17.645 0-32-14.355-32-32z m672 32H416V416h448v416c0 17.645-14.355 32-32 32z" /></svg>

After

Width:  |  Height:  |  Size: 386 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M725.333333 85.333333v85.333334h-42.666666v597.333333c0 94.293333-76.373333 170.666667-170.666667 170.666667s-170.666667-76.373333-170.666667-170.666667V170.666667H298.666667V85.333333h426.666666z m-170.666666 554.666667a42.666667 42.666667 0 1 0 0 85.333333 42.666667 42.666667 0 0 0 0-85.333333z m-85.333334-128a42.666667 42.666667 0 1 0 0 85.333333 42.666667 42.666667 0 0 0 0-85.333333z m128-341.333333h-170.666666v170.666666h170.666666V170.666667z" /></svg>

After

Width:  |  Height:  |  Size: 535 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1026 1024"><path d="M942.622517 803.602649c-10.172185-20.344371-30.516556-33.907285-54.251656-33.907285h-30.516556l-250.913908-250.913907 20.344371-20.344371c10.172185-10.172185 13.562914-20.344371 13.562914-33.907285s-3.390728-23.735099-13.562914-33.907284c-27.125828-27.125828-50.860927-40.688742-74.596026-50.860928-20.344371-6.781457-37.298013-20.344371-44.07947-40.688741-10.172185-27.125828-23.735099-50.860927-50.860928-74.596027L230.569536 33.907285C206.834437 13.562914 176.317881 0 145.801325 0c-33.907285 0-64.423841 13.562914-84.768212 33.907285l-27.125828 27.125828c-20.344371 20.344371-33.907285 50.860927-33.907285 84.768212 0 30.516556 13.562914 61.033113 33.907285 84.768211l227.178808 227.178808c27.125828 27.125828 50.860927 40.688742 74.596026 50.860928 20.344371 6.781457 37.298013 23.735099 44.07947 44.07947 10.172185 27.125828 23.735099 50.860927 50.860928 77.986755 10.172185 10.172185 20.344371 13.562914 33.907284 13.562914s23.735099-3.390728 33.907285-13.562914l20.344371-20.344371 250.913907 250.913907v30.516556c0 23.735099 13.562914 44.07947 33.907285 54.251656l145.801325 74.596027c3.390728 0 3.390728 3.390728 6.781456 3.390728s10.172185-3.390728 13.562914-3.390728l44.079471-44.079471c6.781457-6.781457 6.781457-13.562914 3.390728-20.344371l-74.596026-152.582781zM457.748344 674.754967c-16.953642-3.390728-33.907285-10.172185-47.470198-23.735099-30.516556-30.516556-50.860927-61.033113-61.033113-91.549669 0-3.390728-3.390728-6.781457-3.390728-10.172186-3.390728-3.390728-6.781457-6.781457-13.562914-6.781457s-10.172185 0-13.562914 6.781457l-23.7351 27.125828c-23.735099 20.344371-54.251656 33.907285-91.549668 33.907285-118.675497 0-203.443709 81.377483-203.443709 196.662251 0 6.781457 0 13.562914 3.390728 20.344371v3.390729c0 6.781457 3.390728 10.172185 10.172186 13.562914 3.390728 3.390728 10.172185 3.390728 16.953642 0L169.536424 759.523179c37.298013 20.344371 64.423841 57.642384 67.814569 98.331126L88.15894 949.403974c-3.390728 3.390728-6.781457 6.781457-6.781457 13.562913s3.390728 10.172185 6.781457 13.562914c37.298013 27.125828 77.986755 40.688742 122.066226 40.688742 50.860927 0 105.112583-23.735099 142.410596-67.814569 47.470199-50.860927 67.81457-98.331126 64.423841-149.192053 0-30.516556 13.562914-61.033113 37.298013-88.158941l10.172185-10.172185c3.390728-3.390728 6.781457-10.172185 3.390729-16.953643 0-6.781457-6.781457-10.172185-10.172186-10.172185z m-247.523178 325.509934zM562.860927 349.245033c30.516556 10.172185 61.033113 30.516556 88.158941 57.642384 13.562914 13.562914 20.344371 27.125828 23.735099 44.07947 0 6.781457 6.781457 10.172185 10.172185 13.562914h6.781457c3.390728 0 10.172185-3.390728 13.562914-6.781457l61.033113-64.423841c16.953642 3.390728 33.907285 6.781457 50.860927 6.781457 61.033113 0 115.284768-23.735099 152.582781-61.033112 30.516556-33.907285 50.860927-84.768212 47.470199-142.410596 0-6.781457-3.390728-10.172185-10.172185-13.562914-6.781457-3.390728-10.172185-3.390728-16.953643 0l-118.675496 71.205298c-37.298013-20.344371-64.423841-57.642384-67.81457-98.331126l132.238411-81.377484c3.390728-3.390728 6.781457-6.781457 6.781457-13.562913s-3.390728-10.172185-6.781457-13.562914C901.933775 16.953642 857.854305 0 806.993377 0s-105.112583 23.735099-142.410596 64.423841c-47.470199 50.860927-67.81457 98.331126-67.814569 149.192053 0 30.516556-13.562914 61.033113-37.298013 84.768212l-13.562914 13.562914c0 6.781457-3.390728 13.562914-3.390729 16.953642s3.390728 10.172185 3.390729 13.562914c6.781457 3.390728 10.172185 3.390728 16.953642 6.781457z" /></svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M512 725.333333c47.146667 0 85.333333-38.186667 85.333333-85.333333s-38.186667-85.333333-85.333333-85.333333-85.333333 38.186667-85.333333 85.333333 38.186667 85.333333 85.333333 85.333333z m256-384h-42.666667v-85.333333c0-117.76-95.573333-213.333333-213.333333-213.333333S298.666667 138.24 298.666667 256h81.066666c0-72.96 59.306667-132.266667 132.266667-132.266667 72.96 0 132.266667 59.306667 132.266667 132.266667v85.333333H256c-47.146667 0-85.333333 38.186667-85.333333 85.333334v426.666666c0 47.146667 38.186667 85.333333 85.333333 85.333334h512c47.146667 0 85.333333-38.186667 85.333333-85.333334V426.666667c0-47.146667-38.186667-85.333333-85.333333-85.333334z m0 512H256V426.666667h512v426.666666z" /></svg>

After

Width:  |  Height:  |  Size: 788 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M837.008696 338.365217 583.234783 84.591304c-24.486957-24.486957-66.782609-24.486957-91.269565 0L235.965217 338.365217c-17.808696 17.808696-24.486957 46.747826-13.356522 71.234783 11.130435 24.486957 33.391304 40.069565 60.104348 40.069565l91.269565 0L373.982609 645.565217l46.747826 0L420.730435 402.921739l-135.791304 0c-11.130435 0-15.582609-8.904348-17.808696-11.130435-2.226087-2.226087-4.452174-13.356522 4.452174-20.034783L523.130435 115.756522C527.582609 113.530435 532.034783 111.304348 536.486957 111.304348s8.904348 2.226087 13.356522 4.452174l256 256c8.904348 8.904348 4.452174 17.808696 4.452174 20.034783-2.226087 2.226087-6.678261 11.130435-17.808696 11.130435l-135.791304 0 0 289.391304c0 2.226087-2.226087 2.226087-2.226087 2.226087L373.982609 694.53913l0 46.747826 278.26087 0c26.713043 0 48.973913-22.26087 48.973913-48.973913L701.217391 449.669565l91.269565 0c26.713043 0 48.973913-15.582609 60.104348-40.069565C861.495652 385.113043 857.043478 358.4 837.008696 338.365217L837.008696 338.365217zM837.008696 338.365217M714.573913 839.234783c0 15.582609-11.130435 26.713043-26.713043 26.713043L394.017391 865.947826c-15.582609 0-26.713043-11.130435-26.713043-26.713043l0 0c0-15.582609 11.130435-26.713043 26.713043-26.713043l293.843478 0C703.443478 812.521739 714.573913 823.652174 714.573913 839.234783L714.573913 839.234783 714.573913 839.234783zM714.573913 839.234783M670.052174 946.086957c0 11.130435-8.904348 22.26087-20.034783 22.26087l-220.382609 0c-11.130435 0-20.034783-8.904348-20.034783-22.26087l0 0c0-11.130435 8.904348-22.26087 20.034783-22.26087l220.382609 0C661.147826 923.826087 670.052174 934.956522 670.052174 946.086957L670.052174 946.086957 670.052174 946.086957zM670.052174 946.086957" /></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M707.797333 304.426667c0-114.218667-93.354667-206.805333-208.512-206.805334-115.157333 0-208.512 92.586667-208.512 206.805334 0 114.218667 93.354667 206.805333 208.512 206.805333 115.2 0 208.512-92.586667 208.512-206.805333m292.053334 656c1.365333 4.437333 2.304 9.088 2.304 13.994666 0 26.88-21.930667 48.725333-49.024 48.725334a48.853333 48.853333 0 0 1-48.981334-48.725334v-0.170666h-1.28c-12.757333-203.904-182.741333-365.482667-391.168-365.482667-208.469333 0-378.453333 161.578667-391.253333 365.482667h-1.109333v0.170666c0 26.88-21.930667 48.725333-48.981334 48.725334A48.853333 48.853333 0 0 1 21.333333 974.421333c0-4.608 0.853333-8.96 2.048-13.226666 14.250667-185.045333 131.882667-341.248 296.149334-410.88C243.2 494.976 193.28 405.589333 193.28 304.426667 193.28 136.32 330.453333 0 499.626667 0c169.216 0 306.346667 136.32 306.346666 304.426667a302.933333 302.933333 0 0 1-118.186666 239.914666c172.202667 66.005333 297.088 225.536 312.064 416.085334" /></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1,103 @@
import { ATABootstrapConfig, setupTypeAcquisition } from '@typescript/ata'
type DelegateListener = Required<{
[k in keyof ATABootstrapConfig['delegate']]: Set<NonNullable<ATABootstrapConfig['delegate'][k]>>
}>
const createDelegate = (): DelegateListener => {
return {
receivedFile: new Set(),
progress: new Set(),
errorMessage: new Set(),
finished: new Set(),
started: new Set()
}
}
const delegateListener = createDelegate()
type InferSet<T> = T extends Set<infer U> ? U : never
export interface TypeHelper {
dispose: () => void
acquireType: (code: string) => void
removeListener: <T extends keyof DelegateListener>(
event: T,
handler: InferSet<DelegateListener[T]>
) => void
addListener: <T extends keyof DelegateListener>(
event: T,
handler: InferSet<DelegateListener[T]>
) => void
}
export const createATA = async (): Promise<TypeHelper> => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const ts = await import('https://esm.sh/typescript@5.3.3')
const ata = setupTypeAcquisition({
projectName: 'monaco-ts',
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
typescript: ts,
logger: console,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
fetcher: (input, init) => {
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
return fetch(input, init)
} catch (error) {
console.error('Error fetching data:', error)
}
return new Promise(() => {})
},
delegate: {
receivedFile: (code, path) => {
delegateListener.receivedFile.forEach((fn) => fn(code, path))
},
started: () => {
delegateListener.started.forEach((fn) => fn())
},
progress: (downloaded, estimatedTotal) => {
delegateListener.progress.forEach((fn) => fn(downloaded, estimatedTotal))
},
finished: (files) => {
delegateListener.finished.forEach((fn) => fn(files))
}
}
})
const acquireType = (code: string) => ata(code)
const addListener = <T extends keyof DelegateListener>(
event: T,
handler: InferSet<DelegateListener[T]>
) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
delegateListener[event].add(handler)
}
const removeListener = <T extends keyof DelegateListener>(
event: T,
handler: InferSet<DelegateListener[T]>
) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
delegateListener[event].delete(handler)
}
const dispose = () => {
for (const key in delegateListener) {
delegateListener[key as keyof DelegateListener].clear()
}
}
return {
acquireType,
addListener,
removeListener,
dispose
}
}

View File

@@ -0,0 +1,98 @@
@mixin keyframes($animationName) {
@-webkit-keyframes #{$animationName} {
@content
}
@-moz-keyframes #{$animationName} {
@content
}
@-o-keyframes #{$animationName} {
@content
}
@keyframes #{$animationName} {
@content
}
}
@mixin unique-keyframes {
$animationName: unique-id();
animation-name: $animationName;
@include keyframes($animationName) {
@content
}
}
[data-component=playground-code-editor-editor] {
position: relative;
height: 0;
.monaco-editor-light {
height: 100%;
overflow: hidden;
background-color: var(--border);
.jsx-tag-angle-bracket {
color: #800000;
}
.jsx-text {
color: #000;
}
.jsx-tag-name {
color: #800000;
}
.jsx-tag-attribute-key {
color: #f00;
}
}
.monaco-editor-vs-dark {
height: 100%;
overflow: hidden;
background-color: var(--border);
.jsx-tag-angle-bracket {
color: #808080;
}
.jsx-text {
color: #d4d4d4;
}
.jsx-tag-name {
color: #569cd6;
}
.jsx-tag-attribute-key {
color: #9cdcfe;
}
}
.playground-code-editor-loading {
position: absolute;
top: 0;
right: 0;
margin: 4px;
width: 10px;
height: 10px;
border-radius: 50%;
border: {
top: 2px #666 solid;
bottom: 2px #ddd solid;
left: 2px #ddd solid;
right: 2px #ddd solid;
};
animation: .6s linear infinite;
@include unique-keyframes {
0% {
transform: rotateZ(0);
}
100% {
transform: rotateZ(360deg);
}
}
}
}

View File

@@ -0,0 +1,111 @@
import { editor, IPosition, Selection } from 'monaco-editor'
import ScrollType = editor.ScrollType
import { Monaco } from '@monaco-editor/react'
import { getWorker, MonacoJsxSyntaxHighlight } from 'monaco-jsx-syntax-highlight'
import { createATA, TypeHelper } from '@/components/Playground/CodeEditor/Editor/ata'
export const useEditor = () => {
const doOpenEditor = (
editor: editor.IStandaloneCodeEditor,
input: { options: { selection: Selection } }
) => {
const selection = input.options ? input.options.selection : null
if (selection) {
if (
typeof selection.endLineNumber === 'number' &&
typeof selection.endColumn === 'number'
) {
editor.setSelection(selection)
editor.revealRangeInCenter(selection, ScrollType.Immediate)
} else {
const position: IPosition = {
lineNumber: selection.startLineNumber,
column: selection.startColumn
}
editor.setPosition(position)
editor.revealPositionInCenter(position, ScrollType.Immediate)
}
}
}
const loadJsxSyntaxHighlight = (editor: editor.IStandaloneCodeEditor, monaco: Monaco) => {
const monacoJsxSyntaxHighlight = new MonacoJsxSyntaxHighlight(getWorker(), monaco)
const { highlighter, dispose } = monacoJsxSyntaxHighlight.highlighterBuilder({ editor })
editor.onDidChangeModelContent(() => {
highlighter()
})
highlighter()
return { highlighter, dispose }
}
const autoLoadExtraLib = async (
editor: editor.IStandaloneCodeEditor,
monaco: Monaco,
defaultValue: string,
onWatch: (typeHelper: TypeHelper) => () => void
) => {
const typeHelper = await createATA()
onWatch(typeHelper)
typeHelper.acquireType(`import React from 'react'`)
editor.onDidChangeModelContent(() => {
typeHelper.acquireType(editor.getValue())
})
const addLibraryToRuntime = (code: string, path: string) => {
monaco.languages.typescript.typescriptDefaults.addExtraLib(code, `file://${path}`)
}
typeHelper.addListener('receivedFile', addLibraryToRuntime)
typeHelper.acquireType(defaultValue)
return typeHelper
}
return {
doOpenEditor,
loadJsxSyntaxHighlight,
autoLoadExtraLib
}
}
export const useTypesProgress = () => {
const [progress, setProgress] = useState(0)
const [total, setTotal] = useState(0)
const [finished, setFinished] = useState(false)
const onWatch = (typeHelper: TypeHelper) => {
const handleStarted = () => {
setFinished(false)
}
typeHelper.addListener('started', handleStarted)
const handleProgress = (progress: number, total: number) => {
setProgress(progress)
setTotal(total)
}
typeHelper.addListener('progress', handleProgress)
const handleFinished = () => {
setFinished(true)
}
typeHelper.addListener('progress', handleFinished)
return () => {
typeHelper.removeListener('started', handleStarted)
typeHelper.removeListener('progress', handleProgress)
typeHelper.removeListener('finished', handleFinished)
}
}
return {
progress,
total,
finished,
onWatch
}
}

View File

@@ -0,0 +1,127 @@
import { editor, Selection } from 'monaco-editor'
import MonacoEditor, { Monaco } from '@monaco-editor/react'
import '@/components/Playground/CodeEditor/Editor/editor.scss'
import '@/components/Playground/CodeEditor/Editor/loader'
import { IEditorOptions, IFiles, ITheme, ITsconfig } from '@/components/Playground/shared'
import { fileNameToLanguage, tsconfigJsonDiagnosticsOptions } from '@/components/Playground/files'
import { useEditor, useTypesProgress } from '@/components/Playground/CodeEditor/Editor/hooks'
import { MonacoEditorConfig } from '@/components/Playground/CodeEditor/Editor/monacoConfig'
interface EditorProps {
tsconfig?: ITsconfig
files?: IFiles
selectedFileName?: string
readonly?: boolean
onChange?: (code: string | undefined) => void
options?: IEditorOptions
theme?: ITheme
onJumpFile?: (fileName: string) => void
}
const Editor = ({
tsconfig,
files = {},
selectedFileName = '',
readonly,
theme,
onChange,
options,
onJumpFile
}: EditorProps) => {
const editorRef = useRef<editor.IStandaloneCodeEditor>()
const monacoRef = useRef<Monaco>()
const { doOpenEditor, loadJsxSyntaxHighlight, autoLoadExtraLib } = useEditor()
const jsxSyntaxHighlightRef = useRef<{
highlighter: (code?: string | undefined) => void
dispose: () => void
}>({
highlighter: () => undefined,
dispose: () => undefined
})
const { total, finished, onWatch } = useTypesProgress()
const file = files[selectedFileName] || { name: 'Untitled' }
const handleOnEditorWillMount = (monaco: Monaco) => {
monaco.languages.json.jsonDefaults.setDiagnosticsOptions(tsconfigJsonDiagnosticsOptions)
tsconfig &&
monaco.languages.typescript.typescriptDefaults.setCompilerOptions(
tsconfig.compilerOptions
)
if (files) {
monaco.editor.getModels().forEach((model) => model.dispose())
Object.entries(files).forEach(([key]) => {
if (!monaco.editor.getModel(monaco.Uri.parse(`file:///${key}`))) {
monaco.editor.createModel(
files[key].value,
fileNameToLanguage(key),
monaco.Uri.parse(`file:///${key}`)
)
}
})
}
}
const handleOnEditorDidMount = (editor: editor.IStandaloneCodeEditor, monaco: Monaco) => {
editorRef.current = editor
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => {
void editor.getAction('editor.action.formatDocument')?.run()
})
monacoRef.current = monaco
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
editor['_codeEditorService'].doOpenEditor = function (
editor: editor.IStandaloneCodeEditor,
input: { options: { selection: Selection }; resource: { path: string } }
) {
const path = input.resource.path
if (!path.startsWith('/node_modules/')) {
onJumpFile?.(path.replace('/', ''))
doOpenEditor(editor, input)
}
}
jsxSyntaxHighlightRef.current = loadJsxSyntaxHighlight(editor, monaco)
void autoLoadExtraLib(editor, monaco, file.value, onWatch)
}
useEffect(() => {
editorRef.current?.focus()
jsxSyntaxHighlightRef?.current?.highlighter?.()
}, [file.name])
useEffect(() => {
tsconfig &&
monacoRef.current?.languages.typescript.typescriptDefaults.setCompilerOptions(
tsconfig.compilerOptions
)
}, [tsconfig])
return (
<>
<div data-component={'playground-code-editor-editor'}>
<MonacoEditor
theme={theme}
path={file.name}
className={`monaco-editor-${theme ?? 'light'}`}
language={file.language}
value={file.value}
onChange={onChange}
beforeMount={handleOnEditorWillMount}
onMount={handleOnEditorDidMount}
options={{
...MonacoEditorConfig,
...options,
theme: undefined,
readOnly: readonly
}}
/>
{total > 0 && !finished && <div className={'playground-code-editor-loading'} />}
</div>
</>
)
}
export default Editor

View File

@@ -0,0 +1,7 @@
import { loader } from '@monaco-editor/react'
loader.config({
paths: {
vs: 'https://unpkg.com/monaco-editor@0.45.0/min/vs'
}
})

View File

@@ -0,0 +1,34 @@
import { editor } from 'monaco-editor'
export const MonacoEditorConfig: editor.IStandaloneEditorConstructionOptions = {
automaticLayout: true,
cursorBlinking: 'smooth',
fontLigatures: true,
formatOnPaste: true,
formatOnType: true,
fontSize: 14,
showDeprecated: true,
showUnused: true,
showFoldingControls: 'mouseover',
scrollBeyondLastLine: false,
minimap: {
enabled: false
},
inlineSuggest: {
enabled: false
},
fixedOverflowWidgets: true,
smoothScrolling: true,
smartSelect: {
selectSubwords: true,
selectLeadingAndTrailingWhitespace: true
},
tabSize: 2,
overviewRulerBorder: false, // 不要滚动条的边框
// 滚动条设置
scrollbar: {
verticalScrollbarSize: 6, // 竖滚动条
horizontalScrollbarSize: 6 // 横滚动条
}
// lineNumbers: 'off', // 隐藏控制行号
}

View File

@@ -0,0 +1,141 @@
import { Dispatch, SetStateAction, KeyboardEvent, ChangeEvent, MouseEvent } from 'react'
interface ItemProps {
className?: string
readonly?: boolean
creating?: boolean
value: string
active?: boolean
hasEditing?: boolean
setHasEditing?: Dispatch<SetStateAction<boolean>>
onOk?: (fileName: string) => void
onCancel?: () => void
onRemove?: (fileName: string) => void
onClick?: () => void
onValidate?: (newFileName: string, oldFileName: string) => boolean
}
const Item = ({
className,
readonly = false,
value,
active = false,
hasEditing,
setHasEditing,
onOk,
onCancel,
onRemove,
onClick,
onValidate,
...prop
}: ItemProps) => {
const inputRef = useRef<HTMLInputElement>(null)
const [fileName, setFileName] = useState(value)
const [creating, setCreating] = useState(prop.creating)
const handleOnClick = () => {
if (hasEditing) {
return
}
onClick?.()
}
const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'Enter') {
event.preventDefault()
finishNameFile()
} else if (event.key === 'Escape') {
event.preventDefault()
cancelNameFile()
}
}
const finishNameFile = () => {
if (!creating || onValidate ? !onValidate?.(fileName, value) : false) {
inputRef.current?.focus()
return
}
if (fileName === value && active) {
setCreating(false)
setHasEditing?.(false)
return
}
onOk?.(fileName)
setCreating(false)
setHasEditing?.(false)
}
const cancelNameFile = () => {
setFileName(value)
setCreating(false)
setHasEditing?.(false)
onCancel?.()
}
const handleOnDoubleClick = () => {
if (readonly || creating || hasEditing) {
return
}
setCreating(true)
setHasEditing?.(true)
setFileName(value)
setTimeout(() => {
inputRef.current?.focus()
inputRef.current?.setSelectionRange(0, inputRef.current?.value.lastIndexOf('.'))
})
}
const handleOnChange = (e: ChangeEvent<HTMLInputElement>) => {
setFileName(e.target.value)
}
const handleOnDelete = (e: MouseEvent<HTMLDivElement>) => {
e.stopPropagation()
if (hasEditing) {
return
}
if (confirm(`确定删除文件 ${value} `)) {
onRemove?.(value)
}
}
useEffect(() => {
inputRef.current?.focus()
}, [])
return (
<div
className={`tab-item${active ? ' active' : ''}${className ? ` ${className}` : ''}`}
onClick={handleOnClick}
>
{creating ? (
<div className={'tab-item-input'}>
<input
ref={inputRef}
value={fileName}
onChange={handleOnChange}
onBlur={finishNameFile}
onKeyDown={handleKeyDown}
spellCheck={'false'}
/>
<span className={'tab-item-input-mask'}>{fileName}</span>
</div>
) : (
<>
<div onDoubleClick={handleOnDoubleClick}>{value}</div>
{!readonly && (
<div className={'tab-item-close'} onClick={handleOnDelete}>
<IconOxygenClose />
</div>
)}
</>
)}
</div>
)
}
export default Item

View File

@@ -0,0 +1,86 @@
[data-component=playground-file-selector].tab{
display: flex;
flex: 0 0 auto;
height: 40px;
.multiple {
flex: 1;
width: 0;
.tab-content {
height: 40px;
align-items: flex-end;
gap: 2px;
margin-left: 10px;
.tab-item-add {
padding: 0 12px;
}
.tabs-margin-right {
height: 100%;
> * {
height: 100%;
width: 10px;
}
}
}
}
.sticky {
display: flex;
flex: 0 0 auto;
align-items: flex-end;
margin-right: 10px;
}
.tab-item {
display: flex;
align-items: center;
justify-content: center;
flex: 0 0 auto;
height: 30px;
padding: 0 20px;
border: 1px solid #f0f0f0;
background-color: rgba(0, 0, 0, 0.04);
border-radius: 6px 6px 0 0;
cursor: pointer;
.tab-item-input {
position: relative;
min-width: 40px;
transform: translateY(1px);
.tab-item-input-mask {
display: inline-block;
color: transparent;
}
input {
position: absolute;
background-color: transparent;
width: 100%;
font-size: 1em;
}
}
.tab-item-close {
transform: translateX(10px);
:hover {
fill: #888;
}
svg {
height: 8px;
fill: #666;
}
}
&.active {
background-color: white;
border-bottom: none;
}
}
}

View File

@@ -0,0 +1,228 @@
import '@/components/Playground/CodeEditor/FileSelector/file-selector.scss'
import HideScrollbar, { HideScrollbarElement } from '@/components/common/HideScrollbar'
import FlexBox from '@/components/common/FlexBox'
import { IFiles } from '@/components/Playground/shared'
import {
getFileNameList,
IMPORT_MAP_FILE_NAME,
TS_CONFIG_FILE_NAME
} from '@/components/Playground/files'
import Item from '@/components/Playground/CodeEditor/FileSelector/Item'
interface FileSelectorProps {
files?: IFiles
onChange?: (fileName: string) => void
onError?: (msg: string) => void
readonly?: boolean
notRemovableFiles?: string[]
onRemoveFile?: (fileName: string) => void
onAddFile?: (fileName: string) => void
onUpdateFileName?: (newFileName: string, oldFileName: string) => void
selectedFileName?: string
}
const FileSelector = ({
files = {},
onChange,
onError,
readonly = false,
notRemovableFiles = [],
onRemoveFile,
onAddFile,
onUpdateFileName,
selectedFileName = ''
}: FileSelectorProps) => {
const hideScrollbarRef = useRef<HideScrollbarElement>(null)
const [tabs, setTabs] = useState<string[]>([])
const [creating, setCreating] = useState(false)
const [hasEditing, setHasEditing] = useState(false)
const getMaxSequenceTabName = (filesName: string[]) => {
const result = filesName.reduce((max, filesName) => {
const match = filesName.match(/Component(\d+)\.tsx/)
if (match) {
const sequenceNumber = parseInt(match[1], 10)
return Math.max(Number(max), sequenceNumber)
}
return max
}, 0)
return `Component${result + 1}.tsx`
}
const addTab = () => {
if (hasEditing) {
return
}
setTabs([...tabs, getMaxSequenceTabName(tabs)])
setCreating(true)
setTimeout(() => {
hideScrollbarRef.current?.scrollRight(1000)
})
}
const handleOnCancel = () => {
onError?.('')
if (!creating) {
return
}
tabs.pop()
setTabs([...tabs])
setCreating(false)
}
const handleOnClickTab = (fileName: string) => {
if (creating) {
return
}
onChange?.(fileName)
}
const editImportMap = () => {
if (hasEditing) {
return
}
onChange?.(IMPORT_MAP_FILE_NAME)
}
const editTsconfig = () => {
if (hasEditing) {
return
}
onChange?.(TS_CONFIG_FILE_NAME)
}
const handleOnSaveTab = (value: string, item: string) => {
if (creating) {
onAddFile?.(value)
setCreating(false)
} else {
onUpdateFileName?.(value, item)
}
setTimeout(() => {
handleOnClickTab(value)
})
}
const handleOnValidateTab = (newFileName: string, oldFileName: string) => {
if (newFileName.length > 40) {
onError?.('File name is too long, maximum 40 characters.')
}
if (!/\.(jsx|tsx|js|ts|css|json)$/.test(newFileName)) {
onError?.('Playground only supports *.jsx, *.tsx, *.js, *.ts, *.css, *.json files.')
return false
}
if (
tabs.map((item) => item.toLowerCase()).includes(newFileName.toLowerCase()) &&
newFileName.toLowerCase() !== oldFileName.toLowerCase()
) {
onError?.(`File "${newFileName}" already exists.`)
return false
}
onError?.('')
return true
}
const handleOnRemove = (fileName: string) => {
onRemoveFile?.(fileName)
if (fileName === selectedFileName) {
const keys = getFileNameList(files).filter(
(item) =>
![IMPORT_MAP_FILE_NAME, TS_CONFIG_FILE_NAME].includes(item) &&
!files[item].hidden
)
const index = keys.indexOf(fileName) - 1
if (index >= 0) {
handleOnClickTab(keys[index])
} else {
handleOnClickTab(keys[1])
}
}
}
useEffect(() => {
getFileNameList(files).length
? setTabs(
getFileNameList(files).filter(
(item) =>
![IMPORT_MAP_FILE_NAME, TS_CONFIG_FILE_NAME].includes(item) &&
!files[item].hidden
)
)
: setTabs([])
}, [files])
return (
<>
<div data-component={'playground-file-selector'} className={'tab'}>
<div className={'multiple'}>
<HideScrollbar ref={hideScrollbarRef}>
<FlexBox direction={'horizontal'} className={'tab-content'}>
{tabs.map((item, index) => (
<Item
key={index + item}
value={item}
active={selectedFileName === item}
creating={creating}
readonly={readonly || notRemovableFiles.includes(item)}
hasEditing={hasEditing}
setHasEditing={setHasEditing}
onValidate={handleOnValidateTab}
onOk={(name) => handleOnSaveTab(name, item)}
onCancel={handleOnCancel}
onRemove={handleOnRemove}
onClick={() => handleOnClickTab(item)}
/>
))}
{!readonly && (
<Item
className={'tab-item-add'}
value={'+'}
onClick={addTab}
readonly
/>
)}
<div className={'tabs-margin-right'}>
<div />
</div>
</FlexBox>
</HideScrollbar>
</div>
{(files[IMPORT_MAP_FILE_NAME] || files[TS_CONFIG_FILE_NAME]) && (
<div className={'sticky'}>
{files[TS_CONFIG_FILE_NAME] && (
<Item
value={'tsconfig.json'}
active={selectedFileName === TS_CONFIG_FILE_NAME}
onClick={editTsconfig}
readonly
/>
)}
{files[IMPORT_MAP_FILE_NAME] && (
<Item
value={'Import Map'}
active={selectedFileName === IMPORT_MAP_FILE_NAME}
onClick={editImportMap}
readonly
/>
)}
</div>
)}
</div>
</>
)
}
FileSelector.Item = Item
export default FileSelector

View File

@@ -0,0 +1,5 @@
[data-component=playground-code-editor] {
position: relative;
width: 100%;
height: 100%;
}

Some files were not shown because too many files have changed in this diff Show More