Compare commits

..

No commits in common. 'dev' and 'master' have entirely different histories.
dev ... master

@ -1,10 +0,0 @@
module.exports = {
style: {
postcss: {
plugins: [
require('tailwindcss'),
require('autoprefixer'),
],
},
},
}

562
package-lock.json generated

@ -45,7 +45,6 @@
"jest-resolve": "^27.4.2",
"jest-watch-typeahead": "^1.0.0",
"mini-css-extract-plugin": "^2.4.5",
"openai": "^3.2.1",
"postcss": "^8.4.4",
"postcss-flexbugs-fixes": "^5.0.2",
"postcss-loader": "^6.2.1",
@ -3213,6 +3212,43 @@
"resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz",
"integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A=="
},
"node_modules/@mui/base": {
"version": "5.0.0-alpha.123",
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.123.tgz",
"integrity": "sha512-pxzcAfET3I6jvWqS4kijiLMn1OmdMw+mGmDa0SqmDZo3bXXdvLhpCCPqCkULG3UykhvFCOcU5HclOX3JCA+Zhg==",
"dependencies": {
"@babel/runtime": "^7.21.0",
"@emotion/is-prop-valid": "^1.2.0",
"@mui/types": "^7.2.3",
"@mui/utils": "^5.11.13",
"@popperjs/core": "^2.11.7",
"clsx": "^1.2.1",
"prop-types": "^15.8.1",
"react-is": "^18.2.0"
},
"engines": {
"node": ">=12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/mui"
},
"peerDependencies": {
"@types/react": "^17.0.0 || ^18.0.0",
"react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@mui/base/node_modules/react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
},
"node_modules/@mui/core-downloads-tracker": {
"version": "5.11.15",
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.15.tgz",
@ -3266,19 +3302,19 @@
}
}
},
"node_modules/@mui/material/node_modules/@mui/base": {
"version": "5.0.0-alpha.123",
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.123.tgz",
"integrity": "sha512-pxzcAfET3I6jvWqS4kijiLMn1OmdMw+mGmDa0SqmDZo3bXXdvLhpCCPqCkULG3UykhvFCOcU5HclOX3JCA+Zhg==",
"node_modules/@mui/material/node_modules/react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
},
"node_modules/@mui/private-theming": {
"version": "5.11.13",
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.13.tgz",
"integrity": "sha512-PJnYNKzW5LIx3R+Zsp6WZVPs6w5sEKJ7mgLNnUXuYB1zo5aX71FVLtV7geyPXRcaN2tsoRNK7h444ED0t7cIjA==",
"dependencies": {
"@babel/runtime": "^7.21.0",
"@emotion/is-prop-valid": "^1.2.0",
"@mui/types": "^7.2.3",
"@mui/utils": "^5.11.13",
"@popperjs/core": "^2.11.7",
"clsx": "^1.2.1",
"prop-types": "^15.8.1",
"react-is": "^18.2.0"
"prop-types": "^15.8.1"
},
"engines": {
"node": ">=12.0.0"
@ -3289,8 +3325,7 @@
},
"peerDependencies": {
"@types/react": "^17.0.0 || ^18.0.0",
"react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0"
"react": "^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
@ -3298,17 +3333,13 @@
}
}
},
"node_modules/@mui/material/node_modules/@mui/system": {
"version": "5.11.15",
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.15.tgz",
"integrity": "sha512-vCatoWCTnAPquoNifHbqMCMnOElEbLosVUeW0FQDyjCq+8yMABD9E6iY0s14O7iq1wD+qqU7rFAuDIVvJ/AzzA==",
"node_modules/@mui/styled-engine": {
"version": "5.11.11",
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.11.tgz",
"integrity": "sha512-wV0UgW4lN5FkDBXefN8eTYeuE9sjyQdg5h94vtwZCUamGQEzmCOtir4AakgmbWMy0x8OLjdEUESn9wnf5J9MOg==",
"dependencies": {
"@babel/runtime": "^7.21.0",
"@mui/private-theming": "^5.11.13",
"@mui/styled-engine": "^5.11.11",
"@mui/types": "^7.2.3",
"@mui/utils": "^5.11.13",
"clsx": "^1.2.1",
"@emotion/cache": "^11.10.5",
"csstype": "^3.1.1",
"prop-types": "^15.8.1"
},
@ -3320,9 +3351,8 @@
"url": "https://opencollective.com/mui"
},
"peerDependencies": {
"@emotion/react": "^11.5.0",
"@emotion/react": "^11.4.1",
"@emotion/styled": "^11.3.0",
"@types/react": "^17.0.0 || ^18.0.0",
"react": "^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
@ -3331,19 +3361,21 @@
},
"@emotion/styled": {
"optional": true
},
"@types/react": {
"optional": true
}
}
},
"node_modules/@mui/material/node_modules/@mui/system/node_modules/@mui/private-theming": {
"version": "5.11.13",
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.13.tgz",
"integrity": "sha512-PJnYNKzW5LIx3R+Zsp6WZVPs6w5sEKJ7mgLNnUXuYB1zo5aX71FVLtV7geyPXRcaN2tsoRNK7h444ED0t7cIjA==",
"node_modules/@mui/system": {
"version": "5.11.15",
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.15.tgz",
"integrity": "sha512-vCatoWCTnAPquoNifHbqMCMnOElEbLosVUeW0FQDyjCq+8yMABD9E6iY0s14O7iq1wD+qqU7rFAuDIVvJ/AzzA==",
"dependencies": {
"@babel/runtime": "^7.21.0",
"@mui/private-theming": "^5.11.13",
"@mui/styled-engine": "^5.11.11",
"@mui/types": "^7.2.3",
"@mui/utils": "^5.11.13",
"clsx": "^1.2.1",
"csstype": "^3.1.1",
"prop-types": "^15.8.1"
},
"engines": {
@ -3354,47 +3386,37 @@
"url": "https://opencollective.com/mui"
},
"peerDependencies": {
"@emotion/react": "^11.5.0",
"@emotion/styled": "^11.3.0",
"@types/react": "^17.0.0 || ^18.0.0",
"react": "^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@emotion/react": {
"optional": true
},
"@emotion/styled": {
"optional": true
},
"@types/react": {
"optional": true
}
}
},
"node_modules/@mui/material/node_modules/@mui/system/node_modules/@mui/styled-engine": {
"version": "5.11.11",
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.11.tgz",
"integrity": "sha512-wV0UgW4lN5FkDBXefN8eTYeuE9sjyQdg5h94vtwZCUamGQEzmCOtir4AakgmbWMy0x8OLjdEUESn9wnf5J9MOg==",
"dependencies": {
"@babel/runtime": "^7.21.0",
"@emotion/cache": "^11.10.5",
"csstype": "^3.1.1",
"prop-types": "^15.8.1"
},
"engines": {
"node": ">=12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/mui"
},
"node_modules/@mui/types": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.3.tgz",
"integrity": "sha512-tZ+CQggbe9Ol7e/Fs5RcKwg/woU+o8DCtOnccX6KmbBc7YrfqMYEYuaIcXHuhpT880QwNkZZ3wQwvtlDFA2yOw==",
"peerDependencies": {
"@emotion/react": "^11.4.1",
"@emotion/styled": "^11.3.0",
"react": "^17.0.0 || ^18.0.0"
"@types/react": "*"
},
"peerDependenciesMeta": {
"@emotion/react": {
"optional": true
},
"@emotion/styled": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@mui/material/node_modules/@mui/utils": {
"node_modules/@mui/utils": {
"version": "5.11.13",
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.13.tgz",
"integrity": "sha512-5ltA58MM9euOuUcnvwFJqpLdEugc9XFsRR8Gt4zZNb31XzMfSKJPR4eumulyhsOTK1rWf7K4D63NKFPfX0AxqA==",
@ -3416,39 +3438,11 @@
"react": "^17.0.0 || ^18.0.0"
}
},
"node_modules/@mui/material/node_modules/react-is": {
"node_modules/@mui/utils/node_modules/react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
},
"node_modules/@mui/material/node_modules/react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
"integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
"dependencies": {
"@babel/runtime": "^7.5.5",
"dom-helpers": "^5.0.1",
"loose-envify": "^1.4.0",
"prop-types": "^15.6.2"
},
"peerDependencies": {
"react": ">=16.6.0",
"react-dom": ">=16.6.0"
}
},
"node_modules/@mui/types": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.3.tgz",
"integrity": "sha512-tZ+CQggbe9Ol7e/Fs5RcKwg/woU+o8DCtOnccX6KmbBc7YrfqMYEYuaIcXHuhpT880QwNkZZ3wQwvtlDFA2yOw==",
"peerDependencies": {
"@types/react": "*"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@nicolo-ribaudo/eslint-scope-5-internals": {
"version": "5.1.1-v1",
"resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz",
@ -12699,6 +12693,50 @@
"thenify-all": "^1.0.0"
}
},
"node_modules/nano-css": {
"version": "5.3.5",
"resolved": "https://registry.npmjs.org/nano-css/-/nano-css-5.3.5.tgz",
"integrity": "sha512-vSB9X12bbNu4ALBu7nigJgRViZ6ja3OU7CeuiV1zMIbXOdmkLahgtPmh3GBOlDxbKY0CitqlPdOReGlBLSp+yg==",
"dependencies": {
"css-tree": "^1.1.2",
"csstype": "^3.0.6",
"fastest-stable-stringify": "^2.0.2",
"inline-style-prefixer": "^6.0.0",
"rtl-css-js": "^1.14.0",
"sourcemap-codec": "^1.4.8",
"stacktrace-js": "^2.0.2",
"stylis": "^4.0.6"
},
"peerDependencies": {
"react": "*",
"react-dom": "*"
}
},
"node_modules/nano-css/node_modules/css-tree": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
"integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
"dependencies": {
"mdn-data": "2.0.14",
"source-map": "^0.6.1"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/nano-css/node_modules/mdn-data": {
"version": "2.0.14",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
"integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="
},
"node_modules/nano-css/node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/nanoid": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
@ -13020,36 +13058,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/openai": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/openai/-/openai-3.2.1.tgz",
"integrity": "sha512-762C9BNlJPbjjlWZi4WYK9iM2tAVAv0uUp1UmI34vb0CN5T2mjB/qM6RYBmNKMh/dN9fC+bxqPwWJZUTWW052A==",
"dependencies": {
"axios": "^0.26.0",
"form-data": "^4.0.0"
}
},
"node_modules/openai/node_modules/axios": {
"version": "0.26.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
"integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
"dependencies": {
"follow-redirects": "^1.14.8"
}
},
"node_modules/openai/node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/optionator": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
@ -14964,6 +14972,21 @@
"node": ">=0.10.0"
}
},
"node_modules/react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
"integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
"dependencies": {
"@babel/runtime": "^7.5.5",
"dom-helpers": "^5.0.1",
"loose-envify": "^1.4.0",
"prop-types": "^15.6.2"
},
"peerDependencies": {
"react": ">=16.6.0",
"react-dom": ">=16.6.0"
}
},
"node_modules/react-universal-interface": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz",
@ -14998,50 +15021,6 @@
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-use/node_modules/css-tree": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
"integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
"dependencies": {
"mdn-data": "2.0.14",
"source-map": "^0.6.1"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/react-use/node_modules/mdn-data": {
"version": "2.0.14",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
"integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="
},
"node_modules/react-use/node_modules/nano-css": {
"version": "5.3.5",
"resolved": "https://registry.npmjs.org/nano-css/-/nano-css-5.3.5.tgz",
"integrity": "sha512-vSB9X12bbNu4ALBu7nigJgRViZ6ja3OU7CeuiV1zMIbXOdmkLahgtPmh3GBOlDxbKY0CitqlPdOReGlBLSp+yg==",
"dependencies": {
"css-tree": "^1.1.2",
"csstype": "^3.0.6",
"fastest-stable-stringify": "^2.0.2",
"inline-style-prefixer": "^6.0.0",
"rtl-css-js": "^1.14.0",
"sourcemap-codec": "^1.4.8",
"stacktrace-js": "^2.0.2",
"stylis": "^4.0.6"
},
"peerDependencies": {
"react": "*",
"react-dom": "*"
}
},
"node_modules/react-use/node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@ -20139,6 +20118,28 @@
"resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz",
"integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A=="
},
"@mui/base": {
"version": "5.0.0-alpha.123",
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.123.tgz",
"integrity": "sha512-pxzcAfET3I6jvWqS4kijiLMn1OmdMw+mGmDa0SqmDZo3bXXdvLhpCCPqCkULG3UykhvFCOcU5HclOX3JCA+Zhg==",
"requires": {
"@babel/runtime": "^7.21.0",
"@emotion/is-prop-valid": "^1.2.0",
"@mui/types": "^7.2.3",
"@mui/utils": "^5.11.13",
"@popperjs/core": "^2.11.7",
"clsx": "^1.2.1",
"prop-types": "^15.8.1",
"react-is": "^18.2.0"
},
"dependencies": {
"react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
}
}
},
"@mui/core-downloads-tracker": {
"version": "5.11.15",
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.15.tgz",
@ -20163,95 +20164,74 @@
"react-transition-group": "^4.4.5"
},
"dependencies": {
"@mui/base": {
"version": "5.0.0-alpha.123",
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.123.tgz",
"integrity": "sha512-pxzcAfET3I6jvWqS4kijiLMn1OmdMw+mGmDa0SqmDZo3bXXdvLhpCCPqCkULG3UykhvFCOcU5HclOX3JCA+Zhg==",
"requires": {
"@babel/runtime": "^7.21.0",
"@emotion/is-prop-valid": "^1.2.0",
"@mui/types": "^7.2.3",
"@mui/utils": "^5.11.13",
"@popperjs/core": "^2.11.7",
"clsx": "^1.2.1",
"prop-types": "^15.8.1",
"react-is": "^18.2.0"
}
},
"@mui/system": {
"version": "5.11.15",
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.15.tgz",
"integrity": "sha512-vCatoWCTnAPquoNifHbqMCMnOElEbLosVUeW0FQDyjCq+8yMABD9E6iY0s14O7iq1wD+qqU7rFAuDIVvJ/AzzA==",
"requires": {
"@babel/runtime": "^7.21.0",
"@mui/private-theming": "^5.11.13",
"@mui/styled-engine": "^5.11.11",
"@mui/types": "^7.2.3",
"@mui/utils": "^5.11.13",
"clsx": "^1.2.1",
"csstype": "^3.1.1",
"prop-types": "^15.8.1"
},
"dependencies": {
"@mui/private-theming": {
"version": "5.11.13",
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.13.tgz",
"integrity": "sha512-PJnYNKzW5LIx3R+Zsp6WZVPs6w5sEKJ7mgLNnUXuYB1zo5aX71FVLtV7geyPXRcaN2tsoRNK7h444ED0t7cIjA==",
"requires": {
"@babel/runtime": "^7.21.0",
"@mui/utils": "^5.11.13",
"prop-types": "^15.8.1"
}
},
"@mui/styled-engine": {
"version": "5.11.11",
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.11.tgz",
"integrity": "sha512-wV0UgW4lN5FkDBXefN8eTYeuE9sjyQdg5h94vtwZCUamGQEzmCOtir4AakgmbWMy0x8OLjdEUESn9wnf5J9MOg==",
"requires": {
"@babel/runtime": "^7.21.0",
"@emotion/cache": "^11.10.5",
"csstype": "^3.1.1",
"prop-types": "^15.8.1"
}
}
}
},
"@mui/utils": {
"version": "5.11.13",
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.13.tgz",
"integrity": "sha512-5ltA58MM9euOuUcnvwFJqpLdEugc9XFsRR8Gt4zZNb31XzMfSKJPR4eumulyhsOTK1rWf7K4D63NKFPfX0AxqA==",
"requires": {
"@babel/runtime": "^7.21.0",
"@types/prop-types": "^15.7.5",
"@types/react-is": "^16.7.1 || ^17.0.0",
"prop-types": "^15.8.1",
"react-is": "^18.2.0"
}
},
"react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
},
"react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
"integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
"requires": {
"@babel/runtime": "^7.5.5",
"dom-helpers": "^5.0.1",
"loose-envify": "^1.4.0",
"prop-types": "^15.6.2"
}
}
}
},
"@mui/private-theming": {
"version": "5.11.13",
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.13.tgz",
"integrity": "sha512-PJnYNKzW5LIx3R+Zsp6WZVPs6w5sEKJ7mgLNnUXuYB1zo5aX71FVLtV7geyPXRcaN2tsoRNK7h444ED0t7cIjA==",
"requires": {
"@babel/runtime": "^7.21.0",
"@mui/utils": "^5.11.13",
"prop-types": "^15.8.1"
}
},
"@mui/styled-engine": {
"version": "5.11.11",
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.11.tgz",
"integrity": "sha512-wV0UgW4lN5FkDBXefN8eTYeuE9sjyQdg5h94vtwZCUamGQEzmCOtir4AakgmbWMy0x8OLjdEUESn9wnf5J9MOg==",
"requires": {
"@babel/runtime": "^7.21.0",
"@emotion/cache": "^11.10.5",
"csstype": "^3.1.1",
"prop-types": "^15.8.1"
}
},
"@mui/system": {
"version": "5.11.15",
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.15.tgz",
"integrity": "sha512-vCatoWCTnAPquoNifHbqMCMnOElEbLosVUeW0FQDyjCq+8yMABD9E6iY0s14O7iq1wD+qqU7rFAuDIVvJ/AzzA==",
"requires": {
"@babel/runtime": "^7.21.0",
"@mui/private-theming": "^5.11.13",
"@mui/styled-engine": "^5.11.11",
"@mui/types": "^7.2.3",
"@mui/utils": "^5.11.13",
"clsx": "^1.2.1",
"csstype": "^3.1.1",
"prop-types": "^15.8.1"
}
},
"@mui/types": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.3.tgz",
"integrity": "sha512-tZ+CQggbe9Ol7e/Fs5RcKwg/woU+o8DCtOnccX6KmbBc7YrfqMYEYuaIcXHuhpT880QwNkZZ3wQwvtlDFA2yOw==",
"requires": {}
},
"@mui/utils": {
"version": "5.11.13",
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.13.tgz",
"integrity": "sha512-5ltA58MM9euOuUcnvwFJqpLdEugc9XFsRR8Gt4zZNb31XzMfSKJPR4eumulyhsOTK1rWf7K4D63NKFPfX0AxqA==",
"requires": {
"@babel/runtime": "^7.21.0",
"@types/prop-types": "^15.7.5",
"@types/react-is": "^16.7.1 || ^17.0.0",
"prop-types": "^15.8.1",
"react-is": "^18.2.0"
},
"dependencies": {
"react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
}
}
},
"@nicolo-ribaudo/eslint-scope-5-internals": {
"version": "5.1.1-v1",
"resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz",
@ -27038,6 +27018,42 @@
"thenify-all": "^1.0.0"
}
},
"nano-css": {
"version": "5.3.5",
"resolved": "https://registry.npmjs.org/nano-css/-/nano-css-5.3.5.tgz",
"integrity": "sha512-vSB9X12bbNu4ALBu7nigJgRViZ6ja3OU7CeuiV1zMIbXOdmkLahgtPmh3GBOlDxbKY0CitqlPdOReGlBLSp+yg==",
"requires": {
"css-tree": "^1.1.2",
"csstype": "^3.0.6",
"fastest-stable-stringify": "^2.0.2",
"inline-style-prefixer": "^6.0.0",
"rtl-css-js": "^1.14.0",
"sourcemap-codec": "^1.4.8",
"stacktrace-js": "^2.0.2",
"stylis": "^4.0.6"
},
"dependencies": {
"css-tree": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
"integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
"requires": {
"mdn-data": "2.0.14",
"source-map": "^0.6.1"
}
},
"mdn-data": {
"version": "2.0.14",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
"integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
}
}
},
"nanoid": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
@ -27257,35 +27273,6 @@
"is-wsl": "^2.2.0"
}
},
"openai": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/openai/-/openai-3.2.1.tgz",
"integrity": "sha512-762C9BNlJPbjjlWZi4WYK9iM2tAVAv0uUp1UmI34vb0CN5T2mjB/qM6RYBmNKMh/dN9fC+bxqPwWJZUTWW052A==",
"requires": {
"axios": "^0.26.0",
"form-data": "^4.0.0"
},
"dependencies": {
"axios": {
"version": "0.26.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
"integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
"requires": {
"follow-redirects": "^1.14.8"
}
},
"form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
}
}
}
},
"optionator": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
@ -28488,6 +28475,17 @@
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
"integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A=="
},
"react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
"integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
"requires": {
"@babel/runtime": "^7.5.5",
"dom-helpers": "^5.0.1",
"loose-envify": "^1.4.0",
"prop-types": "^15.6.2"
}
},
"react-universal-interface": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz",
@ -28513,42 +28511,6 @@
"throttle-debounce": "^3.0.1",
"ts-easing": "^0.2.0",
"tslib": "^2.1.0"
},
"dependencies": {
"css-tree": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
"integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
"requires": {
"mdn-data": "2.0.14",
"source-map": "^0.6.1"
}
},
"mdn-data": {
"version": "2.0.14",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
"integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="
},
"nano-css": {
"version": "5.3.5",
"resolved": "https://registry.npmjs.org/nano-css/-/nano-css-5.3.5.tgz",
"integrity": "sha512-vSB9X12bbNu4ALBu7nigJgRViZ6ja3OU7CeuiV1zMIbXOdmkLahgtPmh3GBOlDxbKY0CitqlPdOReGlBLSp+yg==",
"requires": {
"css-tree": "^1.1.2",
"csstype": "^3.0.6",
"fastest-stable-stringify": "^2.0.2",
"inline-style-prefixer": "^6.0.0",
"rtl-css-js": "^1.14.0",
"sourcemap-codec": "^1.4.8",
"stacktrace-js": "^2.0.2",
"stylis": "^4.0.6"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
}
}
},
"read-cache": {

@ -4,7 +4,6 @@
"private": true,
"dependencies": {
"@babel/core": "^7.16.0",
"@craco/craco": "^7.1.0",
"@emotion/react": "^11.10.6",
"@emotion/styled": "^11.10.6",
"@mui/material": "^5.11.15",
@ -41,7 +40,6 @@
"jest-resolve": "^27.4.2",
"jest-watch-typeahead": "^1.0.0",
"mini-css-extract-plugin": "^2.4.5",
"openai": "^3.2.1",
"postcss": "^8.4.4",
"postcss-flexbugs-fixes": "^5.0.2",
"postcss-loader": "^6.2.1",

@ -3,7 +3,7 @@ import { GameUI } from "./scene/ui";
import React from "react";
function App() {
return (
<div className="App w-screen h-screen">
<div className="App">
<GameUI></GameUI>
</div>
);

@ -1,4 +1,4 @@
/* body {
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
@ -10,8 +10,4 @@
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
} */
@tailwind base;
@tailwind components;
@tailwind utilities;
}

@ -1,15 +1,14 @@
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById("root"));
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
// 关闭严格模式避免useEffect执行两次
// <React.StrictMode>
<App />
// </React.StrictMode>
<React.StrictMode>
<App />
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function

@ -1,338 +0,0 @@
import { Keyword } from "types";
/** 字典 */
export const PROMPT_DICT: {
[part: string]: Keyword[];
} = {
test: [
{
value: "黑长直",
class: "adj",
prompts: {
base: ["Flowing tresses", "Sleek and straight strands"],
hairColor: "Glossy black hair",
},
},
{
value: "伪娘",
class: "n",
prompts: {
base: [
"Feminine appearance",
"Cute outfit",
"Shimmering eyeshadow",
"High heeled shoes",
"Flawless skin",
"Feminine accessories",
"Graceful posture",
"Sweet smile",
"Playful demeanor",
"Girly charm",
],
},
},
{
value: "兔女郎",
class: "adj",
prompts: {
base: [
"Bunny girl",
"Rabbit ears",
"Cute",
"Playful",
"Sexy",
"Fluffy tail",
"Carrots",
"Easter",
"Pink",
"Thigh-high stockings",
"Bow tie",
"Curvy",
"Innocent",
"Sassy",
"Furry",
"Lustrous hair",
"Playmate",
],
},
},
{
value: "傲娇",
class: "adj",
prompts: {
base: [
"Arrogant",
"Cocky",
"Self-important",
"Self-centered",
"Narcissistic",
"Insolent",
"Condescending",
"Contemptuous",
],
},
},
{
value: "病娇",
class: "adj",
prompts: {
base: [
"Cutesy yet dangerous",
"Obsessive behavior",
"Innocent appearance with sinister undertones",
"Unstable emotions and mood swings",
"Lovesick and possessive",
"Clingy and needy",
"Outwardly sweet but inwardly devious",
"Intense and volatile personality",
"Can be manipulative and controlling",
"Dark and troubled past",
"Fragile and vulnerable",
"Plays the victim card",
"A mix of sweetness and insanity",
"Hard to resist but dangerous to cross",
"Demanding and high-maintenance",
"Perpetually in a state of emotional turmoil",
"Possesses a hidden dark side",
"Resistant to change and easily offended",
"Can be both alluring and terrifying at the same time",
],
},
},
{
value: "天然呆",
class: "adj",
prompts: {
base: [
"Adorkable",
"Innocent",
"Simple",
"Naive",
"Untainted",
" Quirky ",
" Unassuming ",
" Unsophisticated ",
" Endearing ",
" Sweet ",
" Charming ",
" Innocuous ",
" Childlike ",
" Nurturing ",
" Trusting ",
" Genuine ",
" Unpretentious ",
" Candid ",
" Artless ",
" Pure",
],
},
},
{
value: "抖S",
class: "adj",
prompts: {
base: [
" Whips",
" Dominatrix",
" Leather",
" Corsets",
" Chains",
" Risky behavior",
" Control",
" Submission",
" Spanking",
" Collars",
" Bondage",
" Black latex gloves",
" Safe words",
" Riding crop",
" Discipline",
" Pain",
" Pleasure",
" Body harness",
" Role playing",
" Power exchange",
],
},
},
{
value: "抖M",
class: "adj",
prompts: {
base: [
" Masochistic tendencies",
" Whips and chains",
" Submission",
" Punishment",
" Humiliation",
" Sadomasochism",
" Dominance",
" Role play",
" Bondage",
" Leather gear",
" Safeword",
" Power exchange",
" Consensual non-consent",
" Degradation",
" Foot worship",
" Cuffs and restraints",
" Impact play",
" Verbal humiliation",
" Chastity",
" Teasing and denial",
],
},
},
{
value: "泳装",
class: "adj",
prompts: {
base: [
" Beachwear ",
" Swimsuit ",
" Beach hat ",
" Sunglasses ",
" Sunscreen ",
" Bikini ",
" Poolside ",
" Water sports ",
" Sun-kissed ",
" Tanned skin ",
" Sun hat ",
" Beach bag ",
" Flip-flops ",
" Beach towel ",
" Ocean waves ",
" Board shorts ",
" Surfer girl ",
" Palm trees ",
" Sea shells ",
" Tropical paradise",
],
},
},
{
value: "银发",
class: "adj",
prompts: {
base: [
" Silver hair",
" Elderly person",
" Wise",
" Sophisticated",
" Grandparent",
" Dignified",
" Graceful",
" Experienced",
" Serene",
" Timeless",
" Refined",
" Regal",
" Elegant",
" Respected",
" Majestic",
" Honorable",
" Charismatic",
" Cultured",
" Prestigious",
" Noble",
],
},
},
{
value: "女仆",
class: "n",
prompts: {
base: [
" Maid costume",
" Serving tray",
" Feather duster",
" Bows and ribbons",
" Clean and tidy",
" Apron",
" High heels",
" Polite and respectful",
" Uniform",
" Updo hairstyle",
" Mistress or master",
" Tea set",
" Pinafore dress",
" Chores and tasks",
" Maid headband",
" Lace or frills",
" Domestic service",
" Well-groomed appearance",
" Submissive demeanor",
" Tidy and organized environment",
],
},
},
{
value: "美少女",
class: "n",
prompts: {
base: [
"Cute smile",
"Flowing dress",
"Rosy cheeks",
"Pink lips",
"Playful expression",
"Innocent blush",
"Elegant posture",
"Enchanting gaze",
"Delicate facial features",
"Graceful body language",
],
},
},
{
value: "御姐",
class: "n",
prompts: {
base: [
"Elegant",
"Confident",
"Seductive",
"Mysterious",
"Powerful",
"Regal",
"Graceful",
"Intimidating",
"Alluring",
"Sophisticated",
"Enigmatic",
"Enchanting",
"Imposing",
"Commanding",
"Glamorous",
"Queenly",
],
},
},
{
value: "萝莉",
class: "n",
prompts: {
base: [
"Innocent eyes",
"Petite stature",
"Blushing cheeks",
"Adorable smile",
"Cute bows",
"Vibrant colors",
"Playful expression",
"Over-sized hat",
"Flower headband",
"Candy-colored outfit",
"Plush toys",
],
},
},
],
};
/** 奖池 */
export const getLotteryPool = () =>
Object.values(PROMPT_DICT).reduce((pool, tokens) => {
return [...pool, ...tokens];
}, []);

@ -1,93 +0,0 @@
export const ACTION_BASE = {
"坐": "sitting",
"站": "stand",
"蹲着": "squat",
"趴": "grovel",
"躺": "lie",
"跳": "jump",
"跑": "run",
"走": "walk",
"飞": "fly",
"歪头": "head tilt",
"回头": "looking back",
"向下看": "looking down",
"向上看": "looking up",
"闻": "smelling",
"睡觉": "sleeping",
"洗澡": "bathing",
}
export const ACTION_HAND = {
"手放在嘴边": "hand_to_mouth",
"手放头旁边": "arm at side ",
"手放脑后": "arms behind head",
"手放后面": "arms behind back ",
"手放在自己的胸前": "hand on own chest",
"手交叉于胸前": "arms_crossed",
"手放臀": "hand on another\u0027s hip",
"单手插腰": "hand_on_hip",
"双手叉腰": "hands_on_hips",
"举手": "hands up ",
"伸懒腰": "stretch",
"举手露腋": "armpits",
"手把腿抓着": "leg hold",
"抓住": "grabbing",
"拿着": "holding",
"用手指做出笑脸": "fingersmile",
"拉头发": "hair_pull",
"撮头发": "hair scrunchie",
"手势": "w ",
"耶": "peace symbol ",
"翘大拇指": "thumbs_up",
"比出中指": "middle_finger",
"猫爪手势": "cat_pose",
"手枪手势": "finger_gun",
"嘘手势": "shushing",
"招手": "waving",
"敬礼": "salute",
"张手": "spread_arms",
}
export const ACTION_LEG = {
"张开腿": "spread legs",
"二郎腿": "crossed_legs",
"曲腿至胸": "fetal_position",
"抬一只脚": "leg_lift",
"抬两只脚": "legs_up",
"前倾": "leaning forward",
"婴儿姿势": "fetal position",
"靠墙": " against wall",
"趴着": "on_stomach",
"正坐": "seiza",
"割坐": "wariza/w-sitting",
"侧身坐": "yokozuwari",
"盘腿": "indian_style",
"抱腿": "leg_hug",
"跨坐": "straddling",
"下跪": "kneeling",
"抽烟": "smoking",
"用手支撑住": "arm_support",
}
export const ACTION_COMPOSE = {
"拥抱": "hug",
"膝枕": "lap_pillow",
"公主抱": "princess_carry",
"战斗姿态": "fighting_stance",
"颠倒的": "upside-down",
"趴着翘臀": "top-down_bottom-up",
"翘臀姿势": "bent_over",
"弓身体": "arched_back",
"背对背": "back-to-back",
"手对手": "symmetrical_hand_pose",
"眼对眼(对视)": "eye_contact",
"掏耳勺": "mimikaki",
"牵手": "holding_hands",
"四肢趴地": "all_fours",
"女胸部贴在一起": "symmetrical_docking",
"脱衣服": "undressing",
"掀起裙子": "skirt lift",
"掀起上衣": "shirt lift",
"调整过膝袜": "adjusting_thighhigh"
}

@ -1,259 +0,0 @@
export const BODY_BREASTS = {
"小%3": "small breast",
"中%1": "medium breast",
"大%5": "big breast"
};
export const BODY_CLOTHING = {
"晚礼服%1": "evening dress",
"短裙%3": "Skirt",
"长裙%3": "Long skirt",
"水手服%5": "sailor suit",
"JK%5": "JK",
"黑色丝袜": "black silk stocking",
"白色丝袜": "white silk stocking",
"西装%3": "suit",
"湿衣服%5": "wet clothes",
"比基尼%5": "bikini",
"领子%1": "sailor collar",
"帽子%1": "hat",
"衬衫%1": "shirt",
"水手服 ": "shorts under skirt",
"有领衬衣%1": "collared shirt ",
"学校制服": "school uniform",
"日本学生服": "seifuku",
"职场制服%2": "business_suit",
"夹克%2": "jacket",
"火焰纹章军服%3": "garreg mach monastery uniform",
"礼服长裙": "revealing dress",
"礼服": "pink lucency full dress",
"露出胸口部分的连衣裙%4": "cleavage dress",
"无袖连衣裙": "sleeveless dress",
"白色连衣裙": "whitedress",
"婚纱%3": "wedding_dress",
"水手连衣裙": "Sailor dress",
"毛衣裙": "sweater dress",
"罗纹毛衣": "ribbed sweater",
"毛衣夹克": "sweater jacket",
"工装服": "dungarees",
"棕色开襟衫(外套)": "brown cardigan ",
"连帽衫,卫衣%3": "hoodie ",
"长袍%2": "robe",
"斗篷%3": "cape",
"羊毛衫%2": "cardigan",
"围裙": "apron",
"哥特风格%4": "gothic",
"洛丽塔风格%4": "lolita_fashion",
"哥特洛丽塔风格%4": "gothic_lolita",
"西部风格": "western",
"格子花纹": "tartan",
"露单肩": "off_shoulder",
"露双肩": "bare_shoulders",
"赤脚": "barefoot",
"裸足": "bare_legs",
"横条花纹的": "striped",
"点状花纹的": "polka_dot",
"皱边的": "frills",
"花边": "lace",
"日本女生运动短裤": "buruma",
"运动服": "gym_uniform",
"女用背心": "tank_top",
"裁剪短夹克": "cropped jacket ",
"运动胸罩": "black sports bra ",
"漏脐装": "crop top",
"睡衣": "pajamas",
"和服": "japanese_clothes",
"衣带和服用": "obi",
"网眼上衣": "mesh",
"无袖上衣": "sleeveless shirt",
"袖肩分离装": "detached_sleeves",
"白色灯笼裤": "white bloomers",
"高腰腿裤": "high - waist shorts",
"百褶裙": "pleated_skirt",
"裙子": "skirt",
"迷你裙": "miniskirt",
"热裤": "short shorts",
"夏日长裙": "summer_dress",
"灯笼裤": "bloomers",
"短裤": "shorts",
"自行车短裤": "bike_shorts",
"海豚短裤": "dolphin shorts",
"腰带": "belt",
"吊索比基尼": "sling bikini",
"比基尼乳罩": "bikini_top",
"上身比基尼": " bikini top only ",
"侧边系带比基尼下装": "side - tie bikini bottom",
"系带式比基尼": "side-tie_bikini",
"褶边比基尼": "friled bikini",
"比基尼内衣": " bikini under clothes",
"泳装": "swimsuit",
"学校泳衣": "school swimsuit",
"连体泳衣": "one-piece swimsuit",
"竞技泳衣": "competition swimsuit",
"死库水": "Sukumizu",
"没胸罩": "no bra",
"胸罩": "bra ",
"褶边文胸": "frilled bra ",
"情趣内衣": "sexy lingerie",
"透明内衣": "transparent underwear",
"缠胸布": "sarashi",
"胸衣": "bustier",
"吊带胸衣": "chemise",
"内衣": "underwear",
"内裤(前加颜色)": "panties",
"条纹内裤": "striped_panties",
"没内裤": "no_panties",
"低腰式内裤": "lowleg_panties/low_leg_panties",
"侧系带内裤": "side-tie_panties",
"高腰内裤": "string_panties",
"丁字裤": "thong",
"日式丁字裤": "fundoshi",
"女用贴身内衣裤": "lingerie"
};
export const BODY_LEG_ORNAMENTS = [
"bare legs",
"garter straps",
"garter belt",
"socks",
"kneehighs",
"white kneehighs",
"black kneehighs",
"over-kneehighs",
"single kneehigh",
"tabi",
"bobby socks",
"loose socks",
"single sock",
"no socks",
"socks removed",
"ankle socks",
"striped socks",
"blue socks",
"grey socks",
"red socks",
"frilled socks",
"thighhighs",
"black thighhighs",
"white thighhighs",
"striped thighhighs",
"brown thighhighs",
"blue thighhighs",
"red thighhighs",
"purple thighhighs",
"pink thighhighs",
"grey thighhighs",
"thighhighs under boots",
"green thighhighs",
"yellow thighhighs",
"orange thighhighs",
"vertical-striped thighhighs",
"frilled thighhighs",
"fishnet thighhighs",
"pantyhose",
"black pantyhose",
"white pantyhose",
"thighband pantyhose",
"brown pantyhose",
"fishnet pantyhose",
"striped pantyhose",
"vertical-striped pantyhose",
"grey pantyhose",
"blue pantyhose",
"single leg pantyhose",
"purple pantyhose",
"red pantyhose",
"fishnet legwear",
"bandaged leg",
"bandaid on leg",
"mechanical legs",
"leg belt",
"leg tattoo",
"bound legs",
"leg lock",
"panties under pantyhose",
"panty",
"thighhighs over pantyhose",
"socks over thighhighs",
"panties over pantyhose",
"pantyhose under swimsuit",
"black garter belt",
"neck garter",
"white garter straps",
"black garter straps",
"ankle garter",
"no legwear",
"black legwear",
"white legwear",
"torn legwear",
"striped legwear",
"asymmetrical legwear",
"brown legwear",
"uneven legwear",
"toeless legwear",
"print legwear",
"lace-trimmed legwear",
"red legwear",
"mismatched legwear",
"legwear under shorts",
"purple legwear",
"grey legwear",
"blue legwear",
"pink legwear",
"argyle legwear",
"ribbon-trimmed legwear",
"american flag legwear",
"green legwear",
"vertical-striped legwear",
"frilled legwear",
"stirrup legwear",
"alternate legwear",
"seamed legwear",
"yellow legwear",
"multicolored legwear",
"ribbed legwear",
"fur-trimmed legwear",
"see-through legwear",
"legwear garter",
"two-tone legwear",
"latex legwear",
];
export const BODY_SHOES = {
"鞋子%1": "shoes ",
"靴子%1": "boots",
"乐福鞋%2": "loafers",
"高跟鞋%2": "high heels",
"系带靴%2": "cross-laced_footwear",
"玛丽珍鞋%2": "mary_janes",
"女式学生鞋": "uwabaki",
"拖鞋%2": "slippers",
"马靴": "knee_boots",
"连裤袜%4": "pantyhose",
"大腿连裤袜%4": "thighband pantyhose",
"连腰吊带袜": "garter_belt",
"吊带袜%5": "garter straps",
"短袜%4": "socks",
"横条袜": "striped_socks",
"泡泡袜": "loose_socks",
"裹腿": "legwear",
"黑色紧身裤%5": "black leggings ",
"裤袜%4": "leggings ",
"网袜%5": "fishnets",
"渔网袜%5": "fishnet_pantyhose",
"长袜%3": "kneehighs",
"丝袜%3": "stockings",
"过膝袜%5": "thighhighs",
"条纹过膝袜%4": "striped_thighhighs",
"白色过膝袜%5": "white_thighhighs",
"损坏了的过膝袜%5": "torn_thighhighs",
"日式厚底短袜%5": "tabi",
"蕾丝镶边紧身裤%7": "lace-trimmed legwear",
"腿部花边环%4": "leg_garter",
"腿部系带%4": "ankle_lace-up",
"大腿系带%5": "thigh strap",
"短裤下的紧身裤%4": "legwear under shorts"
};

@ -0,0 +1,37 @@
import { PromptToken } from "types";
/** 字典 */
export const PROMPT_DICT: {
[part: string]: PromptToken[];
} = {
test: [
{ value: "very long light blue hair" },
{ value: "ahoge" },
{ value: "bang to the side" },
{ value: "long bang" },
{ value: "long light blue hair" },
{ value: "military style" },
{ value: "full body" },
{ value: "long white shirt" },
{ value: "small waist" },
{ value: "small breasts" },
{ value: "dark blue jacket" },
{ value: "small jacket" },
{ value: "crop military jacket" },
{ value: "golden aiguillette" },
{ value: "small skirt" },
{ value: "dark blue military skirt" },
{ value: "black garters" },
{ value: "white stockings" },
{ value: "military boots" },
{ value: "high heels" },
{ value: "women boots" },
{ value: "blue round boots" },
],
};
/** 奖池 */
export const getLotteryPool = () =>
Object.values(PROMPT_DICT).reduce((pool, tokens) => {
return [...pool, ...tokens];
}, []);

@ -1,53 +0,0 @@
export const ENVIRONMENT_TIME = [
"day",
"dusk",
"night",
"in spring",
"in summer",
"in autumn",
"in winter",
];
export const ENVIRONMENT_SKY = [
"sun",
"sunset",
"moon",
"full_moon",
"stars",
"cloudy",
"rain",
"in the rain",
"rainy days",
"snow",
];
export const ENVIRONMENT_LOCATION = [
"sky",
"sea",
"mountain",
"on a hill",
"the top of the hill",
"in a meadow",
"plateau",
"on a desert",
"in hawaii",
"cityscape",
"landscape",
"beautiful detailed sky",
"beautiful detailed water",
"on the beach",
"on the ocean",
"over the sea",
"beautiful purple sunset at beach",
"in the ocean",
"against backlight at dusk",
"golden hour lighting",
"strong rim light",
"intense shadows",
"fireworks",
"flower field",
"underwater",
"explosion",
"in the cyberpunk city",
"steam",
];

@ -1,54 +0,0 @@
export const EYE_COLOR = [
"blue eyes",
"red eyes",
"brown eyes",
"green eyes",
"purple eyes",
"yellow eyes",
"pink eyes",
"black eyes",
"aqua eyes",
"orange eyes",
"grey eyes",
"multicolored eyes",
"white eyes",
"gradient eyes",
];
export const EYE_STYLE = [
"eyeshadow",
"red eyeshadow",
"blue eyeshadow",
"purple eyeshadow",
"pink eyeshadow",
"green eyeshadow",
"bags under eyes",
"ringed eyes",
"covered eyes",
"covering eyes",
"shading eyes",
];
export const EYE_STATUS = [
"closed eyes",
"half-closed eyes",
"crying with eyes open",
"narrowed eyes",
"hidden eyes",
"heart-shaped eyes",
"button eyes",
"cephalopod eyes",
"eyes visible through hair",
"glowing eyes",
"empty eyes",
"rolling eyes",
"blank eyes",
"no eyes",
"sparkling eyes",
"extra eyes",
"crazy eyes",
"solid circle eyes",
"solid oval eyes",
"uneven eyes",
"blood from eyes",
];

@ -1,90 +0,0 @@
export const FACIAL_FEATURE = {
"食物在脸上(食物可替换)": "food on face",
"淡淡腮红%R": "light blush",
"面纹%N": "facepaint",
"浓妆%R": "makeup ",
"可爱表情%N": "cute face",
"白色睫毛%SR": "white colored eyelashes",
"长睫毛%R": "longeyelashes",
"白色眉毛%R": "white eyebrows",
"吊眼角": "tsurime",
"渐变眼": "gradient_eyes",
"垂眼角": "tareme",
"猫眼%SR": "slit pupils ",
"异色瞳%SSR": "heterochromia ",
"红蓝眼%SSR": "heterochromia blue red",
"水汪汪大眼%SR": "aqua eyes",
"看你": "looking at viewer",
"盯着看": "eyeball",
"凝视": "stare",
"透过刘海看": "visible through hair",
"看旁边": "looking to the side ",
"收缩的瞳孔": "constricted pupils",
"符号形状的瞳孔%SSR": "symbol-shaped pupils ",
"❤%SSR": "heart in eye",
"爱心瞳孔%SSR": "heart-shaped pupils",
"眨眼%SR": "wink ",
"眼下痣%R": "mole under eye",
"闭眼%N": "eyes closed",
"没鼻子": "no_nose",
"动物耳朵%SR": "animal_ears",
"动物耳绒毛%SR": "animal ear fluff ",
"狐狸耳朵%SR": "fox_ears",
"兔子耳朵%SR": "bunny_ears",
"猫耳%SR": "cat_ears",
"狗耳%SR": "dog_ears",
"叔耳": "mouse_ears",
"头发上耳朵": "hair ear",
"尖耳": "pointy ears"
};
export const FACIAL_EXPRESSION = {
"微笑%1": "smirk",
"诱惑笑%5": "seductive smile",
"露齿而笑%2": "grin",
"笑": "laughing",
"牙": "teeth ",
"兴奋%3": "excited",
"害羞%3": "nose blush ",
"脸红%4": "blush",
"无表情%4": "expressionless",
"失神%1": "expressionless eyes",
"困%2": "sleepy",
"喝醉的%4": "drunk",
"哭%3": "crying with eyes open",
"悲伤的": "sad",
"别扭努嘴%4": "pout",
"叹气": "sigh",
"睁大眼睛%3": "wide eyed",
"生气%2": "angry",
"苦恼的%1": "annoyed",
"皱眉": "frown",
"严肃": "serious",
"鄙夷": "jitome",
"锐利": "scowl",
"疯狂的": "crazy",
"黑化的%5": "dark_persona",
"得意": "smug",
"一只眼睛闭上%4": "one eye closed",
"半闭眼睛%3": "half-closed eyes",
"鼻血": "nosebleed",
"做鬼脸%4": "eyelid pull ",
"舌头": "tongue",
"吐舌%4": "tongue out",
"闭嘴": "closed mouth",
"张嘴": "open mouth",
"口红": "lipstick",
"尖牙": "fangs",
"咬紧牙关": "clenched teeth",
"ω猫嘴%4": ":3",
"向下吐舌头%3": ":p",
"向上吐舌头%3": ":q",
"不耐烦%2": ":t",
"杯型笑脸": ":d",
"下流的表情": "naughty_face",
"忍耐的表情": "endured_face",
"阿黑颜": "ahegao",
"血在脸上": "blood on face",
"唾液": "saliva"
};

@ -1,209 +0,0 @@
// 如需要更新词条,请访问 https://tools.miku.ac/novelai_tag/,并修改以下代码获取词条
// const labels = [];document.querySelectorAll("#pane-头发\\&发饰 > div:nth-child(1) > div.el-checkbox-group > label > span.el-checkbox__label").forEach(label=>labels.push(label.outerHTML.match(/\n(\s|\d|[a-zA-Z]|:|-|_)+/)[0].replace(/(\n|\s)+/,"").replace(/\s$/,"")));labels;
/** 通用特征 */
export const GENERAL_PROMPTS = {};
export const STYLE = {
"原画": "artbook",
"游戏": "game_cg",
"漫画": "comic",
"四格": "4koma",
"格式图片": "animated_gif",
"抱枕": "dakimakura",
"角色扮演": "cosplay",
"穿越": "crossover",
"暗的": "dark",
"亮的": "light",
"猎奇": "guro",
"写实": "realistic",
"照片": "photo",
"真实": "real",
"风景": "landscape/scenery",
"城市风景": "cityscape",
"科技幻想": "science_fiction",
"原创": "original",
"拙劣的模仿": "parody",
"拟人": "personification",
"视觉错误": "optical_illusion",
"名画模仿": "fine_art_parody",
"素描": "sketch",
"传统媒体(基本上是手绘稿)": "traditional_media",
"透明水彩绘": "watercolor_(medium)",
"剪影": "silhouette",
"封面": "covr",
"专辑": "album",
"图上有字样": "sample",
"背影像": "back",
"半身像": "bust",
"侧面绘": "profile",
"表情绘(各种表情)": "expressions",
"一部作品中的主要人物集齐": "everyone",
"一列列小图组成大图": "column_lineup",
"透明的背景": "transparent_background",
"简单的背景无背景": "simple_background",
"渐变的背景": "gradient_background",
"背景是前景的放大版": "zoom_layer"
};
export const CHARACTER = [
"1girl",
"2girls",
"3girls",
"1boy",
"2boys",
"3boys",
"solo",
"multiple girls",
"little girl",
"little boy",
"shota",
"loli",
"kawaii",
"mesugaki",
"adorable girl",
"bishoujo",
"gyaru",
"sisters",
"ojousama",
"mature female",
"mature",
"female pervert",
"milf",
"harem",
];
export const ROLE = {
"女王%SR": "queen",
"学生%N": "student",
"医生%R": "doctor",
"护士%SR": "nurse",
"警察%R": "police",
"士兵%R": "soldier",
"骑士%SR": "knight",
"女仆%SSR": "housemaid",
"天使%SR": "angel",
"啦啦队%SR": "cheerleader",
"版人物": "chibi",
"伪娘%R": "trap",
"魔鬼%SR": "devil",
"人偶%R": "doll",
"妖精%SR": "elf",
"小精灵%SR": "fairy",
"女人%N": "female",
"兽人%N": "furry",
"半兽人%N": "orc",
"女巨人%N": "giantess",
"后宫": "harem",
"偶像%R": "idol",
"兽耳萝莉%SR": "kemonomimi_mode",
"魔法少女%SSR": "magical_girl",
"男人": "male",
"美人鱼%SR": "mermaid",
"巫女%SR": "miko",
"迷你女孩%R": "minigirl",
"怪物": "monster",
"魔幻少女": "multiple_girls",
"忍者%SR": "ninja",
"非人": "no_humans",
"修女%SR": "nun",
"空姐%SR": "stewardess",
"吸血鬼%SR": "vampire",
"女服务员%R": "waitress",
"女巫%R": "witch",
"搞基": "yaoi",
"油库里": "yukkuri_shiteitte_ne",
"百合": "yuri"
};
export const ACTION = [
"head tilt",
"turning around",
"looking back",
"looking down",
"looking up",
"smelling",
"hand_to_mouth",
"arm at side",
"arms behind head",
"arms behind back",
"hand on own chest",
"arms_crossed",
"hand on hip",
"hand on another",
"hand_on_hip",
"hands_on_hips",
"arms up",
"hands up",
"stretch",
"armpits",
"leg hold",
"grabbing",
"holding",
"fingersmile",
"hair_pull",
"hair scrunchie",
"w",
"v",
"peace symbol",
"thumbs_up",
"middle_finger",
"cat_pose",
"finger_gun",
"shushing",
"waving",
"salute",
"spread_arms",
"spread legs",
"crossed_legs",
"fetal_position",
"leg_lift",
"legs_up",
"leaning forward",
"fetal position",
"against wall",
"on_stomach",
"squatting",
"lying",
"sitting",
"sitting on",
"seiza",
"wariza",
"yokozuwari",
"indian_style",
"leg_hug",
"walking",
"running",
"straddle",
"straddling",
"kneeling",
"smoking",
"arm_support",
"caramelldansen niconiconi",
"princess_carry",
"fighting_stance",
"upside-down",
"top-down_bottom-up",
"bent_over",
"arched_back",
"back-to-back",
"symmetrical_hand_pose",
"eye_contact",
"hug",
"lap_pillow",
"sleeping",
"bathing",
"mimikaki",
"holding_hands",
];
export const R18TAG = [
"surrounded, multiple others, exhibitionism, audience, background characters, crowd, public humiliation",
"partially unbuttoned",
"show foot",
"pubic tattoo on underbelly",
"spread pussy",
"ass_visible_through_thighs",
];

@ -1,21 +0,0 @@
import { BODY_BREASTS, BODY_CLOTHING, BODY_LEG_ORNAMENTS, BODY_SHOES } from "./body";
import { FACIAL_EXPRESSION, FACIAL_FEATURE } from "./facial";
import { ROLE, STYLE } from "./general";
import { HAIR_COLOR, HAIR_STYLE } from "./hair";
import { ORNAMENTS } from "./ornament";
/** 全局提示词清单 */
export const GLOBAL_PROMPTS = {
// 抽卡
role: ROLE,
facialFeature: FACIAL_FEATURE,
ornaments: ORNAMENTS,
// 天赋点
hairColor: HAIR_COLOR,
hairStyle: HAIR_STYLE,
facialExpression: FACIAL_EXPRESSION,
bodyBreasts: BODY_BREASTS,
bodyClothing: BODY_CLOTHING,
bodyShoes: BODY_SHOES,
}

@ -1,172 +0,0 @@
/** 头发长度 */
export const HAIR_LENGTH = [
"very short hair",
"short hair",
"medium hair",
"long hair",
"very long hair",
"absurdly long hair",
"hair over shoulder",
"alternate hair length",
];
/** 发色 */
export const HAIR_COLOR = {
"白发%1": "white hair",
"金发%4": "blonde hair ",
"银发%5": "silver hair",
"灰发%2": "grey hair ",
"紫发%2": "purple hair",
"红发%3": "red hair",
"黄发%3": "yellow hair",
"绿发%5": "green hair",
"蓝发%3": "blue hair",
"黑发%4": "black hair",
"棕发%2": "brown hair",
};
/** 发型特征 */
export const HAIR_STYLE = {
"短发%1": "short hair",
"卷发%2": "curly hair",
"长发%4": "long hair",
"马尾%3": "pony-tail",
"双马尾%5": "bunches",
"挑染": "streaked hair",
"灰色渐变%3": "grey gradient hair",
"亮棕": "light brown hair",
"双色": "two-tone hair",
"五颜六色": "multicolored hair",
"高马尾": "high ponytail",
"双马尾 ": "twintails",
"马尾编发": "braided ponytail ",
"马尾辫%2": "ponytail",
"短马尾%2": "short_ponytail",
"双辫子%1": "twin_braids",
"短发 ": "short hair",
"中发": "medium hair",
"长发 ": "long hair",
"超长发%5": "very long hair",
"辫子刘海%2": "braided bangs",
"侧扫刘海": "swept bangs",
"眼间头发%3": "hair between eyes",
"妹妹切%3": "bob cut",
"公主切%4": "hime_cut",
"交叉刘海%3": "crossed bangs",
"刘海%3": "bangs",
"齐刘海": "blunt bangs",
"翼状头发": "hair wings",
"长刘海": "long bangs",
"蓬发": "disheveled hair",
"波浪形头发": "wavy hair",
"卷发 ": "curly_hair",
"收拢": "hair in takes",
"粉色花": "hair pink flowers",
"呆毛%4": "ahoge",
"多根呆毛%4": "antenna hair",
"侧马尾%2": "Side ponytail",
"露额头": "forehead",
"钻头卷公主卷": "drill hair",
"包子头%2": "hair bun",
"俩包子头%3": "double_bun",
"凌乱发型%3": "messy_hair"
};
/** 发辫 */
export const HAIR_BRAID = [
"braid",
"twin braids",
"single braid",
"side braid",
"long braid",
"french braid",
"crown braid",
"braided bun",
"ponytail",
"braided ponytail",
"high ponytail",
"twintails",
"short",
"twin",
"Side ponytail",
];
/** 刘海 */
export const HAIR_BANGS = [
"bangs",
"blunt bangs",
"parted bangs",
"swept bangs",
"crossed bangs",
"asymmetrical bangs",
"braided bangs",
"long bangs",
"bangs pinned back",
"diagonal bangs",
"dyed bangs",
"hair between eyes",
"hair over one eye",
"hair over eyes",
"hair behind ear",
"hair between breasts",
"hair over breasts",
"hair censor",
];
/** 发饰 */
export const HAIR_ORNAMENT = [
"hair ornament",
"hair bow",
"hair ribbon",
"hairband",
"hair flower",
"hair bun",
"hair bobbles",
"hairclip",
"single hair bun",
"x hair ornament x",
"black hairband",
"hair scrunchie",
"hair rings",
"tied hair",
"hairpin",
"white hairband",
"hair tie",
"frog hair ornament",
"food",
"tentacle hair",
"star hair ornament",
"hair bell",
"heart hair ornament",
"red hairband",
"butterfly hair ornament",
"hair stick",
"snake hair ornament",
"lolita hairband",
"crescent hair ornament",
"cone hair bun",
"feather hair ornament",
"blue hairband",
"anchor hair ornament",
"leaf hair ornament",
"bunny hair ornament",
"skull hair ornament",
"yellow hairband",
"pink hairband",
"dark blue hair",
"bow hairband",
"cat hair ornament",
"musical note hair ornament",
"carrot hair ornament",
"purple hairband",
"hair tucking",
"hair beads",
"multiple hair bows",
"hairpods",
"bat hair ornament",
"bone hair ornament",
"orange hairband",
"multi",
"snowflake hair ornament",
];

@ -1,70 +0,0 @@
export const ORNAMENTS = {
"光环%R": "halo",
"迷你礼帽": "mini_top_hat",
"贝雷帽": "beret",
"兜帽": "hood",
"护士帽%SR": "nurse cap",
"皇冠%R": "tiara",
"鬼角": "oni horns",
"恶魔角%SSR": "demon horns",
"发带%SR": "hair_ribbon",
"花丝带": "flower ribbon",
"发卡%R": "hairband",
"发夹%R": "hairclip",
"发花": "hair_flower",
"头饰": "hair_ornament",
"蝴蝶结": "bowtie",
"蝴蝶结发饰": "hair_bow",
"女仆头饰%SSR": "maid_headdress",
"服装饰品头部饰品": "bow",
"发饰": "hair ornament",
"心形%SR": "heart hair ornament",
"创可贴": "bandaid",
"锥形发髻": "cone hair bun",
"双发髻": "double bun",
"半无框的眼镜": "semi-rimless eyewear",
"太阳镜%SR": "sunglasses",
"风镜": "goggles",
"眼罩独眼%SSR": "eyepatch",
"黑色眼罩": "black blindfold",
"耳机%N": "headphones",
"面纱%R": "veil",
"口罩%R": "mouth mask",
"眼镜%R": "glasses",
"耳环%N": "earrings",
"首饰%N": "jewelry",
"铃铛%SSR": "bell",
"颈带%N": "ribbon_choker",
"颈部饰品%N": "black choker ",
"项链%R": "necklace",
"耳机套脖子上%SR": "headphones around neck",
"项圈%SSR": "collar",
"水手领%SR": "sailor_collar",
"领巾%N": "neckerchief",
"领带%N": "necktie",
"十字架%SR": "cross necklace",
"吊坠%N": "pendant",
"围巾%R": "scarf",
"臂章%R": "armband",
"臂环%N": "armlet",
"臂带%N": "arm strap",
"肘部手套%N": "elbow gloves ",
"露指手套%N": "half gloves ",
"手镯%R": "bracelet",
"手套%R": "gloves",
"五指手套%N": "fingerless gloves",
"锁链%SSR": "chains",
"手链%SSR": "shackles",
"手铐%SSR": "handcuffs",
"手表%R": "wristwatch",
"腕带": "wristband",
"腕饰": "wrist_cuffs",
"拿着书%R": "holding book",
"拿着剑%SR": "holding sword",
"球拍%SR": "tennis racket",
"手杖%SR": "cane",
"双肩包": "backpack",
"书包%N": "school bag ",
"肩背书包": "satchel",
"手机%N": "smartphone "
};

@ -1,35 +1,39 @@
import { Button, CircularProgress, Divider, Skeleton } from "@mui/material";
import { Button, Skeleton } from "@mui/material";
import { PRESET_TOKENS } from "prompts/presets";
import React, { useEffect, useState } from "react";
import { generatePicture } from "service/service";
import { GAME_SCENES, SceneProps } from "types";
import { Message } from "./ui";
import { GAME_SCENES, PromptToken, SceneProps } from "types";
import { useDebounce } from "react-use";
type GenerateSceneProps = {
prompts: string[];
tokens: PromptToken[];
} & SceneProps;
export const GenerateScene = ({ setScene, prompts }: GenerateSceneProps) => {
export const GenerateScene = ({ setScene, tokens }: GenerateSceneProps) => {
const [code, setCode] = useState("");
const [loading, setLoading] = useState(false);
const generate = () => {
if (loading) return;
console.time();
setLoading(true);
const prompt = [...PRESET_TOKENS, ...prompts].join(",");
generatePicture({
height: 384,
n_samples: 1,
prompt,
sampler: "k_euler_ancestral",
scale: 12,
seed: new Date().getTime() % 2 ** 32,
steps: 28,
uc: "lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry",
ucPreset: 0,
width: 256,
})
.then((result) => {
useDebounce(
() => {
if (loading) return;
console.time();
setLoading(true);
const prompt = [
...PRESET_TOKENS,
...tokens.map((token) => token.value),
].join(", ");
generatePicture({
height: 384,
n_samples: 1,
prompt,
sampler: "k_euler_ancestral",
scale: 12,
seed: new Date().getTime() % 2 ** 32,
steps: 28,
uc: "lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry",
ucPreset: 0,
width: 256,
}).then((result) => {
setLoading(false);
console.log(result);
const source = result.data.split("\n");
@ -46,40 +50,32 @@ export const GenerateScene = ({ setScene, prompts }: GenerateSceneProps) => {
// const canvas = document.getElementById("picture");
// const context = canvas.getContext("2d");
// context.putImageData(imageData);
})
.catch((e) => {
Message.error(e.message);
});
};
useEffect(() => {
generate();
}, []);
},
500,
[tokens]
);
return (
<div>
{loading && <CircularProgress />}
{loading && (
<Skeleton
sx={{ bgcolor: "grey.900" }}
variant="rectangular"
width={256}
height={384}
/>
)}
{!loading && !!code && (
<div>
<img src={`data:image/jpeg;base64,${code}`}></img>
<Divider />
6.7
<Divider />
<Button
variant={"outlined"}
onClick={() => {
setScene(GAME_SCENES.LOTTERY);
}}
>
</Button>
<Divider />
<Button
variant={"outlined"}
onClick={() => {
setScene(GAME_SCENES.LOTTERY);
}}
>
</Button>
</div>
)}

@ -1,249 +1,70 @@
import { Button, ButtonGroup, CircularProgress, Divider } from "@mui/material";
import { getLotteryPool } from "../keywords/dict";
import React, { useCallback, useState } from "react";
import { FigurePrompts, GAME_SCENES, Keyword, SceneProps } from "types";
// import { OpenAIService } from "service/gpt";
import { Message } from "./ui";
import { randomSelectNoRepeat } from "utils/random";
import { getPrompts, initPrompts, mergePrompts } from "utils/prompt";
import { ROLE } from "prompts/general";
import { FACIAL_EXPRESSION, FACIAL_FEATURE } from "prompts/facial";
import { ORNAMENTS } from "prompts/ornament";
import { HAIR_COLOR, HAIR_STYLE } from "prompts/hair";
import { BODY_BREASTS, BODY_CLOTHING, BODY_LEG_ORNAMENTS, BODY_SHOES } from "prompts/body";
const RARITY_PROPS = {
N: {
color: 'green',
},
R: {
color: 'blue',
},
SR: {
color: 'purple',
},
SSR: {
color: 'gold',
},
}
import { Button } from "@mui/material";
import { getLotteryPool } from "../prompts/dict";
import React, { useState } from "react";
import { GAME_SCENES, PromptToken, SceneProps } from "types";
type LotterySceneProps = {
setPrompts: React.Dispatch<React.SetStateAction<string[]>>;
setTokens: React.Dispatch<React.SetStateAction<PromptToken[]>>;
} & SceneProps;
type ActivePromptToken = {
type: string;
label: string;
rarity: 'N' | 'R' | 'SR' | 'SSR'; // 稀有度
prompt: string;
active: boolean;
};
type ActivePromptSelect = {
label: string;
point: number;
prompt: string;
}
type ActivePromptChoices = {
hairColor?: ActivePromptSelect,
hairStyle?: ActivePromptSelect,
facialExpression?: ActivePromptSelect,
bodyBreasts?: ActivePromptSelect,
bodyClothing?: ActivePromptSelect,
bodyShoes?: ActivePromptSelect,
}
} & PromptToken;
/** 抽奖界面 */
export const LotteryScene = ({ setScene, setPrompts }: LotterySceneProps) => {
const [loading, setLoading] = useState(false);
const [step, setStep] = useState(1);
export const LotteryScene = ({ setScene, setTokens }: LotterySceneProps) => {
const [activeTokens, setActiveTokens] = useState<ActivePromptToken[]>([]);
const [count, setCount] = useState(3);
const [pointPrompts, setPointPrompts] = useState<{ [key: string]: any }>({});
const [point, setPoint] = useState(20);
// 十连抽奖池
const LOTTERY_POOL = [
...Object.entries(ROLE).filter(([key]) => key.includes("%")).map(([key, prompt]) => {
const [label, rarity] = key.split('%')
return {
type: 'role',
label: "角色:" + label,
rarity,
prompt,
}
}),
...Object.entries(FACIAL_FEATURE).filter(([key]) => key.includes("%")).map(([key, prompt]) => {
const [label, rarity] = key.split('%')
return {
type: 'facialFeature',
label: "特征:" + label,
rarity,
prompt,
}
}),
...Object.entries(ORNAMENTS).filter(([key]) => key.includes("%")).map(([key, prompt]) => {
const [label, rarity] = key.split('%')
return {
type: 'ornaments',
label: "装饰:" + label,
rarity,
prompt,
}
}),
];
// 天赋点单项
const SinglePointSelector = useCallback((attr: any, option: object) => {
return <ButtonGroup aria-label="outlined primary button group">
{
Object.entries(option).filter(([key]) => key.includes("%")).map(([key, prompt]) => {
const [label, kpoint] = key.split('%');
const opt = {
key,
label,
point: parseInt(kpoint),
prompt
}
return <Button variant={pointPrompts[attr]?.key === key ? "contained" : "outlined"} key={key} disabled={point < opt.point && (!pointPrompts[attr] || pointPrompts[attr].point + point < opt.point)} onClick={() => {
let p = point;
if (pointPrompts[attr]) p += pointPrompts[attr].point;
p -= opt.point;
setPointPrompts({
...pointPrompts,
[attr]: opt,
});
setPoint(p);
}}>{label}{opt.point}</Button>
})
}</ButtonGroup>;
}, [pointPrompts]);
// 转换成prompts
const getPromptsByTokens = useCallback(async () => {
const promptsInit = {} as any;
Object.entries(pointPrompts).forEach(([attr, value]) => {
promptsInit[attr] = value.prompt;
})
let figurePrompts = initPrompts(promptsInit);
activeTokens
.filter((token) => token.active)
.forEach((token) => {
figurePrompts = mergePrompts(figurePrompts, {
[token.type]: token.prompt,
});
});
const prompts = getPrompts(figurePrompts);
console.log(prompts);
if (prompts) setPrompts(prompts);
}, [setPrompts, activeTokens, pointPrompts]);
const LOTTERY_POOL = getLotteryPool();
return (
<div>
<p>穿</p>
{step === 1 && <div>
<p>10</p>
<p>{count}</p>
<div className=" my-2">
<Button
variant="outlined"
onClick={() => {
setCount(3);
setActiveTokens(
randomSelectNoRepeat(LOTTERY_POOL, 10, (obj) => {
return {
...obj,
active: false,
};
})
);
}}
>
</Button>
</div>
{
activeTokens.length > 0 &&
<Divider />
}
<div className=" my-2">
{activeTokens.map((token, index) => (
<Button
size="small"
variant={token.active ? "contained" : "outlined"}
style={{
color: RARITY_PROPS[token.rarity].color
}}
key={index}
disabled={!activeTokens[index].active && count <= 0}
onClick={() => {
const tokens = [...activeTokens];
if (activeTokens[index].active) setCount(count + 1);
else setCount(count - 1);
tokens[index].active = !activeTokens[index].active;
setActiveTokens(tokens);
}}
>
{token.label}
</Button>
))}
</div>
<Divider />
<div className=" mt-2">
<Button
variant={"outlined"}
onClick={() => {
setStep(2);
}}></Button>
</div>
</div>
}
{step === 2 && <div>
<p></p>
<p>{point}</p>
<div className="my-2"><Divider /></div>
<span></span>{SinglePointSelector('hairColor', HAIR_COLOR)}
<div className="my-2"><Divider /></div>
<span></span>{SinglePointSelector('hairStyle', HAIR_STYLE)}
<div className="my-2"><Divider /></div>
<span></span>{SinglePointSelector('bodyBreasts', BODY_BREASTS)}
<div className="my-2"><Divider /></div>
<span></span>{SinglePointSelector('facialExpression', FACIAL_EXPRESSION)}
<div className="my-2"><Divider /></div>
<span></span>{SinglePointSelector('bodyClothing', BODY_CLOTHING)}
<div className="my-2"><Divider /></div>
<span></span>{SinglePointSelector('bodyShoes', BODY_SHOES)}
<div className="my-2"><Divider /></div>
<Button
variant="outlined"
onClick={() => {
const tokenLength = LOTTERY_POOL.length;
let availableTokenNum = 0;
let lottery = {} as any;
while (availableTokenNum < 10) {
let code = Math.random() * tokenLength;
if (code === tokenLength) code -= 1;
code = Math.floor(code);
if (lottery[code]) continue;
lottery[code] = {
...LOTTERY_POOL[code],
active: false,
};
availableTokenNum++;
}
setActiveTokens(Object.values(lottery));
}}
>
</Button>
{activeTokens.map((token, index) => (
<Button
variant={"outlined"}
variant={activeTokens[index].active ? "contained" : "outlined"}
key={token.value}
onClick={() => {
setStep(1);
}}
>
</Button>
<Button
variant={"outlined"}
onClick={async () => {
try {
setLoading(true);
await getPromptsByTokens();
setLoading(false);
setScene(GAME_SCENES.GENERATE);
} catch (e: any) {
console.log(e);
Message.error(e.message);
}
activeTokens[index].active = !activeTokens[index].active;
setActiveTokens(activeTokens);
}}
>
{loading ? <CircularProgress /> : "开始召唤!"}
{token.value}
</Button>
</div>}
))}
<Button
onClick={() => {
setScene(GAME_SCENES.GENERATE);
setTokens(
activeTokens.map((token) => {
return {
value: token.value,
};
})
);
}}
>
</Button>
</div>
);
};

@ -1,18 +0,0 @@
.arrow {
position: relative; /* 确保箭头相对于其父元素进行定位 */
animation-name: down-fade; /* 指定动画名称 */
animation-duration: 3s; /* 动画持续时间(秒)*/
animation-timing-function: ease-in-out; /* 指定动画变化速度 */
animation-iteration-count: infinite; /* 让动画无限循环 */
}
@keyframes down-fade {
0% {
opacity: 1; /* 开始时完全不透明 */
transform: translateY(0); /* 初始位置 */
}
100% {
opacity: 0.8; /* 最后完全消失 */
transform: translateY(30px);/* 继续向下移动一段距离 */
}
}

@ -1,107 +1,21 @@
import React, { useEffect, useState } from "react";
import { GAME_SCENES, Keyword } from "types";
import React, { useState } from "react";
import { GAME_SCENES, PromptToken } from "types";
import { MenuScene } from "./menu";
import { LotteryScene } from "./lottery";
import { GenerateScene } from "./generate";
import { Alert, Snackbar } from "@mui/material";
import './ui.css'
type SnackSetterFunction = (snack: {
open: boolean;
message: string;
type: "error" | "success" | "warning" | "info";
}) => void;
const Snacker = {} as any;
export const Message = {
error: (message: string) => {
Snacker.setSnack({
open: true,
message,
type: "error",
});
},
warning: (message: string) => {
Snacker.setSnack({
open: true,
message,
type: "warning",
});
},
success: (message: string) => {
Snacker.setSnack({
open: true,
message,
type: "success",
});
},
show: (message: string) => {
Snacker.setSnack({
open: true,
message,
type: "info",
});
},
};
export const GameUI = () => {
const [bgList, setBgList] = useState<string[]>([
'https://telegraph.cwy666.com/file/3139727dc463e5f54fe58.jpg',
'https://telegraph.cwy666.com/file/1f2dd4066229c242eb38e.png'
]);
const [scene, setScene] = useState<GAME_SCENES>(GAME_SCENES.MENU);
const [prompts, setPrompts] = useState<string[]>([]);
const [snack, setSnack] = useState({
open: false,
message: "",
type: "info" as "error" | "success" | "warning" | "info",
});
const handleClose = () => {
setSnack({
...snack,
open: false,
});
};
useEffect(() => {
Snacker.setSnack = setSnack;
}, []);
const handleScrollClick = () => {
// 向下滚动一个屏幕的距离
const t = window.innerHeight
debugger
window.scrollTo(0, t)
}
const [tokens, setTokens] = useState<PromptToken[]>([]);
return (
<div className=" w-full h-full">
<div className="w-1/2 bg-no-repeat bg-cover bg-center relative flex justify-center w-full h-full p-0 m-0" style={{backgroundImage: `url(${bgList[1]}`}}>
<div className=" text-white font-bold text-4xl absolute bottom-10 flex flex-col items-center justify-center ">
<svg onClick={handleScrollClick} className="icon arrow pt-2 cursor-pointer" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2605" width="100" height="50"><path d="M512 777.536l348.416-319.36L960 549.504 512 960 64 549.44 163.584 458.24 512 777.536z m0-394.24L860.416 64 960 155.264 512 565.76 64 155.264 163.584 64 512 383.36z" fill="white" p-id="2606"></path></svg>
</div>
</div>
<div className=" flex flex-col justify-center items-center w-full h-full">
{scene === GAME_SCENES.MENU && <MenuScene setScene={setScene} />}
{scene === GAME_SCENES.LOTTERY && (
<LotteryScene setScene={setScene} setPrompts={setPrompts} />
)}
{scene === GAME_SCENES.GENERATE && (
<GenerateScene setScene={setScene} prompts={prompts} />
)}
</div>
<Snackbar
anchorOrigin={{ vertical: "top", horizontal: "center" }}
open={snack.open}
onClose={handleClose}
>
<Alert
onClose={handleClose}
severity={snack.type}
sx={{ width: "100%" }}
>
{snack.message}
</Alert>
</Snackbar>
<div>
{scene === GAME_SCENES.MENU && <MenuScene setScene={setScene} />}
{scene === GAME_SCENES.LOTTERY && (
<LotteryScene setScene={setScene} setTokens={setTokens} />
)}
{scene === GAME_SCENES.GENERATE && (
<GenerateScene setScene={setScene} tokens={tokens} />
)}
</div>
);
};

@ -1,30 +0,0 @@
import { Configuration, OpenAIApi } from "openai";
const params = {
// organization: "YOUR OWN ORGANIZATION HERE",
// apiKey: "YOUR OWN APIKEY HERE",
};
export const OpenAIService = async () => {
const config = new Configuration(params);
const openai = new OpenAIApi(config);
return {
openai,
getPrompts: async (keywords: string[]) => {
const resp = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
messages: [
{
role: "user",
content: `我想用NovelAI生成一张${keywords.join(
","
)}20使`,
},
],
});
const content = resp.data.choices[0].message?.content;
const prompts = content?.replace(/\d|\./g, "").split("\n");
return prompts;
},
};
};

@ -23,35 +23,6 @@ export type SceneProps = {
setScene: React.Dispatch<React.SetStateAction<GAME_SCENES>>;
};
export type FigurePrompts = {
base?: string[];
style?: string[];
character?: string;
role?: string[];
action?: string;
environmentTime?: string;
environmentSky?: string;
environmentLocation?: string;
hairLength?: string;
hairColor?: string;
hairStyle?: string;
hairBraid?: string;
hairBangs?: string;
hairOrnament?: string;
eyeColor?: string;
eyeStyle?: string;
eyeStatus?: string;
facialFeature?: string;
facialExpression?: string;
bodyBreasts?: string;
bodyClothing?: string;
bodyLegOrnaments?: string;
bodyShoes?: string;
ornaments?: string[];
};
export type Keyword = {
export type PromptToken = {
value: string;
class: "n" | "v" | "adj" | "adv";
prompts: FigurePrompts;
};

@ -1,118 +0,0 @@
import { FigurePrompts } from "types";
import { randomSelect, randomSelectNoRepeat } from "./random";
import { CHARACTER, ROLE } from "prompts/general";
import {
ENVIRONMENT_LOCATION,
ENVIRONMENT_SKY,
ENVIRONMENT_TIME,
} from "prompts/environment";
import {
HAIR_BANGS,
HAIR_BRAID,
HAIR_COLOR,
HAIR_LENGTH,
HAIR_ORNAMENT,
HAIR_STYLE,
} from "prompts/hair";
import { EYE_COLOR, EYE_STATUS, EYE_STYLE } from "prompts/eye";
import { FACIAL_EXPRESSION, FACIAL_FEATURE } from "prompts/facial";
import {
BODY_BREASTS,
BODY_CLOTHING,
BODY_LEG_ORNAMENTS,
BODY_SHOES,
} from "prompts/body";
import { ORNAMENTS } from "prompts/ornament";
export const initPrompts = (p?: FigurePrompts): FigurePrompts => {
const _p: FigurePrompts = {
base: p?.base || [],
style: p?.style || [],
character: p?.character || '1 girl',
role: p?.role,
action: p?.action,
environmentTime: p?.environmentTime || randomSelect(ENVIRONMENT_TIME),
environmentSky: p?.environmentSky || randomSelect(ENVIRONMENT_SKY),
environmentLocation:
p?.environmentLocation || randomSelect(ENVIRONMENT_LOCATION),
hairLength: p?.hairLength || randomSelect(HAIR_LENGTH),
hairColor: p?.hairColor,
hairStyle: p?.hairStyle,
hairBraid: p?.hairBraid,
hairBangs: p?.hairBangs,
hairOrnament: p?.hairOrnament,
eyeColor: p?.eyeColor || randomSelect(EYE_COLOR, 0.5),
eyeStyle: p?.eyeStyle || randomSelect(EYE_STYLE, 0.5),
eyeStatus: p?.eyeStatus || randomSelect(EYE_STATUS, 0.8),
facialFeature: p?.facialFeature,
facialExpression:
p?.facialExpression,
bodyBreasts: p?.bodyBreasts,
bodyClothing: p?.bodyClothing,
bodyLegOrnaments:
p?.bodyLegOrnaments,
bodyShoes: p?.bodyShoes,
ornaments: p?.ornaments,
};
return _p;
};
export const mergeArray = (
arr1: any[] | undefined,
arr2: any[] | undefined
) => {
const arr = [] as any[];
if (Array.isArray(arr1)) {
arr.push(...arr1);
} else if (arr1) {
arr.push(arr1);
}
if (Array.isArray(arr2)) {
arr.push(...arr2);
} else if (arr2) {
arr.push(arr2);
}
return arr;
};
export const mergePrompts = (
p1: FigurePrompts,
p2: FigurePrompts
): FigurePrompts => {
const _p: FigurePrompts = {
base: mergeArray(p1.base, p2.base),
style: mergeArray(p1.style, p2.style),
character: p2.character || p1.character,
role: mergeArray(p1.role, p2.role),
action: p2.action || p1.action,
environmentTime: p2.environmentTime || p1.environmentTime,
environmentSky: p2.environmentSky || p1.environmentSky,
environmentLocation: p2.environmentLocation || p1.environmentLocation,
hairLength: p2.hairLength || p1.hairLength,
hairColor: p2.hairColor || p1.hairColor,
hairStyle: p2.hairStyle || p1.hairStyle,
hairBraid: p2.hairBraid || p1.hairBraid,
hairBangs: p2.hairBangs || p1.hairBangs,
hairOrnament: p2.hairOrnament || p1.hairOrnament,
eyeColor: p2.hairColor || p1.hairColor,
eyeStyle: p2.eyeStyle || p1.eyeStyle,
eyeStatus: p2.eyeStatus || p1.eyeStyle,
facialFeature: p2.facialFeature || p1.facialFeature,
facialExpression: p2.facialExpression || p1.facialExpression,
bodyBreasts: p2.bodyBreasts || p1.bodyBreasts,
bodyClothing: p2.bodyClothing || p1.bodyClothing,
bodyLegOrnaments: p2.bodyLegOrnaments || p1.bodyLegOrnaments,
bodyShoes: p2.bodyShoes || p1.bodyShoes,
ornaments: mergeArray(p1.ornaments, p2.ornaments),
};
return _p;
};
export const getPrompts = (p: FigurePrompts): string[] => {
const prompts = [] as string[];
Object.values(p).forEach((value) => {
if (typeof value === "string") prompts.push(value);
else if (Array.isArray(value)) prompts.push(...value);
});
return prompts;
};

@ -1,33 +0,0 @@
export const randomSelectNoRepeat = (
arr: string[] | any[],
count: number,
mapper?: (obj: any) => any
) => {
if(arr.length < count) return arr;
const length = arr.length;
let availableNum = 0;
let lottery = {} as any;
while (availableNum < count) {
let code = Math.random() * length;
if (code === length) code -= 1;
code = Math.floor(code);
if (lottery[code]) continue;
lottery[code] = mapper
? mapper(arr[code])
: typeof arr[code] === "string"
? arr[code]
: {
...arr[code],
};
availableNum++;
}
return Object.values(lottery) as any[];
};
export const randomSelect = (arr: any[], noReturn = 0) => {
if (Math.random() < noReturn) return undefined;
const length = arr.length;
let code = Math.random() * length;
if (code === length) code -= 1;
return arr[code];
};

@ -1,12 +0,0 @@
module.exports = {
purge: [],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
},
purge: ['./src/**/*.{js,jsx,ts,tsx}', './public/index.html'],
variants: {
extend: {},
},
plugins: [],
}

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save