🚀 chore: update stuff
parent
6a196928e4
commit
9616d906ea
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
displayTypes: ['feat', 'fix', 'styles', 'pref'],
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
# http://editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
[Makefile]
|
||||||
|
indent_style = tab
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
displayTypes: ['feat', 'fix', 'styles', 'pref'],
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
module.exports = {
|
||||||
|
extends: require.resolve('@umijs/lint/dist/config/eslint'),
|
||||||
|
rules: {
|
||||||
|
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
|
||||||
|
'no-param-reassign': 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
# To get started with Dependabot version updates, you'll need to specify which
|
||||||
|
# package ecosystems to update and where the package manifests are located.
|
||||||
|
# Please see the documentation for all configuration options:
|
||||||
|
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||||
|
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: 'npm' # See documentation for possible values
|
||||||
|
directory: '/' # Location of package manifests
|
||||||
|
open-pull-requests-limit: 20
|
||||||
|
schedule:
|
||||||
|
interval: 'daily'
|
||||||
|
time: '19:00'
|
||||||
|
timezone: 'Asia/Shanghai'
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
name: Dependabot Auto Merge
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
types: [labeled, edited]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
merge:
|
||||||
|
if: contains(github.event.pull_request.labels.*.name, 'dependencies')
|
||||||
|
name: Dependabot Auto Merge
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install pnpm
|
||||||
|
uses: pnpm/action-setup@v2
|
||||||
|
with:
|
||||||
|
version: 7
|
||||||
|
|
||||||
|
- name: Setup Node.js environment
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: '16'
|
||||||
|
|
||||||
|
- name: Install deps
|
||||||
|
run: pnpm install
|
||||||
|
|
||||||
|
- name: Merge
|
||||||
|
uses: ahmadnassri/action-dependabot-auto-merge@v2
|
||||||
|
with:
|
||||||
|
command: merge
|
||||||
|
target: minor
|
||||||
|
github-token: ${{ secrets.GH_TOKEN }}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
name: Build and Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: Test
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install pnpm
|
||||||
|
uses: pnpm/action-setup@v2
|
||||||
|
with:
|
||||||
|
version: 7
|
||||||
|
|
||||||
|
- name: Setup Node.js environment
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: '16'
|
||||||
|
|
||||||
|
- name: Install deps
|
||||||
|
run: pnpm install
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: pnpm run test
|
||||||
|
build:
|
||||||
|
needs: test
|
||||||
|
name: Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install pnpm
|
||||||
|
uses: pnpm/action-setup@v2
|
||||||
|
with:
|
||||||
|
version: 7
|
||||||
|
|
||||||
|
- name: Setup Node.js environment
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: '16'
|
||||||
|
|
||||||
|
- name: Install deps
|
||||||
|
run: pnpm install
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: pnpm run build
|
||||||
|
|
||||||
|
- name: Release
|
||||||
|
id: release
|
||||||
|
run: pnpm run release
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
name: Test CI
|
||||||
|
on: [push, pull_request]
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install pnpm
|
||||||
|
uses: pnpm/action-setup@v2
|
||||||
|
with:
|
||||||
|
version: 7
|
||||||
|
|
||||||
|
- name: Setup Node.js environment
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: '16'
|
||||||
|
|
||||||
|
- name: Install deps
|
||||||
|
run: pnpm install
|
||||||
|
|
||||||
|
- name: lint
|
||||||
|
run: pnpm run test
|
||||||
|
|
@ -1,3 +1,26 @@
|
||||||
**/*.svg
|
**/*.svg
|
||||||
**/*.ejs
|
.umi
|
||||||
**/*.html
|
.umi-production
|
||||||
|
/dist
|
||||||
|
.dockerignore
|
||||||
|
.DS_Store
|
||||||
|
.eslintignore
|
||||||
|
*.png
|
||||||
|
*.jpg
|
||||||
|
*.webp
|
||||||
|
*.toml
|
||||||
|
*.py
|
||||||
|
docker
|
||||||
|
.editorconfig
|
||||||
|
Dockerfile*
|
||||||
|
.gitignore
|
||||||
|
.prettierignore
|
||||||
|
LICENSE
|
||||||
|
.eslintcache
|
||||||
|
*.lock
|
||||||
|
yarn-error.log
|
||||||
|
.idea
|
||||||
|
.husky
|
||||||
|
.npmrc
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
|
|
||||||
10
.prettierrc
10
.prettierrc
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"trailingComma": "all",
|
"trailingComma": "es5",
|
||||||
"tabWidth": 2,
|
"tabWidth": 2,
|
||||||
"semi": true,
|
"semi": false,
|
||||||
"arrowParens": "always",
|
"singleQuote": true,
|
||||||
"singleQuote": true
|
"printWidth": 120
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"tabWidth": 2,
|
||||||
|
"semi": false,
|
||||||
|
"singleQuote": true,
|
||||||
|
"printWidth": 120
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
module.exports = {
|
||||||
|
extends: ['semantic-release-config-gitmoji'],
|
||||||
|
branches: ['master'],
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
module.exports = require('@umijs/lint/dist/config/stylelint')
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 CanisMinor
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
74
README.md
74
README.md
|
|
@ -1,6 +1,72 @@
|
||||||
# Kitchen Theme for stable-diffusion-web-ui
|
<p align="center">
|
||||||
|
<img width="160" src="https://gw.alipayobjects.com/mdn/rms_7d1485/afts/img/A*XDYxSJXBjjwAAAAAAAAAAAAAARQnAQ">
|
||||||
|
</p>
|
||||||
|
<h1 align="center">Kitchen Stable Diffusion WebUI</h1>
|
||||||
|
|
||||||
> ⚠️⚠️⚠️ Warning: minimum requirements gradio-3.23.0 & sd-webui [4c1ad74](https://github.com/AUTOMATIC1111/stable-diffusion-webui/commit/4c1ad743e3baf1246db0711aa0107debf036a12b)
|
<div align="center">
|
||||||
|
Kitchen Theme for <a href="https://github.com/AUTOMATIC1111/stable-diffusion-webui" target="_blank">AUTOMATIC1111/stable-diffusion-web-ui</a>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<!-- SHIELD GROUP -->
|
||||||
|
|
||||||
|
[![release][release-shield]][release-url]
|
||||||
|
[![releaseDate][release-date-shield]][release-date-url]
|
||||||
|
[![ciTest][ci-test-shield]][ci-test-url]
|
||||||
|
[![ciRelease][ci-release-shield]][ci-release-url]
|
||||||
|
[![contributors][contributors-shield]][contributors-url]
|
||||||
|
[![forks][forks-shield]][forks-url]
|
||||||
|
[![stargazers][stargazers-shield]][stargazers-url]
|
||||||
|
[![issues][issues-shield]][issues-url]
|
||||||
|
|
||||||
|
<!-- SHIELD LINK GROUP -->
|
||||||
|
|
||||||
|
<!-- release -->
|
||||||
|
|
||||||
|
[release-shield]: https://img.shields.io/github/v/release/canisminor1990/sd-web-ui-kitchen-theme?style=flat&sort=semver&logo=github
|
||||||
|
[release-url]: https://github.com/canisminor1990/sd-web-ui-kitchen-theme/releases
|
||||||
|
|
||||||
|
<!-- releaseDate -->
|
||||||
|
|
||||||
|
[release-date-shield]: https://img.shields.io/github/release-date/canisminor1990/sd-web-ui-kitchen-theme?style=flat
|
||||||
|
[release-date-url]: https://github.com/canisminor1990/sd-web-ui-kitchen-theme/releases
|
||||||
|
|
||||||
|
<!-- ciTest -->
|
||||||
|
|
||||||
|
[ci-test-shield]: https://github.com/canisminor1990/sd-web-ui-kitchen-theme/workflows/Test%20CI/badge.svg
|
||||||
|
[ci-test-url]: https://github.com/canisminor1990/sd-web-ui-kitchen-theme/actions/workflows/test.yml
|
||||||
|
|
||||||
|
<!-- ciRelease -->
|
||||||
|
|
||||||
|
[ci-release-shield]: https://github.com/canisminor1990/sd-web-ui-kitchen-theme/workflows/Build%20and%20Release/badge.svg
|
||||||
|
[ci-release-url]: https://github.com/canisminor1990/sd-web-ui-kitchen-theme/actions/workflows/release.yml
|
||||||
|
|
||||||
|
<!-- contributors -->
|
||||||
|
|
||||||
|
[contributors-shield]: https://img.shields.io/github/contributors/canisminor1990/sd-web-ui-kitchen-theme.svg?style=flat
|
||||||
|
[contributors-url]: https://github.com/canisminor1990/sd-web-ui-kitchen-theme/graphs/contributors
|
||||||
|
|
||||||
|
<!-- forks -->
|
||||||
|
|
||||||
|
[forks-shield]: https://img.shields.io/github/forks/canisminor1990/sd-web-ui-kitchen-theme.svg?style=flat
|
||||||
|
[forks-url]: https://github.com/canisminor1990/sd-web-ui-kitchen-theme/network/members
|
||||||
|
|
||||||
|
<!-- stargazers -->
|
||||||
|
|
||||||
|
[stargazers-shield]: https://img.shields.io/github/stars/canisminor1990/sd-web-ui-kitchen-theme.svg?style=flat
|
||||||
|
[stargazers-url]: https://github.com/canisminor1990/sd-web-ui-kitchen-theme/stargazers
|
||||||
|
|
||||||
|
<!-- issues -->
|
||||||
|
|
||||||
|
[issues-shield]: https://img.shields.io/github/issues/canisminor1990/sd-web-ui-kitchen-theme.svg?style=flat
|
||||||
|
[issues-url]: https://img.shields.io/github/issues/canisminor1990/sd-web-ui-kitchen-theme.svg?style=flat
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
> ⚠️⚠️⚠️ Warning: minimum requirements gradio-3.23.0 & sd-webui [4c1ad74](https://github.com/AUTOMATIC1111/stable-diffusion-webui/commit/4c1ad743e3baf1246db0711aa0107debf036a12b)
|
||||||
|
|
||||||
Launch your WebUI with argument --theme=dark. For example, on Windows your webui-user.bat should include:
|
Launch your WebUI with argument --theme=dark. For example, on Windows your webui-user.bat should include:
|
||||||
|
|
||||||
|
|
@ -8,11 +74,11 @@ Launch your WebUI with argument --theme=dark. For example, on Windows your webui
|
||||||
set COMMANDLINE_ARGS= --theme=dark
|
set COMMANDLINE_ARGS= --theme=dark
|
||||||
```
|
```
|
||||||
|
|
||||||
## Screenshots
|
## 👀 Screenshots
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Installation
|
## 📦 Installation
|
||||||
|
|
||||||
As an extension (recommended)
|
As an extension (recommended)
|
||||||
Either clone the repo into your extensions folder:
|
Either clone the repo into your extensions folder:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
extends: ['gitmoji'],
|
||||||
|
}
|
||||||
25
gulpfile.js
25
gulpfile.js
|
|
@ -1,10 +1,19 @@
|
||||||
const gulp = require('gulp');
|
const gulp = require('gulp')
|
||||||
const less = require('gulp-less');
|
const less = require('gulp-less')
|
||||||
|
const ts = require('gulp-typescript')
|
||||||
|
|
||||||
gulp.task('less', function () {
|
const tsProject = ts.createProject('tsconfig.json')
|
||||||
return gulp.src('src/theme/*.less').pipe(less()).pipe(gulp.dest('./'));
|
gulp.task('compile', () => {
|
||||||
});
|
return gulp.src('src/script/**/*.ts').pipe(tsProject()).pipe(gulp.dest('javascript'))
|
||||||
|
})
|
||||||
|
|
||||||
gulp.task('watch', function () {
|
gulp.task('less', () => {
|
||||||
gulp.watch('src/theme/**/*', gulp.parallel('less'));
|
return gulp.src('src/theme/*.less').pipe(less()).pipe(gulp.dest('./'))
|
||||||
});
|
})
|
||||||
|
|
||||||
|
gulp.task('build', gulp.parallel('compile', 'less'))
|
||||||
|
|
||||||
|
gulp.task('watch', () => {
|
||||||
|
gulp.watch('src/theme/**/*', gulp.parallel('less'))
|
||||||
|
gulp.watch('src/script/**/*', gulp.parallel('compile'))
|
||||||
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,19 @@
|
||||||
|
'use strict'
|
||||||
|
/**
|
||||||
|
* 处理网站的 favicon 图标
|
||||||
|
*/
|
||||||
class FaviconHandler {
|
class FaviconHandler {
|
||||||
|
/**
|
||||||
|
* 设置网站的 favicon 图标
|
||||||
|
*/
|
||||||
static setFavicon() {
|
static setFavicon() {
|
||||||
const link = document.createElement('link');
|
const link = document.createElement('link')
|
||||||
link.rel = 'icon';
|
link.rel = 'icon'
|
||||||
link.type = 'image/svg+xml';
|
link.type = 'image/svg+xml'
|
||||||
link.href =
|
link.href = 'https://gw.alipayobjects.com/zos/bmw-prod/51a51720-8a30-4430-b6c9-be5712364f04.svg'
|
||||||
'https://gw.alipayobjects.com/zos/bmw-prod/51a51720-8a30-4430-b6c9-be5712364f04.svg';
|
document.getElementsByTagName('head')[0].appendChild(link)
|
||||||
document.getElementsByTagName('head')[0].appendChild(link);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
FaviconHandler.setFavicon();
|
FaviconHandler.setFavicon()
|
||||||
});
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,220 +1,249 @@
|
||||||
|
'use strict'
|
||||||
|
/**
|
||||||
|
* 转换器工具类
|
||||||
|
*/
|
||||||
class Converter {
|
class Converter {
|
||||||
|
/**
|
||||||
|
* 将数字四舍五入到小数点后四位
|
||||||
|
* @param value 数字
|
||||||
|
* @returns 四舍五入后的数字
|
||||||
|
*/
|
||||||
static round(value) {
|
static round(value) {
|
||||||
return Math.round(value * 10000) / 10000;
|
return Math.round(value * 10000) / 10000
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 将字符串中的中文冒号和括号转换成英文冒号和括号
|
||||||
|
* @param srt 字符串
|
||||||
|
* @returns 转换后的字符串
|
||||||
|
*/
|
||||||
static convertStr(srt) {
|
static convertStr(srt) {
|
||||||
return srt.replace(/:/g, ':').replace(/(/g, '(').replace(/)/g, ')');
|
return srt.replace(/:/g, ':').replace(/(/g, '(').replace(/)/g, ')')
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 将字符串按照括号分割成数组
|
||||||
|
* @param str 字符串
|
||||||
|
* @returns 分割后的数组
|
||||||
|
*/
|
||||||
static convertStr2Array(str) {
|
static convertStr2Array(str) {
|
||||||
// 匹配各种括号中的内容,包括括号本身
|
// 匹配各种括号中的内容,包括括号本身
|
||||||
const bracketRegex = /(\(|\)|<|>|\[|\])/g;
|
const bracketRegex = /(\(|\)|<|>|\[|\])/g
|
||||||
|
/**
|
||||||
// 将字符串按照各种括号分割成数组
|
* 将字符串按照各种括号分割成数组
|
||||||
|
* @param str 字符串
|
||||||
|
* @returns 分割后的数组
|
||||||
|
*/
|
||||||
const splitByBracket = (str) => {
|
const splitByBracket = (str) => {
|
||||||
const arr = [];
|
const arr = []
|
||||||
let start = 0;
|
let start = 0
|
||||||
let depth = 0;
|
let depth = 0
|
||||||
let match;
|
let match
|
||||||
while ((match = bracketRegex.exec(str)) !== null) {
|
while ((match = bracketRegex.exec(str)) !== null) {
|
||||||
if (depth === 0 && match.index > start) {
|
if (depth === 0 && match.index > start) {
|
||||||
arr.push(str.substring(start, match.index));
|
arr.push(str.substring(start, match.index))
|
||||||
start = match.index;
|
start = match.index
|
||||||
}
|
}
|
||||||
if (match[0] === '(' || match[0] === '<' || match[0] === '[') {
|
if (match[0] === '(' || match[0] === '<' || match[0] === '[') {
|
||||||
depth++;
|
depth++
|
||||||
} else if (match[0] === ')' || match[0] === '>' || match[0] === ']') {
|
} else if (match[0] === ')' || match[0] === '>' || match[0] === ']') {
|
||||||
depth--;
|
depth--
|
||||||
}
|
}
|
||||||
if (depth === 0) {
|
if (depth === 0) {
|
||||||
arr.push(str.substring(start, match.index + 1));
|
arr.push(str.substring(start, match.index + 1))
|
||||||
start = match.index + 1;
|
start = match.index + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (start < str.length) {
|
if (start < str.length) {
|
||||||
arr.push(str.substring(start));
|
arr.push(str.substring(start))
|
||||||
}
|
}
|
||||||
return arr;
|
return arr
|
||||||
};
|
}
|
||||||
|
/**
|
||||||
// 将字符串按照逗号和各种括号分割成数组
|
* 将字符串按照逗号和各种括号分割成数组
|
||||||
|
* @param str 字符串
|
||||||
|
* @returns 分割后的数组
|
||||||
|
*/
|
||||||
const splitByComma = (str) => {
|
const splitByComma = (str) => {
|
||||||
const arr = [];
|
const arr = []
|
||||||
let start = 0;
|
let start = 0
|
||||||
let inBracket = false;
|
let inBracket = false
|
||||||
for (let i = 0; i < str.length; i++) {
|
for (let i = 0; i < str.length; i++) {
|
||||||
if (str[i] === ',' && !inBracket) {
|
if (str[i] === ',' && !inBracket) {
|
||||||
arr.push(str.substring(start, i).trim());
|
arr.push(str.substring(start, i).trim())
|
||||||
start = i + 1;
|
start = i + 1
|
||||||
} else if (str[i].match(bracketRegex)) {
|
} else if (str[i].match(bracketRegex)) {
|
||||||
inBracket = !inBracket;
|
inBracket = !inBracket
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
arr.push(str.substring(start).trim());
|
arr.push(str.substring(start).trim())
|
||||||
return arr;
|
return arr
|
||||||
};
|
}
|
||||||
|
/**
|
||||||
// 清洗字符串并输出数组
|
* 清洗字符串并输出数组
|
||||||
|
* @param str 字符串
|
||||||
|
* @returns 清洗后的数组
|
||||||
|
*/
|
||||||
const cleanStr = (str) => {
|
const cleanStr = (str) => {
|
||||||
let arr = splitByBracket(str);
|
let arr = splitByBracket(str)
|
||||||
arr = arr.flatMap((s) => splitByComma(s));
|
arr = arr.flatMap((s) => splitByComma(s))
|
||||||
return arr.filter((s) => s !== '');
|
return arr.filter((s) => s !== '')
|
||||||
};
|
}
|
||||||
|
|
||||||
return cleanStr(str)
|
return cleanStr(str)
|
||||||
.filter((item) => {
|
.filter((item) => {
|
||||||
const pattern = /^[,\s, ]+$/;
|
const pattern = /^[,\s, ]+$/
|
||||||
return !pattern.test(item);
|
return !pattern.test(item)
|
||||||
})
|
})
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
return a.includes('<') && !b.includes('<')
|
return a.includes('<') && !b.includes('<') ? 1 : b.includes('<') && !a.includes('<') ? -1 : 0
|
||||||
? 1
|
})
|
||||||
: b.includes('<') && !a.includes('<')
|
|
||||||
? -1
|
|
||||||
: 0;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 将数组转换成字符串
|
||||||
|
* @param array 数组
|
||||||
|
* @returns 转换后的字符串
|
||||||
|
*/
|
||||||
static convertArray2Str(array) {
|
static convertArray2Str(array) {
|
||||||
const newArray = array.map((item) => {
|
const newArray = array.map((item) => {
|
||||||
if (item.includes('<')) return item;
|
if (item.includes('<')) return item
|
||||||
const newItem = item
|
const newItem = item
|
||||||
.replace(/\s+/g, ' ')
|
.replace(/\s+/g, ' ')
|
||||||
.replace([/\,|\.|\。/g, ','])
|
.replace(/\,|\.|\。/g, ',')
|
||||||
.replace([/\“|\‘|\”|\"|\\|\//g, ''])
|
.replace(/\“|\‘|\”|\"|\\|\//g, '')
|
||||||
.replace(/\, /g, ',')
|
.replace(/\, /g, ',')
|
||||||
.replace(/\,\,/g, ',')
|
.replace(/\,\,/g, ',')
|
||||||
.replace(/\,/g, ', ');
|
.replace(/\,/g, ', ')
|
||||||
return Converter.convertStr2Array(newItem).join(', ');
|
return Converter.convertStr2Array(newItem).join(', ')
|
||||||
});
|
})
|
||||||
return newArray.join(', ');
|
return newArray.join(', ')
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 将输入的字符串转换成特定格式的字符串
|
||||||
|
* @param input 输入的字符串
|
||||||
|
* @returns 转换后的字符串
|
||||||
|
*/
|
||||||
static convert(input) {
|
static convert(input) {
|
||||||
const re_attention = /\{|\[|\}|\]|[^\{\}\[\]]+/gmu;
|
const re_attention = /\{|\[|\}|\]|[^\{\}\[\]]+/gmu
|
||||||
|
let text = Converter.convertStr(input)
|
||||||
let text = Converter.convertStr(input);
|
const textArray = Converter.convertStr2Array(text)
|
||||||
text = Converter.convertStr2Array(text);
|
text = Converter.convertArray2Str(textArray)
|
||||||
text = Converter.convertArray2Str(text);
|
let res = []
|
||||||
|
const curly_bracket_multiplier = 1.05
|
||||||
let res = [];
|
const square_bracket_multiplier = 1 / 1.05
|
||||||
|
|
||||||
const curly_bracket_multiplier = 1.05;
|
|
||||||
const square_bracket_multiplier = 1 / 1.05;
|
|
||||||
|
|
||||||
const brackets = {
|
const brackets = {
|
||||||
'{': { stack: [], multiplier: curly_bracket_multiplier },
|
'{': { stack: [], multiplier: curly_bracket_multiplier },
|
||||||
'[': { stack: [], multiplier: square_bracket_multiplier },
|
'[': { stack: [], multiplier: square_bracket_multiplier },
|
||||||
};
|
}
|
||||||
|
/**
|
||||||
|
* 将指定范围内的数字乘以指定倍数
|
||||||
|
* @param start_position 起始位置
|
||||||
|
* @param multiplier 倍数
|
||||||
|
*/
|
||||||
function multiply_range(start_position, multiplier) {
|
function multiply_range(start_position, multiplier) {
|
||||||
for (let pos = start_position; pos < res.length; pos++) {
|
for (let pos = start_position; pos < res.length; pos++) {
|
||||||
res[pos][1] = Converter.round(res[pos][1] * multiplier);
|
res[pos][1] = Converter.round(res[pos][1] * multiplier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const match of text.matchAll(re_attention)) {
|
for (const match of text.matchAll(re_attention)) {
|
||||||
let word = match[0];
|
let word = match[0]
|
||||||
|
|
||||||
if (word in brackets) {
|
if (word in brackets) {
|
||||||
brackets[word].stack.push(res.length);
|
brackets[word].stack.push(res.length)
|
||||||
} else if (word == '}' || word == ']') {
|
} else if (word == '}' || word == ']') {
|
||||||
const bracket = brackets[word === '}' ? '{' : '['];
|
const bracket = brackets[word === '}' ? '{' : '[']
|
||||||
if (bracket.stack.length > 0) {
|
if (bracket.stack.length > 0) {
|
||||||
multiply_range(bracket.stack.pop(), bracket.multiplier);
|
multiply_range(bracket.stack.pop(), bracket.multiplier)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
res.push([word, 1.0]);
|
res.push([word, 1.0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const bracketType in brackets) {
|
for (const bracketType in brackets) {
|
||||||
for (const pos of brackets[bracketType].stack) {
|
for (const pos of brackets[bracketType].stack) {
|
||||||
multiply_range(pos, brackets[bracketType].multiplier);
|
multiply_range(pos, brackets[bracketType].multiplier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.length == 0) {
|
if (res.length == 0) {
|
||||||
res = [['', 1.0]];
|
res = [['', 1.0]]
|
||||||
}
|
}
|
||||||
|
let i = 0
|
||||||
let i = 0;
|
|
||||||
while (i + 1 < res.length) {
|
while (i + 1 < res.length) {
|
||||||
if (res[i][1] == res[i + 1][1]) {
|
if (res[i][1] == res[i + 1][1]) {
|
||||||
res[i][0] += res[i + 1][0];
|
res[i][0] += res[i + 1][0]
|
||||||
res.splice(i + 1, 1);
|
res.splice(i + 1, 1)
|
||||||
} else {
|
} else {
|
||||||
i += 1;
|
i += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let result = ''
|
||||||
let result = '';
|
|
||||||
for (const [word, value] of res) {
|
for (const [word, value] of res) {
|
||||||
result += value === 1.0 ? word : `(${word}:${value.toString()})`;
|
result += value === 1.0 ? word : `(${word}:${value.toString()})`
|
||||||
}
|
}
|
||||||
return result;
|
return result
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 触发 input 事件
|
||||||
|
* @param target 目标元素
|
||||||
|
*/
|
||||||
static dispatchInputEvent(target) {
|
static dispatchInputEvent(target) {
|
||||||
let inputEvent = new Event('input');
|
let inputEvent = new Event('input')
|
||||||
Object.defineProperty(inputEvent, 'target', { value: target });
|
Object.defineProperty(inputEvent, 'target', { value: target })
|
||||||
target.dispatchEvent(inputEvent);
|
target.dispatchEvent(inputEvent)
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 点击转换按钮的事件处理函数
|
||||||
|
* @param type 类型
|
||||||
|
*/
|
||||||
static onClickConvert(type) {
|
static onClickConvert(type) {
|
||||||
const default_prompt = '';
|
const default_prompt = ''
|
||||||
const default_negative = '';
|
const default_negative = ''
|
||||||
|
const prompt = gradioApp().querySelector(`#${type}_prompt > label > textarea`)
|
||||||
const prompt = gradioApp().querySelector(
|
const result = Converter.convert(prompt.value)
|
||||||
`#${type}_prompt > label > textarea`,
|
prompt.value = result.match(/^masterpiece, best quality,/) === null ? default_prompt + result : result
|
||||||
);
|
Converter.dispatchInputEvent(prompt)
|
||||||
const result = Converter.convert(prompt.value);
|
const negprompt = gradioApp().querySelector(`#${type}_neg_prompt > label > textarea`)
|
||||||
prompt.value =
|
const negResult = Converter.convert(negprompt.value)
|
||||||
result.match(/^masterpiece, best quality,/) === null
|
|
||||||
? default_prompt + result
|
|
||||||
: result;
|
|
||||||
Converter.dispatchInputEvent(prompt);
|
|
||||||
const negprompt = gradioApp().querySelector(
|
|
||||||
`#${type}_neg_prompt > label > textarea`,
|
|
||||||
);
|
|
||||||
const negResult = Converter.convert(negprompt.value);
|
|
||||||
negprompt.value =
|
negprompt.value =
|
||||||
negResult.match(/^lowres,/) === null
|
negResult.match(/^lowres,/) === null
|
||||||
? negResult.length === 0
|
? negResult.length === 0
|
||||||
? default_negative
|
? default_negative
|
||||||
: default_negative + negResult
|
: default_negative + negResult
|
||||||
: negResult;
|
: negResult
|
||||||
Converter.dispatchInputEvent(negprompt);
|
Converter.dispatchInputEvent(negprompt)
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 创建转换按钮
|
||||||
|
* @param id 按钮 id
|
||||||
|
* @param innerHTML 按钮文本
|
||||||
|
* @param onClick 点击事件处理函数
|
||||||
|
* @returns 新建的按钮元素
|
||||||
|
*/
|
||||||
static createButton(id, innerHTML, onClick) {
|
static createButton(id, innerHTML, onClick) {
|
||||||
const button = document.createElement('button');
|
const button = document.createElement('button')
|
||||||
button.id = id;
|
button.id = id
|
||||||
button.type = 'button';
|
button.type = 'button'
|
||||||
button.innerHTML = innerHTML;
|
button.innerHTML = innerHTML
|
||||||
button.title = 'Format prompt~🪄';
|
button.title = 'Format prompt~🪄'
|
||||||
button.className = 'lg secondary gradio-button tool svelte-1ipelgc';
|
button.className = 'lg secondary gradio-button tool svelte-1ipelgc'
|
||||||
button.addEventListener('click', onClick);
|
button.addEventListener('click', onClick)
|
||||||
return button;
|
return button
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 添加转换按钮
|
||||||
|
* @param type - 组件类型
|
||||||
|
*/
|
||||||
static addPromptButton(type) {
|
static addPromptButton(type) {
|
||||||
const generateBtn = gradioApp().querySelector(`#${type}_generate`);
|
const generateBtn = gradioApp().querySelector(`#${type}_generate`)
|
||||||
const actionsColumn = gradioApp().querySelector(`#${type}_style_create`);
|
const actionsColumn = gradioApp().querySelector(`#${type}_style_create`)
|
||||||
const nai2local = gradioApp().querySelector(`#${type}_formatconvert`);
|
const nai2local = gradioApp().querySelector(`#${type}_formatconvert`)
|
||||||
if (!generateBtn || !actionsColumn || nai2local) return;
|
if (!generateBtn || !actionsColumn || nai2local) return
|
||||||
const convertBtn = Converter.createButton(
|
const convertBtn = Converter.createButton(`${type}_formatconvert`, '🪄', () => Converter.onClickConvert(type))
|
||||||
`${type}_formatconvert`,
|
actionsColumn.parentNode?.append(convertBtn)
|
||||||
'🪄',
|
|
||||||
() => Converter.onClickConvert(type),
|
|
||||||
);
|
|
||||||
actionsColumn.parentNode.append(convertBtn);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 注册UI更新回调函数
|
||||||
|
* 在UI更新时添加提示按钮
|
||||||
|
*/
|
||||||
onUiUpdate(() => {
|
onUiUpdate(() => {
|
||||||
Converter.addPromptButton('txt2img');
|
Converter.addPromptButton('txt2img')
|
||||||
Converter.addPromptButton('img2img');
|
Converter.addPromptButton('img2img')
|
||||||
});
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,68 +1,68 @@
|
||||||
|
'use strict'
|
||||||
class BracketChecker {
|
class BracketChecker {
|
||||||
|
textArea
|
||||||
|
counterElt
|
||||||
|
errorStrings
|
||||||
constructor(textArea, counterElt) {
|
constructor(textArea, counterElt) {
|
||||||
this.textArea = textArea;
|
this.textArea = textArea
|
||||||
this.counterElt = counterElt;
|
this.counterElt = counterElt
|
||||||
this.errorStrings = [
|
this.errorStrings = [
|
||||||
{
|
{
|
||||||
regex: /\(/g,
|
regex: '\\(',
|
||||||
error:
|
error: '(...) - Different number of opening and closing parentheses detected.\n',
|
||||||
'(...) - Different number of opening and closing parentheses detected.\n',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
regex: /\[/g,
|
regex: '\\[',
|
||||||
error:
|
error: '[...] - Different number of opening and closing square brackets detected.\n',
|
||||||
'[...] - Different number of opening and closing square brackets detected.\n',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
regex: /\{/g,
|
regex: '\\{',
|
||||||
error:
|
error: '{...} - Different number of opening and closing curly brackets detected.\n',
|
||||||
'{...} - Different number of opening and closing curly brackets detected.\n',
|
|
||||||
},
|
},
|
||||||
];
|
]
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
check() {
|
* 检查文本框中的括号是否匹配,并更新计数器元素的标题和样式
|
||||||
var title = '';
|
*/
|
||||||
|
check = () => {
|
||||||
|
let title = ''
|
||||||
this.errorStrings.forEach(({ regex, error }) => {
|
this.errorStrings.forEach(({ regex, error }) => {
|
||||||
var openMatches = (this.textArea.value.match(regex) || []).length;
|
const openMatches = (this.textArea.value.match(new RegExp(regex, 'g')) || []).length
|
||||||
var closeMatches = (
|
const closeMatches = (
|
||||||
this.textArea.value.match(
|
this.textArea.value.match(new RegExp(regex.replace(/\(/g, ')').replace(/\[/g, ']').replace(/\{/g, '}'), 'g')) ||
|
||||||
regex.replace(/\(/g, ')').replace(/\[/g, ']').replace(/\{/g, '}'),
|
[]
|
||||||
) || []
|
).length
|
||||||
).length;
|
if (openMatches !== closeMatches) {
|
||||||
if (openMatches != closeMatches) {
|
|
||||||
if (!this.counterElt.title.includes(error)) {
|
if (!this.counterElt.title.includes(error)) {
|
||||||
title += error;
|
title += error
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
title = this.counterElt.title.replace(error, '');
|
title = this.counterElt.title.replace(error, '')
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
this.counterElt.title = title;
|
this.counterElt.title = title
|
||||||
this.counterElt.classList.toggle('error', !!title);
|
this.counterElt.classList.toggle('error', !!title)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
function setupBracketChecking(id_prompt, id_counter) {
|
* 初始化括号匹配检查器
|
||||||
var textarea = gradioApp().querySelector(`#${id_prompt} > label > textarea`);
|
* @param id_prompt 包含文本框的元素的 ID
|
||||||
var counter = gradioApp().getElementById(id_counter);
|
* @param id_counter 显示计数器的元素的 ID
|
||||||
var bracketChecker = new BracketChecker(textarea, counter);
|
*/
|
||||||
textarea.addEventListener('input', () => bracketChecker.check());
|
function setupBracketChecking(idPrompt, idCounter) {
|
||||||
|
const textarea = gradioApp().querySelector(`#${idPrompt} > label > textarea`)
|
||||||
|
const counter = gradioApp().getElementById(idCounter)
|
||||||
|
const bracketChecker = new BracketChecker(textarea, counter)
|
||||||
|
textarea.addEventListener('input', bracketChecker.check)
|
||||||
}
|
}
|
||||||
|
|
||||||
const shadowRootLoaded = setInterval(() => {
|
const shadowRootLoaded = setInterval(() => {
|
||||||
var shadowRoot = document.querySelector('gradio-app').shadowRoot;
|
const shadowRoot = document.querySelector('gradio-app')?.shadowRoot
|
||||||
if (!shadowRoot) return;
|
if (!shadowRoot) return
|
||||||
var shadowTextArea = shadowRoot.querySelector(
|
const shadowTextArea = shadowRoot.querySelector(`#txt2img_prompt > label > textarea`)
|
||||||
`#txt2img_prompt > label > textarea`,
|
if (!shadowTextArea) return
|
||||||
);
|
clearInterval(shadowRootLoaded)
|
||||||
if (!shadowTextArea) return;
|
;['txt2img', 'txt2img_neg', 'img2img', 'img2img_neg'].forEach((prompt) => {
|
||||||
clearInterval(shadowRootLoaded);
|
setupBracketChecking(`${prompt}_prompt`, `${prompt}_token_counter`)
|
||||||
['txt2img', 'txt2img_neg', 'img2img', 'img2img_neg'].forEach((prompt) => {
|
setupBracketChecking(`${prompt}_prompt`, `${prompt}_negative_token_counter`)
|
||||||
setupBracketChecking(`${prompt}_prompt`, `${prompt}_token_counter`);
|
})
|
||||||
setupBracketChecking(
|
}, 1000)
|
||||||
`${prompt}_prompt`,
|
|
||||||
`${prompt}_negative_token_counter`,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}, 1000);
|
|
||||||
|
|
|
||||||
44
package.json
44
package.json
|
|
@ -1,25 +1,45 @@
|
||||||
{
|
{
|
||||||
"name": "sd-web-ui-kitchen-theme",
|
"name": "sd-web-ui-kitchen-theme",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"main": "index.js",
|
|
||||||
"author": "canisminor1990 <i@canisminor.cc>",
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"author": "canisminor1990 <i@canisminor.cc>",
|
||||||
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"build": "gulp build",
|
||||||
"dev": "gulp watch",
|
"dev": "gulp watch",
|
||||||
"build": "gulp less",
|
"lint": "eslint \"{src,test}/**/*.{js,jsx,ts,tsx}\" --fix",
|
||||||
"prettier": "prettier --write **/*.{js,jsx,tsx,ts,less,css,md,json}"
|
"prepare": "husky install",
|
||||||
},
|
"prettier": "prettier -c --write \"**/**\"",
|
||||||
"dependencies": {},
|
"release": "semantic-release",
|
||||||
"devDependencies": {
|
"setup": "umi setup"
|
||||||
"husky": "4.3.8",
|
|
||||||
"gulp": "^4.0.2",
|
|
||||||
"gulp-less": "^5.0.0",
|
|
||||||
"lint-staged": "^13.2.0",
|
|
||||||
"prettier": "^2.8.7"
|
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*.{js,jsx,less,css,md,json}": [
|
"*.{js,jsx,less,css,md,json}": [
|
||||||
"prettier --write"
|
"prettier --write"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"dependencies": {},
|
||||||
|
"devDependencies": {
|
||||||
|
"@commitlint/cli": "^17",
|
||||||
|
"@umijs/lint": "^4.0.64",
|
||||||
|
"commitlint": "^17",
|
||||||
|
"commitlint-config-gitmoji": "^2",
|
||||||
|
"eslint": "^8",
|
||||||
|
"eslint-import-resolver-alias": "^1.1.2",
|
||||||
|
"eslint-import-resolver-typescript": "^2.2.1",
|
||||||
|
"gulp": "^4.0.2",
|
||||||
|
"gulp-less": "^5.0.0",
|
||||||
|
"gulp-typescript": "^6.0.0-alpha.1",
|
||||||
|
"gulp-use-tsconfig": "^1.5.4",
|
||||||
|
"husky": "^8.0.3",
|
||||||
|
"lint-staged": "^13.2.0",
|
||||||
|
"prettier": "^2",
|
||||||
|
"prettier-plugin-organize-imports": "^3",
|
||||||
|
"prettier-plugin-packagejson": "^2",
|
||||||
|
"semantic-release": "^19",
|
||||||
|
"semantic-release-config-gitmoji": "^1",
|
||||||
|
"stylelint": "^15.4.0",
|
||||||
|
"typescript": "^5.0.0",
|
||||||
|
"umi": "^4.0.64"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
/**
|
||||||
|
* 处理网站的 favicon 图标
|
||||||
|
*/
|
||||||
|
class FaviconHandler {
|
||||||
|
/**
|
||||||
|
* 设置网站的 favicon 图标
|
||||||
|
*/
|
||||||
|
static setFavicon(): void {
|
||||||
|
const link: HTMLLinkElement = document.createElement('link')
|
||||||
|
link.rel = 'icon'
|
||||||
|
link.type = 'image/svg+xml'
|
||||||
|
link.href = 'https://gw.alipayobjects.com/zos/bmw-prod/51a51720-8a30-4430-b6c9-be5712364f04.svg'
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(link)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
FaviconHandler.setFavicon()
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,275 @@
|
||||||
|
/**
|
||||||
|
* 转换器工具类
|
||||||
|
*/
|
||||||
|
class Converter {
|
||||||
|
/**
|
||||||
|
* 将数字四舍五入到小数点后四位
|
||||||
|
* @param value 数字
|
||||||
|
* @returns 四舍五入后的数字
|
||||||
|
*/
|
||||||
|
static round(value: number): number {
|
||||||
|
return Math.round(value * 10000) / 10000
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将字符串中的中文冒号和括号转换成英文冒号和括号
|
||||||
|
* @param srt 字符串
|
||||||
|
* @returns 转换后的字符串
|
||||||
|
*/
|
||||||
|
static convertStr(srt: string): string {
|
||||||
|
return srt.replace(/:/g, ':').replace(/(/g, '(').replace(/)/g, ')')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将字符串按照括号分割成数组
|
||||||
|
* @param str 字符串
|
||||||
|
* @returns 分割后的数组
|
||||||
|
*/
|
||||||
|
static convertStr2Array(str: string): string[] {
|
||||||
|
// 匹配各种括号中的内容,包括括号本身
|
||||||
|
const bracketRegex = /(\(|\)|<|>|\[|\])/g
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将字符串按照各种括号分割成数组
|
||||||
|
* @param str 字符串
|
||||||
|
* @returns 分割后的数组
|
||||||
|
*/
|
||||||
|
const splitByBracket = (str: string): string[] => {
|
||||||
|
const arr: string[] = []
|
||||||
|
let start = 0
|
||||||
|
let depth = 0
|
||||||
|
let match
|
||||||
|
while ((match = bracketRegex.exec(str)) !== null) {
|
||||||
|
if (depth === 0 && match.index > start) {
|
||||||
|
arr.push(str.substring(start, match.index))
|
||||||
|
start = match.index
|
||||||
|
}
|
||||||
|
if (match[0] === '(' || match[0] === '<' || match[0] === '[') {
|
||||||
|
depth++
|
||||||
|
} else if (match[0] === ')' || match[0] === '>' || match[0] === ']') {
|
||||||
|
depth--
|
||||||
|
}
|
||||||
|
if (depth === 0) {
|
||||||
|
arr.push(str.substring(start, match.index + 1))
|
||||||
|
start = match.index + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (start < str.length) {
|
||||||
|
arr.push(str.substring(start))
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将字符串按照逗号和各种括号分割成数组
|
||||||
|
* @param str 字符串
|
||||||
|
* @returns 分割后的数组
|
||||||
|
*/
|
||||||
|
const splitByComma = (str: string): string[] => {
|
||||||
|
const arr: string[] = []
|
||||||
|
let start = 0
|
||||||
|
let inBracket = false
|
||||||
|
for (let i = 0; i < str.length; i++) {
|
||||||
|
if (str[i] === ',' && !inBracket) {
|
||||||
|
arr.push(str.substring(start, i).trim())
|
||||||
|
start = i + 1
|
||||||
|
} else if (str[i].match(bracketRegex)) {
|
||||||
|
inBracket = !inBracket
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arr.push(str.substring(start).trim())
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清洗字符串并输出数组
|
||||||
|
* @param str 字符串
|
||||||
|
* @returns 清洗后的数组
|
||||||
|
*/
|
||||||
|
const cleanStr = (str: string): string[] => {
|
||||||
|
let arr = splitByBracket(str)
|
||||||
|
arr = arr.flatMap((s) => splitByComma(s))
|
||||||
|
return arr.filter((s) => s !== '')
|
||||||
|
}
|
||||||
|
|
||||||
|
return cleanStr(str)
|
||||||
|
.filter((item) => {
|
||||||
|
const pattern = /^[,\s, ]+$/
|
||||||
|
return !pattern.test(item)
|
||||||
|
})
|
||||||
|
.filter(Boolean)
|
||||||
|
.sort((a, b) => {
|
||||||
|
return a.includes('<') && !b.includes('<') ? 1 : b.includes('<') && !a.includes('<') ? -1 : 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将数组转换成字符串
|
||||||
|
* @param array 数组
|
||||||
|
* @returns 转换后的字符串
|
||||||
|
*/
|
||||||
|
static convertArray2Str(array: string[]): string {
|
||||||
|
const newArray = array.map((item) => {
|
||||||
|
if (item.includes('<')) return item
|
||||||
|
const newItem = item
|
||||||
|
.replace(/\s+/g, ' ')
|
||||||
|
.replace(/\,|\.|\。/g, ',')
|
||||||
|
.replace(/\“|\‘|\”|\"|\\|\//g, '')
|
||||||
|
.replace(/\, /g, ',')
|
||||||
|
.replace(/\,\,/g, ',')
|
||||||
|
.replace(/\,/g, ', ')
|
||||||
|
return Converter.convertStr2Array(newItem).join(', ')
|
||||||
|
})
|
||||||
|
return newArray.join(', ')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将输入的字符串转换成特定格式的字符串
|
||||||
|
* @param input 输入的字符串
|
||||||
|
* @returns 转换后的字符串
|
||||||
|
*/
|
||||||
|
static convert(input: string): string {
|
||||||
|
const re_attention = /\{|\[|\}|\]|[^\{\}\[\]]+/gmu
|
||||||
|
|
||||||
|
let text = Converter.convertStr(input)
|
||||||
|
const textArray = Converter.convertStr2Array(text)
|
||||||
|
text = Converter.convertArray2Str(textArray)
|
||||||
|
|
||||||
|
let res: [string, number][] = []
|
||||||
|
|
||||||
|
const curly_bracket_multiplier = 1.05
|
||||||
|
const square_bracket_multiplier = 1 / 1.05
|
||||||
|
|
||||||
|
const brackets: Record<string, { stack: number[]; multiplier: number }> = {
|
||||||
|
'{': { stack: [], multiplier: curly_bracket_multiplier },
|
||||||
|
'[': { stack: [], multiplier: square_bracket_multiplier },
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将指定范围内的数字乘以指定倍数
|
||||||
|
* @param start_position 起始位置
|
||||||
|
* @param multiplier 倍数
|
||||||
|
*/
|
||||||
|
function multiply_range(start_position: number, multiplier: number) {
|
||||||
|
for (let pos = start_position; pos < res.length; pos++) {
|
||||||
|
res[pos][1] = Converter.round(res[pos][1] * multiplier)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const match of text.matchAll(re_attention)) {
|
||||||
|
let word = match[0]
|
||||||
|
|
||||||
|
if (word in brackets) {
|
||||||
|
brackets[word].stack.push(res.length)
|
||||||
|
} else if (word == '}' || word == ']') {
|
||||||
|
const bracket = brackets[word === '}' ? '{' : '[']
|
||||||
|
if (bracket.stack.length > 0) {
|
||||||
|
multiply_range(bracket.stack.pop()!, bracket.multiplier)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res.push([word, 1.0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const bracketType in brackets) {
|
||||||
|
for (const pos of brackets[bracketType].stack) {
|
||||||
|
multiply_range(pos, brackets[bracketType].multiplier)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.length == 0) {
|
||||||
|
res = [['', 1.0]]
|
||||||
|
}
|
||||||
|
|
||||||
|
let i = 0
|
||||||
|
while (i + 1 < res.length) {
|
||||||
|
if (res[i][1] == res[i + 1][1]) {
|
||||||
|
res[i][0] += res[i + 1][0]
|
||||||
|
res.splice(i + 1, 1)
|
||||||
|
} else {
|
||||||
|
i += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = ''
|
||||||
|
for (const [word, value] of res) {
|
||||||
|
result += value === 1.0 ? word : `(${word}:${value.toString()})`
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 触发 input 事件
|
||||||
|
* @param target 目标元素
|
||||||
|
*/
|
||||||
|
static dispatchInputEvent(target: EventTarget) {
|
||||||
|
let inputEvent = new Event('input')
|
||||||
|
Object.defineProperty(inputEvent, 'target', { value: target })
|
||||||
|
target.dispatchEvent(inputEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 点击转换按钮的事件处理函数
|
||||||
|
* @param type 类型
|
||||||
|
*/
|
||||||
|
static onClickConvert(type: string) {
|
||||||
|
const default_prompt = ''
|
||||||
|
const default_negative = ''
|
||||||
|
|
||||||
|
const prompt = gradioApp().querySelector(`#${type}_prompt > label > textarea`) as HTMLTextAreaElement
|
||||||
|
const result = Converter.convert(prompt.value)
|
||||||
|
prompt.value = result.match(/^masterpiece, best quality,/) === null ? default_prompt + result : result
|
||||||
|
Converter.dispatchInputEvent(prompt)
|
||||||
|
const negprompt = gradioApp().querySelector(`#${type}_neg_prompt > label > textarea`) as HTMLTextAreaElement
|
||||||
|
const negResult = Converter.convert(negprompt.value)
|
||||||
|
negprompt.value =
|
||||||
|
negResult.match(/^lowres,/) === null
|
||||||
|
? negResult.length === 0
|
||||||
|
? default_negative
|
||||||
|
: default_negative + negResult
|
||||||
|
: negResult
|
||||||
|
Converter.dispatchInputEvent(negprompt)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建转换按钮
|
||||||
|
* @param id 按钮 id
|
||||||
|
* @param innerHTML 按钮文本
|
||||||
|
* @param onClick 点击事件处理函数
|
||||||
|
* @returns 新建的按钮元素
|
||||||
|
*/
|
||||||
|
static createButton(id: string, innerHTML: string, onClick: () => void): HTMLButtonElement {
|
||||||
|
const button = document.createElement('button')
|
||||||
|
button.id = id
|
||||||
|
button.type = 'button'
|
||||||
|
button.innerHTML = innerHTML
|
||||||
|
button.title = 'Format prompt~🪄'
|
||||||
|
button.className = 'lg secondary gradio-button tool svelte-1ipelgc'
|
||||||
|
button.addEventListener('click', onClick)
|
||||||
|
return button
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加转换按钮
|
||||||
|
* @param type - 组件类型
|
||||||
|
*/
|
||||||
|
static addPromptButton(type: string): void {
|
||||||
|
const generateBtn: HTMLElement | null = gradioApp().querySelector(`#${type}_generate`)
|
||||||
|
const actionsColumn: HTMLElement | null = gradioApp().querySelector(`#${type}_style_create`)
|
||||||
|
const nai2local: HTMLElement | null = gradioApp().querySelector(`#${type}_formatconvert`)
|
||||||
|
if (!generateBtn || !actionsColumn || nai2local) return
|
||||||
|
const convertBtn: HTMLElement = Converter.createButton(`${type}_formatconvert`, '🪄', () =>
|
||||||
|
Converter.onClickConvert(type)
|
||||||
|
)
|
||||||
|
actionsColumn.parentNode?.append(convertBtn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册UI更新回调函数
|
||||||
|
* 在UI更新时添加提示按钮
|
||||||
|
*/
|
||||||
|
onUiUpdate(() => {
|
||||||
|
Converter.addPromptButton('txt2img')
|
||||||
|
Converter.addPromptButton('img2img')
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
interface ErrorString {
|
||||||
|
regex: string
|
||||||
|
error: string
|
||||||
|
}
|
||||||
|
|
||||||
|
class BracketChecker {
|
||||||
|
private textArea: HTMLTextAreaElement
|
||||||
|
private counterElt: HTMLElement
|
||||||
|
private errorStrings: ErrorString[]
|
||||||
|
|
||||||
|
constructor(textArea: HTMLTextAreaElement, counterElt: HTMLElement) {
|
||||||
|
this.textArea = textArea
|
||||||
|
this.counterElt = counterElt
|
||||||
|
this.errorStrings = [
|
||||||
|
{
|
||||||
|
regex: '\\(',
|
||||||
|
error: '(...) - Different number of opening and closing parentheses detected.\n',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
regex: '\\[',
|
||||||
|
error: '[...] - Different number of opening and closing square brackets detected.\n',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
regex: '\\{',
|
||||||
|
error: '{...} - Different number of opening and closing curly brackets detected.\n',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查文本框中的括号是否匹配,并更新计数器元素的标题和样式
|
||||||
|
*/
|
||||||
|
public check = (): void => {
|
||||||
|
let title = ''
|
||||||
|
this.errorStrings.forEach(({ regex, error }) => {
|
||||||
|
const openMatches = (this.textArea.value.match(new RegExp(regex, 'g')) || []).length
|
||||||
|
const closeMatches = (
|
||||||
|
this.textArea.value.match(new RegExp(regex.replace(/\(/g, ')').replace(/\[/g, ']').replace(/\{/g, '}'), 'g')) ||
|
||||||
|
[]
|
||||||
|
).length
|
||||||
|
if (openMatches !== closeMatches) {
|
||||||
|
if (!this.counterElt.title.includes(error)) {
|
||||||
|
title += error
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
title = this.counterElt.title.replace(error, '')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.counterElt.title = title
|
||||||
|
this.counterElt.classList.toggle('error', !!title)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化括号匹配检查器
|
||||||
|
* @param id_prompt 包含文本框的元素的 ID
|
||||||
|
* @param id_counter 显示计数器的元素的 ID
|
||||||
|
*/
|
||||||
|
function setupBracketChecking(idPrompt: string, idCounter: string): void {
|
||||||
|
const textarea = gradioApp().querySelector(`#${idPrompt} > label > textarea`) as HTMLTextAreaElement
|
||||||
|
const counter = gradioApp().getElementById(idCounter) as HTMLElement
|
||||||
|
const bracketChecker = new BracketChecker(textarea, counter)
|
||||||
|
textarea.addEventListener('input', bracketChecker.check)
|
||||||
|
}
|
||||||
|
|
||||||
|
const shadowRootLoaded = setInterval(() => {
|
||||||
|
const shadowRoot = document.querySelector('gradio-app')?.shadowRoot
|
||||||
|
if (!shadowRoot) return
|
||||||
|
const shadowTextArea = shadowRoot.querySelector(`#txt2img_prompt > label > textarea`) as HTMLTextAreaElement
|
||||||
|
if (!shadowTextArea) return
|
||||||
|
clearInterval(shadowRootLoaded)
|
||||||
|
;['txt2img', 'txt2img_neg', 'img2img', 'img2img_neg'].forEach((prompt) => {
|
||||||
|
setupBracketChecking(`${prompt}_prompt`, `${prompt}_token_counter`)
|
||||||
|
setupBracketChecking(`${prompt}_prompt`, `${prompt}_negative_token_counter`)
|
||||||
|
})
|
||||||
|
}, 1000)
|
||||||
|
|
@ -9,11 +9,7 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background: linear-gradient(
|
background: linear-gradient(180deg, rgba(0, 0, 0, 0.8), transparent) !important;
|
||||||
180deg,
|
|
||||||
rgba(0, 0, 0, 0.8),
|
|
||||||
transparent
|
|
||||||
) !important;
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
&:hover {
|
&:hover {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
|
|
||||||
|
|
@ -63,10 +63,9 @@
|
||||||
--paddingXL: calc(8px * var(--paddingBase));
|
--paddingXL: calc(8px * var(--paddingBase));
|
||||||
|
|
||||||
/* Shadow */
|
/* Shadow */
|
||||||
--boxShadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08),
|
--boxShadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
|
||||||
0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
|
--boxShadowSecondary: 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12),
|
||||||
--boxShadowSecondary: 0 6px 16px 0 rgba(0, 0, 0, 0.08),
|
0 9px 28px 8px rgba(0, 0, 0, 0.05);
|
||||||
0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
|
|
||||||
|
|
||||||
/* Border */
|
/* Border */
|
||||||
--borderRadiusBase: 2;
|
--borderRadiusBase: 2;
|
||||||
|
|
|
||||||
|
|
@ -54,9 +54,8 @@
|
||||||
--loader-color: var(--color-accent);
|
--loader-color: var(--color-accent);
|
||||||
|
|
||||||
/* Typography */
|
/* Typography */
|
||||||
--font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
--font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif,
|
||||||
'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji',
|
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
||||||
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
|
||||||
--font-mono: 'Hack', 'IBM Plex Mono', 'ui-monospace', 'Consolas', monospace;
|
--font-mono: 'Hack', 'IBM Plex Mono', 'ui-monospace', 'Consolas', monospace;
|
||||||
--prose-header-text-weight: 600;
|
--prose-header-text-weight: 600;
|
||||||
--prose-text-weight: 400;
|
--prose-text-weight: 400;
|
||||||
|
|
@ -132,10 +131,8 @@
|
||||||
--block-title-text-color: var(--neutral-200);
|
--block-title-text-color: var(--neutral-200);
|
||||||
--block-info-text-size: var(--text-sm);
|
--block-info-text-size: var(--text-sm);
|
||||||
--block-label-padding: var(--spacing-sm) var(--spacing-lg);
|
--block-label-padding: var(--spacing-sm) var(--spacing-lg);
|
||||||
--block-label-radius: calc(var(--radius-lg) - 1px) 0
|
--block-label-radius: calc(var(--radius-lg) - 1px) 0 calc(var(--radius-lg) - 1px) 0;
|
||||||
calc(var(--radius-lg) - 1px) 0;
|
--block-label-right-radius: 0 calc(var(--radius-lg) - 1px) 0 calc(var(--radius-lg) - 1px);
|
||||||
--block-label-right-radius: 0 calc(var(--radius-lg) - 1px) 0
|
|
||||||
calc(var(--radius-lg) - 1px);
|
|
||||||
--block-label-text-size: var(--text-sm);
|
--block-label-text-size: var(--text-sm);
|
||||||
--block-padding: var(--spacing-xl) calc(var(--spacing-xl) + 2px);
|
--block-padding: var(--spacing-xl) calc(var(--spacing-xl) + 2px);
|
||||||
--block-radius: var(--radius-lg);
|
--block-radius: var(--radius-lg);
|
||||||
|
|
@ -168,9 +165,7 @@
|
||||||
--button-primary-border-color-hover: var(--button-primary-border-color);
|
--button-primary-border-color-hover: var(--button-primary-border-color);
|
||||||
--button-primary-text-color-hover: var(--button-primary-text-color);
|
--button-primary-text-color-hover: var(--button-primary-text-color);
|
||||||
--button-secondary-background-fill: var(--neutral-600);
|
--button-secondary-background-fill: var(--neutral-600);
|
||||||
--button-secondary-background-fill-hover: var(
|
--button-secondary-background-fill-hover: var(--button-secondary-background-fill);
|
||||||
--button-secondary-background-fill
|
|
||||||
);
|
|
||||||
--button-secondary-border-color: var(--neutral-600);
|
--button-secondary-border-color: var(--neutral-600);
|
||||||
--button-secondary-border-color-hover: var(--button-secondary-border-color);
|
--button-secondary-border-color-hover: var(--button-secondary-border-color);
|
||||||
--button-secondary-text-color-hover: var(--button-secondary-text-color);
|
--button-secondary-text-color-hover: var(--button-secondary-text-color);
|
||||||
|
|
@ -195,12 +190,8 @@
|
||||||
--checkbox-border-color-selected: var(--secondary-600);
|
--checkbox-border-color-selected: var(--secondary-600);
|
||||||
--checkbox-border-width: var(--input-border-width);
|
--checkbox-border-width: var(--input-border-width);
|
||||||
--checkbox-label-background-fill: var(--button-secondary-background-fill);
|
--checkbox-label-background-fill: var(--button-secondary-background-fill);
|
||||||
--checkbox-label-background-fill-hover: var(
|
--checkbox-label-background-fill-hover: var(--button-secondary-background-fill-hover);
|
||||||
--button-secondary-background-fill-hover
|
--checkbox-label-background-fill-selected: var(--checkbox-label-background-fill);
|
||||||
);
|
|
||||||
--checkbox-label-background-fill-selected: var(
|
|
||||||
--checkbox-label-background-fill
|
|
||||||
);
|
|
||||||
--checkbox-label-border-color: var(--border-color-primary);
|
--checkbox-label-border-color: var(--border-color-primary);
|
||||||
--checkbox-label-border-color-hover: var(--checkbox-label-border-color);
|
--checkbox-label-border-color-hover: var(--checkbox-label-border-color);
|
||||||
--checkbox-label-border-width: var(--input-border-width);
|
--checkbox-label-border-width: var(--input-border-width);
|
||||||
|
|
|
||||||
|
|
@ -54,9 +54,8 @@
|
||||||
--loader-color: var(--color-accent);
|
--loader-color: var(--color-accent);
|
||||||
|
|
||||||
/* Typography */
|
/* Typography */
|
||||||
--font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
--font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif,
|
||||||
'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji',
|
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
||||||
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
|
||||||
--font-mono: 'Hack', 'IBM Plex Mono', 'ui-monospace', 'Consolas', monospace;
|
--font-mono: 'Hack', 'IBM Plex Mono', 'ui-monospace', 'Consolas', monospace;
|
||||||
--prose-header-text-weight: 600;
|
--prose-header-text-weight: 600;
|
||||||
--prose-text-weight: 400;
|
--prose-text-weight: 400;
|
||||||
|
|
@ -130,10 +129,8 @@
|
||||||
--block-label-background-fill: var(--background-fill-primary);
|
--block-label-background-fill: var(--background-fill-primary);
|
||||||
--block-label-border-color: var(--border-color-primary);
|
--block-label-border-color: var(--border-color-primary);
|
||||||
--block-label-padding: var(--spacing-sm) var(--spacing-lg);
|
--block-label-padding: var(--spacing-sm) var(--spacing-lg);
|
||||||
--block-label-radius: calc(var(--radius-lg) - 1px) 0
|
--block-label-radius: calc(var(--radius-lg) - 1px) 0 calc(var(--radius-lg) - 1px) 0;
|
||||||
calc(var(--radius-lg) - 1px) 0;
|
--block-label-right-radius: 0 calc(var(--radius-lg) - 1px) 0 calc(var(--radius-lg) - 1px);
|
||||||
--block-label-right-radius: 0 calc(var(--radius-lg) - 1px) 0
|
|
||||||
calc(var(--radius-lg) - 1px);
|
|
||||||
--block-label-text-color: var(--neutral-500);
|
--block-label-text-color: var(--neutral-500);
|
||||||
--block-label-text-size: var(--text-sm);
|
--block-label-text-size: var(--text-sm);
|
||||||
--block-padding: var(--spacing-xl) calc(var(--spacing-xl) + 2px);
|
--block-padding: var(--spacing-xl) calc(var(--spacing-xl) + 2px);
|
||||||
|
|
@ -170,9 +167,7 @@
|
||||||
--button-primary-text-color: var(--primary-600);
|
--button-primary-text-color: var(--primary-600);
|
||||||
--button-primary-text-color-hover: var(--button-primary-text-color);
|
--button-primary-text-color-hover: var(--button-primary-text-color);
|
||||||
--button-secondary-background-fill: var(--neutral-200);
|
--button-secondary-background-fill: var(--neutral-200);
|
||||||
--button-secondary-background-fill-hover: var(
|
--button-secondary-background-fill-hover: var(--button-secondary-background-fill);
|
||||||
--button-secondary-background-fill
|
|
||||||
);
|
|
||||||
--button-secondary-border-color: var(--neutral-200);
|
--button-secondary-border-color: var(--neutral-200);
|
||||||
--button-secondary-border-color-hover: var(--button-secondary-border-color);
|
--button-secondary-border-color-hover: var(--button-secondary-border-color);
|
||||||
--button-secondary-text-color: var(--neutral-700);
|
--button-secondary-text-color: var(--neutral-700);
|
||||||
|
|
@ -196,12 +191,8 @@
|
||||||
--checkbox-border-radius: var(--radius-sm);
|
--checkbox-border-radius: var(--radius-sm);
|
||||||
--checkbox-border-width: var(--input-border-width);
|
--checkbox-border-width: var(--input-border-width);
|
||||||
--checkbox-label-background-fill: var(--button-secondary-background-fill);
|
--checkbox-label-background-fill: var(--button-secondary-background-fill);
|
||||||
--checkbox-label-background-fill-hover: var(
|
--checkbox-label-background-fill-hover: var(--button-secondary-background-fill-hover);
|
||||||
--button-secondary-background-fill-hover
|
--checkbox-label-background-fill-selected: var(--checkbox-label-background-fill);
|
||||||
);
|
|
||||||
--checkbox-label-background-fill-selected: var(
|
|
||||||
--checkbox-label-background-fill
|
|
||||||
);
|
|
||||||
--checkbox-label-border-color: var(--border-color-primary);
|
--checkbox-label-border-color: var(--border-color-primary);
|
||||||
--checkbox-label-border-color-hover: var(--checkbox-label-border-color);
|
--checkbox-label-border-color-hover: var(--checkbox-label-border-color);
|
||||||
--checkbox-label-border-width: var(--input-border-width);
|
--checkbox-label-border-width: var(--input-border-width);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
declare const gradioApp: () => DocumentFragment
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
declare const onUiUpdate: (callback: () => void) => void
|
||||||
|
declare const onUiLoaded: (callback: () => void) => void
|
||||||
|
declare const onUiTabChange: (callback: () => void) => void
|
||||||
|
declare const switch_to_txt2img: () => void
|
||||||
|
declare const switch_to_img2img: () => void
|
||||||
|
interface Window {
|
||||||
|
threedopenpose: {
|
||||||
|
onResize: (width: number, height: number) => void
|
||||||
|
onChangeCameraNear: (value: number) => void
|
||||||
|
onChangeCameraFar: (value: number) => void
|
||||||
|
onChangeCameraFocalLength: (value: number) => void
|
||||||
|
onChangeHeadSize: (value: number) => void
|
||||||
|
onChangeNoseToNeck: (value: number) => void
|
||||||
|
onChangeShoulderWidth: (value: number) => void
|
||||||
|
onChangeShoulderToHip: (value: number) => void
|
||||||
|
onChangeArmLength: (value: number) => void
|
||||||
|
onChangeForearm: (value: number) => void
|
||||||
|
onChangeUpperArm: (value: number) => void
|
||||||
|
onChangeHandSize: (value: number) => void
|
||||||
|
onChangeHips: (value: number) => void
|
||||||
|
onChangeLegLength: (value: number) => void
|
||||||
|
onChangeThigh: (value: number) => void
|
||||||
|
onChangeLowerLeg: (value: number) => void
|
||||||
|
onChangeFootSize: (value: number) => void
|
||||||
|
detectImage: () => void
|
||||||
|
setBackground: () => void
|
||||||
|
saveScene: () => void
|
||||||
|
loadScene: () => void
|
||||||
|
restoreLastSavedScene: () => void
|
||||||
|
undo: () => void
|
||||||
|
redo: () => void
|
||||||
|
randomPose: () => void
|
||||||
|
copyBodyZ: () => void
|
||||||
|
copyBodyX: () => void
|
||||||
|
removeBody: () => void
|
||||||
|
onChangeMoveMode: (value: boolean) => void
|
||||||
|
onChangeOnlyHand: (value: boolean) => void
|
||||||
|
onChangeEnablePreview: (value: boolean) => void
|
||||||
|
makeImages: () => void
|
||||||
|
sendTxt2img: (
|
||||||
|
pose_image: string | null,
|
||||||
|
pose_target: string,
|
||||||
|
depth_image: string | null,
|
||||||
|
depth_target: string,
|
||||||
|
normal_image: string | null,
|
||||||
|
normal_target: string,
|
||||||
|
canny_image: string | null,
|
||||||
|
canny_target: string
|
||||||
|
) => void
|
||||||
|
sendImg2img: (
|
||||||
|
pose_image: string,
|
||||||
|
pose_target: string,
|
||||||
|
depth_image: string,
|
||||||
|
depth_target: string,
|
||||||
|
normal_image: string,
|
||||||
|
normal_target: string,
|
||||||
|
canny_image: string,
|
||||||
|
canny_target: string
|
||||||
|
) => void
|
||||||
|
downloadPoseImage: (image: string | null) => void
|
||||||
|
downloadDepthImage: (image: string | null) => void
|
||||||
|
downloadNormalImage: (image: string | null) => void
|
||||||
|
downloadCannyImage: (image: string | null) => void
|
||||||
|
}
|
||||||
|
}
|
||||||
59
style.css
59
style.css
|
|
@ -366,10 +366,9 @@ template {
|
||||||
--paddingLG: calc(6px * var(--paddingBase));
|
--paddingLG: calc(6px * var(--paddingBase));
|
||||||
--paddingXL: calc(8px * var(--paddingBase));
|
--paddingXL: calc(8px * var(--paddingBase));
|
||||||
/* Shadow */
|
/* Shadow */
|
||||||
--boxShadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08),
|
--boxShadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
|
||||||
0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
|
--boxShadowSecondary: 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12),
|
||||||
--boxShadowSecondary: 0 6px 16px 0 rgba(0, 0, 0, 0.08),
|
0 9px 28px 8px rgba(0, 0, 0, 0.05);
|
||||||
0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
|
|
||||||
/* Border */
|
/* Border */
|
||||||
--borderRadiusBase: 2;
|
--borderRadiusBase: 2;
|
||||||
--borderRadiusXS: calc(1px * var(--borderRadiusBase));
|
--borderRadiusXS: calc(1px * var(--borderRadiusBase));
|
||||||
|
|
@ -430,9 +429,8 @@ template {
|
||||||
--link-text-color-visited: var(--secondary-500);
|
--link-text-color-visited: var(--secondary-500);
|
||||||
--loader-color: var(--color-accent);
|
--loader-color: var(--color-accent);
|
||||||
/* Typography */
|
/* Typography */
|
||||||
--font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
--font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif,
|
||||||
'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji',
|
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
||||||
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
|
||||||
--font-mono: 'Hack', 'IBM Plex Mono', 'ui-monospace', 'Consolas', monospace;
|
--font-mono: 'Hack', 'IBM Plex Mono', 'ui-monospace', 'Consolas', monospace;
|
||||||
--prose-header-text-weight: 600;
|
--prose-header-text-weight: 600;
|
||||||
--prose-text-weight: 400;
|
--prose-text-weight: 400;
|
||||||
|
|
@ -501,10 +499,8 @@ template {
|
||||||
--block-label-background-fill: var(--background-fill-primary);
|
--block-label-background-fill: var(--background-fill-primary);
|
||||||
--block-label-border-color: var(--border-color-primary);
|
--block-label-border-color: var(--border-color-primary);
|
||||||
--block-label-padding: var(--spacing-sm) var(--spacing-lg);
|
--block-label-padding: var(--spacing-sm) var(--spacing-lg);
|
||||||
--block-label-radius: calc(var(--radius-lg) - 1px) 0
|
--block-label-radius: calc(var(--radius-lg) - 1px) 0 calc(var(--radius-lg) - 1px) 0;
|
||||||
calc(var(--radius-lg) - 1px) 0;
|
--block-label-right-radius: 0 calc(var(--radius-lg) - 1px) 0 calc(var(--radius-lg) - 1px);
|
||||||
--block-label-right-radius: 0 calc(var(--radius-lg) - 1px) 0
|
|
||||||
calc(var(--radius-lg) - 1px);
|
|
||||||
--block-label-text-color: var(--neutral-500);
|
--block-label-text-color: var(--neutral-500);
|
||||||
--block-label-text-size: var(--text-sm);
|
--block-label-text-size: var(--text-sm);
|
||||||
--block-padding: var(--spacing-xl) calc(var(--spacing-xl) + 2px);
|
--block-padding: var(--spacing-xl) calc(var(--spacing-xl) + 2px);
|
||||||
|
|
@ -539,9 +535,7 @@ template {
|
||||||
--button-primary-text-color: var(--primary-600);
|
--button-primary-text-color: var(--primary-600);
|
||||||
--button-primary-text-color-hover: var(--button-primary-text-color);
|
--button-primary-text-color-hover: var(--button-primary-text-color);
|
||||||
--button-secondary-background-fill: var(--neutral-200);
|
--button-secondary-background-fill: var(--neutral-200);
|
||||||
--button-secondary-background-fill-hover: var(
|
--button-secondary-background-fill-hover: var(--button-secondary-background-fill);
|
||||||
--button-secondary-background-fill
|
|
||||||
);
|
|
||||||
--button-secondary-border-color: var(--neutral-200);
|
--button-secondary-border-color: var(--neutral-200);
|
||||||
--button-secondary-border-color-hover: var(--button-secondary-border-color);
|
--button-secondary-border-color-hover: var(--button-secondary-border-color);
|
||||||
--button-secondary-text-color: var(--neutral-700);
|
--button-secondary-text-color: var(--neutral-700);
|
||||||
|
|
@ -564,12 +558,8 @@ template {
|
||||||
--checkbox-border-radius: var(--radius-sm);
|
--checkbox-border-radius: var(--radius-sm);
|
||||||
--checkbox-border-width: var(--input-border-width);
|
--checkbox-border-width: var(--input-border-width);
|
||||||
--checkbox-label-background-fill: var(--button-secondary-background-fill);
|
--checkbox-label-background-fill: var(--button-secondary-background-fill);
|
||||||
--checkbox-label-background-fill-hover: var(
|
--checkbox-label-background-fill-hover: var(--button-secondary-background-fill-hover);
|
||||||
--button-secondary-background-fill-hover
|
--checkbox-label-background-fill-selected: var(--checkbox-label-background-fill);
|
||||||
);
|
|
||||||
--checkbox-label-background-fill-selected: var(
|
|
||||||
--checkbox-label-background-fill
|
|
||||||
);
|
|
||||||
--checkbox-label-border-color: var(--border-color-primary);
|
--checkbox-label-border-color: var(--border-color-primary);
|
||||||
--checkbox-label-border-color-hover: var(--checkbox-label-border-color);
|
--checkbox-label-border-color-hover: var(--checkbox-label-border-color);
|
||||||
--checkbox-label-border-width: var(--input-border-width);
|
--checkbox-label-border-width: var(--input-border-width);
|
||||||
|
|
@ -651,9 +641,8 @@ template {
|
||||||
--color-accent-soft: var(--neutral-700);
|
--color-accent-soft: var(--neutral-700);
|
||||||
--loader-color: var(--color-accent);
|
--loader-color: var(--color-accent);
|
||||||
/* Typography */
|
/* Typography */
|
||||||
--font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
--font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif,
|
||||||
'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji',
|
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
||||||
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
|
||||||
--font-mono: 'Hack', 'IBM Plex Mono', 'ui-monospace', 'Consolas', monospace;
|
--font-mono: 'Hack', 'IBM Plex Mono', 'ui-monospace', 'Consolas', monospace;
|
||||||
--prose-header-text-weight: 600;
|
--prose-header-text-weight: 600;
|
||||||
--prose-text-weight: 400;
|
--prose-text-weight: 400;
|
||||||
|
|
@ -724,10 +713,8 @@ template {
|
||||||
--block-title-text-color: var(--neutral-200);
|
--block-title-text-color: var(--neutral-200);
|
||||||
--block-info-text-size: var(--text-sm);
|
--block-info-text-size: var(--text-sm);
|
||||||
--block-label-padding: var(--spacing-sm) var(--spacing-lg);
|
--block-label-padding: var(--spacing-sm) var(--spacing-lg);
|
||||||
--block-label-radius: calc(var(--radius-lg) - 1px) 0
|
--block-label-radius: calc(var(--radius-lg) - 1px) 0 calc(var(--radius-lg) - 1px) 0;
|
||||||
calc(var(--radius-lg) - 1px) 0;
|
--block-label-right-radius: 0 calc(var(--radius-lg) - 1px) 0 calc(var(--radius-lg) - 1px);
|
||||||
--block-label-right-radius: 0 calc(var(--radius-lg) - 1px) 0
|
|
||||||
calc(var(--radius-lg) - 1px);
|
|
||||||
--block-label-text-size: var(--text-sm);
|
--block-label-text-size: var(--text-sm);
|
||||||
--block-padding: var(--spacing-xl) calc(var(--spacing-xl) + 2px);
|
--block-padding: var(--spacing-xl) calc(var(--spacing-xl) + 2px);
|
||||||
--block-radius: var(--radius-lg);
|
--block-radius: var(--radius-lg);
|
||||||
|
|
@ -758,9 +745,7 @@ template {
|
||||||
--button-primary-border-color-hover: var(--button-primary-border-color);
|
--button-primary-border-color-hover: var(--button-primary-border-color);
|
||||||
--button-primary-text-color-hover: var(--button-primary-text-color);
|
--button-primary-text-color-hover: var(--button-primary-text-color);
|
||||||
--button-secondary-background-fill: var(--neutral-600);
|
--button-secondary-background-fill: var(--neutral-600);
|
||||||
--button-secondary-background-fill-hover: var(
|
--button-secondary-background-fill-hover: var(--button-secondary-background-fill);
|
||||||
--button-secondary-background-fill
|
|
||||||
);
|
|
||||||
--button-secondary-border-color: var(--neutral-600);
|
--button-secondary-border-color: var(--neutral-600);
|
||||||
--button-secondary-border-color-hover: var(--button-secondary-border-color);
|
--button-secondary-border-color-hover: var(--button-secondary-border-color);
|
||||||
--button-secondary-text-color-hover: var(--button-secondary-text-color);
|
--button-secondary-text-color-hover: var(--button-secondary-text-color);
|
||||||
|
|
@ -784,12 +769,8 @@ template {
|
||||||
--checkbox-border-color-selected: var(--secondary-600);
|
--checkbox-border-color-selected: var(--secondary-600);
|
||||||
--checkbox-border-width: var(--input-border-width);
|
--checkbox-border-width: var(--input-border-width);
|
||||||
--checkbox-label-background-fill: var(--button-secondary-background-fill);
|
--checkbox-label-background-fill: var(--button-secondary-background-fill);
|
||||||
--checkbox-label-background-fill-hover: var(
|
--checkbox-label-background-fill-hover: var(--button-secondary-background-fill-hover);
|
||||||
--button-secondary-background-fill-hover
|
--checkbox-label-background-fill-selected: var(--checkbox-label-background-fill);
|
||||||
);
|
|
||||||
--checkbox-label-background-fill-selected: var(
|
|
||||||
--checkbox-label-background-fill
|
|
||||||
);
|
|
||||||
--checkbox-label-border-color: var(--border-color-primary);
|
--checkbox-label-border-color: var(--border-color-primary);
|
||||||
--checkbox-label-border-color-hover: var(--checkbox-label-border-color);
|
--checkbox-label-border-color-hover: var(--checkbox-label-border-color);
|
||||||
--checkbox-label-border-width: var(--input-border-width);
|
--checkbox-label-border-width: var(--input-border-width);
|
||||||
|
|
@ -1127,11 +1108,7 @@ div.svelte-awbtu4 .gradio-file {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background: linear-gradient(
|
background: linear-gradient(180deg, rgba(0, 0, 0, 0.8), transparent) !important;
|
||||||
180deg,
|
|
||||||
rgba(0, 0, 0, 0.8),
|
|
||||||
transparent
|
|
||||||
) !important;
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
.extra-network-thumbs .actions .additional > ul:hover {
|
.extra-network-thumbs .actions .additional > ul:hover {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"noEmit": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"extends": "./src/.umi/tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ESNext",
|
||||||
|
"useDefineForClassFields": true,
|
||||||
|
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
||||||
|
"allowJs": false,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"esModuleInterop": false,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"strict": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "Node",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"jsx": "react-jsx"
|
||||||
|
},
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import 'umi/typings'
|
||||||
|
|
@ -1,27 +1,27 @@
|
||||||
const fs = require('fs');
|
const fs = require('fs')
|
||||||
const path = require('path');
|
const path = require('path')
|
||||||
|
|
||||||
// 从本地文件读取CSS
|
// 从本地文件读取CSS
|
||||||
const cssFilePath = path.resolve(__dirname, 'style.css');
|
const cssFilePath = path.resolve(__dirname, 'style.css')
|
||||||
const css = fs.readFileSync(cssFilePath, 'utf-8');
|
const css = fs.readFileSync(cssFilePath, 'utf-8')
|
||||||
|
|
||||||
// 用于存储变量及其值的对象
|
// 用于存储变量及其值的对象
|
||||||
const cssVariables = {};
|
const cssVariables = {}
|
||||||
|
|
||||||
// 正则表达式用于匹配CSS变量及其值
|
// 正则表达式用于匹配CSS变量及其值
|
||||||
const cssVarRegex = /--\w+[^:]*:\s*([^;]*);/g;
|
const cssVarRegex = /--\w+[^:]*:\s*([^;]*);/g
|
||||||
const cssVarReferenceRegex = /var\((--\w+)\)/g;
|
const cssVarReferenceRegex = /var\((--\w+)\)/g
|
||||||
|
|
||||||
// 解析CSS变量及其值
|
// 解析CSS变量及其值
|
||||||
let match;
|
let match
|
||||||
while ((match = cssVarRegex.exec(css))) {
|
while ((match = cssVarRegex.exec(css))) {
|
||||||
const variable = match[0].split(':')[0].trim();
|
const variable = match[0].split(':')[0].trim()
|
||||||
const value = match[1].trim();
|
const value = match[1].trim()
|
||||||
cssVariables[variable] = value;
|
cssVariables[variable] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
// 对变量进行排序,确保被引用的变量在引用它的变量之前
|
// 对变量进行排序,确保被引用的变量在引用它的变量之前
|
||||||
const sortedVariables = Object.keys(cssVariables);
|
const sortedVariables = Object.keys(cssVariables)
|
||||||
|
|
||||||
// 按类别对变量进行分组
|
// 按类别对变量进行分组
|
||||||
const groups = {
|
const groups = {
|
||||||
|
|
@ -38,68 +38,63 @@ const groups = {
|
||||||
input: [],
|
input: [],
|
||||||
table: [],
|
table: [],
|
||||||
other: [],
|
other: [],
|
||||||
};
|
}
|
||||||
|
|
||||||
sortedVariables.forEach((variable) => {
|
sortedVariables.forEach((variable) => {
|
||||||
const value = cssVariables[variable];
|
const value = cssVariables[variable]
|
||||||
const isColor =
|
const isColor =
|
||||||
value.startsWith('#') ||
|
value.startsWith('#') ||
|
||||||
value.includes('rgb') ||
|
value.includes('rgb') ||
|
||||||
value.includes('color') ||
|
value.includes('color') ||
|
||||||
variable.includes('color') ||
|
variable.includes('color') ||
|
||||||
variable.includes('fill') ||
|
variable.includes('fill') ||
|
||||||
variable.includes('neutral');
|
variable.includes('neutral')
|
||||||
const isTypography =
|
const isTypography =
|
||||||
variable.includes('text') ||
|
variable.includes('text') || variable.includes('font') || variable.includes('prose') || variable.includes('link')
|
||||||
variable.includes('font') ||
|
|
||||||
variable.includes('prose') ||
|
|
||||||
variable.includes('link');
|
|
||||||
const isSpacing =
|
const isSpacing =
|
||||||
variable.includes('spacing') ||
|
variable.includes('spacing') ||
|
||||||
variable.includes('padding') ||
|
variable.includes('padding') ||
|
||||||
variable.includes('gap') ||
|
variable.includes('gap') ||
|
||||||
variable.includes('margin');
|
variable.includes('margin')
|
||||||
value.includes('padding') || value.includes('margin');
|
value.includes('padding') || value.includes('margin')
|
||||||
const isBorder = variable.includes('radius') || variable.includes('border');
|
const isBorder = variable.includes('radius') || variable.includes('border')
|
||||||
const isBoxShadow = variable.includes('shadow');
|
const isBoxShadow = variable.includes('shadow')
|
||||||
if (variable.includes('--body')) {
|
if (variable.includes('--body')) {
|
||||||
groups.body.push(variable);
|
groups.body.push(variable)
|
||||||
} else if (variable.includes('--block')) {
|
} else if (variable.includes('--block')) {
|
||||||
groups.block.push(variable);
|
groups.block.push(variable)
|
||||||
} else if (variable.includes('--panel')) {
|
} else if (variable.includes('--panel')) {
|
||||||
groups.panel.push(variable);
|
groups.panel.push(variable)
|
||||||
} else if (variable.includes('--button')) {
|
} else if (variable.includes('--button')) {
|
||||||
groups.button.push(variable);
|
groups.button.push(variable)
|
||||||
} else if (variable.includes('--checkbox')) {
|
} else if (variable.includes('--checkbox')) {
|
||||||
groups.checkbox.push(variable);
|
groups.checkbox.push(variable)
|
||||||
} else if (variable.includes('--input')) {
|
} else if (variable.includes('--input')) {
|
||||||
groups.input.push(variable);
|
groups.input.push(variable)
|
||||||
} else if (variable.includes('--table')) {
|
} else if (variable.includes('--table')) {
|
||||||
groups.table.push(variable);
|
groups.table.push(variable)
|
||||||
} else if (isBorder) {
|
} else if (isBorder) {
|
||||||
groups.border.push(variable);
|
groups.border.push(variable)
|
||||||
} else if (isBoxShadow) {
|
} else if (isBoxShadow) {
|
||||||
groups.boxShadow.push(variable);
|
groups.boxShadow.push(variable)
|
||||||
} else if (isColor) {
|
} else if (isColor) {
|
||||||
groups.colors.push(variable);
|
groups.colors.push(variable)
|
||||||
} else if (isTypography) {
|
} else if (isTypography) {
|
||||||
groups.typography.push(variable);
|
groups.typography.push(variable)
|
||||||
} else if (isSpacing) {
|
} else if (isSpacing) {
|
||||||
groups.spacing.push(variable);
|
groups.spacing.push(variable)
|
||||||
} else {
|
} else {
|
||||||
groups.other.push(variable);
|
groups.other.push(variable)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
// 生成排序后的CSS变量
|
// 生成排序后的CSS变量
|
||||||
const generateGroupCss = (groupName) => {
|
const generateGroupCss = (groupName) => {
|
||||||
const cache = groups[groupName].map(
|
const cache = groups[groupName].map((variable) => `${variable}: ${cssVariables[variable]};`)
|
||||||
(variable) => `${variable}: ${cssVariables[variable]};`,
|
const firstPart = cache.filter((item) => item.includes('var'))
|
||||||
);
|
const secondPart = cache.filter((item) => !item.includes('var'))
|
||||||
const firstPart = cache.filter((item) => item.includes('var'));
|
return [...secondPart, ...firstPart].join('\n')
|
||||||
const secondPart = cache.filter((item) => !item.includes('var'));
|
}
|
||||||
return [...secondPart, ...firstPart].join('\n');
|
|
||||||
};
|
|
||||||
|
|
||||||
const sortedCss =
|
const sortedCss =
|
||||||
'#output {\n' +
|
'#output {\n' +
|
||||||
|
|
@ -129,9 +124,9 @@ const sortedCss =
|
||||||
generateGroupCss('table') +
|
generateGroupCss('table') +
|
||||||
`\n\n/* Other */\n` +
|
`\n\n/* Other */\n` +
|
||||||
generateGroupCss('other') +
|
generateGroupCss('other') +
|
||||||
'}';
|
'}'
|
||||||
|
|
||||||
console.log(sortedCss);
|
console.log(sortedCss)
|
||||||
|
|
||||||
// 将排序后的CSS变量写入文件
|
// 将排序后的CSS变量写入文件
|
||||||
fs.writeFileSync('sorted-css-variables.css', sortedCss);
|
fs.writeFileSync('sorted-css-variables.css', sortedCss)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue