✨ updated
This commit is contained in:
35
app/core/api/common/captcha/verify/verify_rotate_captcha.go
Normal file
35
app/core/api/common/captcha/verify/verify_rotate_captcha.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package verify
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
"github.com/wenlng/go-captcha/v2/rotate"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
)
|
||||
|
||||
// VerifyRotateCaptcha verify rotate captcha
|
||||
func VerifyRotateCaptcha(context context.Context, redis *redis.Client, angle int64, key string) bool {
|
||||
cacheDataByte := redis.Get(context, constant.UserCaptchaPrefix+key).Val()
|
||||
if len(cacheDataByte) == 0 {
|
||||
return false
|
||||
}
|
||||
var dct *rotate.Block
|
||||
if err := json.Unmarshal([]byte(cacheDataByte), &dct); err != nil {
|
||||
return false
|
||||
}
|
||||
sAngle, err := strconv.ParseFloat(fmt.Sprintf("%v", angle), 64)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
chkRet := rotate.CheckAngle(int64(sAngle), int64(dct.Angle), 2)
|
||||
if chkRet {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
}
|
36
app/core/api/common/captcha/verify/verify_slide_captcha.go
Normal file
36
app/core/api/common/captcha/verify/verify_slide_captcha.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package verify
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
"github.com/wenlng/go-captcha/v2/slide"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
)
|
||||
|
||||
// VerifySlideCaptcha verify slide captcha
|
||||
func VerifySlideCaptcha(context context.Context, redis *redis.Client, point []int64, key string) bool {
|
||||
cacheDataByte := redis.Get(context, constant.UserCaptchaPrefix+key).Val()
|
||||
if len(cacheDataByte) == 0 {
|
||||
return false
|
||||
}
|
||||
var dct *slide.Block
|
||||
if err := json.Unmarshal([]byte(cacheDataByte), &dct); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
chkRet := false
|
||||
if 2 == len(point) {
|
||||
sx, _ := strconv.ParseFloat(fmt.Sprintf("%v", point[0]), 64)
|
||||
sy, _ := strconv.ParseFloat(fmt.Sprintf("%v", point[1]), 64)
|
||||
chkRet = slide.CheckPoint(int64(sx), int64(sy), int64(dct.X), int64(dct.Y), 4)
|
||||
}
|
||||
if chkRet {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
8
app/core/api/common/constant/redis_prefix.go
Normal file
8
app/core/api/common/constant/redis_prefix.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package constant
|
||||
|
||||
const (
|
||||
UserClientPrefix string = "user:client:"
|
||||
UserSessionPrefix string = "user:session:"
|
||||
UserCaptchaPrefix string = "user:captcha:"
|
||||
UserTokenPrefix string = "user:token:"
|
||||
)
|
3
app/core/api/common/constant/session_key.go
Normal file
3
app/core/api/common/constant/session_key.go
Normal file
@@ -0,0 +1,3 @@
|
||||
package constant
|
||||
|
||||
const SESSION_KEY = "SESSION"
|
16
app/core/api/common/i18n/bundle.go
Normal file
16
app/core/api/common/i18n/bundle.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package i18n
|
||||
|
||||
import (
|
||||
i18n2 "github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"github.com/pelletier/go-toml/v2"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
func NewBundle(tag language.Tag, configs ...string) *i18n2.Bundle {
|
||||
bundle := i18n2.NewBundle(tag)
|
||||
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
|
||||
for _, file := range configs {
|
||||
bundle.LoadMessageFile(file)
|
||||
}
|
||||
return bundle
|
||||
}
|
62
app/core/api/common/i18n/cache.go
Normal file
62
app/core/api/common/i18n/cache.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package i18n
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
i18n2 "github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"golang.org/x/text/language"
|
||||
"google.golang.org/grpc/metadata"
|
||||
)
|
||||
|
||||
/*
|
||||
type Cache interface {
|
||||
GetLocalizer() (*i18n2.Localizer, bool)
|
||||
SetLocalizer(l *i18n2.Localizer)
|
||||
}
|
||||
*/
|
||||
|
||||
func getLocalizer(ctx context.Context) (*i18n2.Localizer, bool) {
|
||||
v := ctx.Value(I18nKey)
|
||||
if l, b := v.(*i18n2.Localizer); b {
|
||||
return l, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func withRequest(r *http.Request, currentLang language.Tag, bundle *i18n2.Bundle) *http.Request {
|
||||
|
||||
accept := r.Header.Get(defaultLangHeaderKey)
|
||||
localizer := i18n2.NewLocalizer(bundle, accept)
|
||||
ctx := setLocalizer(r.Context(), localizer)
|
||||
ctx = setCurrentLang(ctx, currentLang)
|
||||
ctx = metadata.AppendToOutgoingContext(ctx, defaultLangHeaderKey, accept)
|
||||
return r.WithContext(ctx)
|
||||
}
|
||||
|
||||
func setCurrentLang(ctx context.Context, currentLang language.Tag) context.Context {
|
||||
return context.WithValue(ctx, I18nCurrentLangKey, currentLang)
|
||||
}
|
||||
|
||||
func setLocalizer(ctx context.Context, l *i18n2.Localizer) context.Context {
|
||||
return context.WithValue(ctx, I18nKey, l)
|
||||
}
|
||||
|
||||
func IsHasI18n(ctx context.Context) bool {
|
||||
v := ctx.Value(I18nKey)
|
||||
if v != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// func isHasI18n(ctx context.Context) bool {
|
||||
// if use, exist := ctx.Value(isUseI18n).(bool); exist {
|
||||
// return use
|
||||
// }
|
||||
// return false
|
||||
// }
|
||||
//
|
||||
// func setHasI18n(ctx context.Context, use bool) context.Context {
|
||||
// return context.WithValue(ctx, isUseI18n, use)
|
||||
// }
|
61
app/core/api/common/i18n/i18n.go
Normal file
61
app/core/api/common/i18n/i18n.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package i18n
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
i18n2 "github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
func FormatText(ctx context.Context, msgId string, defaultText string) string {
|
||||
return FormatTextWithData(ctx, msgId, defaultText, nil)
|
||||
}
|
||||
|
||||
func FormatTextWithData(ctx context.Context, msgId string, defaultText string, args map[string]interface{}) string {
|
||||
return FormatMessage(ctx, &i18n2.Message{
|
||||
ID: msgId,
|
||||
Other: defaultText,
|
||||
}, args)
|
||||
}
|
||||
|
||||
func FormatMessage(ctx context.Context, message *i18n2.Message, args map[string]interface{}) string {
|
||||
if localizer, ok := getLocalizer(ctx); ok {
|
||||
return localizer.MustLocalize(&i18n2.LocalizeConfig{
|
||||
DefaultMessage: message,
|
||||
TemplateData: args,
|
||||
})
|
||||
}
|
||||
return formatInternalMessage(message, args)
|
||||
}
|
||||
|
||||
func formatInternalMessage(message *i18n2.Message, args map[string]interface{}) string {
|
||||
if args == nil {
|
||||
return message.Other
|
||||
}
|
||||
tpl := i18n2.NewMessageTemplate(message)
|
||||
msg, err := tpl.Execute("other", args, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
func FetchCurrentLanguageFromCtx(ctx context.Context) (*language.Tag, bool) {
|
||||
v := ctx.Value(I18nCurrentLangKey)
|
||||
if l, b := v.(language.Tag); b {
|
||||
return &l, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func LocalizedString(ctx context.Context, defaultValue string, langMap map[language.Tag]string) string {
|
||||
langTag, tagExists := FetchCurrentLanguageFromCtx(ctx)
|
||||
if !tagExists {
|
||||
return defaultValue
|
||||
}
|
||||
str, ok := langMap[*langTag]
|
||||
if !ok {
|
||||
return defaultValue
|
||||
}
|
||||
return str
|
||||
}
|
21
app/core/api/common/i18n/keys.go
Normal file
21
app/core/api/common/i18n/keys.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package i18n
|
||||
|
||||
const I18nKey = "i18n"
|
||||
const I18nCurrentLangKey = "lang"
|
||||
|
||||
var (
|
||||
defaultLangHeaderKey = "Accept-Language"
|
||||
defaultErrCode uint32 = 10001
|
||||
)
|
||||
|
||||
// SetDefaultLangHeaderKey sets the default value of the lang header key.
|
||||
// need to be set before use
|
||||
func SetDefaultLangHeaderKey(key string) {
|
||||
defaultLangHeaderKey = key
|
||||
}
|
||||
|
||||
// SetDefaultErrCode sets the default value of the err code.
|
||||
// need to be set before use
|
||||
func SetDefaultErrCode(code uint32) {
|
||||
defaultErrCode = code
|
||||
}
|
28
app/core/api/common/i18n/middleware.go
Normal file
28
app/core/api/common/i18n/middleware.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package i18n
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
type I18nMiddleware struct {
|
||||
supportTags []language.Tag
|
||||
localizationFiles []string
|
||||
}
|
||||
|
||||
func NewI18nMiddleware(supportTags []language.Tag, localizationFiles []string) *I18nMiddleware {
|
||||
return &I18nMiddleware{
|
||||
supportTags: supportTags,
|
||||
localizationFiles: localizationFiles,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *I18nMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
lang := r.Header.Get(defaultLangHeaderKey)
|
||||
langTag := MatchCurrentLanguageTag(lang, m.supportTags)
|
||||
bundle := NewBundle(langTag, m.localizationFiles...)
|
||||
next(w, withRequest(r, langTag, bundle))
|
||||
}
|
||||
}
|
14
app/core/api/common/i18n/parse.go
Normal file
14
app/core/api/common/i18n/parse.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package i18n
|
||||
|
||||
import "golang.org/x/text/language"
|
||||
|
||||
func MatchCurrentLanguageTag(accept string, supportTags []language.Tag) language.Tag {
|
||||
langTags, _, err := language.ParseAcceptLanguage(accept)
|
||||
if err != nil {
|
||||
langTags = []language.Tag{language.English}
|
||||
}
|
||||
var matcher = language.NewMatcher(supportTags)
|
||||
_, i, _ := matcher.Match(langTags...)
|
||||
tag := supportTags[i]
|
||||
return tag
|
||||
}
|
74
app/core/api/common/i18n/rpc_interceptor.go
Normal file
74
app/core/api/common/i18n/rpc_interceptor.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package i18n
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
|
||||
i18n2 "github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"golang.org/x/text/language"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/metadata"
|
||||
)
|
||||
|
||||
var rpcInterceptorDebug = false
|
||||
|
||||
func WithRpcInterceptorDebug(debug bool) {
|
||||
rpcInterceptorDebug = debug
|
||||
}
|
||||
|
||||
type I18nGrpcInterceptor struct {
|
||||
supportTags []language.Tag
|
||||
localizationFiles []string
|
||||
}
|
||||
|
||||
func NewI18nGrpcInterceptor(supportTags []language.Tag, localizationFiles []string) *I18nGrpcInterceptor {
|
||||
if len(supportTags) == 0 {
|
||||
panic("supportTags can not be empty")
|
||||
}
|
||||
return &I18nGrpcInterceptor{
|
||||
supportTags: supportTags,
|
||||
localizationFiles: localizationFiles,
|
||||
}
|
||||
}
|
||||
|
||||
func (i *I18nGrpcInterceptor) Interceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
|
||||
ctx, err = i.saveLocalize(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return handler(ctx, req)
|
||||
}
|
||||
|
||||
func (i *I18nGrpcInterceptor) saveLocalize(ctx context.Context) (context.Context, error) {
|
||||
respHeader, ok := metadata.FromIncomingContext(ctx)
|
||||
// lang := "en-US" //language.English
|
||||
langTag := i.supportTags[0]
|
||||
lang := langTag.String()
|
||||
if ok {
|
||||
langs := respHeader.Get(defaultLangHeaderKey)
|
||||
if len(langs) == 0 {
|
||||
// return nil, status.Error(codes.Code(defaultErrCode), "can not correct get language")
|
||||
if rpcInterceptorDebug {
|
||||
log.Printf("can not correct get language")
|
||||
}
|
||||
} else {
|
||||
lang = langs[0]
|
||||
langTag = MatchCurrentLanguageTag(lang, i.supportTags)
|
||||
}
|
||||
} else {
|
||||
if rpcInterceptorDebug {
|
||||
log.Printf("can not correct get metadata1")
|
||||
}
|
||||
// return nil, status.Error(codes.Code(defaultErrCode), "can not correct get metadata1")
|
||||
}
|
||||
|
||||
// lang := langs[0]
|
||||
// langTag := MatchCurrentLanguageTag(lang, i.supportTags)
|
||||
bundle := NewBundle(langTag, i.localizationFiles...)
|
||||
localizer := i18n2.NewLocalizer(bundle, lang)
|
||||
ctx = setLocalizer(ctx, localizer)
|
||||
|
||||
// Append the language metadata to the outgoing context
|
||||
ctx = metadata.AppendToOutgoingContext(ctx, defaultLangHeaderKey, lang)
|
||||
return ctx, nil
|
||||
}
|
51
app/core/api/common/jwt/access_token.go
Normal file
51
app/core/api/common/jwt/access_token.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package jwt
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/zeromicro/go-zero/core/logc"
|
||||
)
|
||||
|
||||
type AccessJWTPayload struct {
|
||||
UserID string `json:"user_id"`
|
||||
Type string `json:"type" default:"access"`
|
||||
}
|
||||
type AccessJWTClaims struct {
|
||||
AccessJWTPayload
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
func GenerateAccessToken(secret string, payload AccessJWTPayload) string {
|
||||
claims := AccessJWTClaims{
|
||||
AccessJWTPayload: payload,
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Minute * 15)),
|
||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||
NotBefore: jwt.NewNumericDate(time.Now()),
|
||||
},
|
||||
}
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
accessToken, err := token.SignedString([]byte(secret))
|
||||
if err != nil {
|
||||
logc.Error(context.Background(), err)
|
||||
return ""
|
||||
}
|
||||
return accessToken
|
||||
}
|
||||
|
||||
// ParseAccessToken parses a JWT token and returns the payload
|
||||
func ParseAccessToken(secret string, tokenString string) *AccessJWTPayload {
|
||||
token, err := jwt.ParseWithClaims(tokenString, &AccessJWTClaims{}, func(token *jwt.Token) (interface{}, error) {
|
||||
return []byte(secret), nil
|
||||
})
|
||||
if err != nil {
|
||||
logc.Error(context.Background(), err)
|
||||
return nil
|
||||
}
|
||||
if claims, ok := token.Claims.(*AccessJWTClaims); ok && token.Valid {
|
||||
return &claims.AccessJWTPayload
|
||||
}
|
||||
return nil
|
||||
}
|
52
app/core/api/common/jwt/refresh_token.go
Normal file
52
app/core/api/common/jwt/refresh_token.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package jwt
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/zeromicro/go-zero/core/logc"
|
||||
)
|
||||
|
||||
type RefreshJWTPayload struct {
|
||||
UserID string `json:"user_id"`
|
||||
Type string `json:"type" default:"refresh"`
|
||||
}
|
||||
type RefreshJWTClaims struct {
|
||||
RefreshJWTPayload
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
// GenerateRefreshToken generates a JWT token with the given payload, and returns the accessToken and refreshToken
|
||||
func GenerateRefreshToken(secret string, payload RefreshJWTPayload, days time.Duration) string {
|
||||
refreshClaims := RefreshJWTClaims{
|
||||
RefreshJWTPayload: payload,
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(days)),
|
||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||
NotBefore: jwt.NewNumericDate(time.Now()),
|
||||
},
|
||||
}
|
||||
refreshToken := jwt.NewWithClaims(jwt.SigningMethodHS256, refreshClaims)
|
||||
refreshTokenString, err := refreshToken.SignedString([]byte(secret))
|
||||
if err != nil {
|
||||
logc.Error(context.Background(), err)
|
||||
return ""
|
||||
}
|
||||
return refreshTokenString
|
||||
}
|
||||
|
||||
// ParseRefreshToken parses a JWT token and returns the payload
|
||||
func ParseRefreshToken(secret string, refreshTokenString string) *RefreshJWTPayload {
|
||||
token, err := jwt.ParseWithClaims(refreshTokenString, &RefreshJWTClaims{}, func(token *jwt.Token) (interface{}, error) {
|
||||
return []byte(secret), nil
|
||||
})
|
||||
if err != nil {
|
||||
logc.Error(context.Background(), err)
|
||||
return nil
|
||||
}
|
||||
if claims, ok := token.Claims.(*RefreshJWTClaims); ok && token.Valid {
|
||||
return &claims.RefreshJWTPayload
|
||||
}
|
||||
return nil
|
||||
}
|
12
app/core/api/common/middleware/cors_middleware.go
Normal file
12
app/core/api/common/middleware/cors_middleware.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package middleware
|
||||
|
||||
import "net/http"
|
||||
|
||||
func CORSMiddleware() func(http.Header) {
|
||||
return func(header http.Header) {
|
||||
header.Set("Access-Control-Allow-Origin", "*")
|
||||
header.Add("Access-Control-Allow-Headers", "UserHeader1, UserHeader2")
|
||||
header.Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, PATCH")
|
||||
header.Set("Access-Control-Expose-Headers", "Content-Length, Content-Type")
|
||||
}
|
||||
}
|
24
app/core/api/common/middleware/i18n_middleware.go
Normal file
24
app/core/api/common/middleware/i18n_middleware.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/i18n"
|
||||
)
|
||||
|
||||
func I18nMiddleware(next http.HandlerFunc) http.HandlerFunc {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
zhPath := filepath.Join(cwd, "/resources/language/", "active.zh.toml")
|
||||
enPath := filepath.Join(cwd, "/resources/language/", "active.en.toml")
|
||||
return i18n.NewI18nMiddleware([]language.Tag{
|
||||
language.English,
|
||||
language.Chinese,
|
||||
}, []string{enPath, zhPath}).Handle(next)
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
package middleware
|
||||
|
||||
import "net/http"
|
||||
|
||||
func SecurityHeadersMiddleware(w http.ResponseWriter, r *http.Request) {
|
||||
r.Header.Set("X-Frame-Options", "DENY")
|
||||
r.Header.Set("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
|
||||
r.Header.Set("X-XSS-Protection", "1; mode=block")
|
||||
r.Header.Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
|
||||
r.Header.Set("Referrer-Policy", "strict-origin")
|
||||
r.Header.Set("X-Content-Type-Options", "nosniff")
|
||||
r.Header.Set("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
|
||||
}
|
48
app/core/api/common/response/response.go
Normal file
48
app/core/api/common/response/response.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package response
|
||||
|
||||
import "schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
|
||||
// Success returns a success response with the given data.
|
||||
func Success[T any](data T) *types.Response {
|
||||
return &types.Response{
|
||||
Code: 200,
|
||||
Message: "success",
|
||||
Data: data,
|
||||
}
|
||||
}
|
||||
|
||||
// SuccessWithMessage returns a success response with the given message.
|
||||
func SuccessWithMessage(message string) *types.Response {
|
||||
return &types.Response{
|
||||
Code: 200,
|
||||
Message: message,
|
||||
Data: nil,
|
||||
}
|
||||
}
|
||||
|
||||
// Error returns an error response with the given message.
|
||||
func Error() *types.Response {
|
||||
return &types.Response{
|
||||
Code: 500,
|
||||
Message: "error",
|
||||
Data: nil,
|
||||
}
|
||||
}
|
||||
|
||||
// ErrorWithCode returns an error response with the given code and message.
|
||||
func ErrorWithCode(code int64, message string) *types.Response {
|
||||
return &types.Response{
|
||||
Code: code,
|
||||
Message: message,
|
||||
Data: nil,
|
||||
}
|
||||
}
|
||||
|
||||
// ErrorWithMessage returns an error response with the given message.
|
||||
func ErrorWithMessage(message string) *types.Response {
|
||||
return &types.Response{
|
||||
Code: 500,
|
||||
Message: message,
|
||||
Data: nil,
|
||||
}
|
||||
}
|
20
app/core/api/common/utils/encrypt.go
Normal file
20
app/core/api/common/utils/encrypt.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package utils
|
||||
|
||||
import "golang.org/x/crypto/bcrypt"
|
||||
|
||||
// Encrypt 加密
|
||||
func Encrypt(val string) (string, error) {
|
||||
// 使用bcrypt库的GenerateFromPassword函数进行哈希处理
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(val), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(hashedPassword), err
|
||||
}
|
||||
|
||||
// Verify 验证
|
||||
func Verify(hashedVal string, val string) bool {
|
||||
// 使用bcrypt库的CompareHashAndPassword函数比较密码
|
||||
err := bcrypt.CompareHashAndPassword([]byte(hashedVal), []byte(val))
|
||||
return err == nil
|
||||
}
|
683
app/core/api/common/utils/generate_avatar.go
Normal file
683
app/core/api/common/utils/generate_avatar.go
Normal file
@@ -0,0 +1,683 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"math"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
Theme int
|
||||
Part int
|
||||
}
|
||||
|
||||
var svgStart = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 231 231\">"
|
||||
var svgEnd = "</svg>"
|
||||
var env = "<path d=\"M33.83,33.83a115.5,115.5,0,1,1,0,163.34,115.49,115.49,0,0,1,0-163.34Z\" style=\"fill:#01;\"/>"
|
||||
var head = "<path d=\"m115.5 51.75a63.75 63.75 0 0 0-10.5 126.63v14.09a115.5 115.5 0 0 0-53.729 19.027 115.5 115.5 0 0 0 128.46 0 115.5 115.5 0 0 0-53.729-19.029v-14.084a63.75 63.75 0 0 0 53.25-62.881 63.75 63.75 0 0 0-63.65-63.75 63.75 63.75 0 0 0-0.09961 0z\" style=\"fill:#000;\"/>"
|
||||
|
||||
// Themes
|
||||
var themes [16][3]map[string][]string
|
||||
|
||||
// Shapes
|
||||
var sp [16]map[string]string
|
||||
|
||||
func init() {
|
||||
// Robo
|
||||
themes[0][0] = map[string][]string{
|
||||
"env": {"#ff2f2b"},
|
||||
"clo": {"#fff", "#000"},
|
||||
"head": {"#fff"},
|
||||
"mouth": {"#fff", "#000", "#000"},
|
||||
"eyes": {"#000", "none", "#0ff"},
|
||||
"top": {"#fff", "#fff"},
|
||||
}
|
||||
themes[0][1] = map[string][]string{
|
||||
"env": {"#ff1ec1"},
|
||||
"clo": {"#000", "#fff"},
|
||||
"head": {"#ffc1c1"},
|
||||
"mouth": {"#fff", "#000", "#000"},
|
||||
"eyes": {"#FF2D00", "#fff", "none"},
|
||||
"top": {"#a21d00", "#fff"},
|
||||
}
|
||||
themes[0][2] = map[string][]string{
|
||||
"env": {"#0079b1"},
|
||||
"clo": {"#0e00b1", "#d1fffe"},
|
||||
"head": {"#f5aa77"},
|
||||
"mouth": {"#fff", "#000", "#000"},
|
||||
"eyes": {"#0c00de", "#fff", "none"},
|
||||
"top": {"#acfffd", "#acfffd"},
|
||||
}
|
||||
|
||||
// Girl
|
||||
themes[1][0] = map[string][]string{
|
||||
"env": {"#a50000"},
|
||||
"clo": {"#f06", "#8e0039"},
|
||||
"head": {"#85492C"},
|
||||
"mouth": {"#000"},
|
||||
"eyes": {"#000", "#ff9809"},
|
||||
"top": {"#ff9809", "#ff9809", "none", "none"},
|
||||
}
|
||||
themes[1][1] = map[string][]string{
|
||||
"env": {"#40E83B"},
|
||||
"clo": {"#00650b", "#62ce5a"},
|
||||
"head": {"#f7c1a6"},
|
||||
"mouth": {"#6e1c1c"},
|
||||
"eyes": {"#000", "#ff833b"},
|
||||
"top": {"#67FFCC", "none", "none", "#ecff3b"},
|
||||
}
|
||||
themes[1][2] = map[string][]string{
|
||||
"env": {"#ff2c2c"},
|
||||
"clo": {"#fff", "#000"},
|
||||
"head": {"#ffce8b"},
|
||||
"mouth": {"#000"},
|
||||
"eyes": {"#000", "#0072ff"},
|
||||
"top": {"#ff9809", "none", "#ffc809", "none"},
|
||||
}
|
||||
|
||||
// Blonde
|
||||
themes[2][0] = map[string][]string{
|
||||
"env": {"#ff7520"},
|
||||
"clo": {"#d12823"},
|
||||
"head": {"#fee3c5"},
|
||||
"mouth": {"#d12823"},
|
||||
"eyes": {"#000", "none"},
|
||||
"top": {"#000", "none", "none", "#FFCC00", "red"},
|
||||
}
|
||||
themes[2][1] = map[string][]string{
|
||||
"env": {"#ff9700"},
|
||||
"clo": {"#000"},
|
||||
"head": {"#d2ad6d"},
|
||||
"mouth": {"#000"},
|
||||
"eyes": {"#000", "#00ffdc"},
|
||||
"top": {"#fdff00", "#fdff00", "none", "none", "none"},
|
||||
}
|
||||
themes[2][2] = map[string][]string{
|
||||
"env": {"#26a7ff"},
|
||||
"clo": {"#d85cd7"},
|
||||
"head": {"#542e02"},
|
||||
"mouth": {"#f70014"},
|
||||
"eyes": {"#000", "magenta"},
|
||||
"top": {"#FFCC00", "#FFCC00", "#FFCC00", "#ff0000", "yellow"},
|
||||
}
|
||||
|
||||
// Evilnormie
|
||||
themes[3][0] = map[string][]string{
|
||||
"env": {"#6FC30E"},
|
||||
"clo": {"#b4e1fa", "#5b5d6e", "#515262", "#a0d2f0", "#a0d2f0"},
|
||||
"head": {"#fae3b9"},
|
||||
"mouth": {"#fff", "#000"},
|
||||
"eyes": {"#000"},
|
||||
"top": {"#8eff45", "#8eff45", "none", "none"},
|
||||
}
|
||||
themes[3][1] = map[string][]string{
|
||||
"env": {"#00a58c"},
|
||||
"clo": {"#000", "#5b00", "#5100", "#a000", "#a000"},
|
||||
"head": {"#FAD2B9"},
|
||||
"mouth": {"#fff", "#000"},
|
||||
"eyes": {"#000"},
|
||||
"top": {"#FFC600", "none", "#FFC600", "none"},
|
||||
}
|
||||
themes[3][2] = map[string][]string{
|
||||
"env": {"#ff501f"},
|
||||
"clo": {"#000", "#ff0000", "#ff0000", "#7d7d7d", "#7d7d7d"},
|
||||
"head": {"#fff3dc"},
|
||||
"mouth": {"#d2001b", "none"},
|
||||
"eyes": {"#000"},
|
||||
"top": {"#D2001B", "none", "none", "#D2001B"},
|
||||
}
|
||||
|
||||
// Country
|
||||
themes[4][0] = map[string][]string{
|
||||
"env": {"#fc0"},
|
||||
"clo": {"#901e0e", "#ffbe1e", "#ffbe1e", "#c55f54"},
|
||||
"head": {"#f8d9ad"},
|
||||
"mouth": {"#000", "none", "#000", "none"},
|
||||
"eyes": {"#000"},
|
||||
"top": {"#583D00", "#AF892E", "#462D00", "#a0a0a0"},
|
||||
}
|
||||
themes[4][1] = map[string][]string{
|
||||
"env": {"#386465"},
|
||||
"clo": {"#fff", "#333", "#333", "#333"},
|
||||
"head": {"#FFD79D"},
|
||||
"mouth": {"#000", "#000", "#000", "#000"},
|
||||
"eyes": {"#000"},
|
||||
"top": {"#27363C", "#5DCAD4", "#314652", "#333"},
|
||||
}
|
||||
themes[4][2] = map[string][]string{
|
||||
"env": {"#DFFF00"},
|
||||
"clo": {"#304267", "#aab0b1", "#aab0b1", "#aab0b1"},
|
||||
"head": {"#e6b876"},
|
||||
"mouth": {"#50230a", "#50230a", "#50230a", "#50230a"},
|
||||
"eyes": {"#000"},
|
||||
"top": {"#333", "#afafaf", "#222", "#6d3a1d"},
|
||||
}
|
||||
|
||||
// Johnyold
|
||||
themes[5][0] = map[string][]string{
|
||||
"env": {"#a09300"},
|
||||
"clo": {"#c7d4e2", "#435363", "#435363", "#141720", "#141720", "#e7ecf2", "#e7ecf2"},
|
||||
"head": {"#f5d4a6"},
|
||||
"mouth": {"#000", "#cf9f76"},
|
||||
"eyes": {"#000", "#000", "#000", "#000", "#000", "#000", "#fff", "#fff", "#fff", "#fff", "#000", "#000"},
|
||||
"top": {"none", "#fdff00"},
|
||||
}
|
||||
themes[5][1] = map[string][]string{
|
||||
"env": {"#b3003e"},
|
||||
"clo": {"#000", "#435363", "#435363", "#000", "none", "#e7ecf2", "#e7ecf2"},
|
||||
"head": {"#f5d4a6"},
|
||||
"mouth": {"#000", "#af9f94"},
|
||||
"eyes": {"#9ff3ffdb", "#000", "#9ff3ffdb", "#000", "#2f508a", "#000", "#000", "#000", "none", "none", "none", "none"},
|
||||
"top": {"#ff9a00", "#ff9a00"},
|
||||
}
|
||||
themes[5][2] = map[string][]string{
|
||||
"env": {"#884f00"},
|
||||
"clo": {"#ff0000", "#fff", "#fff", "#141720", "#141720", "#e7ecf2", "#e7ecf2"},
|
||||
"head": {"#c57b14"},
|
||||
"mouth": {"#000", "#cf9f76"},
|
||||
"eyes": {"none", "#000", "none", "#000", "#5a0000", "#000", "#000", "#000", "none", "none", "none", "none"},
|
||||
"top": {"#efefef", "none"},
|
||||
}
|
||||
|
||||
// Asian
|
||||
themes[6][0] = map[string][]string{
|
||||
"env": {"#8acf00"},
|
||||
"clo": {"#ee2829", "#ff0"},
|
||||
"head": {"#ffce73"},
|
||||
"mouth": {"#fff", "#000"},
|
||||
"eyes": {"#000"},
|
||||
"top": {"#000", "#000", "none", "#000", "#ff4e4e", "#000"},
|
||||
}
|
||||
themes[6][1] = map[string][]string{
|
||||
"env": {"#00d2a3"},
|
||||
"clo": {"#0D0046", "#ffce73"},
|
||||
"head": {"#ffce73"},
|
||||
"mouth": {"#000", "none"},
|
||||
"eyes": {"#000"},
|
||||
"top": {"#000", "#000", "#000", "none", "#ffb358", "#000", "none", "none"},
|
||||
}
|
||||
themes[6][2] = map[string][]string{
|
||||
"env": {"#ff184e"},
|
||||
"clo": {"#000", "none"},
|
||||
"head": {"#ffce73"},
|
||||
"mouth": {"#ff0000", "none"},
|
||||
"eyes": {"#000"},
|
||||
"top": {"none", "none", "none", "none", "none", "#ffc107", "none", "none"},
|
||||
}
|
||||
|
||||
// Punk
|
||||
themes[7][0] = map[string][]string{
|
||||
"env": {"#00deae"},
|
||||
"clo": {"#ff0000"},
|
||||
"head": {"#ffce94"},
|
||||
"mouth": {"#f73b6c", "#000"},
|
||||
"eyes": {"#e91e63", "#000", "#e91e63", "#000", "#000", "#000"},
|
||||
"top": {"#dd104f", "#dd104f", "#f73b6c", "#dd104f"},
|
||||
}
|
||||
themes[7][1] = map[string][]string{
|
||||
"env": {"#181284"},
|
||||
"clo": {"#491f49", "#ff9809", "#491f49"},
|
||||
"head": {"#f6ba97"},
|
||||
"mouth": {"#ff9809", "#000"},
|
||||
"eyes": {"#c4ffe4", "#000", "#c4ffe4", "#000", "#000", "#000"},
|
||||
"top": {"none", "none", "#d6f740", "#516303"},
|
||||
}
|
||||
themes[7][2] = map[string][]string{
|
||||
"env": {"#bcf700"},
|
||||
"clo": {"#ff14e4", "#000", "#14fffd"},
|
||||
"head": {"#7b401e"},
|
||||
"mouth": {"#666", "#000"},
|
||||
"eyes": {"#00b5b4", "#000", "#00b5b4", "#000", "#000", "#000"},
|
||||
"top": {"#14fffd", "#14fffd", "#14fffd", "#0d3a62"},
|
||||
}
|
||||
|
||||
// Afrohair
|
||||
themes[8][0] = map[string][]string{
|
||||
"env": {"#0df"},
|
||||
"clo": {"#571e57", "#ff0"},
|
||||
"head": {"#f2c280"},
|
||||
"mouth": {"#ff0000"},
|
||||
"eyes": {"#795548", "#000"},
|
||||
"top": {"#de3b00", "none"},
|
||||
}
|
||||
themes[8][1] = map[string][]string{
|
||||
"env": {"#B400C2"},
|
||||
"clo": {"#0D204A", "#00ffdf"},
|
||||
"head": {"#ca8628"},
|
||||
"mouth": {"#1a1a1a"},
|
||||
"eyes": {"#cbbdaf", "#000"},
|
||||
"top": {"#000", "#000"},
|
||||
}
|
||||
themes[8][2] = map[string][]string{
|
||||
"env": {"#ffe926"},
|
||||
"clo": {"#00d6af", "#000"},
|
||||
"head": {"#8c5100"},
|
||||
"mouth": {"#7d0000"},
|
||||
"eyes": {"none", "#000"},
|
||||
"top": {"#f7f7f7", "none"},
|
||||
}
|
||||
|
||||
// Normie female
|
||||
themes[9][0] = map[string][]string{
|
||||
"env": {"#4aff0c"},
|
||||
"clo": {"#101010", "#fff", "#fff"},
|
||||
"head": {"#dbbc7f"},
|
||||
"mouth": {"#000"},
|
||||
"eyes": {"#000", "none", "none"},
|
||||
"top": {"#531148", "#531148", "#531148", "none"},
|
||||
}
|
||||
themes[9][1] = map[string][]string{
|
||||
"env": {"#FFC107"},
|
||||
"clo": {"#033c58", "#fff", "#fff"},
|
||||
"head": {"#dbc97f"},
|
||||
"mouth": {"#000"},
|
||||
"eyes": {"none", "#fff", "#000"},
|
||||
"top": {"#FFEB3B", "#FFEB3B", "none", "#FFEB3B"},
|
||||
}
|
||||
themes[9][2] = map[string][]string{
|
||||
"env": {"#FF9800"},
|
||||
"clo": {"#b40000", "#fff", "#fff"},
|
||||
"head": {"#E2AF6B"},
|
||||
"mouth": {"#000"},
|
||||
"eyes": {"none", "#fff", "#000"},
|
||||
"top": {"#ec0000", "#ec0000", "none", "none"},
|
||||
}
|
||||
|
||||
// Older
|
||||
themes[10][0] = map[string][]string{
|
||||
"env": {"#104c8c"},
|
||||
"clo": {"#354B65", "#3D8EBB", "#89D0DA", "#00FFFD"},
|
||||
"head": {"#cc9a5c"},
|
||||
"mouth": {"#222", "#fff"},
|
||||
"eyes": {"#000", "#000"},
|
||||
"top": {"#fff", "#fff", "none"},
|
||||
}
|
||||
themes[10][1] = map[string][]string{
|
||||
"env": {"#0DC15C"},
|
||||
"clo": {"#212121", "#fff", "#212121", "#fff"},
|
||||
"head": {"#dca45f"},
|
||||
"mouth": {"#111", "#633b1d"},
|
||||
"eyes": {"#000", "#000"},
|
||||
"top": {"none", "#792B74", "#792B74"},
|
||||
}
|
||||
themes[10][2] = map[string][]string{
|
||||
"env": {"#ffe500"},
|
||||
"clo": {"#1e5e80", "#fff", "#1e5e80", "#fff"},
|
||||
"head": {"#e8bc86"},
|
||||
"mouth": {"#111", "none"},
|
||||
"eyes": {"#000", "#000"},
|
||||
"top": {"none", "none", "#633b1d"},
|
||||
}
|
||||
|
||||
// Firehair
|
||||
themes[11][0] = map[string][]string{
|
||||
"env": {"#4a3f73"},
|
||||
"clo": {"#e6e9ee", "#f1543f", "#ff7058", "#fff", "#fff"},
|
||||
"head": {"#b27e5b"},
|
||||
"mouth": {"#191919", "#191919"},
|
||||
"eyes": {"#000", "#000", "#57FFFD"},
|
||||
"top": {"#ffc", "#ffc", "#ffc"},
|
||||
}
|
||||
themes[11][1] = map[string][]string{
|
||||
"env": {"#00a08d"},
|
||||
"clo": {"#FFBA32", "#484848", "#4e4e4e", "#fff", "#fff"},
|
||||
"head": {"#ab5f2c"},
|
||||
"mouth": {"#191919", "#191919"},
|
||||
"eyes": {"#000", "#ff23fa63", "#000"},
|
||||
"top": {"#ff90f4", "#ff90f4", "#ff90f4"},
|
||||
}
|
||||
themes[11][2] = map[string][]string{
|
||||
"env": {"#22535d"},
|
||||
"clo": {"#000", "#ff2500", "#ff2500", "#fff", "#fff"},
|
||||
"head": {"#a76c44"},
|
||||
"mouth": {"#191919", "#191919"},
|
||||
"eyes": {"#000", "none", "#000"},
|
||||
"top": {"none", "#00efff", "none"},
|
||||
}
|
||||
|
||||
// Blond
|
||||
themes[12][0] = map[string][]string{
|
||||
"env": {"#2668DC"},
|
||||
"clo": {"#2385c6", "#b8d0e0", "#b8d0e0"},
|
||||
"head": {"#ad8a60"},
|
||||
"mouth": {"#000", "#4d4d4d"},
|
||||
"eyes": {"#7fb5a2", "#d1eddf", "#301e19"},
|
||||
"top": {"#fff510", "#fff510"},
|
||||
}
|
||||
themes[12][1] = map[string][]string{
|
||||
"env": {"#643869"},
|
||||
"clo": {"#D67D1B", "#b8d0e0", "#b8d0e0"},
|
||||
"head": {"#CC985A", "none0000"},
|
||||
"mouth": {"#000", "#ececec"},
|
||||
"eyes": {"#1f2644", "#9b97ce", "#301e19"},
|
||||
"top": {"#00eaff", "none"},
|
||||
}
|
||||
themes[12][2] = map[string][]string{
|
||||
"env": {"#F599FF"},
|
||||
"clo": {"#2823C6", "#b8d0e0", "#b8d0e0"},
|
||||
"head": {"#C7873A"},
|
||||
"mouth": {"#000", "#4d4d4d"},
|
||||
"eyes": {"#581b1b", "#FF8B8B", "#000"},
|
||||
"top": {"none", "#9c0092"},
|
||||
}
|
||||
|
||||
// Ateam
|
||||
themes[13][0] = map[string][]string{
|
||||
"env": {"#d10084"},
|
||||
"clo": {"#efedee", "#00a1e0", "#00a1e0", "#efedee", "#ffce1c"},
|
||||
"head": {"#b35f49"},
|
||||
"mouth": {"#3a484a", "#000"},
|
||||
"eyes": {"#000"},
|
||||
"top": {"#000", "none", "#000", "none"},
|
||||
}
|
||||
themes[13][1] = map[string][]string{
|
||||
"env": {"#E6C117"},
|
||||
"clo": {"#efedee", "#ec0033", "#ec0033", "#efedee", "#f2ff05"},
|
||||
"head": {"#ffc016"},
|
||||
"mouth": {"#4a3737", "#000"},
|
||||
"eyes": {"#000"},
|
||||
"top": {"#ffe900", "#ffe900", "none", "#ffe900"},
|
||||
}
|
||||
themes[13][2] = map[string][]string{
|
||||
"env": {"#1d8c00"},
|
||||
"clo": {"#e000cb", "#fff", "#fff", "#e000cb", "#ffce1c"},
|
||||
"head": {"#b96438"},
|
||||
"mouth": {"#000", "#000"},
|
||||
"eyes": {"#000"},
|
||||
"top": {"#53ffff", "#53ffff", "none", "none"},
|
||||
}
|
||||
|
||||
// Rasta
|
||||
themes[14][0] = map[string][]string{
|
||||
"env": {"#fc0065"},
|
||||
"clo": {"#708913", "#fdea14", "#708913", "#fdea14", "#708913"},
|
||||
"head": {"#DEA561"},
|
||||
"mouth": {"#444", "#000"},
|
||||
"eyes": {"#000"},
|
||||
"top": {"#32393f", "#32393f", "#32393f", "#32393f", "#32393f", "#32393f", "#32393f", "#32393f", "#32393f", "#32393f", "#32393f", "#32393f", "#32393f", "#32393f", "#32393f", "#32393f", "#32393f"},
|
||||
}
|
||||
themes[14][1] = map[string][]string{
|
||||
"env": {"#81f72e"},
|
||||
"clo": {"#ff0000", "#ffc107", "#ff0000", "#ffc107", "#ff0000"},
|
||||
"head": {"#ef9831"},
|
||||
"mouth": {"#6b0000", "#000"},
|
||||
"eyes": {"#000"},
|
||||
"top": {"#FFFAAD", "#FFFAAD", "#FFFAAD", "#FFFAAD", "#FFFAAD", "#FFFAAD", "#FFFAAD", "#FFFAAD", "#FFFAAD", "#FFFAAD", "#FFFAAD", "#FFFAAD", "#FFFAAD", "none", "none", "none", "none"},
|
||||
}
|
||||
themes[14][2] = map[string][]string{
|
||||
"env": {"#00D872"},
|
||||
"clo": {"#590D00", "#FD1336", "#590D00", "#FD1336", "#590D00"},
|
||||
"head": {"#c36c00"},
|
||||
"mouth": {"#56442b", "#000"},
|
||||
"eyes": {"#000"},
|
||||
"top": {"#004E4C", "#004E4C", "#004E4C", "#004E4C", "#004E4C", "#004E4C", "#004E4C", "#004E4C", "#004E4C", "none", "none", "none", "none", "none", "none", "none", "none"},
|
||||
}
|
||||
|
||||
// Meta
|
||||
themes[15][0] = map[string][]string{
|
||||
"env": {"#111"},
|
||||
"clo": {"#000", "#00FFFF"},
|
||||
"head": {"#755227"},
|
||||
"mouth": {"#fff", "#000"},
|
||||
"eyes": {"black", "#008a", "aqua"},
|
||||
"top": {"#fff", "#fff", "#fff", "#fff", "#fff"},
|
||||
}
|
||||
themes[15][1] = map[string][]string{
|
||||
"env": {"#00D0D4"},
|
||||
"clo": {"#000", "#fff"},
|
||||
"head": {"#755227"},
|
||||
"mouth": {"#fff", "#000"},
|
||||
"eyes": {"black", "#1df7ffa3", "#fcff2c"},
|
||||
"top": {"#fff539", "none", "#fff539", "none", "#fff539"},
|
||||
}
|
||||
themes[15][2] = map[string][]string{
|
||||
"env": {"#DC75FF"},
|
||||
"clo": {"#000", "#FFBDEC"},
|
||||
"head": {"#997549"},
|
||||
"mouth": {"#fff", "#000"},
|
||||
"eyes": {"black", "black", "aqua"},
|
||||
"top": {"#00fffd", "none", "none", "none", "none"},
|
||||
}
|
||||
|
||||
// Robo
|
||||
sp[0] = map[string]string{
|
||||
"clo": "<path d=\"m141.74 195a114.93 114.93 0 0 1 37.912 16.45l0.07 0.05c-1.17 0.79-2.3601 1.55-3.5601 2.29a115.55 115.55 0 0 1-120.95 0.21q-2.0001-1.23-4.0002-2.54a114.79 114.79 0 0 1 38.002-16.5 116.21 116.21 0 0 1 15.791-2.49v-14.57c1.32 0.22 2.6501 0.39 4.0002 0.51 2.0001 0.19 4.0002 0.28 6.1202 0.29a64.333 64.33 0 0 0 8.8804-0.62c0.67003-0.09 1.3401-0.2 2.0001-0.31v14.69a118 118 0 0 1 15.741 2.54z\" style=\"fill:#fff;\"/><path d=\"m79.292 212a3.4601 3.46 0 0 0 3.8902 5.07 3.3801 3.38 0 0 0 2.1001-1.61 3.4701 3.47 0 0 0-1.2801-4.72 3.4201 3.42 0 0 0-2.6201-0.34 3.5101 3.51 0 0 0-2.0901 1.6zm60.122 0.46a3.4901 3.49 0 0 0 1.21 4.7h0.06a3.4601 3.46 0 0 0 4.7202-1.27l0.07-0.13a3.4601 3.46 0 0 0-1.34-4.6 3.4601 3.46 0 0 0-2.5801-0.32 3.5301 3.53 0 0 0-2.1001 1.61zm9.8004 5.7 5.8602 5.87c-1.39 0.5-2.7901 1-4.2102 1.44l-4.4802-4.47a7.5203 7.52 0 0 1-1.9401 0.81 7.8303 7.83 0 0 1-6.0002-0.79 7.8703 7.87 0 0 1-2.9201-10.69v-0.07a7.8903 7.89 0 0 1 10.77-2.88l0.12 0.07a7.8603 7.86 0 0 1 2.7901 10.62v0.07zm-37.701-2.36-9.5004 9.51v4.9c-1.35-0.16-2.6801-0.33-4.0002-0.54v-6l0.58002-0.58 10.1-10.09a7.8703 7.87 0 1 1 2.8401 2.86zm7.3203-5.91a3.4601 3.46 0 1 0-1.6101 2.1 3.3801 3.38 0 0 0 1.6101-2.1zm-29.741 7.82 3.0901 3.1 0.59002 0.59v7.36c-1.3401-0.26-2.6801-0.55-4.0002-0.87v-4.84l-2.5101-2.51a7.5203 7.52 0 0 1-1.9401 0.81 7.8803 7.88 0 1 1 1.9101-14.43 7.8703 7.87 0 0 1 2.8901 10.75z\" style=\"fill:#1a1a1a;\"/>",
|
||||
"mouth": "<path d=\"m94.19 136.84h42.632a3.7801 3.78 0 0 1 3.7802 3.78v3.22a15.231 15.23 0 0 1-15.211 15.16h-19.781a15.251 15.25 0 0 1-15.221-15.16v-3.22a3.8002 3.8 0 0 1 3.7802-3.78z\" style=\"fill:#fff;stroke-linecap:round;stroke-linejoin:round;stroke-width:3px;stroke:#1a1a1a;\"/><path d=\"m130.96 136.84v21.16m-30.911-21.16v21.16m10.34-21.16v22.16m10.31-22.2v22.2\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:3px;stroke:#1a1a1a;\"/>",
|
||||
"eyes": "<path d=\"m83.739 83.92h63.533a19.101 19.1 0 0 1 19.051 19 19.111 19.11 0 0 1-19.051 19h-63.533a19.091 19.09 0 0 1-19.001-19 19.091 19.09 0 0 1 19.001-19z\" style=\"fill:#1a1a1a;\"/><path d=\"m140.23 93.54a9.3804 9.38 0 1 0 9.3804 9.38 9.3804 9.38 0 0 0-9.3804-9.38zm-49.402 0a9.3804 9.38 0 1 0 9.3804 9.38 9.3904 9.39 0 0 0-9.3804-9.38z\" style=\"fill:#e6e7e8;\"/><rect x=\"79.795\" y=\"98.627\" width=\"71.471\" height=\"8.5859\" ry=\"4.2929\" style=\"fill:#b3b3b3;\"/>",
|
||||
"top": "<path d=\"m32.902 67.662c-0.36295 1.7227-6.2342 30.695 5.6133 52.596 4.5843 8.4743 9.0081 13.239 12.75 15.893a67.7 67.7 0 0 1-3.4688-21.35 67.7 67.7 0 0 1 2.332-17.658c-4.4914-2.4646-10.868-6.9012-13.834-13.52-4.1626-9.285-3.6155-14.673-3.3926-15.961zm165.19 0c0.22292 1.2882 0.77005 6.6759-3.3926 15.961-2.9664 6.6183-9.3426 11.055-13.834 13.52a67.7 67.7 0 0 1 2.332 17.658 67.7 67.7 0 0 1-3.4688 21.35c3.7419-2.6532 8.1657-7.4183 12.75-15.893 11.847-21.9 5.9762-50.873 5.6133-52.596z\" style=\"fill:#fff;\"/><path d=\"m115.73 13.191c-7.3787-0.13351-13.509 5.7888-13.631 13.168-0.10128 5.8827 3.4508 10.518 8.0566 12.52 1.061 0.46115 2.1869 0.78009 3.3418 0.95703v8.4291c0.66778-0.02035 1.3358-0.03077 2.0039-0.03125 0.66547-9e-5 1.3309 0.0097 1.9961 0.0293v-8.4115c2.6002-0.38406 5.1586-1.5484 7.3086-3.625 4.2322-4.0878 4.9991-9.8755 3.1582-14.549-1.8407-4.6726-6.3502-8.3834-12.232-8.4863z\" style=\"fill:#fff;\"/>",
|
||||
}
|
||||
|
||||
// Girl
|
||||
sp[1] = map[string]string{
|
||||
"clo": "<path d=\"m141.75 195a114.79 114.79 0 0 1 38 16.5 115.53 115.53 0 0 1-128.46 0 114.79 114.79 0 0 1 38-16.5c0 10.76 11.75 19.48 26.25 19.48s26.25-8.72 26.25-19.48z\" style=\"fill:#1a1a1a;\"/><path d=\"m92.502 194.27v0.70391c0 4.3033 2.4373 8.2583 6.3807 11.183 4.2199 3.1204 10.106 5.0508 16.661 5.0508 6.548 0 12.434-1.9303 16.654-5.0508 3.9434-2.9245 6.388-6.8795 6.388-11.183v-0.67489c1.0768 0.21771 2.1463 0.44994 3.2158 0.69666h-7e-3c1.0695 0.24672 2.1318 0.50798 3.1867 0.791-0.27648 6.103-3.6524 11.553-8.9708 15.493-5.2821 3.9114-12.521 6.328-20.466 6.328-7.9449 0-15.184-2.4165-20.474-6.328-5.333-3.9477-8.7089-9.4194-8.9708-15.544 1.055-0.27577 2.1099-0.53702 3.1722-0.78376 1.0695-0.23947 2.1463-0.46443 3.2304-0.68213z\" style=\"fill:#b3b3b3;\"/>",
|
||||
"mouth": "<path d=\"m100.35 143.85a7.67 7.67 0 0 0 7.58 7.7v0a7.66 7.66 0 0 0 7.57-7.7 7.66 7.66 0 0 0 7.57 7.7v0a7.67 7.67 0 0 0 7.58-7.7\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:6.3998px;stroke:#333;\"/>",
|
||||
"eyes": "<path d=\"m78.73 111a10.9 10.9 0 0 1 15.19 0m43.16 0a10.9 10.9 0 0 1 15.19 0\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:6.1999px;stroke:#333;\"/><path d=\"m79.804 123.74h7.07m57.273 0h7.05\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:5.9998px;stroke:#b8b8b8;\"/>",
|
||||
"top": "<path d=\"m57.534 142.03c-6.9383-31.75-0.57294-52.577 14.174-62.344 22.562-12.283 62.082-12.222 83.484-1.8846 21.348 11.177 22.124 37.396 18.498 63.733 8.1279-14.155 13.164-31.598 14.085-48.902 1.0828-11.795-1.1756-18.866-7.4833-27.972-26.465-37.685-103.45-31.56-129.66-2.8372-7.8504 9.4615-9.6006 17.478-9.275 26.667 1.0024 18.667 6.9688 38.508 16.18 53.54z\" style=\"fill:#b3b3b3;\"/><path d=\"m111.26 3.0423c-6.013 0.1128-12.629 2.6924-15.291 7.9082-1.1676 3.2383-1.6758 6.2069-1.6758 8.8926 0.89228-0.2661 1.8005-0.5164 2.7266-0.7441 3.7502-1.0672 7.4851-1.7135 11.129-1.9981 1.1007-0.086 2.1953-0.1391 3.2773-0.1601h2e-3c5.6969-0.1133 11.09 0.6603 15.904 2.0527 0.0552-3.042-0.70696-5.9824-2.1738-8.5-1.8411-3.1599-4.7033-5.5568-8.4297-6.8262-1.6883-0.4952-3.5163-0.662-5.4688-0.625zm3.0664 17.449c-0.69317-0.01-1.3919-0.01-2.0938 0h-2e-3c-1.1591 0.019-2.3326 0.064-3.5117 0.1386-3.9035 0.246-7.9025 0.8061-11.92 1.7285-15.159 3.0075-26.469 9.9279-22.068 19.682 22.891-8.7773 52.315-10.403 76.023-2.2129 2.1414-9.5529-14.939-19.081-36.428-19.34z\" style=\"fill:#b3b3b3;\"/><path d=\"m165.62 16.981c-0.8575 0-1.9406 0.54389-3.3476 1.3574-7.3382 4.7652-13.452 10.867-19.516 18.363 9.2734 2.1825 17.903 5.6706 25.213 10.604 1.1512-9.1263 1.9137-18.503 0.055-26.996-0.57-2.4184-1.3017-3.3267-2.4043-3.3281zm-104.09 1.6934c-1.1026 0-1.8342 0.91165-2.4043 3.3301-1.8794 8.5869-1.0806 18.078 0.092 27.299 7.0559-4.6638 15.687-8.3667 25.111-10.984-6.043-7.4601-12.139-13.537-19.451-18.285-1.407-0.81353-2.4901-1.3605-3.3477-1.3594z\" style=\"fill:#b3b3b3;\"/><path d=\"m162.45 16.686c-2.3175 2e-3 -4.6276 0.57608-6.8926 1.668-8.4768 6.0155-11.113 13.349-10.133 19.787 10.323 2.7077 19.762 7.0658 27.346 13.279 9.848-4.9363 11.32-17.137 4.6152-25.852-4.7104-6.1222-9.8371-8.8878-14.936-8.8828zm-97.318 4.1387c-2.4569 0.0556-5.1642 0.54474-8.1172 1.5176-13.487 4.4433-19.06 21.215-3.6484 31.84 7.2476-6.0694 16.961-10.896 27.892-14.229 0.2193-3.3241-0.3201-7.0817-1.8691-11.236-2.8049-4.8445-7.2233-7.721-13.221-7.8906-0.3408-0.01-0.6861-0.01-1.0371-2e-3z\" style=\"fill:#b3b3b3;\"/>",
|
||||
}
|
||||
|
||||
// Blonde
|
||||
sp[2] = map[string]string{
|
||||
"clo": "<path d=\"m141.75 195a114.79 114.79 0 0 1 38 16.5 115.53 115.53 0 0 1-128.46 0 114.79 114.79 0 0 1 38-16.5c0 10.76 11.75 19.48 26.25 19.48s26.25-8.72 26.25-19.48z\" style=\"fill:#5a5a5a;\"/>",
|
||||
"mouth": "<path d=\"m115.5 161.71c-8.24 0-14.46-4.15-19.19-11.25 3.37-2.44 6.51-4.57 10-6.79a5.25 5.25 0 0 1 5.48-0.17 28.19 28.19 0 0 1 3.68 2.75 28.19 28.19 0 0 1 3.68-2.75 5.25 5.25 0 0 1 5.48 0.17c3.52 2.22 6.66 4.35 10 6.79-4.74 7.1-11 11.25-19.19 11.25z\" style=\"fill:#5a5a5a;\"/>",
|
||||
"eyes": "<path d=\"m172.7 90.75h-6.54c-0.14-0.1-0.26-0.22-0.4-0.3-4.48-2.76-22.75-2.11-33.71 1.2-1 0.3-1.91 0.61-2.75 0.94-1.8937 0.79244-3.8739 1.3597-5.9 1.69-5.5051 0.79002-10.403 0.79002-15.908 0-2.0261-0.33034-4.0063-0.89756-5.9-1.69-0.84-0.33-1.76-0.64-2.75-0.94-11-3.31-29.23-4-33.71-1.2-0.13832 0.08869-0.2688 0.18906-0.39 0.3h-6.55c-1.1046 0-2 0.89543-2 2v4.66c-0.0013 0.98185 0.49088 1.8986 1.31 2.44l1.9 1.27c0.59238 0.38889 0.93475 1.0622 0.9 1.77-0.14175 5.4854 0.88072 10.939 3 16 3.58 8.38 16 10.9 24.93 10.9 2.6976 0.0771 5.3921-0.2361 8-0.93 4.35-1.43 8.24-7.36 10.45-12.42 1.7607-3.8506 2.7493-8.009 2.91-12.24 7.3e-4 -0.7138 0.38183-1.3731 1-1.73 3.2281-1.951 6.5798-1.951 9.8079 0 0.61817 0.3569 0.99927 1.0162 1 1.73 0.16067 4.231 1.1493 8.3894 2.91 12.24 2.21 5.06 6.1 11 10.45 12.42 2.6079 0.6939 5.3024 1.0071 8 0.93 8.92 0 21.35-2.52 24.93-10.9 2.1193-5.0614 3.1418-10.515 3-16-0.0348-0.70778 0.30762-1.3811 0.9-1.77l1.9-1.27c0.81913-0.54136 1.3113-1.4582 1.31-2.44v-4.6c0.0336-1.1048-0.83521-2.0274-1.94-2.06z\" style=\"fill:#1a1a1a;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.5;stroke:#b3b3b3;\"/>",
|
||||
"top": "<path d=\"m124.22 13.61c-19.783 0-36.945 8.0887-39.695 24.106-15.332 0.23539-31.831 2.7712-41.663 15.782-6.0238 7.9604-7.0402 19.901-6.8476 31.724 0.46007 28.503 10.742 64.228-4.3012 89.714 16.584 5.7777 43.086 10.742 73.59 11.662v-8.6558c-1.851-0.35308-3.6592-0.78105-5.4353-1.2732-30.953-8.4632-50.672-36.635-47.259-68.669 1.5514-10.603 4.6221-19.665 10.025-27.69 5.3818-7.9925 13.267-15.717 23.892-21.41 0.40658 0.72757 1.9901 3.5843 2.4074 4.3012 7.5003 12.775 17.986 23.849 33.157 26.866 12.433 2.4609 23.849 3.4666 36.346 1.1555 4.2584-0.78106 10.667-2.3967 14.851-2.4181 14.861 33.404-1.0806 75.035-40.668 87.457-2.2255 0.70616-4.5258 1.316-6.8904 1.8189 0 2.707-0.0428 5.6493-0.0642 8.5274 23.603-0.72757 48.682-4.0444 72.874-11.234-18.521-32.152 0.81315-89.083-10.036-121.46-9.0731-26.973-38.85-40.315-64.282-40.305z\" style=\"fill:#c5c5c5;\"/><path d=\"m33.147 172.32c-2.6535 5.1143-6.088 9.9504-10.1 12.411 7.8427 10.453 17.387 19.516 28.257 26.781 16.038-10.731 35.629-17.055 54-18.606v-9.0089c-30.065-0.94155-56.108-5.8847-72.157-11.577zm164.06 0.55637c-23.731 7.0723-48.361 10.325-71.525 11.042-0.0321 3.1242-0.0535 6.2377-0.0107 9.0517 19.227 1.7226 37.908 7.8534 53.989 18.542 0.0107 0 0.0107 0 0.0214 0.0107 10.731-7.1686 20.179-16.081 27.958-26.374-4.2798-2.3967-7.832-6.9653-10.432-12.272z\" style=\"fill:#c5c5c5;\"/><path d=\"m50.02 46.5c-2.9297 1.9143-6.1313 3.8826-10.154 7.9805-14.091 14.359-16.145 27.701-6.1406 44.018 4.2049 6.8583 6.1414 13.706-0.24609 20.5-7.7143 8.1957-21.559 4.2912-21.537 16.061 0.0214 8.613 15.063 7.9178 22.531 13.984 3.7662 3.0707 5.0836 8.3992 2.0664 12.508-4.2156 5.7456-16.006 7.3715-22.629 8.9336 5.8811 10.843 13.45 20.638 22.355 29.033l0.0039 0.0234 0.0059-0.0137c2e-3 2e-3 0.0038 4e-3 0.0059 6e-3 0.0034-0.0112 0.0063-0.0219 0.0098-0.0332 14.775-12.218 20.268-20.965 49.461-28.434-17.404-10.258-30.68-27.122-24.143-35.34 4.4123-5.5444 5.6612-7.8633 6.4062-12.078 2.3582-13.339-10.208-22.335-9.2363-32.715 1.9432-8.2346 11.379-11.173 16.947-15.115 5.4577-3.9082 9.8014-8.7695 10.799-16.918-13.558-4.8896-17.609-5.8617-36.506-12.4zm140.87 19.357c-3.4404-0.91243-23.311 122.43 4.4121 133.14 8.9661-8.5809 16.552-18.584 22.404-29.658 0-0.31029-25.133-3.9922-25.979-14.018-0.10699-1.1769 0.11822-1.4855 0.86718-2.502 6.6764-9.2122 30.716-11.416 29.646-23.496-0.27818-3.1563-4.1617-5.2334-6.7402-6.4531-12.155-5.767-32.942-9.6494-15.031-24.543 9.2122-7.3505 10.43-8.4323 0.59766-14.691-9.4583-6.0238-9.394-11.993-9.7578-16.326-0.0767-0.93035-0.22089-1.4003-0.41992-1.4531z\" style=\"fill:#c5c5c5;\"/><path d=\"m133.83 39.909c-11.33 1.393-9.5492 16.204-2e-3 16.643-4.5102 10.717 9.0165 16.181 14.441 8.3125 6.562 8.6765 18.596 0.94751 14.457-8.3125 11.718-1.5381 9.2769-16.099 0-16.643 4.503-10.867-9.4883-16.101-14.457-8.3301-6.8832-9.0411-18.509-0.47321-14.439 8.3301z\" style=\"fill:#333;\"/><path d=\"m153.86 48.222c0-3.0528-2.5184-5.5648-5.5791-5.5648-3.0783 0-5.5793 2.512-5.5793 5.5648 0 3.0703 2.501 5.5648 5.5793 5.5648 3.0606 0 5.5791-2.4946 5.5791-5.5648z\" style=\"fill:#f9f9f9;\"/>",
|
||||
}
|
||||
|
||||
// Guy
|
||||
sp[3] = map[string]string{
|
||||
"clo": "<path d=\"m141.75 195c13.563 3.1499 26.439 8.7409 38 16.5-38.873 26.001-89.587 26.001-128.46 0 11.561-7.7591 24.437-13.35 38-16.5 8.4869 8.8011 26.21 25.619 26.21 25.619s17.603-16.972 26.25-25.619z\" style=\"fill:#d6d6d6;\"/><path d=\"m109 230.81 1.6836-14.33h9.6328l1.6836 14.33c-2.16 0.12-4.33 0.19-6.51 0.19s-4.35-0.07-6.51-0.19z\" style=\"fill:#5e5e5e;\"/><path d=\"m124.17 210.6h-17.349v5.53a3.8828 3.29 0 0 0 3.8828 3.29h9.583a3.8828 3.29 0 0 0 3.8828-3.29z\" style=\"fill:#535353;\"/><path d=\"m140.57 190.36-25.066 20.245c5.9686 3.2455 11.597 7.0814 16.8 11.45 1.5989 1.3338 3.9762 1.1189 5.31-0.48 0.21005-0.25749 0.38802-0.53956 0.52999-0.84l10.826-23.805-4-6c-0.90256-1.351-2.7298-1.7137-4.08-0.81-0.11612 0.0786-0.22641 0.16549-0.33 0.26z\" style=\"fill:#c6c6c6;\"/><path d=\"m90.434 190.36 25.066 20.245c-5.9686 3.2455-11.597 7.0814-16.8 11.45-1.5989 1.3338-3.9762 1.1189-5.31-0.48-0.21005-0.25749-0.38802-0.53956-0.52999-0.84l-10.826-23.805 4-6c0.90256-1.351 2.7298-1.7137 4.08-0.81 0.11612 0.0786 0.22641 0.16549 0.33 0.26z\" style=\"fill:#c6c6c6;\"/>",
|
||||
"mouth": "<path d=\"m136.21 147.09a21.77 21.77 0 0 1-40.13 0z\" style=\"fill:#fff;stroke-linecap:round;stroke-linejoin:round;stroke-width:3.4999px;stroke:#000;\"/>",
|
||||
"eyes": "<path d=\"m145.39 104.7-11.52 11.2h17.26m-65.52-11.2 11.52 11.2h-17.26\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:5.4998px;stroke:#000;\"/>",
|
||||
"top": "<path d=\"m43.891 77.836c-5.1124 28.237 2.1347 61.004 24.792 81.332-6.2362-12.503-9.5362-33.948-9.4887-45.458-0.50203-37.473 41.439-46.335 56.149-17.614 18.8-31.2 52.825-16.872 54.062 13.714 0.56018 13.844-0.43568 25.598-7.0962 48.966 18.372-12.47 28.012-53.959 23.545-80.941-47.486-2.2552-94.831-2.5724-141.96 0z\" style=\"fill:#1a1a1a;\"/><path d=\"m111.26 12.782c-18.508 0.0791-32.594 3.6163-32.594 3.6163 24.513 5.6002 32.807 10.504 31.743 19.835-0.87227 9.702-11.092 10.875-20.811 11.554-5.2548 0.36414-10.949 0.71523-16.391 1.7525-11.862 2.2818-19.946 4.3736-24.447 11.956-1.7012 2.8662-3.7945 10.428-4.8689 16.34h141.96c-5.7242-38.563-32.557-65.073-74.595-65.054z\" style=\"fill:#1a1a1a;\"/><path d=\"m73.292 44.77c-11.788 2.2816-18.923 5.5444-23.394 13.126-2.8484 6.7586-4.8454 13.238-6.0072 19.939h141.96c-1.9772-14.576-6.8677-28.248-19.277-32.098-28.834-6.3308-63.774-6.3553-93.285-0.96761z\" style=\"fill:#1a1a1a;\"/><path d=\"m165.95 35.642c-11.178 21.829-91.89 19.36-103.98 2.3011-9.703 12.267-15.605 25.883-18.079 39.892h141.96c-3.0096-17.158-9.7424-32.688-19.902-42.193z\" style=\"fill:#1a1a1a;\"/>",
|
||||
}
|
||||
|
||||
// Country
|
||||
sp[4] = map[string]string{
|
||||
"clo": "<path d=\"m141.75 195a114.79 114.79 0 0 1 38 16.5 115.53 115.53 0 0 1-128.46 0 114.79 114.79 0 0 1 38-16.5l15.71 15.75h21z\" style=\"fill:#949494;\"/><path d=\"m115.45 211.34-10.55 10.54a2.51 2.51 0 0 1-3.5599 0 2 2 0 0 1-0.26999-0.30994l-18.48-25.4 5.8901-5.8899a2.52 2.52 0 0 1 3.5199-0.0791l23.49 21.14z\" style=\"fill:#c0c0c0;\"/><path d=\"m115.45 211.34 10.55 10.54a2.51 2.51 0 0 0 3.5599 0 2 2 0 0 0 0.26999-0.30994l18.48-25.4-5.8901-5.8899a2.52 2.52 0 0 0-3.4699-0.089l-23.49 21.14z\" style=\"fill:#c0c0c0;\"/><path d=\"m158.41 199.58-10.11-3.2401v29.93q5.1601-1.5299 10.11-3.51zm-75.82 26.66v-29.9l-10.1 3.2401v23.14c3.2901 1.3199 6.67 2.4999 10.1 3.5199z\" style=\"fill:#7c7c7c;\"/>",
|
||||
"mouth": "<path d=\"m118.05 148.38c-1.5064 0.59192-2.595 2.0264-2.6191 3.9863-0.0574 1.3977 0.53421 3.5611 3.6758 5.7949 8.0544 4.9446 21.507 3.6862 21.255-7.1658-4.664 4.8219-10.021 5.6377-14.773 0.73907-1.2328-1.1599-2.3694-2.4032-3.9294-3.1408-1.0946-0.50424-2.2257-0.61071-3.6096-0.21337z\" style=\"fill:#333;\"/><path d=\"m133.61 154.93c3.0731-0.48816 5.5702-2.8457 5.4438-4.5059-0.47801-4.8311-5.7317-3.0917-4.3369-0.31405-2.8103-1.4445-1.8343-3.8862 0.50427-4.7324 2.0509-0.79942 5.0937 0.34314 6.2002 2.6376 2.2229 7.3422-3.4376 11.68-10.384 12.561z\" style=\"fill:#333;\"/><path d=\"m112.81 148.38c1.5064 0.59192 2.595 2.0264 2.6191 3.9863 0.0574 1.3977-0.53421 3.5611-3.6758 5.7949-8.0544 4.9446-21.507 3.6862-21.255-7.1658 4.664 4.8219 10.021 5.6377 14.773 0.73907 1.2328-1.1599 2.3694-2.4032 3.9294-3.1408 1.0946-0.50424 2.2257-0.61071 3.6096-0.21337z\" style=\"fill:#333;\"/><path d=\"m97.252 154.93c-3.0731-0.48816-5.5702-2.8457-5.4438-4.5059 0.47801-4.8311 5.7317-3.0917 4.3369-0.31405 2.8103-1.4445 1.8343-3.8862-0.50427-4.7324-2.0509-0.79942-5.0937 0.34314-6.2002 2.6376-2.2229 7.3422 3.4376 11.68 10.384 12.561z\" style=\"fill:#333;\"/>",
|
||||
"eyes": "<path d=\"m131.64 114.09 7.5801-7.5801 7.5801 7.5801m-62.6 0 7.5801-7.5801 7.5799 7.5801\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:6.4998px;stroke:#000;\"/>",
|
||||
"top": "<path d=\"m137.38 11.148c-12.23 1.9593-18.511 14.606-43.436 9.4915-11.285-3.2054-16.406-3.573-20.389 0.58594-4.1548 4.3384-7.033 12.435-9.8184 21.706-2.1354 7.4136-3.7187 14.381-4.7461 21.646h112.7c-3.4878-24.293-10.822-43.281-25.182-51.061-3.5314-1.623-6.5274-2.2959-9.1289-2.3613z\" style=\"fill:#b3b3b3;\"/><path d=\"m114.37 43.383c-19.445 0.088-38.524 2.0724-52.379 5.6992-1.2766 4.5795-2.4317 10.169-3.2285 16.807h113.11c-0.83731-6.0107-1.9164-11.674-3.3184-16.924-15.229-3.8842-34.873-5.6693-54.18-5.582z\" style=\"fill:#e6e6e6;\"/><path d=\"m115.5 55.773c-58.39 0-105.73 15.476-105.73 34.57h0.0312c0 11.295 16.496 21.319 42.126 27.627-0.10331-7.7704 2.788-21.904 5.2734-31.031 6.0935-1.7168 6.9294-1.8971 13.167-2.9919 14.874-2.8256 29.99-4.2037 45.133-4.1153 15.143-0.0884 30.259 1.2897 45.133 4.1153 6.2372 1.0947 7.2065 1.2751 13.3 2.9919 2.4854 9.1267 5.3768 23.26 5.2734 31.031 25.63-6.3082 41.993-16.332 41.993-27.627h0.0312c0-19.093-47.34-34.57-105.73-34.57z\" style=\"fill:#818181;\"/><path d=\"m72.088 83.533c-6.9765 1.1147-13.357 2.856-18.439 4.3477-1.1861 7.415-2.0038 18.858-1.8926 26.293 4.3278-0.62795 10.155-1.3644 13.295-1.6465-0.40554 0.30198 2.7344-17.827 7.0371-28.994zm86.824 0c4.3028 11.167 7.4426 29.296 7.0371 28.994 3.1396 0.28213 8.9671 1.0185 13.295 1.6465 0.11119-7.4351-0.70652-18.878-1.8926-26.293-5.0822-1.4916-11.463-3.2329-18.439-4.3477z\" style=\"fill:#434343;\"/>",
|
||||
}
|
||||
|
||||
// Geeknot
|
||||
sp[5] = map[string]string{
|
||||
"clo": "<path d=\"m141.75 194.98a114.79 114.78 0 0 1 38 16.498 115.53 115.52 0 0 1-128.46 0 114.79 114.78 0 0 1 38-16.498l15.71 15.748h21z\" style=\"fill:#d2d2d2;\"/><path d=\"m70 200.88v20.77c-2.22-0.95325-4.3999-1.9698-6.5399-3.0496h-0.10088v-14.621c2.17-1.1 4.39-2.1399 6.64-3.0996z\" style=\"fill:#505050;\"/><path d=\"m161 200.88v20.77c1.9-0.80986 3.7702-1.6798 5.6201-2.5898l0.0989-0.0494 0.82005-0.40997h0.10088v-14.621c-2.17-1.1-4.39-2.1399-6.6402-3.0996z\" style=\"fill:#505050;\"/><polygon transform=\"matrix(1 0 0 .99987 4e-5 -3e-5)\" points=\"97.32 201.93 115.5 223.72 133.68 201.93\" style=\"fill:#171717;\"/><path d=\"m111.2 230.88 1.31-16.908c0.32992 1.2798 5.6399 1.2798 5.9999 0l1.3201 16.938c-1.4301 0.0494-2.8601 0.089-4.3 0.089s-2.87 0-4.3-0.089z\" style=\"fill:#171717;\"/><path d=\"m115.49 201.79v0.0692l-7.55 12.678-7.0001 11.809-19.19-26.487c0.60999-0.42995 1.22-0.89985 1.8001-1.3899a52 51.993 0 0 0 10.07-10.619l21.79 13.878z\" style=\"fill:#ebebeb;\"/><path d=\"m149.24 199.86-19.08 26.517-7.0001-11.809-7.57-12.678-0.0593-0.10086 21.94-13.998a52.21 52.203 0 0 0 10.08 10.699c0.58013 0.47009 1.1502 0.92002 1.7301 1.3399z\" style=\"fill:#ebebeb;\"/>",
|
||||
"mouth": "<path d=\"m122.83 151.88a10.49 10.489 0 0 1-14.66 0\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:6.1996px;stroke:#333;\"/>",
|
||||
"eyes": "<path d=\"m70.959 94.985h35.031c2.4086 1e-5 4.3612 1.9523 4.3612 4.3606l-2.5864 17.511c-0.3515 2.3799-1.7218 4.3606-3.8457 4.3606h-30.9c-2.1239-1e-5 -3.8457-1.9523-3.8457-4.3606l-2.5864-17.511c1e-5 -2.4082 1.9526-4.3606 4.3612-4.3606z\" style=\"fill:#1a1a1a;stroke-linecap:round;stroke-linejoin:round;stroke-width:3.0045px;stroke:#333;\"/><path d=\"m160.05 94.985h-35.031c-2.4086 1e-5 -4.3612 1.9523-4.3612 4.3606l2.5864 17.511c0.35149 2.3799 1.7218 4.3606 3.8457 4.3606h30.9c2.1239-1e-5 3.8457-1.9523 3.8457-4.3606l2.5864-17.511c-1e-5 -2.4082-1.9526-4.3606-4.3612-4.3606z\" style=\"fill:#1a1a1a;stroke-linecap:round;stroke-linejoin:round;stroke-width:3.0045px;stroke:#333;\"/><path d=\"m90.607 102.35a4.6337 4.6332 0 1 0 4.6892 4.6337 4.6337 4.6332 0 0 0-4.6892-4.6337zm49.72 0a4.6337 4.6332 0 1 0 4.6444 4.6337 4.6337 4.6332 0 0 0-4.6444-4.6337z\" style=\"fill:#1a1a1a;\"/><path d=\"m70.66 94.985h-11.775\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:3.0045px;stroke:#333;\"/><path d=\"m172.13 94.985h-19.484\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:3.0045px;stroke:#333;\"/><path d=\"m109.32 106.2c4.2045-2.427 9.3036-1.913 12.353-0.0258\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:3.0045px;stroke:#333;\"/><path d=\"m148.33 109.79-5.7626-8.2324\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:4;stroke:#fff;\"/><path d=\"m156.27 105-2.403-3.4328\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:4;stroke:#fff;\"/><path d=\"m82.748 114.34-8.9489-12.784\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:4;stroke:#fff;\"/><path d=\"m91.408 109.79-5.7626-8.2324\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:4;stroke:#fff;\"/>",
|
||||
"top": "<path d=\"m41.835 75.131c-2.8674 12.582 1.2304 27.241 6.0238 39.031 0.25861 0.63658 0.51208 1.3075 0.79989 1.9683 0.71726 1.658 2.1184 3.9751 3.0038 3.9266 0.56895-0.0312 0.71637-1.5512 1.0228-3.1562 2.1988-19.097 8.8981-27.915 15.636-38.107 2.8783-4.0645 3.8616-7.2293 1.0644-9.9325-6.3236-3.5596-14.924-2.8574-21.367-0.67406-3.2312 1.4765-5.2427 3.4773-6.1842 6.9439zm125.65-8.5679c7.65-0.70616 19.714-0.1307 21.694 8.5679 1.455 6.4083 0.26915 17.747-1.0542 24.579-1.1961 5.3203-3.8066 14.231-7.8782 19.75-0.5565 0.44544-0.96888 0.13656-1.4159-1.1606-0.90692-3.0353-1.4298-7.8372-2.2556-10.727-3.4822-12.79-8.2195-21.875-14.429-29.94-5.5782-6.8415-4.2152-9.7207 5.3393-11.069z\" style=\"fill:#4d4d4d;\"/><path d=\"m112.27 73.826c-18.585-7.5217-34.987-14.797-48.939 5.018-4.9752 7.083-3.7876 8.8056-4.9217 0.0749-1.637-12.476-4.7505-34.174 1.9259-45.194 7.6822-12.7 19.323-13.128 31.039-5.3818 10.796 7.7784 24.277 14.647 38.015 12.219 12.732-2.2576 15.835-7.7464 15.707-19.912-0.0215-2.6-0.0963-5.2106-0.2033-7.7999 13.631 3.9267 24.609 14.776 26.513 29.049 0.88804 6.6336 0.26749 12.722-1.9259 19.013-5.9702 17.108-30.119 20.896-45.74 16.841-3.9588-1.0378-7.6822-2.4181-11.47-3.9267z\" style=\"fill:#4d4d4d;\"/>",
|
||||
}
|
||||
|
||||
// Asian
|
||||
sp[6] = map[string]string{
|
||||
"clo": "<path d=\"m115.5 231a115 115 0 0 0 64.23-19.5 114.79 114.79 0 0 0-38-16.5l-2.41-9a125.19 125.19 0 0 0-13.32-2.28v8.75q3.52 0.32 7 0.84l-17.5 17.48-17.5-17.48q3.45-0.52 7-0.84v-8.75a125.55 125.55 0 0 0-13.34 2.28l-2.41 9a114.79 114.79 0 0 0-38 16.5 114.94 114.94 0 0 0 64.25 19.5z\" style=\"fill:#646464;\"/><path d=\"m132.98 193.33-36.185 36.155-2.4-0.42 36.108-36.081z\" style=\"fill:#e3e3e3;\"/>",
|
||||
"mouth": "<path d=\"m127.84 146.73c-2.24 8.93-6.92 15.08-12.34 15.08s-10.1-6.15-12.34-15.08z\" style=\"fill:#fff;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.9999px;stroke:#1a1a1a;\"/>",
|
||||
"eyes": "<path d=\"m129.31 114.14 20-5.37m-47.66 5.37-20-5.37\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:4.9998px;stroke:#1a1a1a;\"/>",
|
||||
"top": "<path d=\"m169.65 90.998c3.137 11.94 4.9371 36.484-3.4118 58.213l5.129 3.1164c10.044-15.199 14.959-39.163 13.943-61.33z\" style=\"fill:#1a1a1a;\"/><path d=\"m45.081 90.989c-0.88085 4.9304-0.87534 14.953-0.15027 21.75 2.1318 19.98 16.671 42.505 16.671 42.505l5.7352-4.4331s-13.244-31.348-6.0571-52.751c0.52108-1.5517 0.95592-2.916 1.3462-4.1835z\" style=\"fill:#1a1a1a;\"/><path d=\"m117 3.4883c-8.2136-0.19887-19.13 7.933-18.494 9.3516 1.6214 3.6186 11.176 22.55 11.889 23.963h10.148c2.6022-6.3102 11.32-26.531 11.32-26.531s-4.1382-4.138-12.416-6.4375c-0.77605-0.21556-1.5976-0.32513-2.4473-0.3457z\" style=\"fill:#1a1a1a;\"/><path d=\"m115.95 4.5428c-3.1563 0-6.3123 0.57462-9.2165 1.715-5.8084 2.2817-10.532 6.808-12.779 12.245v-5e-3c-1.8166 4.397-2.0233 9.3441-0.58058 13.857 0.69352 2.1687 1.7693 4.2296 3.1533 6.0968h38.893c0.71032-0.95769 1.3441-1.9641 1.8787-3.0144 2.6811-5.2673 2.9296-11.542 0.67253-16.975-2.257-5.4337-6.9893-9.9522-12.802-12.224-2.9064-1.1335-6.0633-1.6987-9.2196-1.6956z\" style=\"fill:#1a1a1a;\"/><path d=\"m92.512 28.125c0.13387 1.4318 0.41877 2.8511 0.85962 4.2306 1.4429 4.5127 4.5278 8.5654 8.6411 11.353 4.1135 2.7873 9.2311 4.2913 14.336 4.2165 5.1052-0.0764 10.168-1.7333 14.181-4.6419 2.8754-2.0834 5.2132-4.7932 6.7665-7.8447 1.2005-2.3586 1.9085-4.9188 2.127-7.5156-15.037-2.6407-31.421-3.4671-46.912 0.20253z\" style=\"fill:#b3b3b3;\"/><path d=\"m34.426 90.63c14.714 4.0779 22.683 6.4085 45.254 7.4257 2.5318-18.185 4.6689-28.672 10.023-38.352 3.2025 13.403 3.8346 25.22 2.9106 42.253l11.172-0.23161c1.4706-11.886 3.8989-29.213 2.1636-42.021 10.416 12.631 11.373 23.624 13.077 39.726 30.174-0.76004 59.808-4.5121 77.845-10.128-10.76-38.608-41.475-55.66-80.38-56.104-38.182-0.45134-74.543 22.405-82.065 57.432z\" style=\"fill:#1a1a1a;\"/>",
|
||||
}
|
||||
|
||||
// Punk
|
||||
sp[7] = map[string]string{
|
||||
"clo": "<path d=\"m88.18 194.11c-4.2079 1.021-8.3545 2.2792-12.42 3.7695v26.072a115.5 115.5 0 0 0 79.48 0v-26.072c-4.0858-1.4904-8.2529-2.7486-12.48-3.7695v8.7051c0 9.3888-7.6112 17-17 17h-20.58c-9.3888 0-17-7.6112-17-17v-8.7051z\" style=\"fill:#efefef;\"/>",
|
||||
"mouth": "<polygon points=\"121.61 160.74 109.39 160.74 115.5 171.31\" style=\"fill:#797979;\"/><path d=\"m132.64 144.06a34.42 34.42 0 0 1-34.24 0\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:5.9998px;stroke:#000;\"/>",
|
||||
"eyes": "<path d=\"m170.25 100c1.69 9.62-4.79 29.23-22.4 29.23-6.81 0-15-3.66-20.23-10-4.34-5.33-7.56-12.87-6.2-19.45 1.63-7.89 7.07-11.45 14.67-12.92a68.16 68.16 0 0 1 12.52-1c10.77 0 19.78 3.61 21.64 14.22z\" style=\"fill:#565656;stroke-width:3.99px;stroke:#000;\"/><path d=\"m60.75 100c-1.69 9.62 4.79 29.23 22.4 29.23 6.81 0 15-3.66 20.23-10 4.34-5.33 7.56-12.87 6.2-19.45-1.63-7.89-7.07-11.45-14.67-12.92a68.16 68.16 0 0 0-12.52-1c-10.77 0-19.78 3.61-21.64 14.22z\" style=\"fill:#565656;stroke-width:3.99px;stroke:#000;\"/><line x1=\"100.2\" x2=\"130.8\" y1=\"87.92\" y2=\"87.92\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:3.99px;stroke:#000;\"/><path d=\"m109.87 101.73c0-2.59 2.52-4.69 5.63-4.69s5.63 2.1 5.63 4.69\" style=\"fill:none;stroke-width:3.99px;stroke:#000;\"/>",
|
||||
"top": "<path d=\"m30.622 70.381c2.0971-3.9374 4.6649-7.9604 7.6822-12.037 3.0172-4.0765 6.0987-7.6929 9.2229-10.817l22.897 22.897c-4.4402 4.4403-8.2278 9.5439-11.213 15.14z\" style=\"fill:#999;\"/><path d=\"m160.58 70.423 22.907-22.897c3.1242 3.1242 6.2056 6.7406 9.2229 10.817 3.0065 4.0765 5.5744 8.0994 7.6715 12.037l-28.578 15.182c-2.9851-5.5958-6.7727-10.689-11.224-15.14z\" style=\"fill:#999;\"/><path d=\"m92.411 15.247c3.8197-0.87736 7.6715-1.5407 11.534-1.9794 4.0765-0.46007 7.9282-0.69546 11.555-0.69546 1.53 0 3.1563 0.0428 4.8682 0.1391l1.851 22.255 5.767-21.57c3.1028 0.37449 6.0666 0.86666 8.8912 1.4658l-10.55 49.763c-1.9259-0.41729-3.702-0.70617-5.3176-0.87736-1.423-0.14979-3.2633-0.22468-5.5102-0.22468-2.2362 0-4.237 0.10699-5.981 0.29958-1.9473 0.22469-3.8732 0.55636-5.767 0.99504z\" style=\"fill:#999;\"/><path d=\"m92.411 15.247c1.9152-0.43869 4.023-0.84526 6.3233-1.2304 2.065-0.34238 4.1514-0.62057 6.2698-0.84525l5.1785 50.565c-1.0913 0.10699-2.1827 0.25679-3.2954 0.43868-0.86665 0.14979-1.9152 0.36378-3.1349 0.64196z\" style=\"fill:#4d4d4d;\"/>",
|
||||
}
|
||||
|
||||
// Afrohair
|
||||
sp[8] = map[string]string{
|
||||
"clo": "<path d=\"m141.89 195a114.79 114.79 0 0 1 38 16.5 115.55 115.55 0 0 1-128.47 0 114.79 114.79 0 0 1 38-16.5l15.75 15.75h21z\" style=\"fill:#353535;\"/><path d=\"m146.4 196.14-17.4 17.44-1.17 1.17h-24.34l-1.18-1.17-17.43-17.44c1.49-0.41 3-0.79 4.51-1.14l4.67-1 12.74 12.74h17.69l12.73-12.74 4.67 1c1.52 0.35 3 0.73 4.51 1.14z\" style=\"fill:#919191;\"/>",
|
||||
"mouth": "<path d=\"m115.68 160.64c7.08 0 13.11-4.93 15.46-11.84a2.14 2.14 0 0 0-1.51-2.6101 2.3 2.3 0 0 0-0.73995-0.0593h-26.42a2.12 2.12 0 0 0-2.31 1.9099 1.85 1.85 0 0 0 0.0593 0.73995c2.3401 6.9301 8.3802 11.86 15.46 11.86z\" style=\"fill:#2f2f2f;\"/>",
|
||||
"eyes": "<path d=\"m145.38 95.628c-5.1601 2.2597-11.03 2.2597-16.19 0m-47.29 1.75c5.1755-2.2694 11.065-2.2694 16.24 0\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:5.9998px;stroke:#5e5e5e;\"/><path d=\"m90.016 106.28c-4.4506-0.0105-6.6902 5.3657-3.5508 8.5195 3.1394 3.1539 8.5252 0.93887 8.5352-3.5117 0.0063-2.7522-2.2204-4.9898-4.9727-4.9961l-0.011719-0.01172zm47.281 0c-4.4506-0.0105-6.6902 5.3657-3.5508 8.5195 3.1394 3.1539 8.5252 0.93887 8.5352-3.5117 6e-3 -2.7522-2.2204-4.9898-4.9727-4.9961l-0.01171-0.01172z\" style=\"fill:#1a1a1a;\"/>",
|
||||
"top": "<path d=\"m108.37 22.019c-6.2698-12.829-17.151-13.396-18.949 1.1769-11.448-9.4583-26.021-4.483-20.361 12.422-12.251-7.9282-24.919 1.7761-17.076 20.853-27.08 2.3646-22.715 24.726-10.111 31.435-9.9002 3.3566-10.701 9.4006-8.464 14.497 2.6574 4.7842 9.0126 6.4737 11.545 9.6519-6.624 0.59419-8.4112 5.6011-5.7404 9.5192 1.6896 2.4787 5.2756 4.2218 8.5971 5.5455 1.0485 0.40658 3.702 1.2732 3.9053 2.4181 0.18744 1.2156-6.7884 3.0055-5.7281 5.2612 0.60648 1.4227 1.7764 2.7151 2.6466 3.7156 1.2807 1.6595 10.755 8.0351 9.4583 4.2049-1.0271-3.7234-2.2148-7.4682-3.1456-11.192-1.1662-5.3069-1.7868-10.721-1.102-16.156 1.4223-5.455 5.069-4.4265 7.7837-8.3588 3.5264-5.7505 2.0296-11.614 2.124-13.575 0.107-1.7868 1.5407-1.1876 3.1884-1.4337 4.3868-0.64196 7.0081-2.1185 8.8377-6.2698 0.77035-1.9259 0.62057-9.7578 0.52426-11.78 0.36378-4.6328 4.1835 0 6.548 0.64196 3.2633 0.88805 6.8797 0.21399 9.0731-2.5037 1.7547-2.3753 2.0864-2.8888 4.6114-0.80245 2.6856 2.2148 4.0979 3.1349 7.6929 3.274 5.5637 0.20329 8.7735-6.2698 11.32-5.6386 3.5201 0.87735 3.6057 5.4567 10.261 4.8682 2.386-0.20329 3.8304-0.86665 5.4032-2.6428 0.88805-0.99505 1.958-2.5037 3.4345-2.6214 1.4658-0.1177 2.3218 2.3646 3.0065 3.4452 1.1926 2.6755 4.0295 3.6513 6.2377 3.3168 1.958-0.17119 3.854-1.4115 5.4268-2.4707 0.99679-0.66102 1.8284-0.81128 1.9256 0.2071 0.29592 2.2271 0.0862 7.7025 0.1596 8.4821 0.10556 8.4609 5.37 10.569 13.223 10.333-0.31871 3.7464 0.0583 11.28 5.4353 14.562 3.9481 2.7604 6.6657 1.2732 6.7299 7.8534 7e-3 6.1914-0.43693 13.061-1.2946 18.189-0.69547 4.0444-1.2412 6.4838-2.5251 10.378-0.64196 1.9152-0.81315 1.9687 1.4123 1.0699 7.1472-3.1456 10.539-11.48 8.3562-18.842-0.43869-2.0436 0.84525-1.7226 2.8781-2.6106 9.5248-4.2363 8.1264-11.335-0.75967-14.273 11.988-3.0926 13.886-8.9002 6.6871-15.375 7.3077-5.9168 3.6378-16.177-2.8032-16.991 12.422-7.0937 5.7349-22.062-5.1036-18.499 4.1728-12.037-5.5637-26.203-21.121-16.894 6.9653-11.373 2.065-22.661-12.101-10.785-3.4559-18.382-15.14-16.584-23.902-5.018 0.09435-20.075-16.001-17.42-18.146-2.5892z\" style=\"fill:#1a1a1a;\"/><path d=\"m5.4353 80.502c7.4468 9.1373 15.632 8.8912 15.632 8.8912s-6.0772 3.7983-6.8369 9.8755c-0.75966 6.088 4.5579 9.6295 8.0994 10.646 3.5522 1.0058 7.0937-2.7925 7.0937-2.7925s-5.8312 10.646-1.5193 15.964c4.3012 5.3176 11.908 3.0386 11.908 3.0386s-5.3283 10.132 1.0057 14.187c5.8312 3.7234 18.542 7.6715 20.511 8.2706-6.0666-9.7472-9.576-21.249-9.576-33.575v-0.0428c0-35.201 28.546-63.747 63.747-63.747 35.212 0 63.758 28.546 63.758 63.747 0 12.476-3.5843 24.116-9.7899 33.949h0.53496s13.931-1.0057 16.21-9.3727c2.279-8.3562 0.75967-9.8756 0.75967-9.8756s10.635 2.0329 13.417-7.5966l2.7926-9.6295s10.132 0 10.892-7.083c0.75963-7.0937-7.0295-12.411-7.0295-12.411s11.459 0.82385 14.498-10.453c1.0164-3.7555 0.83456-8.2171 0.1391-12.497-17.665-41.161-58.569-69.995-106.18-69.995-30.632 0-60.034 12.187-81.679 33.831v0.0107c-13.171 13.171-22.833 29.22-28.386 46.66z\" style=\"fill:#1a1a1a;\"/>",
|
||||
}
|
||||
|
||||
// Normie Female
|
||||
sp[9] = map[string]string{
|
||||
"clo": "<path d=\"m141.75 195a114.79 114.79 0 0 1 38 16.5 115.53 115.53 0 0 1-128.46 0 114.79 114.79 0 0 1 38-16.5l13.85 13.85v-1.2h17.86v3.1h5z\" style=\"fill:#333;\"/><polygon points=\"115.36 207.65 123.37 224.2 148.3 196.86 143.08 189.95\" style=\"fill:#fff;\"/><polygon points=\"115.36 207.65 107.35 224.2 82.42 196.86 87.63 189.95\" style=\"fill:#fff;\"/>",
|
||||
"mouth": "<path d=\"m126.28 149.82c-6.16 2.43-15.52 2.42-21.56 0\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:5.9998px;stroke:#1c1c1c;\"/>",
|
||||
"eyes": "<path d=\"m83.527 103.98v10h10v-10h-10zm53.945 0v10h10v-10h-10z\" style=\"fill:#1a1a1a;\"/><path d=\"m56.621 94.906v11.688h5.3418v6.4922h5.3418v6.1055h5.3223v6.2324h26.846v-6.2324h5.3047v-6.1055h5.1445v-6.0039h11.154v6.0039h5.1446v6.1055h5.3066v6.2324h26.846v-6.2324h5.3203v-6.1055h5.3438v-6.4922h5.3418v-11.688z\" style=\"fill:#1a1a1a;\"/><path d=\"m67.387 100.65v5.9394h5.1992v-5.9394zm5.1992 5.9394v6.4922h5.4238v-6.4922zm5.4238 0h5.1992v-5.9394h-5.1992zm5.1992 0v6.4922h5.4258v-6.4922zm5.4258 6.4922v6.1055h5.1426v-6.1055zm-10.625 0v6.1055h5.1445v-6.1055zm48.281-12.432v5.9394h5.1992v-5.9394zm5.1992 5.9394v6.4922h5.4238v-6.4922zm5.4238 0h5.1992v-5.9394h-5.1992zm5.1992 0v6.4922h5.4258v-6.4922zm5.4258 6.4922v6.1055h5.1426v-6.1055zm-10.625 0v6.1055h5.1445v-6.1055z\" style=\"fill:#fff;\"/>",
|
||||
"top": "<path d=\"m157.79 67.5a61.31 61.31 0 0 1-42.79 17.43h-55.7c18.16-37.74 68.27-46.85 98.49-17.43z\" style=\"fill:#4d4d4d;\"/><path d=\"m122.93 7.0078c-10.503-0.15729-21.09 1.6448-29.545 5.4316-17.141 7.8999-32.169 23.297-43.973 38.779-5.1703 6.8631-8.7779 13.46-8.1855 18.395 0.93114 12.312 10.372 26.483 11.068 36.9 15.663-72.081 105.99-70.452 124.91-7.0525l4e-3 0.0156c5.616-10.926 8.0682-20.188 8.352-27.653 0.43654-15.607-7.8088-21.149-21.735-28.249 1.7934-3.7704 1.7273-7.5023 2.0625-10.154-0.79964-7.8568-3.6796-13.51-10.43-17.758-5.9434-3.7404-13.06-6.0867-18.463-7.2266-4.5319-0.87895-9.2901-1.3562-14.064-1.4277z\" style=\"fill:#4d4d4d;\"/><path d=\"m42.426 75.338c0.52158 18.689 10.557 74.338-18.115 101.25 12.38 10.603 28.352 19.061 46.025 24.594 11.032-4.6874 22.88-7.4147 34.817-8.5046l0.0633-14.477c-22.49-4.3813-40.766-18.898-48.862-39.967-8.096-21.07-4.7931-44.72 9.2478-62.393zm124.67 2.7207c7.8997 10.886 11.743 24.64 11.787 37.441-0.36632 30.178-22.389 57.576-53.12 62.708l0.0238 14.471c12.282 1.1216 24.518 3.9888 35.825 8.9128 15.488-5.1448 30.007-13.325 42.396-25.043-13.136-22.051-23.282-63.045-18.694-101.55z\" style=\"fill:#4d4d4d;\"/><path d=\"m143.61 46.383c-11.639 0.12482-20.998 1.8906-20.998 1.8906l-9 3.5059c0.63003-0.0191 1.2603-0.0289 1.8906-0.0293h0.0996c35.169 0.055 60.959 27.235 63.283 63.383 7.4e-4 31.157-22.742 57.213-53.106 63.079l-0.0216 14.498c11.567 1.0563 23.154 3.6067 33.887 8.0463 35.952-15.315 55.082-52.303 36.709-68.279-5.018-7.9035-10.44-15.409-9.5544-23.03 5.0545-50.452 0.39626-63.561-43.189-63.064zm-69.966 21.09c-15.286 3.244-17.096 3.73-31.734 6.6953 3.0304 13.081 3.0583 22.274 1.2085 30.012-3.8004 11.361-8.9712 19.787-12.286 28.764-6.8823 22.459-2.9157 31.982 12.093 46.165 8.6595 8.0693 19.861 16.209 30.939 20.647 2.669-1.0316 5.3729-1.9628 8.106-2.792 7.4979-2.275 15.388-3.6535 23.206-4.3673l0.0433-14.393c-23.933-4.5937-44.283-21.98-50.77-45.817-6.3319-23.265 0.51104-48.752 19.195-64.914z\" style=\"fill:#4d4d4d;\"/>",
|
||||
}
|
||||
|
||||
// Older
|
||||
sp[10] = map[string]string{
|
||||
"clo": "<path d=\"m141.75 195a114.79 114.79 0 0 1 38 16.5 115.53 115.53 0 0 1-128.46 0 114.79 114.79 0 0 1 38-16.5l15.71 15.75h21z\" style=\"fill:#666;\"/><path d=\"m89.291 195a114.79 114.79 0 0 0-38.002 16.5 115.53 115.53 0 0 0 38.002 16.482zm52.434 0v32.982a115.53 115.53 0 0 0 38-16.482 114.79 114.79 0 0 0-38-16.5z\" style=\"fill:#999;\"/><path d=\"m157.15 199.75c0.2548 7.4501 1.54 14.855 4.9512 21.432a115.53 115.53 0 0 0 17.619-9.6797 114.79 114.79 0 0 0-22.57-11.752zm-83.295 2e-3a114.79 114.79 0 0 0-22.57 11.75 115.53 115.53 0 0 0 17.621 9.6797c3.411-6.5765 4.6944-13.98 4.9492-21.43z\" style=\"fill:#ccc;\"/><path d=\"m99.197 204.97v2e-3l16.302 16.301 16.301-16.301v-2e-3z\" style=\"fill:#fff;\"/>",
|
||||
"mouth": "<path d=\"m100.19 152.09c2.8726 4.0616 9.8095 4.7232 15.119-0.45432 5.0656 4.5134 11.167 5.6898 15.495 0.31458\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:5.8949;stroke:#333;\"/><path d=\"m109.67 135.53c-0.9758 0.0743-2.05 0.45327-3.1485 0.99414-4.3235 2.1399-7.3862 4.2557-10.639 7.1406-0.6251 0.5715 0.1168 0.77785 1.4238 0.87304 5.6967 0.0536 14.384 0.41404 15.098-0.875 1.9251-2.0788 1.7969-5.3303-0.1816-7.3008-0.701-0.67533-1.5769-0.90632-2.5527-0.83203zm11.656 0c-0.9758-0.0743-1.8517 0.1567-2.5527 0.83203-1.9785 1.9705-2.1067 5.222-0.1817 7.3008 0.7142 1.289 9.401 0.9286 15.098 0.875 1.307-0.0952 2.0489-0.30154 1.4238-0.87304-3.2524-2.8849-6.3151-5.0007-10.639-7.1406-1.0985-0.54087-2.1727-0.91985-3.1485-0.99414z\" style=\"fill:#333;\"/>",
|
||||
"eyes": "<path d=\"m97.56 107.84a10.63 10.63 0 0 1-15 0.13l-0.13-0.13\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:6.3px;stroke:#000;\"/><path d=\"m148.59 107.84a10.63 10.63 0 0 1-15 0.13l-0.13-0.13\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:6.3px;stroke:#000;\"/>",
|
||||
"top": "<path d=\"m41.668 87.073c-9.2319-0.0231-11.63 6.5104 2.2676 17.66-14.015 1.1231-4.3662 16.457 4.875 24.66 4.0686 3.0199 6.4647 5.4657 5.5078 1.1348-1.2079-4.9178-1.8184-9.9634-1.8184-15.027 3.26e-4 -7.5692 1.2547-15.016 3.7883-22.183 0.57048-1.7876 1.0689-2.0306-0.37721-2.6839-5.5405-2.4478-10.375-3.5511-14.243-3.5608z\" style=\"fill:#ccc;\"/><path d=\"m185.48 89.513c-2.4418-0.11189-5.4618 0.81187-9.5148 3.2121-1.314 0.81729-0.70075 1.995-0.32301 3.2653 3.194 10.982 3.8215 22.462 1.2538 33.628-0.31613 1.688-0.47649 3.569 2.6953 1.3516 7.7016-5.371 19.17-18.734 16.918-26.105-1.4251-3.9177-11.4-0.35546-11.4-0.35546s4.987-4.2755 5.3437-9.6191c0.20048-3.0057-1.5237-5.2189-4.9726-5.377z\" style=\"fill:#ccc;\"/><path d=\"m91.689 36.108c-3.7298-7.3864-9.5859-10.504-17.578-6.7891-9.5194 4.5907-15.629 18.444-13.416 29.232 0 0-8.5511-4.9878-18.17-3.5625-19.623 8.094-1.4102 29.869 10.817 37.342 2.075 1.297 2.5792 1.7432 3.4291-0.37685 2.6746-6.5374 6.1886-12.722 11.297-17.709 4.1039 8.7427 14.629 4.1809 20.006-0.14062 4.4873 9.6838 10.377 6.3535 15.377 3.4785 4.0764 7.8829 10.756 7.25 17.631 0.0625 4.875 4.5625 14.713 4.1867 15.555-3.426 8.4753 2.6244 14.012 10.437 22.962-1.4764 8.8552 6.8221 14.407 16.853 17.122 27.51 0.34 1.554 1.175 0.85565 2.2212 0.44315 10.255-4.286 22.842-15.749 15.705-23.975-3.5623-3.5623-13.539-2.1387-13.539-2.1387s6.77-7.1233 9.2637-18.168c2.4936-11.043-23.514-4.9883-23.514-4.9883s7.4818-5.6993 12.113-13.537c4.6314-7.8378-2.4943-11.756-11.045-11.043-8.5496 0.71204-17.1 7.4805-17.1 7.4805s3.3946-7.8055-3.5625-12.826c-9.5935-6.9234-23.869 6.4121-23.869 6.4121-4.2562-26.835-24.872-6.386-31.707 8.1953z\" style=\"fill:#ccc;\"/>",
|
||||
}
|
||||
|
||||
// Firehair
|
||||
sp[11] = map[string]string{
|
||||
"clo": "<path d=\"m116 203.13c-0.12 0-0.25 0.12-0.49 0.12s-0.25-0.12-0.49-0.12zm-27.29-8c0.87-0.25 1.72-0.47 2.56-0.69a32.37 32.37 0 0 0 0.3 8.57 21.5 21.5 0 0 0 7 6.88c6.41-6 16.8-6.64 16.8-6.64s10.5 0.58 17 6.69a21.61 21.61 0 0 0 6.93-6.66 32.34 32.34 0 0 0 0.35-8.84l2.13 0.56a114.79 114.79 0 0 1 38 16.5 115.53 115.53 0 0 1-128.46 0 114.64 114.64 0 0 1 37.38-16.37z\" style=\"fill:#e9e9e9;\"/><path d=\"m126.15 206-3.92 7.83h-13.46l-3.92-7.83a36.59 36.59 0 0 1 10.65-2.7 35.66 35.66 0 0 1 10.65 2.7z\" style=\"fill:#818181;\"/><path d=\"m124.54 230.65-2.18-16.74h-13.47l-2.19 16.76c2.9 0.22 5.84 0.33 8.8 0.33s6.06-0.12 9-0.35z\" style=\"fill:#989898;\"/><path d=\"m134.84 186s0.86 9.8-19.34 17.26c0 0 15.79 0.86 20.57 11.76 0.12 0.49 9.3-23.26-1.23-29z\" style=\"fill:#fff;\"/><path d=\"m96.16 186c-10.41 5.76-1.35 29.39-1.1 29 4.65-10.78 20.56-11.76 20.56-11.76-20.32-7.45-19.46-17.24-19.46-17.24z\" style=\"fill:#fff;\"/>",
|
||||
"mouth": "<path d=\"m118.57 165.14a8.66 8.66 0 0 0-2.76-4.23h-0.62a8 8 0 0 0-2.76 4.22c-0.52 1.89 2.07 10.61 2.76 12.53h0.62c0.64-1.76 3.19-10.82 2.76-12.52z\" style=\"fill:#333;\"/><path d=\"m102.81 152.24a2.4921 2.4921 0 1 1 1.19-4.84l0.21 0.06a37.1 37.1 0 0 0 5.43 1.12 44.52 44.52 0 0 0 11.76 0 37.1 37.1 0 0 0 5.43-1.12 2.4903 2.4903 0 0 1 1.59 4.72l-0.21 0.06a43.08 43.08 0 0 1-6.15 1.29 48.55 48.55 0 0 1-13.08 0 42.79 42.79 0 0 1-6.17-1.29z\" style=\"fill:#333;\"/>",
|
||||
"eyes": "<path d=\"m86.851 100.39a4.94 4.94 0 1 0 4.9297 5 5 5 0 0 0-4.9297-5zm57.221 0a4.94 4.94 0 1 0 4.9394 4.9394 4.94 4.94 0 0 0-4.9394-4.9394z\" style=\"fill:#333;\"/><path d=\"m86.207 89.365c-25.504 0-21.503 6.8561-21.035 19.596 0.80177 18.121 17.763 16.514 21.201 16.639 14.758-0.041 20.518-8.227 22.951-22.932 1.8166-10.731-9.251-13.174-23.117-13.303zm58.598 0c-13.866 0.1284-24.936 2.5717-23.119 13.303 2.4332 14.705 8.1936 22.891 22.951 22.932 3.4383-0.125 20.399 1.4828 21.201-16.639 0-18.965-0.47958-19.596-21.033-19.596z\" style=\"fill:#4d4d4d;\"/><path d=\"m169.87 90.255a0.51 0.51 0 0 0-0.43991-0.52 167.64 167.64 0 0 0-22.6-1.6801c-12 0-27.47 3.7601-30.17 3.7601h-2.4c-1.2499 0-5.29-0.80996-10.45-1.6801a124.35 124.35 0 0 0-19.72-2.08 166.18 166.18 0 0 0-19.31 1.24c-1.56 0.17999-2.69 0.35009-3.2899 0.44009a0.51 0.51 0 0 0-0.44007 0.52l-0.091 6.4501a0.57 0.57 0 0 0 0.33012 0.52l0.73994 0.23992c1.08 0.41992 1.0001 19.85 6.78 24.71 3.4401 2.8599 6.51 4.4899 19.42 4.4899 7.4699 0 12.17-1.9999 16.63-8 3.21-4.32 6.0999-14.55 6.0999-14.55 0.82006-4.07 3.7702-4.52 4.43-4.5801h0.12068c0.11078 0 3.66 0.0593 4.57 4.5801 0 0 2.8599 10.22 6.0699 14.54 4.4601 5.9999 9.1601 8 16.63 8 12.91 0 16-1.63 19.42-4.4901 5.7898-4.86 5.6998-24.29 6.78-24.71l0.73994-0.23993a0.57 0.57 0 0 0 0.32996-0.52l-0.12068-6.4501zm-65 23c-1.9101 4.5-6.8 10.29-13.7 10.64-20.7 0.99985-21.65-4.7401-23-9.3201a31.45 31.45 0 0 1-1.2099-13.18c0.53997-4.5799 1.7-7.2699 3.7801-8.6201a9.3 9.3 0 0 1 4.3499-1.51 85.07 85.07 0 0 1 11.4-0.52 59.23 59.23 0 0 1 9.2099 0.69999c7.37 1.2 12.35 3.7001 12.35 6.1601a46.12 46.12 0 0 1-3.23 15.64zm58 1.3201c-1.34 4.5799-2.29 10.36-23 9.3201-6.91-0.3501-11.81-6.1401-13.71-10.64a46.35 46.35 0 0 1-3.22-15.64c0-3.39 9.43-6.8599 21.56-6.8599 12.13 0 14 0.89996 15.75 1.9999 2.08 1.3502 3.2398 4 3.77 8.6201a31.23 31.23 0 0 1-1.1601 13.17z\" style=\"fill:#333;\"/>",
|
||||
"top": "<path d=\"m156.1 15.879c-0.38556 5.3015-1.7049 9.4762-3.6602 12.76-0.41226 23.773-9.2343 35.229-15.154 42.797l15.062-4.6641c-0.66253 2.8135-2.4628 7.156-0.34766 12.137 1.6334-2.3144 7.9395-5.807 13-3.3477-0.43442 3.5532-0.95271 7.094-1.4512 10.639l8.9648 0.85937c0.83453 3.8792 0.51719 9.3449-0.59961 11.736l5.5508 2.0098c0.20764 2.7646 0.10001 5.4906-0.74609 8.875 8.4545-1.7225 14.213-4.3896 19.641-13.188 2.8639-4.7524 4.9018-10.483 4.7305-17.242-4.1612 4.916-9.6484 7.2485-15.26 10.109 6.507-11.065 8.8648-22.768 8.1367-30.58-7.3456 10.251-11.649 13.06-19.918 16.9 1.2386-11.4 5.5249-18.582 12.461-27.27-11.392-1.3025-16.301 1.4749-24.891 6.4395 4.5466-14.036 2.2208-26.679-5.5195-38.971zm-117.76 28.682c9.3378 3.6366 19.581 9.0234 21.129 18.549-7.6182 0.0414-14.897-3.5072-20.242-7.1894-0.15967 8.2309 2.8451 12.252 6.7734 19.08-7.2127 1.6129-12.084 4.8315-17.471 9.4805 7.2948-0.15715 12.299-1.0502 16.891 4.2793-6.0512 5.0164-11.99 10.79-11.99 19.24 9.257-6.1688 12.495-5.9486 21.137-2.2012 1.2906-8.0996 2.3978-14.872 2.7869-16.435 2.4719-0.73247 3.5247-0.94807 5.9221-1.2938-2.1556-7.4281 1.0996-9.5176 2.4141-11.6l7.543 1.5059c-3.9093-6.1699 2.6565-12.483 7.1445-15.51-4.4474-7.2082-5.6649-11.558-7.377-16.797-11.198-8.2947-23.895-6.2742-34.66-1.1094z\" style=\"fill:#f9f9f9;\"/><path d=\"m101.9 7.6408c-10.047 6.2416-12.441 28.646-12.131 33.289-6.9249-5.8258-7.8992-13.75-7.7695-19.203-9.6235 6.0158-10.666 14.421-9 23.943 1.1061 5.1411 2.3972 10.461 7.377 16.797 2e-3 -1e-3 4e-3 -3e-3 6e-3 -4e-3 2.7742 2.8742 5.4644 5.5941 8.3477 8.3574 0.41187-6.971 0.45449-13.622 7.1856-15.824 3.9532 2.8169 7.4123 5.9388 11.084 9.1035l10.559-10.25c5.6447 3.961 5.4531 6.5652 6.5215 14.104 2.153-1.7546 8.719-9.0037 15.844-10.139 0.98706 4.1261-0.99388 10.308-2.6387 13.621 0 0 14.32-11.846 15.195-27.971 0.33968-6.2599 0.2237-11.146-0.041-14.826-3.2125 5.5652-8.7118 8.7799-13.789 10.15-4.2715-9.2486-2.4785-21.435-0.48047-29.309-12.21 3.0195-20.932 18.337-22.172 25.07-9.2678-7.397-13.605-16.146-14.098-26.91z\" style=\"fill:#f9f9f9;\"/>",
|
||||
}
|
||||
|
||||
// Blond
|
||||
sp[12] = map[string]string{
|
||||
"clo": "<path d=\"m141.75 195a114.79 114.79 0 0 1 38 16.5 115.53 115.53 0 0 1-128.46 0 114.79 114.79 0 0 1 38-16.5l26.23 13 26.27-13z\" style=\"fill:#131111;\"/><polygon points=\"115.5 208.03 115.5 207.74 82.72 188.91 80.45 198.86 101.46 222.72\" style=\"fill:#cbcbcb;\"/><polygon points=\"115.5 208.03 115.5 207.74 148.28 188.91 150.55 198.86 129.54 222.72\" style=\"fill:#cbcbcb;\"/>",
|
||||
"mouth": "<path d=\"m123.07 154.05a10.61 10.61 0 0 1-15 0.14l-0.14-0.14\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:6.3px;stroke:#000;\"/><path d=\"m120.1 142.22 0.19-0.11c3-1.87 5.45-2.4 7.3-1.46 2.15 1.1 3.12 3.84 4.84 5.5a5.18 5.18 0 0 0 6.68 0.73m-28.21-4.66-0.19-0.11c-3-1.87-5.45-2.4-7.3-1.46-2.15 1.1-3.12 3.84-4.84 5.5a5.18 5.18 0 0 1-6.68 0.73\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:5.9998px;stroke:#4d4d4d;\"/>",
|
||||
"eyes": "<path d=\"m161.73 86.016h-92.51c-3.37 0-6.0001 2.3998-6.0001 5.2999v28.45c0 3.0002 2.74 5.3001 6.0001 5.3001h32.36c7.0901 0 7.44-19.43 13.82-19.43s6.8801 19.44 13.83 19.44h32.36c3.37 0 5.9999-2.4 5.9999-5.3001v-28.46c0.14043-2.9001-2.6-5.2999-5.9-5.2999z\" style=\"fill:#8f8f8f;\"/><path d=\"m161.73 86.016h-92.51c-3.37 0-6.0001 2.3998-6.0001 5.2999v28.45l104.55-28.45c0-2.9001-2.74-5.2999-5.9999-5.2999z\" style=\"fill:#e3e3e3;\"/><path d=\"m161.73 86.016h-92.51c-3.37 0-6.0001 2.3998-6.0001 5.2999v28.45c0 3.0002 2.74 5.3001 6.0001 5.3001h32.36c7.0901 0 7.44-19.43 13.82-19.43s6.8801 19.44 13.83 19.44h32.36c3.37 0 5.9999-2.4 5.9999-5.3001v-28.46c0.14043-2.9001-2.6-5.2999-5.9-5.2999z\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:4.0026px;stroke:#232323;\"/>",
|
||||
"top": "<path d=\"m69.834 33.826c-8.2001-0.0626-16.444 2.6753-23.152 7.7038-8.5298 6.9899-12.159 19.61-12.329 32.68-0.2041 15.476 1.6092 34.752 1.7464 51.915 0.10414 13.047 0.53485 25.984-2.9197 33.995-2.4994 5.81-9.0955 9.6006-16.196 12.311 7.9599 2.8301 25.009 2.8094 33.58 1.5393 10.8-1.59 17.238-6.5294 17.159-22.699-0.0911-15.93-1.3894-29.23-1.559-45.83-0.3208-11.983-1.569-24.291 4.9774-33.987 4.2139-6.1265 10.452-10.521 17.116-13.588 3.9292-1.8575 8.0384-3.3083 12.263-4.3297-6.8718-13.574-18.732-19.618-30.687-19.709z\" style=\"fill:#b3b3b3;\"/><path d=\"m90.8 76.246c11.918-17.125 31.996-23.218 49.743-17.488 11.81 3.9496 20.692 13.389 22.313 28.237 0.51051 6.2098 0.63413 12.445 0.37007 18.67-0.23973 11.2-0.72946 23.82-1.0995 34.08-0.82005 22.43 0.0593 35.1 24.589 36.3 8.5635 0.32122 17.137-0.22845 25.59-1.6405h-0.0198c-10.74-3.3799-17.98-15.609-19.3-26.289-1.29-10.41-0.6098-23.43-0.7898-38.091-0.1701-14.96 1.0398-29.819 0.28008-42.089-1.414-22.777-14.947-38.505-34.126-45.152-27.813-7.35-51.083 0.091-61.672 17.343-5.4698 8.9112-7.7413 20.07-5.8788 36.121z\" style=\"fill:#b3b3b3;\"/>",
|
||||
}
|
||||
|
||||
// Ateam
|
||||
sp[13] = map[string]string{
|
||||
"clo": "<path d=\"M61.11,205.59l3.49,3.69-6.26,6.6A115.45,115.45,0,0,0,72,222.51v-22a115.19,115.19,0,0,0-10.85,5.1Z\" style=\"fill:#eee;\"/><path d=\"M93.24,228.85V199l-4-4A114.43,114.43,0,0,0,72,200.49v22a114.43,114.43,0,0,0,21.28,6.34Z\" style=\"fill:#787878;\"/><path d=\"m159 222.51v-22a114.63 114.63 0 0 0-17.25-5.51l-4 4v29.86a114.16 114.16 0 0 0 21.25-6.35z\" style=\"fill:#787878;\"/><path d=\"m169.89 205.59-3.49 3.69 6.26 6.6a115.45 115.45 0 0 1-13.66 6.63v-22a115.19 115.19 0 0 1 10.85 5.1z\" style=\"fill:#eee;\"/><path d=\"M115.5,219.62A28.5,28.5,0,0,1,87.25,195c2.93-.74,5.92-1.36,8.94-1.87a19.41,19.41,0,0,0,38.62,0c3,.51,6,1.13,8.94,1.87a28.49,28.49,0,0,1-28.25,24.63Z\" style=\"fill:#c9c9c9;\"/>",
|
||||
"mouth": "<path d=\"m115.5 153.93a14 14 0 0 1-10.5-4.69 3.4209 3.4209 0 0 1 5-4.67l0.08 0.08 0.08 0.09a7.35 7.35 0 0 0 10.39 0.37l0.37-0.37a3.4206 3.4206 0 1 1 5.23 4.41l-0.08 0.09a14 14 0 0 1-10.53 4.69z\" /><path d=\"m115.27 127.32c-7.6627-0.03-15.251 1.4419-20.646 5.1465-7.62 5.33-9.9053 11.512-14.127 18.109-3.4379 5.2447-9.326 10.024-13.467 6.334 25.425 29.755 71.409 29.786 96.875 0.0664-6.8104 3.9305-11.545-2.47-13.508-6.4004-10.697-17.605-14.115-22.656-35.127-23.256zm-0.26758 8.3984c7.457 0.0802 14.986 1.2966 17.146 5.9522 2.5765 11.319-7.5878 17.454-16.681 17.515-6.09-0.05-12.2-2.3802-15.26-7.7402-6.36-11.16 3.6349-15.607 14.795-15.727z\" style=\"fill:#404040;\"/>",
|
||||
"eyes": "<path d=\"m91.72 97.36v11.4m47.56-11.4v11.4\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:7.9999px;stroke:#333;\"/>",
|
||||
"top": "<path d=\"m52.107 57.293c-1.3411 14.839-3.8707 52.771 1.3145 72.715-0.67572-43.829 12.389-70.177 62.078-70.187 49.689 0.010061 62.754 26.359 62.078 70.187 5.1852-19.944 2.6556-57.876 1.3145-72.715h-63.393-63.393z\" style=\"fill:#4d4d4d;\"/><path d=\"m52.339 30.629c-1.3825 24.448-2.1216 45.905-1.4497 66.517 9.4643-48.304 112.77-54.916 129.22 0 0.67191-20.612-0.3798-47.256-1.4928-66.517-32.241 14.296-91.346 18.861-126.28 0z\" style=\"fill:#4d4d4d;\"/><path d=\"m115.5 24.92c-22.25 0-44.5 4.2296-56.72 12.69-3.32 2.3-5.0602 6.4392-5.5903 10.269-0.45275 3.23-0.84043 6.7561-1.1785 10.461h126.98c-0.33704-3.7047-0.72492-7.2306-1.1775-10.461-0.53009-3.8301-2.2697-7.9992-5.5897-10.269-12.22-8.4601-34.47-12.69-56.72-12.69z\" style=\"fill:#4d4d4d;\"/><path d=\"m76.521 39.139c21.233 3.3965 33.116-13.392 37.59-31.72 4.3614 17.158 14.175 34.968 36.577 31.584-33.921 20.594-57.646 11.594-74.167 0.1345z\" style=\"fill:#4d4d4d;\"/>",
|
||||
}
|
||||
|
||||
// Rasta
|
||||
sp[14] = map[string]string{
|
||||
"clo": "<path d=\"m91.92 194.41a101.47 101.47 0 0 1 23.58 17.09 101.47 101.47 0 0 1 23.58-17.09c0.89 0.19 1.78 0.38 2.67 0.59a114.79 114.79 0 0 1 38 16.5 115.53 115.53 0 0 1-128.46 0 114.79 114.79 0 0 1 38-16.5c0.88-0.21 1.78-0.4 2.67-0.59z\" style=\"fill:#757575;\"/><path d=\"m73.65 199.82c16.59 8.23 28.72 18.91 34.27 30.93a114.86 114.86 0 0 1-56.65-19.25 115.06 115.06 0 0 1 22.38-11.68z\" style=\"fill:#d8d8d8;\"/><path d=\"m60.63 205.85c12.35 5.94 21.93 13.44 27.59 21.91a114.7 114.7 0 0 1-36.95-16.26q4.53-3 9.36-5.65z\" style=\"fill:#757575;\"/><path d=\"m157.35 199.82c-16.6 8.23-28.72 18.91-34.27 30.93a114.86 114.86 0 0 0 56.65-19.25 115.06 115.06 0 0 0-22.38-11.68z\" style=\"fill:#d8d8d8;\"/><path d=\"m170.37 205.85c-12.35 5.94-21.93 13.44-27.59 21.91a114.7 114.7 0 0 0 36.95-16.26q-4.53-3-9.36-5.65z\" style=\"fill:#757575;\"/>",
|
||||
"mouth": "<path d=\"m115.5 131c-17.71 0.65-27 9.41-29.61 23.69-1 5.62-0.43 7.06 2.76 7.17 22.76 0.76 22.23 18.21 26.85 18.89 4.62-0.68 4.09-18.13 26.85-18.89 3.19-0.11 3.79-1.55 2.76-7.17-2.62-14.28-11.9-23-29.61-23.69zm0 29.31c-10 0-18-5-18-11.17s8.08-11.17 18-11.17 18 5 18 11.17-8.08 11.17-18 11.17z\" style=\"fill:#333;\"/><path d=\"m123.54 148.46a11.53 11.53 0 0 1-16.09 0\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:6.7998px;stroke:#000;\"/>",
|
||||
"eyes": "<path d=\"m133 108.17h14.17m-63.26 0h14.09m-20.69-8.93a21.31 21.31 0 0 1 27.29 0m21.8 0a21.31 21.31 0 0 1 27.29 0\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:4.8243px;stroke:#000;\"/>",
|
||||
"top": "<path d=\"m115.5 51.75c-38.702 5.3101-54.215 18.038-59.863 35.101\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:12;stroke:#333;\"/><path d=\"m115.5 51.75c-7.8393 3.6337-5.5974 16.583-14.341 23.452\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:12;stroke:#333;\"/><path d=\"m111.35 48.614c-22.634-6.9181-42.457-3.1988-55.733 2.5105\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:12;stroke:#333;\"/><path d=\"m115.47 54.008c0.1965-6.7774-0.1436-26.309 0.05-38.184\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:12;stroke:#333;\"/><path d=\"m68.874 28.177c34.115-3.382 41.987 13.321 45.17 19.602\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:12;stroke:#333;\"/><path d=\"m116.49 48.69c2.8876-6.3019 10.358-21.518 43.469-22.326\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:12;stroke:#333;\"/><path d=\"m116.92 51.766c1.5094 6.3991 3.4988 15.595 10.088 23.058\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:12;stroke:#333;\"/><path d=\"m113.81 51.532c22.03-7.8674 46.709-7.3614 59.444-2.0465\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:12;stroke:#333;\"/><path d=\"m114.53 52.278c36.226 4.8583 52.414 17.092 59.373 33.347\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:12;stroke:#333;\"/><path d=\"m55.637 86.851c-4.1213 12.452-2.9877 27.213-1.777 43.084\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:12;stroke:#333;\"/><path d=\"m55.614 51.124c-13.422 5.5019-21.908 16.409-24.712 28.774-1.8322 8.4632-1.9809 18.156-1.6096 28.486\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:12;stroke:#333;\"/><path d=\"m173.26 49.486c24.917 10.399 26.707 36.537 27.209 59.62\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:12;stroke:#333;\"/><path d=\"m173.9 85.625c5.4042 12.625 5.2413 27.675 4.5745 43.58\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:12;stroke:#333;\"/><path d=\"m53.86 129.93c1.293 16.951 2.6738 35.169-2.1664 53.193\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:12;stroke:#333;\"/><path d=\"m29.292 108.38c0.6173 17.177 2.6722 36.119 0.8158 54.108\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:12;stroke:#333;\"/><path d=\"m200.47 109.11c0.3586 18.529-1.2751 36.94 1.9231 48.985\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:12;stroke:#333;\"/><path d=\"m178.48 129.2c-0.7279 17.362-2.0563 35.743 2.6011 53.099\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:12;stroke:#333;\"/>",
|
||||
}
|
||||
|
||||
// Meta
|
||||
sp[15] = map[string]string{
|
||||
"clo": "<path d=\"m141.75 195a114.79 114.79 0 0 1 38 16.5 115.53 115.53 0 0 1-128.46 0 114.79 114.79 0 0 1 38-16.5 115.77 115.77 0 0 1 15.71-2.53v-14.09a63.8 63.8 0 0 0 21 0v14.09a116.6 116.6 0 0 1 15.75 2.53z\" style=\"fill:#1a1a1a;\"/><path d=\"m60.984 205.66 6.2675 2.2051 3.4074-6.819 2.8018-1.1353-3.9911 7.9907 27.222-3.0857 3.2541-11.739 2.1451-0.2692-3.2833 11.819 20.393-1.6011-14.191-15.945v-2.4379l17.606-5.7274 3.3855-0.473v1.47l-19.167 6.2295 14.731 16.542 19.839-7.7432 3.3636 0.8223-21.371 8.34 20.532 13.842 2.6777-21.687 1.9481 0.5604-2.7726 22.378 0.0584 0.0364 8.5075 4.9923-2.4807 0.85145-6.4718-3.7916-1.2987 6.0622-2.1524 0.53125 1.3425-6.2804-17.037 8.8348-5.0271 0.35661 21.59-11.193-20.962-14.133-7.5006 25.457-2.0721-0.0364 7.6392-25.915-21.05 1.652 9.0109 24.052-1.4155-0.0946-0.49615-0.0437-0.073-7e-3 -0.2043-0.0145-8.3688-22.342-10.127 19.242-1.9846-0.52399 10.514-19.962-26.04 2.9547 13.425 16.418-3.4438-1.0625-12.083-14.781-8.1645 5.9675-1.9043-1.077 8.128-5.9385-6.9898-2.4598 2.3348-1.2881zm92.509-7.2556 14.228 20.093-1.8095 0.89514-15.614-22.043z\" style=\"fill:#b2b2b2;\"/>",
|
||||
"mouth": "<path d=\"m97.06 144.59a20.15 20.15 0 0 0 36.88 4.53z\" style=\"fill:#fff;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.9999px;stroke:#000;\"/>",
|
||||
"eyes": "<line x1=\"85.29\" x2=\"85.29\" y1=\"98.73\" y2=\"109.79\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:8.7999px;stroke:#000;\"/><path d=\"m108.28 72.16h62.18c9.19 0 13.32 1.21 14.71 8.52 3.61 18.95 2.2 33.49-0.44 43.75a65.07 65.07 0 0 1-5.89 14.78 73.52 73.52 0 0 1-7.06 10.26c-1.8 2.27-5.17 1.21-4.19-1.09 0.14-0.47 0.27-1 0.4-1.48a14.29 14.29 0 0 0 0.52-6.62 12.52 12.52 0 0 0-3.88-6.3c-4.17-3.9-12.81-8.71-32.53-13.66-6.4-1.6-10.69-2.24-11.76-2.79a7.08 7.08 0 0 1-3.85-6.31v-9c0-2.39 0.18-4.55-1.56-6.57s-4.16-2.13-6.65-2.14a6 6 0 0 1-6-6v-9.35a6 6 0 0 1 6-6z\" style=\"fill:#1a1a1a;\"/><path d=\"m135.9 98.73v9.27m15.22-9.29v9.29\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:7.7998px;stroke:#b2b2b2;\"/>",
|
||||
"top": "<path d=\"m109.99 15.57c-13.46 3.6301-19.789 11.95-24.069 24.08-6.9996-7-8.7307-10.82-7.5606-21.43a41 41 0 0 0-9.2698 24.988c0.0366 7.6776 5.6462 13.939 12.697 15.297-13.315 5.8106-15.258 22.033-14.045 33.524 5.7687-11.861 14.254-20.981 27.258-22.951-0.43017 6.6-2.5099 10.22-7.29 17.66 18.29-2.8601 25.119-7.8199 37.15-18.24 0.46001 0 1.0001 0.089 1.4606 0.12058-0.33023 3.5601-1.0906 6.5598-5.0004 12.46 9.5298-1.32 14.721-5.8006 17.539-11.671 8.8862 0.95314 15.836 6.785 21.26 14.818 1.928-15.211-4.4766-26.6-19.807-34.036 1.4167-2.6974 8.0143-11.925 17.661-15.721-1.424-0.28569-2.8883-0.49486-4.4033-0.61125-5.71-0.41992-13.62-0.99982-24.89 4.1703 2.8501-8.5101 10.21-11 18.05-13.12-15.131-1.2501-28.61-2.5898-40.53 8.1801-1.8997-6.21-0.18055-12.54 3.7889-17.52z\" style=\"fill:#111;\"/><path d=\"m172.63 69.954c1.2292 14.064 0.93841 29.96 0.34635 45.169 1.7887 6.796 3.0379 13.235 3.8842 18.388l0.13973-0.011c1.0001 6.56 2.3597 13.18 3.2698 19.73 2.0002-6.5699 2.5303-18.25 3.2405-25.43 1.2597-13 1.8296-29.311-0.43017-41.931-0.85041-4.72-2.0007-7.6896-2.0007-8.4796 4.6205 3.5601 8.6606 9.2204 13.001 14.15-0.6751-3.4318-1.347-6.6004-2.0567-9.5273-4.047-5.7183-13.726-12.154-19.393-12.06z\" style=\"fill:#111;\"/><path d=\"m157.97 34.471c-10.339 2.7579-17.715 13.543-19.132 16.24 15.33 7.4361 20.783 17.96 21.278 33.517 5.9534 8.8179 10.066 20.289 12.857 30.895 0.87636-13.178 1.8186-27.726 0.26566-44.28 2.5698 0.44857 9.1372 1.3934 18.781 11.17-2.1158-8.7321-4.5671-15.31-8.4539-20.283-4.5598-5.8401-10.999-10.431-23.809-13 9.6502-3.34 16.27-0.76993 25.5 2.1301-8.1388-7.4315-16.474-14.219-27.287-16.389z\" style=\"fill:#111;\"/><path d=\"m61.473 73.354c-7.256-0.77501-13.024 2.3746-16.262 5.3879 0.73789-0.45409 1.3868-0.74208 1.8489-0.74208 0 0-1.5198 10.359-1.6197 11.519-1.56 19.73 0.99957 43.401 6.37 62.471 1.3099 4.6899 1.1895 3.0893 1.8898-0.9107 1.7526-10.061 3.3891-24.703 6.9739-38.864-5.068-17.627-4.2508-32.403 0.79937-38.861z\" style=\"fill:#111;\"/><path d=\"m69.09 43.21c-0.0253 1.0803-8e-3 2.1612 0.0523 3.2402-3.8402 0-12.46 0.71984-16 2.1598-4.4504 1.8001-8.48 5.4801-11.67 11.83 7.2999-3.94 11.899-3.8502 16.66-1.8102-10.39 3.45-19.52 11.37-20.32 26.9 1.1456-1.5053 4.6079-4.9789 7.1393-6.6285 0.09-0.0587 0.17427-0.10556 0.26167-0.15946 3.7141-2.3211 9.0494-5.1247 15.181-4.9553-5.0501 6.4577-6.6824 20.434 0.28207 38.428 1.7866-7.0567 4.0574-13.994 7.0681-20.184-1e-3 -11.664 2.0764-27.774 15.391-33.585-7.0508-2.1538-12.709-7.991-14.043-15.236z\" style=\"fill:#111;\"/>",
|
||||
}
|
||||
}
|
||||
|
||||
func SvgCode(avatarId string, sansEnv bool, opts *Options) (svg string, err error) {
|
||||
if avatarId == "" {
|
||||
err = errors.New("avatar id is required")
|
||||
return
|
||||
}
|
||||
|
||||
h := sha256.New()
|
||||
h.Write([]byte(avatarId))
|
||||
sum := h.Sum(nil)
|
||||
s := hex.EncodeToString(sum)
|
||||
reg := regexp.MustCompile("[0-9]")
|
||||
hash := reg.FindAllString(s, -1)[0:12]
|
||||
|
||||
var p = make(map[string][2]int, 6)
|
||||
var num int
|
||||
num, err = strconv.Atoi(strings.Join(hash[:2], ""))
|
||||
if err != nil {
|
||||
num = 0
|
||||
}
|
||||
p["env"] = getKey(int(math.Floor(.47*float64(num)+.5)), opts)
|
||||
|
||||
num, err = strconv.Atoi(strings.Join(hash[2:4], ""))
|
||||
if err != nil {
|
||||
num = 0
|
||||
}
|
||||
p["clo"] = getKey(int(math.Floor(.47*float64(num)+.5)), opts)
|
||||
|
||||
num, err = strconv.Atoi(strings.Join(hash[4:6], ""))
|
||||
if err != nil {
|
||||
num = 0
|
||||
}
|
||||
p["head"] = getKey(int(math.Floor(.47*float64(num)+.5)), opts)
|
||||
|
||||
num, err = strconv.Atoi(strings.Join(hash[6:8], ""))
|
||||
if err != nil {
|
||||
num = 0
|
||||
}
|
||||
p["mouth"] = getKey(int(math.Floor(.47*float64(num)+.5)), opts)
|
||||
|
||||
num, err = strconv.Atoi(strings.Join(hash[8:10], ""))
|
||||
if err != nil {
|
||||
num = 0
|
||||
}
|
||||
p["eyes"] = getKey(int(math.Floor(.47*float64(num)+.5)), opts)
|
||||
|
||||
num, err = strconv.Atoi(strings.Join(hash[10:], ""))
|
||||
if err != nil {
|
||||
num = 0
|
||||
}
|
||||
p["top"] = getKey(int(math.Floor(.47*float64(num)+.5)), opts)
|
||||
|
||||
var final = make(map[string]string, 6)
|
||||
for k, v := range p {
|
||||
colors := themes[v[0]][v[1]][k]
|
||||
var svgPart string
|
||||
if k == "env" {
|
||||
svgPart = env
|
||||
} else if k == "head" {
|
||||
svgPart = head
|
||||
} else {
|
||||
svgPart = sp[v[0]][k]
|
||||
}
|
||||
|
||||
reg := regexp.MustCompile("#(.*?)+(;)")
|
||||
match := reg.FindAllString(svgPart, -1)
|
||||
for i, rm := range match {
|
||||
svgPart = strings.Replace(svgPart, rm, colors[i]+";", 1)
|
||||
}
|
||||
final[k] = svgPart
|
||||
}
|
||||
|
||||
var builder strings.Builder
|
||||
builder.WriteString(svgStart)
|
||||
builder.WriteString(final["env"])
|
||||
builder.WriteString(final["head"])
|
||||
builder.WriteString(final["clo"])
|
||||
builder.WriteString(final["top"])
|
||||
builder.WriteString(final["eyes"])
|
||||
builder.WriteString(final["mouth"])
|
||||
builder.WriteString(svgEnd)
|
||||
svg = builder.String()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func getKey(v int, opts *Options) [2]int {
|
||||
if opts != nil {
|
||||
return [2]int{opts.Part, opts.Theme}
|
||||
}
|
||||
|
||||
if v > 31 {
|
||||
return [2]int{v - 32, 2}
|
||||
} else if v > 15 {
|
||||
return [2]int{v - 16, 1}
|
||||
} else {
|
||||
return [2]int{v, 0}
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateAvatar generates an avatar for the given user ID.
|
||||
func GenerateAvatar(userId string) (baseImg string) {
|
||||
svg, err := SvgCode(userId, true, nil)
|
||||
if err != nil {
|
||||
return "data:image/svg+xml;charset=utf-8;base64,PHN2ZyB0PSIxNzMwNDUwODA4NDIwIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjkyMDMiIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIj48cGF0aCBkPSJNOTc0LjU5NjU0NiA1MDUuOTYwNTg0YzAgMjU1LjQ4NDg0My0yMDcuMTA3NTczIDQ2Ni40MjA0NzctNDYyLjU5NjU0NiA0NjYuNDIwNDc3LTI1NS40ODg5NzMgMC00NjIuNTk2NTQ2LTIxMC45MzU2MzQtNDYyLjU5NjU0Ni00NjYuNDIwNDc3QzQ5LjQwMzQ1NCAyNTAuNDcxNjEyIDI1Ni41MTEwMjcgNDMuMzU5OTA5IDUxMiA0My4zNTk5MDljMjU1LjQ4ODk3MyAwIDQ2Mi41OTY1NDYgMjA3LjExMTcwMyA0NjIuNTk2NTQ2IDQ2Mi42MDA2NzV6IiBmaWxsPSIjRkZFNTc4IiBwLWlkPSI5MjA0Ij48L3BhdGg+PHBhdGggZD0iTTUxMiAxMDAzLjM1MjQyNGMtMjcyLjE1NTY5NiAwLTQ5My41Njc5MDktMjIzLjEzMDA5Mi00OTMuNTY3OTA5LTQ5Ny4zOTE4NEMxOC40MzIwOTEgMjMzLjgwNDg4OCAyMzkuODQ0MzA0IDEyLjM4ODU0NSA1MTIgMTIuMzg4NTQ1czQ5My41Njc5MDkgMjIxLjQxNjM0MyA0OTMuNTY3OTA5IDQ5My41Njc5MWMwIDI3NC4yNjU4NzgtMjIxLjQxMjIxNCA0OTcuMzk1OTctNDkzLjU2NzkwOSA0OTcuMzk1OTY5ek01MTIgNzQuMzMxMjczQzI3My45OTk1MjQgNzQuMzMxMjczIDgwLjM3NDgxOCAyNjcuOTYwMTA4IDgwLjM3NDgxOCA1MDUuOTYwNTg0YzAgMjQwLjExMDY1OCAxOTMuNjI4ODM2IDQzNS40NDkxMTMgNDMxLjYyNTE4MiA0MzUuNDQ5MTEzczQzMS42MjUxODItMTk1LjM0MjU4NCA0MzEuNjI1MTgyLTQzNS40NDkxMTNDOTQzLjYyNTE4MiAyNjcuOTYwMTA4IDc1MC4wMDA0NzYgNzQuMzMxMjczIDUxMiA3NC4zMzEyNzN6IiBmaWxsPSIjNkU2RTk2IiBwLWlkPSI5MjA1Ij48L3BhdGg+PHBhdGggZD0iTTUxMS43OTc2NTQgNDMuMzU5OTA5Yy0yMzUuMDY4NTIgMC00MjkuMTc2Mzc5IDE3NS4zMzkyMTMtNDU4LjY5ODI4NCA0MDIuMzYzNDM4IDEuMDk0MzIyIDIuMTUxNDc3IDEuNzI2MTM3IDMuMjg3MDk0IDEuNzI2MTM4IDMuMjg3MDk0aDI1MC42MDM3NTZsNDIuMDUwODUzLTE4MC4wODgxNTYgMzguMjMxMDUxIDE4MC4wODgxNTZoNTg1LjE4OTQ2MkM5NDIuODMyMzE1IDIyMC4zOTYzNTMgNzQ3Ljk5NzY2MSA0My4zNTk5MDkgNTExLjc5NzY1NCA0My4zNTk5MDl6IiBmaWxsPSIjOUM5Q0JDIiBwLWlkPSI5MjA2Ij48L3BhdGg+PHBhdGggZD0iTTI1MC4wNTY1OTUgNjA5LjE4MTk0NWE4MC4yODYwMzMgNjguODE0MjQgOTAgMSAwIDEzNy42Mjg0ODEgMCA4MC4yODYwMzMgNjguODE0MjQgOTAgMSAwLTEzNy42Mjg0ODEgMFoiIGZpbGw9IiM2RTZFOTYiIHAtaWQ9IjkyMDciPjwvcGF0aD48cGF0aCBkPSJNNjMzLjMyOTI4NCA2MDkuMTgxOTQ1YTgwLjI4NjAzMyA2OC44MTAxMTEgOTAgMSAwIDEzNy42MjAyMjIgMCA4MC4yODYwMzMgNjguODEwMTExIDkwIDEgMC0xMzcuNjIwMjIyIDBaIiBmaWxsPSIjNkU2RTk2IiBwLWlkPSI5MjA4Ij48L3BhdGg+PHBhdGggZD0iTTEwMDUuOTA2NTI5IDQ3OS45ODE4MDRIMzYwLjYyNDM2M2wtMTQuNTg1NDQ3LTY4LjY5NDQ4NC0xNi4wMzkwMzcgNjguNjk0NDg0SDM2LjY2MzlsLTguOTE5NzUyLTE1LjkzOTkyOHMtMC44MjU5MDMtMS40NzAxMDctMi4yNDIzMjctNC4yNjE2NmwtNC4zNTI1MDktOC41NDM5NjcgMS4yMzQ3MjUtOS41MDYxNDNDNTQuMjE0MzQgMTk2Ljk2NTQ4NCAyNjQuNjEzMTM2IDEyLjM4ODU0NSA1MTEuNzk3NjU0IDEyLjM4ODU0NWMyNDguOTY0MzM5IDAgNDU5LjU0ODk2MyAxODYuMDg0MjExIDQ4OS44NDcyMTYgNDMyLjg0NzUxOWw0LjI2MTY1OSAzNC43NDU3NHogbS01OTUuMTEyNjg2LTYxLjk0MjcyN2g1MjMuNjU5Njg2Qzg5My41MjE3NzUgMjE5LjgwMTcwMyA3MTcuNjYyMjQzIDc0LjMzMTI3MyA1MTEuNzk3NjU0IDc0LjMzMTI3MyAzMDYuNDM2ODY2IDc0LjMzMTI3MyAxMzAuMTEwNjk4IDIxOS45ODc1MzEgODkuMTM3NjQ5IDQxOC4wMzkwNzdoMTkxLjcxMjc0MWwzNi40NjM2MTgtMTU2LjE1NzYxNSA2MC40NTYxMDIgMC42MTExNjggMzMuMDIzNzMzIDE1NS41NDY0NDd6IiBmaWxsPSIjNkU2RTk2IiBwLWlkPSI5MjA5Ij48L3BhdGg+PC9zdmc+"
|
||||
}
|
||||
svgBytes := []byte(svg)
|
||||
return "data:image/svg+xml;base64," + base64.StdEncoding.EncodeToString(svgBytes)
|
||||
}
|
26
app/core/api/common/utils/get_client_ip.go
Normal file
26
app/core/api/common/utils/get_client_ip.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// GetClientIP returns the client IP address from the request.
|
||||
func GetClientIP(r *http.Request) string {
|
||||
xForwardedFor := strings.TrimSpace(r.Header.Get("X-Forwarded-For"))
|
||||
if xForwardedFor != "" {
|
||||
return strings.Split(xForwardedFor, ",")[0]
|
||||
}
|
||||
|
||||
ip := strings.TrimSpace(r.Header.Get("X-Real-Ip"))
|
||||
if ip != "" {
|
||||
return ip
|
||||
}
|
||||
|
||||
ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr))
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return ip
|
||||
}
|
90
app/core/api/common/utils/image_util.go
Normal file
90
app/core/api/common/utils/image_util.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
||||
// GetMimeType 获取 MIME 类型
|
||||
func GetMimeType(data []byte) string {
|
||||
if len(data) < 4 {
|
||||
return "application/octet-stream" // 默认类型
|
||||
}
|
||||
|
||||
// 判断 JPEG
|
||||
if data[0] == 0xFF && data[1] == 0xD8 {
|
||||
return "image/jpeg"
|
||||
}
|
||||
|
||||
// 判断 PNG
|
||||
if len(data) >= 8 && data[0] == 0x89 && data[1] == 0x50 && data[2] == 0x4E && data[3] == 0x47 &&
|
||||
data[4] == 0x0D && data[5] == 0x0A && data[6] == 0x1A && data[7] == 0x0A {
|
||||
return "image/png"
|
||||
}
|
||||
|
||||
// 判断 GIF
|
||||
if len(data) >= 6 && data[0] == 'G' && data[1] == 'I' && data[2] == 'F' {
|
||||
return "image/gif"
|
||||
}
|
||||
// 判断 WEBP
|
||||
if len(data) >= 12 && data[0] == 0x52 && data[1] == 0x49 && data[2] == 0x46 && data[3] == 0x46 &&
|
||||
data[8] == 0x57 && data[9] == 0x45 && data[10] == 0x42 && data[11] == 0x50 {
|
||||
return "image/webp"
|
||||
}
|
||||
// 判断svg
|
||||
if len(data) >= 4 && data[0] == '<' && data[1] == '?' && data[2] == 'x' && data[3] == 'm' {
|
||||
return "image/svg+xml"
|
||||
}
|
||||
// 判断JPG
|
||||
if len(data) >= 3 && data[0] == 0xFF && data[1] == 0xD8 && data[2] == 0xFF {
|
||||
return "image/jpeg"
|
||||
}
|
||||
|
||||
return "application/octet-stream" // 默认类型
|
||||
}
|
||||
|
||||
// ProcessImages 处理图片,将 base64 字符串转换为字节数组
|
||||
func ProcessImages(images []string) ([][]byte, error) {
|
||||
var imagesData [][]byte
|
||||
dataChan := make(chan []byte, len(images)) // 创建一个带缓冲的 channel
|
||||
re := regexp.MustCompile(`^data:image/\w+;base64,`)
|
||||
|
||||
for _, img := range images {
|
||||
wg.Add(1) // 增加 WaitGroup 的计数
|
||||
go func(img string) {
|
||||
defer wg.Done() // 函数结束时减少计数
|
||||
|
||||
imgWithoutPrefix := re.ReplaceAllString(img, "")
|
||||
data, err := Base64ToBytes(imgWithoutPrefix)
|
||||
if err != nil {
|
||||
return // 出错时直接返回
|
||||
}
|
||||
dataChan <- data // 将结果发送到 channel
|
||||
}(img)
|
||||
}
|
||||
|
||||
wg.Wait() // 等待所有 goroutine 完成
|
||||
close(dataChan) // 关闭 channel
|
||||
|
||||
for data := range dataChan { // 收集所有结果
|
||||
imagesData = append(imagesData, data)
|
||||
}
|
||||
|
||||
return imagesData, nil
|
||||
}
|
||||
|
||||
// Base64ToBytes 将base64字符串转换为字节数组
|
||||
func Base64ToBytes(base64Str string) ([]byte, error) {
|
||||
reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(base64Str))
|
||||
data, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to decode base64 string")
|
||||
}
|
||||
return data, nil
|
||||
}
|
21
app/core/api/common/utils/ip2location.go
Normal file
21
app/core/api/common/utils/ip2location.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func RemoveZeroAndAdjust(s string) string {
|
||||
// 正则表达式匹配 "|0|" 或 "|0" 或 "0|" 并替换为 "|"
|
||||
re := regexp.MustCompile(`(\|0|0\||0)`)
|
||||
result := re.ReplaceAllString(s, "|")
|
||||
|
||||
// 移除可能出现的连续 "|"
|
||||
re = regexp.MustCompile(`\|+`)
|
||||
result = re.ReplaceAllString(result, "|")
|
||||
|
||||
// 移除字符串开头和结尾可能出现的 "|"
|
||||
result = strings.Trim(result, "|")
|
||||
|
||||
return result
|
||||
}
|
39
app/core/api/common/utils/match.go
Normal file
39
app/core/api/common/utils/match.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package utils
|
||||
|
||||
import "regexp"
|
||||
|
||||
// IsEmail 判断是否为邮箱
|
||||
func IsEmail(email string) bool {
|
||||
// 邮箱的正则表达式
|
||||
emailRegex := `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`
|
||||
match, _ := regexp.MatchString(emailRegex, email)
|
||||
return match
|
||||
}
|
||||
|
||||
// IsPhone 判断是否为手机号
|
||||
func IsPhone(phone string) bool {
|
||||
// 手机号的正则表达式,这里以中国大陆的手机号为例
|
||||
phoneRegex := `^1[3-9]\d{9}$`
|
||||
match, _ := regexp.MatchString(phoneRegex, phone)
|
||||
return match
|
||||
}
|
||||
|
||||
// IsUsername 用户名的正则表达式
|
||||
func IsUsername(username string) bool {
|
||||
/**
|
||||
1.用户名仅能使用数字,大小写字母和下划线。
|
||||
2.用户名中的数字必须在最后。 数字可以有零个或多个。
|
||||
3.用户名不能以数字开头。 用户名字母可以是小写字母和大写字母。
|
||||
4.用户名长度必须至少为3个字符。 两位用户名只能使用字母,最多20个字符
|
||||
*/
|
||||
phoneRegex := `^[a-zA-Z_]{2,18}[0-9]*$`
|
||||
match, _ := regexp.MatchString(phoneRegex, username)
|
||||
return match
|
||||
}
|
||||
|
||||
// IsPassword 密码的正则表达式
|
||||
func IsPassword(password string) bool {
|
||||
phoneRegex := `^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{6,18}$`
|
||||
match, _ := regexp.MatchString(phoneRegex, password)
|
||||
return match
|
||||
}
|
@@ -35,10 +35,19 @@ type (
|
||||
LoginResponse {
|
||||
AccessToken string `json:"access_token"`
|
||||
UID string `json:"uid"`
|
||||
Username string `json:"username,optional"`
|
||||
Username string `json:"username,omitempty"`
|
||||
Nickname string `json:"nickname"`
|
||||
Avatar string `json:"avatar"`
|
||||
Status int64 `json:"status"`
|
||||
Status int8 `json:"status"`
|
||||
}
|
||||
)
|
||||
|
||||
// 统一响应参数
|
||||
type (
|
||||
Response {
|
||||
Code int64 `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data interface{} `json:"data,optional"`
|
||||
}
|
||||
)
|
||||
|
||||
@@ -56,14 +65,30 @@ type (
|
||||
service core {
|
||||
// 账户登录
|
||||
@handler accountLogin
|
||||
post /login (AccountLoginRequest) returns (LoginResponse)
|
||||
post /login (AccountLoginRequest) returns (Response)
|
||||
|
||||
// 手机号登录
|
||||
@handler phoneLogin
|
||||
post /phone_login (PhoneLoginRequest) returns (LoginResponse)
|
||||
post /phone_login (PhoneLoginRequest) returns (Response)
|
||||
|
||||
// 重置密码
|
||||
@handler resetPassword
|
||||
post /reset_password (ResetPasswordRequest) returns (string)
|
||||
post /reset_password (ResetPasswordRequest) returns (Response)
|
||||
}
|
||||
|
||||
// 客户端服务
|
||||
@server (
|
||||
group: client // 微服务分组
|
||||
prefix: /api/client // 微服务前缀
|
||||
timeout: 10s // 超时时间
|
||||
maxBytes: 1048576 // 最大请求大小
|
||||
signature: false // 是否开启签名验证
|
||||
middleware: SecurityHeadersMiddleware // 注册中间件
|
||||
MaxConns: true // 是否开启最大连接数限制
|
||||
Recover: true // 是否开启自动恢复
|
||||
)
|
||||
service core {
|
||||
@handler generateClientId
|
||||
get /generate_client_id returns (Response)
|
||||
}
|
||||
|
||||
|
@@ -4,10 +4,10 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/middleware"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/config"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/handler"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/common/middleware"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/conf"
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
@@ -21,7 +21,7 @@ func main() {
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
|
||||
server := rest.MustNewServer(c.RestConf, rest.WithCustomCors(middleware.CORSMiddleware(), nil, "*"))
|
||||
server := rest.MustNewServer(c.RestConf, rest.WithCors())
|
||||
defer server.Stop()
|
||||
// i18n middleware
|
||||
server.Use(middleware.I18nMiddleware)
|
||||
|
@@ -1,6 +1,10 @@
|
||||
Name: main
|
||||
Host: 0.0.0.0
|
||||
Port: 8888
|
||||
Port: 80
|
||||
Web:
|
||||
Addr: localhost:8080
|
||||
Middlewares:
|
||||
Log: true
|
||||
Mysql:
|
||||
DataSource: root:1611@tcp(localhost:3306)/schisandra-cloud-album?charset=utf8mb4&parseTime=True&loc=Local
|
||||
Auth:
|
||||
@@ -8,9 +12,8 @@ Auth:
|
||||
AccessExpire: 86400
|
||||
Redis:
|
||||
Host: 1.95.0.111:6379
|
||||
Type: node
|
||||
Pass: LDQ20020618xxx
|
||||
Tls: false
|
||||
DB: 0
|
||||
Mongo:
|
||||
Uri: mongodb://1.95.0.111:27017
|
||||
Username: landaiqing
|
||||
|
@@ -13,9 +13,8 @@ type Config struct {
|
||||
}
|
||||
Redis struct {
|
||||
Host string
|
||||
Type string
|
||||
Pass string
|
||||
Tls bool
|
||||
DB int
|
||||
}
|
||||
Mongo struct {
|
||||
Uri string
|
||||
|
@@ -0,0 +1,24 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/utils"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/client"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
)
|
||||
|
||||
func GenerateClientIdHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
clientIP := utils.GetClientIP(r)
|
||||
l := client.NewGenerateClientIdLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GenerateClientId(clientIP)
|
||||
if err != nil || resp.Code == 500 {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
@@ -7,6 +7,7 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
client "schisandra-album-cloud-microservices/app/core/api/internal/handler/client"
|
||||
user "schisandra-album-cloud-microservices/app/core/api/internal/handler/user"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
|
||||
@@ -14,6 +15,22 @@ import (
|
||||
)
|
||||
|
||||
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.SecurityHeadersMiddleware},
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/generate_client_id",
|
||||
Handler: client.GenerateClientIdHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithPrefix("/api/client"),
|
||||
rest.WithTimeout(10000*time.Millisecond),
|
||||
rest.WithMaxBytes(1048576),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.SecurityHeadersMiddleware},
|
||||
|
@@ -19,8 +19,8 @@ func AccountLoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
}
|
||||
|
||||
l := user.NewAccountLoginLogic(r.Context(), svcCtx)
|
||||
resp, err := l.AccountLogin(&req)
|
||||
if err != nil {
|
||||
resp, err := l.AccountLogin(w, r, &req)
|
||||
if err != nil || resp.Code == 500 {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
|
@@ -20,7 +20,7 @@ func PhoneLoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
|
||||
l := user.NewPhoneLoginLogic(r.Context(), svcCtx)
|
||||
resp, err := l.PhoneLogin(&req)
|
||||
if err != nil {
|
||||
if err != nil || resp.Code == 500 {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
|
@@ -20,7 +20,7 @@ func ResetPasswordHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
|
||||
l := user.NewResetPasswordLogic(r.Context(), svcCtx)
|
||||
resp, err := l.ResetPassword(&req)
|
||||
if err != nil {
|
||||
if err != nil || resp.Code == 500 {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
|
@@ -0,0 +1,43 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/ccpwcn/kgo"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/response"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GenerateClientIdLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGenerateClientIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GenerateClientIdLogic {
|
||||
return &GenerateClientIdLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GenerateClientIdLogic) GenerateClientId(clientIP string) (resp *types.Response, err error) {
|
||||
clientId := l.svcCtx.RedisClient.Get(l.ctx, constant.UserClientPrefix+clientIP).Val()
|
||||
|
||||
if clientId != "" {
|
||||
return response.Success(clientId), nil
|
||||
}
|
||||
simpleUuid := kgo.SimpleUuid()
|
||||
if err = l.svcCtx.RedisClient.SetEx(l.ctx, constant.UserClientPrefix+clientIP, simpleUuid, time.Hour*24*7).Err(); err != nil {
|
||||
l.Error(err)
|
||||
return response.Error(), err
|
||||
}
|
||||
return response.Success(simpleUuid), nil
|
||||
}
|
@@ -2,14 +2,27 @@ package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/lionsoul2014/ip2region/binding/golang/xdb"
|
||||
"github.com/mssola/useragent"
|
||||
"github.com/zeromicro/go-zero/core/logc"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/captcha/verify"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/i18n"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/jwt"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/response"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/utils"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mongodb/collection"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mongodb/model"
|
||||
"schisandra-album-cloud-microservices/common/i18n"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent/scaauthuser"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent/scaauthuserdevice"
|
||||
types3 "schisandra-album-cloud-microservices/app/core/api/repository/redis_session/types"
|
||||
types2 "schisandra-album-cloud-microservices/app/core/api/repository/redisx/types"
|
||||
)
|
||||
|
||||
type AccountLoginLogic struct {
|
||||
@@ -26,13 +39,160 @@ func NewAccountLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Acco
|
||||
}
|
||||
}
|
||||
|
||||
func (l *AccountLoginLogic) AccountLogin(req *types.AccountLoginRequest) (resp *types.LoginResponse, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
i18n.IsHasI18n(l.ctx)
|
||||
text := i18n.FormatText(l.ctx, "user.name", "landaiqing")
|
||||
collection.MustNewCollection[model.CommentImage](l.svcCtx, "comment_image")
|
||||
func (l *AccountLoginLogic) AccountLogin(w http.ResponseWriter, r *http.Request, req *types.AccountLoginRequest) (resp *types.Response, err error) {
|
||||
verifyResult := verify.VerifyRotateCaptcha(l.ctx, l.svcCtx.RedisClient, req.Angle, req.Key)
|
||||
if !verifyResult {
|
||||
return response.ErrorWithMessage(i18n.FormatText(l.ctx, "captcha.verificationFailure", "验证失败!")), nil
|
||||
}
|
||||
var user *ent.ScaAuthUser
|
||||
var query *ent.ScaAuthUserQuery
|
||||
|
||||
return &types.LoginResponse{
|
||||
AccessToken: text,
|
||||
}, nil
|
||||
switch {
|
||||
case utils.IsPhone(req.Account):
|
||||
query = l.svcCtx.MySQLClient.ScaAuthUser.Query().Where(scaauthuser.PhoneEQ(req.Account), scaauthuser.DeletedEQ(0))
|
||||
case utils.IsEmail(req.Account):
|
||||
query = l.svcCtx.MySQLClient.ScaAuthUser.Query().Where(scaauthuser.EmailEQ(req.Account), scaauthuser.DeletedEQ(0))
|
||||
case utils.IsUsername(req.Account):
|
||||
query = l.svcCtx.MySQLClient.ScaAuthUser.Query().Where(scaauthuser.UsernameEQ(req.Account), scaauthuser.DeletedEQ(0))
|
||||
default:
|
||||
return response.ErrorWithMessage(i18n.FormatText(l.ctx, "login.invalidAccount", "无效账号!")), nil
|
||||
}
|
||||
|
||||
user, err = query.First(l.ctx)
|
||||
if err != nil {
|
||||
if ent.IsNotFound(err) {
|
||||
return response.ErrorWithMessage(i18n.FormatText(l.ctx, "login.notFoundAccount", "无效账号!")), nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !utils.Verify(user.Password, req.Password) {
|
||||
return response.ErrorWithMessage(i18n.FormatText(l.ctx, "login.invalidPassword", "密码错误!")), nil
|
||||
}
|
||||
data, result := HandleUserLogin(user, l, req.AutoLogin, r, w, l.svcCtx.Ip2Region, l.svcCtx.MySQLClient)
|
||||
if !result {
|
||||
return response.ErrorWithMessage(i18n.FormatText(l.ctx, "login.loginFailed", "登录失败!")), nil
|
||||
}
|
||||
return response.Success(data), nil
|
||||
}
|
||||
|
||||
// HandleUserLogin 处理用户登录
|
||||
func HandleUserLogin(user *ent.ScaAuthUser, l *AccountLoginLogic, autoLogin bool, r *http.Request, w http.ResponseWriter, ip2location *xdb.Searcher, entClient *ent.Client) (*types.LoginResponse, bool) {
|
||||
// 生成jwt token
|
||||
accessToken := jwt.GenerateAccessToken(l.svcCtx.Config.Auth.AccessSecret, jwt.AccessJWTPayload{
|
||||
UserID: user.UID,
|
||||
})
|
||||
var days time.Duration
|
||||
if autoLogin {
|
||||
days = 7 * 24 * time.Hour
|
||||
} else {
|
||||
days = time.Hour * 24
|
||||
}
|
||||
refreshToken := jwt.GenerateRefreshToken(l.svcCtx.Config.Auth.AccessSecret, jwt.RefreshJWTPayload{
|
||||
UserID: user.UID,
|
||||
}, days)
|
||||
data := types.LoginResponse{
|
||||
AccessToken: accessToken,
|
||||
UID: user.UID,
|
||||
Username: user.Username,
|
||||
Nickname: user.Nickname,
|
||||
Avatar: user.Avatar,
|
||||
Status: user.Status,
|
||||
}
|
||||
|
||||
redisToken := types2.RedisToken{
|
||||
AccessToken: accessToken,
|
||||
UID: user.UID,
|
||||
}
|
||||
err := l.svcCtx.RedisClient.SetEx(l.ctx, constant.UserTokenPrefix+user.UID, redisToken, days).Err()
|
||||
if err != nil {
|
||||
logc.Error(l.ctx, err)
|
||||
return nil, false
|
||||
}
|
||||
sessionData := types3.SessionData{
|
||||
RefreshToken: refreshToken,
|
||||
UID: user.UID,
|
||||
}
|
||||
session, err := l.svcCtx.Session.Get(r, constant.SESSION_KEY)
|
||||
if err != nil {
|
||||
logc.Error(l.ctx, err)
|
||||
return nil, false
|
||||
}
|
||||
session.Values[constant.SESSION_KEY] = sessionData
|
||||
if err = session.Save(r, w); err != nil {
|
||||
logc.Error(l.ctx, err)
|
||||
return nil, false
|
||||
}
|
||||
// 记录用户登录设备
|
||||
if !getUserLoginDevice(user.UID, r, ip2location, entClient, l.ctx) {
|
||||
return nil, false
|
||||
}
|
||||
return &data, true
|
||||
|
||||
}
|
||||
|
||||
// getUserLoginDevice 获取用户登录设备
|
||||
func getUserLoginDevice(userId string, r *http.Request, ip2location *xdb.Searcher, entClient *ent.Client, ctx context.Context) bool {
|
||||
userAgent := r.Header.Get("User-Agent")
|
||||
if userAgent == "" {
|
||||
return false
|
||||
}
|
||||
ip := utils.GetClientIP(r)
|
||||
location, err := ip2location.SearchByStr(ip)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
location = utils.RemoveZeroAndAdjust(location)
|
||||
|
||||
ua := useragent.New(userAgent)
|
||||
isBot := ua.Bot()
|
||||
browser, browserVersion := ua.Browser()
|
||||
os := ua.OS()
|
||||
mobile := ua.Mobile()
|
||||
mozilla := ua.Mozilla()
|
||||
platform := ua.Platform()
|
||||
engine, engineVersion := ua.Engine()
|
||||
|
||||
device, err := entClient.ScaAuthUserDevice.Query().
|
||||
Where(scaauthuserdevice.UserID(userId), scaauthuserdevice.IP(ip), scaauthuserdevice.Agent(userAgent)).
|
||||
Only(ctx)
|
||||
|
||||
// 如果有错误,表示设备不存在,执行插入
|
||||
if ent.IsNotFound(err) {
|
||||
// 创建新的设备记录
|
||||
entClient.ScaAuthUserDevice.Create().
|
||||
SetBot(isBot).
|
||||
SetAgent(userAgent).
|
||||
SetBrowser(browser).
|
||||
SetBrowserVersion(browserVersion).
|
||||
SetEngineName(engine).
|
||||
SetEngineVersion(engineVersion).
|
||||
SetIP(ip).
|
||||
SetLocation(location).
|
||||
SetOperatingSystem(os).
|
||||
SetMobile(mobile).
|
||||
SetMozilla(mozilla).
|
||||
SetPlatform(platform).
|
||||
SaveX(ctx)
|
||||
} else if err == nil {
|
||||
// 如果设备存在,执行更新
|
||||
device.Update().
|
||||
SetBot(isBot).
|
||||
SetAgent(userAgent).
|
||||
SetBrowser(browser).
|
||||
SetBrowserVersion(browserVersion).
|
||||
SetEngineName(engine).
|
||||
SetEngineVersion(engineVersion).
|
||||
SetIP(ip).
|
||||
SetLocation(location).
|
||||
SetOperatingSystem(os).
|
||||
SetMobile(mobile).
|
||||
SetMozilla(mozilla).
|
||||
SetPlatform(platform).
|
||||
SaveX(ctx)
|
||||
} else {
|
||||
logc.Error(ctx, err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@@ -3,10 +3,10 @@ package user
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type PhoneLoginLogic struct {
|
||||
@@ -23,7 +23,7 @@ func NewPhoneLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PhoneL
|
||||
}
|
||||
}
|
||||
|
||||
func (l *PhoneLoginLogic) PhoneLogin(req *types.PhoneLoginRequest) (resp *types.LoginResponse, err error) {
|
||||
func (l *PhoneLoginLogic) PhoneLogin(req *types.PhoneLoginRequest) (resp *types.Response, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return
|
||||
|
@@ -3,10 +3,10 @@ package user
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ResetPasswordLogic struct {
|
||||
@@ -23,7 +23,7 @@ func NewResetPasswordLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Res
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ResetPasswordLogic) ResetPassword(req *types.ResetPasswordRequest) (resp string, err error) {
|
||||
func (l *ResetPasswordLogic) ResetPassword(req *types.ResetPasswordRequest) (resp *types.Response, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return
|
||||
|
@@ -3,7 +3,7 @@ package middleware
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"schisandra-album-cloud-microservices/common/middleware"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/middleware"
|
||||
)
|
||||
|
||||
type SecurityHeadersMiddleware struct {
|
||||
|
@@ -1,24 +1,31 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||
"github.com/lionsoul2014/ip2region/binding/golang/xdb"
|
||||
"github.com/rbcervilla/redisstore/v9"
|
||||
"github.com/redis/go-redis/v9"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
"go.mongodb.org/mongo-driver/v2/mongo"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/config"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/middleware"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/ip2region"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mongodb"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/redis_session"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/redisx"
|
||||
)
|
||||
|
||||
type ServiceContext struct {
|
||||
Config config.Config
|
||||
SecurityHeadersMiddleware rest.Middleware
|
||||
MySQLClient *ent.Client
|
||||
RedisClient *redis.Redis
|
||||
RedisClient *redis.Client
|
||||
MongoClient *mongo.Database
|
||||
Session *redisstore.RedisStore
|
||||
Ip2Region *xdb.Searcher
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
@@ -26,12 +33,9 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
||||
Config: c,
|
||||
SecurityHeadersMiddleware: middleware.NewSecurityHeadersMiddleware().Handle,
|
||||
MySQLClient: mysql.NewMySQL(c.Mysql.DataSource),
|
||||
RedisClient: redis.MustNewRedis(redis.RedisConf{
|
||||
Host: c.Redis.Host,
|
||||
Pass: c.Redis.Pass,
|
||||
Type: c.Redis.Type,
|
||||
Tls: c.Redis.Tls,
|
||||
}),
|
||||
MongoClient: mongodb.NewMongoDB(c.Mongo.Uri, c.Mongo.Username, c.Mongo.Password, c.Mongo.AuthSource, c.Mongo.Database),
|
||||
RedisClient: redisx.NewRedis(c.Redis.Host, c.Redis.Pass, c.Redis.DB),
|
||||
MongoClient: mongodb.NewMongoDB(c.Mongo.Uri, c.Mongo.Username, c.Mongo.Password, c.Mongo.AuthSource, c.Mongo.Database),
|
||||
Session: redis_session.NewRedisSession(c.Redis.Host, c.Redis.Pass),
|
||||
Ip2Region: ip2region.NewIP2Region(),
|
||||
}
|
||||
}
|
||||
|
@@ -14,10 +14,10 @@ type AccountLoginRequest struct {
|
||||
type LoginResponse struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
UID string `json:"uid"`
|
||||
Username string `json:"username,optional"`
|
||||
Username string `json:"username,omitempty"`
|
||||
Nickname string `json:"nickname"`
|
||||
Avatar string `json:"avatar"`
|
||||
Status int64 `json:"status"`
|
||||
Status int8 `json:"status"`
|
||||
}
|
||||
|
||||
type PhoneLoginRequest struct {
|
||||
@@ -32,3 +32,9 @@ type ResetPasswordRequest struct {
|
||||
Password string `json:"password"`
|
||||
Repassword string `json:"repassword"`
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
Code int64 `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data interface{} `json:"data,optional"`
|
||||
}
|
||||
|
27
app/core/api/repository/ip2region/init.go
Normal file
27
app/core/api/repository/ip2region/init.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package ip2region
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/lionsoul2014/ip2region/binding/golang/xdb"
|
||||
)
|
||||
|
||||
// NewIP2Region creates a new IP2Region searcher instance.
|
||||
func NewIP2Region() *xdb.Searcher {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
dbPath := filepath.Join(cwd, "resources/ip2region", "ip2region.xdb")
|
||||
cBuff, err := xdb.LoadContentFromFile(dbPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
searcher, err := xdb.NewWithBuffer(cBuff)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil
|
||||
}
|
||||
return searcher
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package model
|
||||
package types
|
||||
|
||||
import "github.com/chenmingyong0423/go-mongox/v2"
|
||||
|
@@ -107,8 +107,8 @@ var schemaGraph = func() *sqlgraph.Schema {
|
||||
scaauthuserdevice.FieldBrowser: {Type: field.TypeString, Column: scaauthuserdevice.FieldBrowser},
|
||||
scaauthuserdevice.FieldOperatingSystem: {Type: field.TypeString, Column: scaauthuserdevice.FieldOperatingSystem},
|
||||
scaauthuserdevice.FieldBrowserVersion: {Type: field.TypeString, Column: scaauthuserdevice.FieldBrowserVersion},
|
||||
scaauthuserdevice.FieldMobile: {Type: field.TypeInt, Column: scaauthuserdevice.FieldMobile},
|
||||
scaauthuserdevice.FieldBot: {Type: field.TypeInt, Column: scaauthuserdevice.FieldBot},
|
||||
scaauthuserdevice.FieldMobile: {Type: field.TypeBool, Column: scaauthuserdevice.FieldMobile},
|
||||
scaauthuserdevice.FieldBot: {Type: field.TypeBool, Column: scaauthuserdevice.FieldBot},
|
||||
scaauthuserdevice.FieldMozilla: {Type: field.TypeString, Column: scaauthuserdevice.FieldMozilla},
|
||||
scaauthuserdevice.FieldPlatform: {Type: field.TypeString, Column: scaauthuserdevice.FieldPlatform},
|
||||
scaauthuserdevice.FieldEngineName: {Type: field.TypeString, Column: scaauthuserdevice.FieldEngineName},
|
||||
@@ -622,13 +622,13 @@ func (f *ScaAuthUserDeviceFilter) WhereBrowserVersion(p entql.StringP) {
|
||||
f.Where(p.Field(scaauthuserdevice.FieldBrowserVersion))
|
||||
}
|
||||
|
||||
// WhereMobile applies the entql int predicate on the mobile field.
|
||||
func (f *ScaAuthUserDeviceFilter) WhereMobile(p entql.IntP) {
|
||||
// WhereMobile applies the entql bool predicate on the mobile field.
|
||||
func (f *ScaAuthUserDeviceFilter) WhereMobile(p entql.BoolP) {
|
||||
f.Where(p.Field(scaauthuserdevice.FieldMobile))
|
||||
}
|
||||
|
||||
// WhereBot applies the entql int predicate on the bot field.
|
||||
func (f *ScaAuthUserDeviceFilter) WhereBot(p entql.IntP) {
|
||||
// WhereBot applies the entql bool predicate on the bot field.
|
||||
func (f *ScaAuthUserDeviceFilter) WhereBot(p entql.BoolP) {
|
||||
f.Where(p.Field(scaauthuserdevice.FieldBot))
|
||||
}
|
||||
|
||||
|
@@ -109,8 +109,8 @@ var (
|
||||
{Name: "browser", Type: field.TypeString, Size: 20, Comment: "浏览器"},
|
||||
{Name: "operating_system", Type: field.TypeString, Size: 20, Comment: "操作系统"},
|
||||
{Name: "browser_version", Type: field.TypeString, Size: 20, Comment: "浏览器版本"},
|
||||
{Name: "mobile", Type: field.TypeInt, Comment: "是否为手机 0否1是"},
|
||||
{Name: "bot", Type: field.TypeInt, Comment: "是否为bot 0否1是"},
|
||||
{Name: "mobile", Type: field.TypeBool, Comment: "是否为手机 0否1是"},
|
||||
{Name: "bot", Type: field.TypeBool, Comment: "是否为bot 0否1是"},
|
||||
{Name: "mozilla", Type: field.TypeString, Size: 10, Comment: "火狐版本"},
|
||||
{Name: "platform", Type: field.TypeString, Size: 20, Comment: "平台"},
|
||||
{Name: "engine_name", Type: field.TypeString, Size: 20, Comment: "引擎名称"},
|
||||
|
@@ -3193,10 +3193,8 @@ type ScaAuthUserDeviceMutation struct {
|
||||
browser *string
|
||||
operating_system *string
|
||||
browser_version *string
|
||||
mobile *int
|
||||
addmobile *int
|
||||
bot *int
|
||||
addbot *int
|
||||
mobile *bool
|
||||
bot *bool
|
||||
mozilla *string
|
||||
platform *string
|
||||
engine_name *string
|
||||
@@ -3708,13 +3706,12 @@ func (m *ScaAuthUserDeviceMutation) ResetBrowserVersion() {
|
||||
}
|
||||
|
||||
// SetMobile sets the "mobile" field.
|
||||
func (m *ScaAuthUserDeviceMutation) SetMobile(i int) {
|
||||
m.mobile = &i
|
||||
m.addmobile = nil
|
||||
func (m *ScaAuthUserDeviceMutation) SetMobile(b bool) {
|
||||
m.mobile = &b
|
||||
}
|
||||
|
||||
// Mobile returns the value of the "mobile" field in the mutation.
|
||||
func (m *ScaAuthUserDeviceMutation) Mobile() (r int, exists bool) {
|
||||
func (m *ScaAuthUserDeviceMutation) Mobile() (r bool, exists bool) {
|
||||
v := m.mobile
|
||||
if v == nil {
|
||||
return
|
||||
@@ -3725,7 +3722,7 @@ func (m *ScaAuthUserDeviceMutation) Mobile() (r int, exists bool) {
|
||||
// OldMobile returns the old "mobile" field's value of the ScaAuthUserDevice entity.
|
||||
// If the ScaAuthUserDevice object wasn't provided to the builder, the object is fetched from the database.
|
||||
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||
func (m *ScaAuthUserDeviceMutation) OldMobile(ctx context.Context) (v int, err error) {
|
||||
func (m *ScaAuthUserDeviceMutation) OldMobile(ctx context.Context) (v bool, err error) {
|
||||
if !m.op.Is(OpUpdateOne) {
|
||||
return v, errors.New("OldMobile is only allowed on UpdateOne operations")
|
||||
}
|
||||
@@ -3739,38 +3736,18 @@ func (m *ScaAuthUserDeviceMutation) OldMobile(ctx context.Context) (v int, err e
|
||||
return oldValue.Mobile, nil
|
||||
}
|
||||
|
||||
// AddMobile adds i to the "mobile" field.
|
||||
func (m *ScaAuthUserDeviceMutation) AddMobile(i int) {
|
||||
if m.addmobile != nil {
|
||||
*m.addmobile += i
|
||||
} else {
|
||||
m.addmobile = &i
|
||||
}
|
||||
}
|
||||
|
||||
// AddedMobile returns the value that was added to the "mobile" field in this mutation.
|
||||
func (m *ScaAuthUserDeviceMutation) AddedMobile() (r int, exists bool) {
|
||||
v := m.addmobile
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// ResetMobile resets all changes to the "mobile" field.
|
||||
func (m *ScaAuthUserDeviceMutation) ResetMobile() {
|
||||
m.mobile = nil
|
||||
m.addmobile = nil
|
||||
}
|
||||
|
||||
// SetBot sets the "bot" field.
|
||||
func (m *ScaAuthUserDeviceMutation) SetBot(i int) {
|
||||
m.bot = &i
|
||||
m.addbot = nil
|
||||
func (m *ScaAuthUserDeviceMutation) SetBot(b bool) {
|
||||
m.bot = &b
|
||||
}
|
||||
|
||||
// Bot returns the value of the "bot" field in the mutation.
|
||||
func (m *ScaAuthUserDeviceMutation) Bot() (r int, exists bool) {
|
||||
func (m *ScaAuthUserDeviceMutation) Bot() (r bool, exists bool) {
|
||||
v := m.bot
|
||||
if v == nil {
|
||||
return
|
||||
@@ -3781,7 +3758,7 @@ func (m *ScaAuthUserDeviceMutation) Bot() (r int, exists bool) {
|
||||
// OldBot returns the old "bot" field's value of the ScaAuthUserDevice entity.
|
||||
// If the ScaAuthUserDevice object wasn't provided to the builder, the object is fetched from the database.
|
||||
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||
func (m *ScaAuthUserDeviceMutation) OldBot(ctx context.Context) (v int, err error) {
|
||||
func (m *ScaAuthUserDeviceMutation) OldBot(ctx context.Context) (v bool, err error) {
|
||||
if !m.op.Is(OpUpdateOne) {
|
||||
return v, errors.New("OldBot is only allowed on UpdateOne operations")
|
||||
}
|
||||
@@ -3795,28 +3772,9 @@ func (m *ScaAuthUserDeviceMutation) OldBot(ctx context.Context) (v int, err erro
|
||||
return oldValue.Bot, nil
|
||||
}
|
||||
|
||||
// AddBot adds i to the "bot" field.
|
||||
func (m *ScaAuthUserDeviceMutation) AddBot(i int) {
|
||||
if m.addbot != nil {
|
||||
*m.addbot += i
|
||||
} else {
|
||||
m.addbot = &i
|
||||
}
|
||||
}
|
||||
|
||||
// AddedBot returns the value that was added to the "bot" field in this mutation.
|
||||
func (m *ScaAuthUserDeviceMutation) AddedBot() (r int, exists bool) {
|
||||
v := m.addbot
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// ResetBot resets all changes to the "bot" field.
|
||||
func (m *ScaAuthUserDeviceMutation) ResetBot() {
|
||||
m.bot = nil
|
||||
m.addbot = nil
|
||||
}
|
||||
|
||||
// SetMozilla sets the "mozilla" field.
|
||||
@@ -4246,14 +4204,14 @@ func (m *ScaAuthUserDeviceMutation) SetField(name string, value ent.Value) error
|
||||
m.SetBrowserVersion(v)
|
||||
return nil
|
||||
case scaauthuserdevice.FieldMobile:
|
||||
v, ok := value.(int)
|
||||
v, ok := value.(bool)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
m.SetMobile(v)
|
||||
return nil
|
||||
case scaauthuserdevice.FieldBot:
|
||||
v, ok := value.(int)
|
||||
v, ok := value.(bool)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
@@ -4298,12 +4256,6 @@ func (m *ScaAuthUserDeviceMutation) AddedFields() []string {
|
||||
if m.adddeleted != nil {
|
||||
fields = append(fields, scaauthuserdevice.FieldDeleted)
|
||||
}
|
||||
if m.addmobile != nil {
|
||||
fields = append(fields, scaauthuserdevice.FieldMobile)
|
||||
}
|
||||
if m.addbot != nil {
|
||||
fields = append(fields, scaauthuserdevice.FieldBot)
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
@@ -4314,10 +4266,6 @@ func (m *ScaAuthUserDeviceMutation) AddedField(name string) (ent.Value, bool) {
|
||||
switch name {
|
||||
case scaauthuserdevice.FieldDeleted:
|
||||
return m.AddedDeleted()
|
||||
case scaauthuserdevice.FieldMobile:
|
||||
return m.AddedMobile()
|
||||
case scaauthuserdevice.FieldBot:
|
||||
return m.AddedBot()
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
@@ -4334,20 +4282,6 @@ func (m *ScaAuthUserDeviceMutation) AddField(name string, value ent.Value) error
|
||||
}
|
||||
m.AddDeleted(v)
|
||||
return nil
|
||||
case scaauthuserdevice.FieldMobile:
|
||||
v, ok := value.(int)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
m.AddMobile(v)
|
||||
return nil
|
||||
case scaauthuserdevice.FieldBot:
|
||||
v, ok := value.(int)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
m.AddBot(v)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unknown ScaAuthUserDevice numeric field %s", name)
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ import (
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent/scaauthuser"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent/scaauthuserdevice"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent/scaauthusersocial"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/schema"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/model"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
// (default values, validators, hooks and policies) and stitches it
|
||||
// to their package variables.
|
||||
func init() {
|
||||
scaauthpermissionruleFields := schema.ScaAuthPermissionRule{}.Fields()
|
||||
scaauthpermissionruleFields := model.ScaAuthPermissionRule{}.Fields()
|
||||
_ = scaauthpermissionruleFields
|
||||
// scaauthpermissionruleDescPtype is the schema descriptor for ptype field.
|
||||
scaauthpermissionruleDescPtype := scaauthpermissionruleFields[1].Descriptor()
|
||||
@@ -46,10 +46,10 @@ func init() {
|
||||
scaauthpermissionruleDescV5 := scaauthpermissionruleFields[7].Descriptor()
|
||||
// scaauthpermissionrule.V5Validator is a validator for the "v5" field. It is called by the builders before save.
|
||||
scaauthpermissionrule.V5Validator = scaauthpermissionruleDescV5.Validators[0].(func(string) error)
|
||||
scaauthroleMixin := schema.ScaAuthRole{}.Mixin()
|
||||
scaauthroleMixin := model.ScaAuthRole{}.Mixin()
|
||||
scaauthroleMixinFields0 := scaauthroleMixin[0].Fields()
|
||||
_ = scaauthroleMixinFields0
|
||||
scaauthroleFields := schema.ScaAuthRole{}.Fields()
|
||||
scaauthroleFields := model.ScaAuthRole{}.Fields()
|
||||
_ = scaauthroleFields
|
||||
// scaauthroleDescCreatedAt is the schema descriptor for created_at field.
|
||||
scaauthroleDescCreatedAt := scaauthroleMixinFields0[0].Descriptor()
|
||||
@@ -75,10 +75,10 @@ func init() {
|
||||
scaauthroleDescRoleKey := scaauthroleFields[2].Descriptor()
|
||||
// scaauthrole.RoleKeyValidator is a validator for the "role_key" field. It is called by the builders before save.
|
||||
scaauthrole.RoleKeyValidator = scaauthroleDescRoleKey.Validators[0].(func(string) error)
|
||||
scaauthuserMixin := schema.ScaAuthUser{}.Mixin()
|
||||
scaauthuserMixin := model.ScaAuthUser{}.Mixin()
|
||||
scaauthuserMixinFields0 := scaauthuserMixin[0].Fields()
|
||||
_ = scaauthuserMixinFields0
|
||||
scaauthuserFields := schema.ScaAuthUser{}.Fields()
|
||||
scaauthuserFields := model.ScaAuthUser{}.Fields()
|
||||
_ = scaauthuserFields
|
||||
// scaauthuserDescCreatedAt is the schema descriptor for created_at field.
|
||||
scaauthuserDescCreatedAt := scaauthuserMixinFields0[0].Descriptor()
|
||||
@@ -144,10 +144,10 @@ func init() {
|
||||
scaauthuserDescCompany := scaauthuserFields[13].Descriptor()
|
||||
// scaauthuser.CompanyValidator is a validator for the "company" field. It is called by the builders before save.
|
||||
scaauthuser.CompanyValidator = scaauthuserDescCompany.Validators[0].(func(string) error)
|
||||
scaauthuserdeviceMixin := schema.ScaAuthUserDevice{}.Mixin()
|
||||
scaauthuserdeviceMixin := model.ScaAuthUserDevice{}.Mixin()
|
||||
scaauthuserdeviceMixinFields0 := scaauthuserdeviceMixin[0].Fields()
|
||||
_ = scaauthuserdeviceMixinFields0
|
||||
scaauthuserdeviceFields := schema.ScaAuthUserDevice{}.Fields()
|
||||
scaauthuserdeviceFields := model.ScaAuthUserDevice{}.Fields()
|
||||
_ = scaauthuserdeviceFields
|
||||
// scaauthuserdeviceDescCreatedAt is the schema descriptor for created_at field.
|
||||
scaauthuserdeviceDescCreatedAt := scaauthuserdeviceMixinFields0[0].Descriptor()
|
||||
@@ -209,10 +209,10 @@ func init() {
|
||||
scaauthuserdeviceDescEngineVersion := scaauthuserdeviceFields[13].Descriptor()
|
||||
// scaauthuserdevice.EngineVersionValidator is a validator for the "engine_version" field. It is called by the builders before save.
|
||||
scaauthuserdevice.EngineVersionValidator = scaauthuserdeviceDescEngineVersion.Validators[0].(func(string) error)
|
||||
scaauthusersocialMixin := schema.ScaAuthUserSocial{}.Mixin()
|
||||
scaauthusersocialMixin := model.ScaAuthUserSocial{}.Mixin()
|
||||
scaauthusersocialMixinFields0 := scaauthusersocialMixin[0].Fields()
|
||||
_ = scaauthusersocialMixinFields0
|
||||
scaauthusersocialFields := schema.ScaAuthUserSocial{}.Fields()
|
||||
scaauthusersocialFields := model.ScaAuthUserSocial{}.Fields()
|
||||
_ = scaauthusersocialFields
|
||||
// scaauthusersocialDescCreatedAt is the schema descriptor for created_at field.
|
||||
scaauthusersocialDescCreatedAt := scaauthusersocialMixinFields0[0].Descriptor()
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
package runtime
|
||||
|
||||
// The schema-stitching logic is generated in schisandra-album-cloud-microservices/app/main/api/repository/mysql/ent/runtime.go
|
||||
// The schema-stitching logic is generated in schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent/runtime.go
|
||||
|
||||
const (
|
||||
Version = "v0.14.1" // Version of ent codegen.
|
||||
|
@@ -40,9 +40,9 @@ type ScaAuthUserDevice struct {
|
||||
// 浏览器版本
|
||||
BrowserVersion string `json:"browser_version,omitempty"`
|
||||
// 是否为手机 0否1是
|
||||
Mobile int `json:"mobile,omitempty"`
|
||||
Mobile bool `json:"mobile,omitempty"`
|
||||
// 是否为bot 0否1是
|
||||
Bot int `json:"bot,omitempty"`
|
||||
Bot bool `json:"bot,omitempty"`
|
||||
// 火狐版本
|
||||
Mozilla string `json:"mozilla,omitempty"`
|
||||
// 平台
|
||||
@@ -83,7 +83,9 @@ func (*ScaAuthUserDevice) scanValues(columns []string) ([]any, error) {
|
||||
values := make([]any, len(columns))
|
||||
for i := range columns {
|
||||
switch columns[i] {
|
||||
case scaauthuserdevice.FieldID, scaauthuserdevice.FieldDeleted, scaauthuserdevice.FieldMobile, scaauthuserdevice.FieldBot:
|
||||
case scaauthuserdevice.FieldMobile, scaauthuserdevice.FieldBot:
|
||||
values[i] = new(sql.NullBool)
|
||||
case scaauthuserdevice.FieldID, scaauthuserdevice.FieldDeleted:
|
||||
values[i] = new(sql.NullInt64)
|
||||
case scaauthuserdevice.FieldUserID, scaauthuserdevice.FieldIP, scaauthuserdevice.FieldLocation, scaauthuserdevice.FieldAgent, scaauthuserdevice.FieldBrowser, scaauthuserdevice.FieldOperatingSystem, scaauthuserdevice.FieldBrowserVersion, scaauthuserdevice.FieldMozilla, scaauthuserdevice.FieldPlatform, scaauthuserdevice.FieldEngineName, scaauthuserdevice.FieldEngineVersion:
|
||||
values[i] = new(sql.NullString)
|
||||
@@ -173,16 +175,16 @@ func (saud *ScaAuthUserDevice) assignValues(columns []string, values []any) erro
|
||||
saud.BrowserVersion = value.String
|
||||
}
|
||||
case scaauthuserdevice.FieldMobile:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
if value, ok := values[i].(*sql.NullBool); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field mobile", values[i])
|
||||
} else if value.Valid {
|
||||
saud.Mobile = int(value.Int64)
|
||||
saud.Mobile = value.Bool
|
||||
}
|
||||
case scaauthuserdevice.FieldBot:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
if value, ok := values[i].(*sql.NullBool); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field bot", values[i])
|
||||
} else if value.Valid {
|
||||
saud.Bot = int(value.Int64)
|
||||
saud.Bot = value.Bool
|
||||
}
|
||||
case scaauthuserdevice.FieldMozilla:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
|
@@ -106,12 +106,12 @@ func BrowserVersion(v string) predicate.ScaAuthUserDevice {
|
||||
}
|
||||
|
||||
// Mobile applies equality check predicate on the "mobile" field. It's identical to MobileEQ.
|
||||
func Mobile(v int) predicate.ScaAuthUserDevice {
|
||||
func Mobile(v bool) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldEQ(FieldMobile, v))
|
||||
}
|
||||
|
||||
// Bot applies equality check predicate on the "bot" field. It's identical to BotEQ.
|
||||
func Bot(v int) predicate.ScaAuthUserDevice {
|
||||
func Bot(v bool) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldEQ(FieldBot, v))
|
||||
}
|
||||
|
||||
@@ -721,85 +721,25 @@ func BrowserVersionContainsFold(v string) predicate.ScaAuthUserDevice {
|
||||
}
|
||||
|
||||
// MobileEQ applies the EQ predicate on the "mobile" field.
|
||||
func MobileEQ(v int) predicate.ScaAuthUserDevice {
|
||||
func MobileEQ(v bool) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldEQ(FieldMobile, v))
|
||||
}
|
||||
|
||||
// MobileNEQ applies the NEQ predicate on the "mobile" field.
|
||||
func MobileNEQ(v int) predicate.ScaAuthUserDevice {
|
||||
func MobileNEQ(v bool) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldNEQ(FieldMobile, v))
|
||||
}
|
||||
|
||||
// MobileIn applies the In predicate on the "mobile" field.
|
||||
func MobileIn(vs ...int) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldIn(FieldMobile, vs...))
|
||||
}
|
||||
|
||||
// MobileNotIn applies the NotIn predicate on the "mobile" field.
|
||||
func MobileNotIn(vs ...int) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldNotIn(FieldMobile, vs...))
|
||||
}
|
||||
|
||||
// MobileGT applies the GT predicate on the "mobile" field.
|
||||
func MobileGT(v int) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldGT(FieldMobile, v))
|
||||
}
|
||||
|
||||
// MobileGTE applies the GTE predicate on the "mobile" field.
|
||||
func MobileGTE(v int) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldGTE(FieldMobile, v))
|
||||
}
|
||||
|
||||
// MobileLT applies the LT predicate on the "mobile" field.
|
||||
func MobileLT(v int) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldLT(FieldMobile, v))
|
||||
}
|
||||
|
||||
// MobileLTE applies the LTE predicate on the "mobile" field.
|
||||
func MobileLTE(v int) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldLTE(FieldMobile, v))
|
||||
}
|
||||
|
||||
// BotEQ applies the EQ predicate on the "bot" field.
|
||||
func BotEQ(v int) predicate.ScaAuthUserDevice {
|
||||
func BotEQ(v bool) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldEQ(FieldBot, v))
|
||||
}
|
||||
|
||||
// BotNEQ applies the NEQ predicate on the "bot" field.
|
||||
func BotNEQ(v int) predicate.ScaAuthUserDevice {
|
||||
func BotNEQ(v bool) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldNEQ(FieldBot, v))
|
||||
}
|
||||
|
||||
// BotIn applies the In predicate on the "bot" field.
|
||||
func BotIn(vs ...int) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldIn(FieldBot, vs...))
|
||||
}
|
||||
|
||||
// BotNotIn applies the NotIn predicate on the "bot" field.
|
||||
func BotNotIn(vs ...int) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldNotIn(FieldBot, vs...))
|
||||
}
|
||||
|
||||
// BotGT applies the GT predicate on the "bot" field.
|
||||
func BotGT(v int) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldGT(FieldBot, v))
|
||||
}
|
||||
|
||||
// BotGTE applies the GTE predicate on the "bot" field.
|
||||
func BotGTE(v int) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldGTE(FieldBot, v))
|
||||
}
|
||||
|
||||
// BotLT applies the LT predicate on the "bot" field.
|
||||
func BotLT(v int) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldLT(FieldBot, v))
|
||||
}
|
||||
|
||||
// BotLTE applies the LTE predicate on the "bot" field.
|
||||
func BotLTE(v int) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldLTE(FieldBot, v))
|
||||
}
|
||||
|
||||
// MozillaEQ applies the EQ predicate on the "mozilla" field.
|
||||
func MozillaEQ(v string) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldEQ(FieldMozilla, v))
|
||||
|
@@ -106,14 +106,14 @@ func (saudc *ScaAuthUserDeviceCreate) SetBrowserVersion(s string) *ScaAuthUserDe
|
||||
}
|
||||
|
||||
// SetMobile sets the "mobile" field.
|
||||
func (saudc *ScaAuthUserDeviceCreate) SetMobile(i int) *ScaAuthUserDeviceCreate {
|
||||
saudc.mutation.SetMobile(i)
|
||||
func (saudc *ScaAuthUserDeviceCreate) SetMobile(b bool) *ScaAuthUserDeviceCreate {
|
||||
saudc.mutation.SetMobile(b)
|
||||
return saudc
|
||||
}
|
||||
|
||||
// SetBot sets the "bot" field.
|
||||
func (saudc *ScaAuthUserDeviceCreate) SetBot(i int) *ScaAuthUserDeviceCreate {
|
||||
saudc.mutation.SetBot(i)
|
||||
func (saudc *ScaAuthUserDeviceCreate) SetBot(b bool) *ScaAuthUserDeviceCreate {
|
||||
saudc.mutation.SetBot(b)
|
||||
return saudc
|
||||
}
|
||||
|
||||
@@ -395,11 +395,11 @@ func (saudc *ScaAuthUserDeviceCreate) createSpec() (*ScaAuthUserDevice, *sqlgrap
|
||||
_node.BrowserVersion = value
|
||||
}
|
||||
if value, ok := saudc.mutation.Mobile(); ok {
|
||||
_spec.SetField(scaauthuserdevice.FieldMobile, field.TypeInt, value)
|
||||
_spec.SetField(scaauthuserdevice.FieldMobile, field.TypeBool, value)
|
||||
_node.Mobile = value
|
||||
}
|
||||
if value, ok := saudc.mutation.Bot(); ok {
|
||||
_spec.SetField(scaauthuserdevice.FieldBot, field.TypeInt, value)
|
||||
_spec.SetField(scaauthuserdevice.FieldBot, field.TypeBool, value)
|
||||
_node.Bot = value
|
||||
}
|
||||
if value, ok := saudc.mutation.Mozilla(); ok {
|
||||
|
@@ -161,47 +161,33 @@ func (saudu *ScaAuthUserDeviceUpdate) SetNillableBrowserVersion(s *string) *ScaA
|
||||
}
|
||||
|
||||
// SetMobile sets the "mobile" field.
|
||||
func (saudu *ScaAuthUserDeviceUpdate) SetMobile(i int) *ScaAuthUserDeviceUpdate {
|
||||
saudu.mutation.ResetMobile()
|
||||
saudu.mutation.SetMobile(i)
|
||||
func (saudu *ScaAuthUserDeviceUpdate) SetMobile(b bool) *ScaAuthUserDeviceUpdate {
|
||||
saudu.mutation.SetMobile(b)
|
||||
return saudu
|
||||
}
|
||||
|
||||
// SetNillableMobile sets the "mobile" field if the given value is not nil.
|
||||
func (saudu *ScaAuthUserDeviceUpdate) SetNillableMobile(i *int) *ScaAuthUserDeviceUpdate {
|
||||
if i != nil {
|
||||
saudu.SetMobile(*i)
|
||||
func (saudu *ScaAuthUserDeviceUpdate) SetNillableMobile(b *bool) *ScaAuthUserDeviceUpdate {
|
||||
if b != nil {
|
||||
saudu.SetMobile(*b)
|
||||
}
|
||||
return saudu
|
||||
}
|
||||
|
||||
// AddMobile adds i to the "mobile" field.
|
||||
func (saudu *ScaAuthUserDeviceUpdate) AddMobile(i int) *ScaAuthUserDeviceUpdate {
|
||||
saudu.mutation.AddMobile(i)
|
||||
return saudu
|
||||
}
|
||||
|
||||
// SetBot sets the "bot" field.
|
||||
func (saudu *ScaAuthUserDeviceUpdate) SetBot(i int) *ScaAuthUserDeviceUpdate {
|
||||
saudu.mutation.ResetBot()
|
||||
saudu.mutation.SetBot(i)
|
||||
func (saudu *ScaAuthUserDeviceUpdate) SetBot(b bool) *ScaAuthUserDeviceUpdate {
|
||||
saudu.mutation.SetBot(b)
|
||||
return saudu
|
||||
}
|
||||
|
||||
// SetNillableBot sets the "bot" field if the given value is not nil.
|
||||
func (saudu *ScaAuthUserDeviceUpdate) SetNillableBot(i *int) *ScaAuthUserDeviceUpdate {
|
||||
if i != nil {
|
||||
saudu.SetBot(*i)
|
||||
func (saudu *ScaAuthUserDeviceUpdate) SetNillableBot(b *bool) *ScaAuthUserDeviceUpdate {
|
||||
if b != nil {
|
||||
saudu.SetBot(*b)
|
||||
}
|
||||
return saudu
|
||||
}
|
||||
|
||||
// AddBot adds i to the "bot" field.
|
||||
func (saudu *ScaAuthUserDeviceUpdate) AddBot(i int) *ScaAuthUserDeviceUpdate {
|
||||
saudu.mutation.AddBot(i)
|
||||
return saudu
|
||||
}
|
||||
|
||||
// SetMozilla sets the "mozilla" field.
|
||||
func (saudu *ScaAuthUserDeviceUpdate) SetMozilla(s string) *ScaAuthUserDeviceUpdate {
|
||||
saudu.mutation.SetMozilla(s)
|
||||
@@ -435,16 +421,10 @@ func (saudu *ScaAuthUserDeviceUpdate) sqlSave(ctx context.Context) (n int, err e
|
||||
_spec.SetField(scaauthuserdevice.FieldBrowserVersion, field.TypeString, value)
|
||||
}
|
||||
if value, ok := saudu.mutation.Mobile(); ok {
|
||||
_spec.SetField(scaauthuserdevice.FieldMobile, field.TypeInt, value)
|
||||
}
|
||||
if value, ok := saudu.mutation.AddedMobile(); ok {
|
||||
_spec.AddField(scaauthuserdevice.FieldMobile, field.TypeInt, value)
|
||||
_spec.SetField(scaauthuserdevice.FieldMobile, field.TypeBool, value)
|
||||
}
|
||||
if value, ok := saudu.mutation.Bot(); ok {
|
||||
_spec.SetField(scaauthuserdevice.FieldBot, field.TypeInt, value)
|
||||
}
|
||||
if value, ok := saudu.mutation.AddedBot(); ok {
|
||||
_spec.AddField(scaauthuserdevice.FieldBot, field.TypeInt, value)
|
||||
_spec.SetField(scaauthuserdevice.FieldBot, field.TypeBool, value)
|
||||
}
|
||||
if value, ok := saudu.mutation.Mozilla(); ok {
|
||||
_spec.SetField(scaauthuserdevice.FieldMozilla, field.TypeString, value)
|
||||
@@ -639,47 +619,33 @@ func (sauduo *ScaAuthUserDeviceUpdateOne) SetNillableBrowserVersion(s *string) *
|
||||
}
|
||||
|
||||
// SetMobile sets the "mobile" field.
|
||||
func (sauduo *ScaAuthUserDeviceUpdateOne) SetMobile(i int) *ScaAuthUserDeviceUpdateOne {
|
||||
sauduo.mutation.ResetMobile()
|
||||
sauduo.mutation.SetMobile(i)
|
||||
func (sauduo *ScaAuthUserDeviceUpdateOne) SetMobile(b bool) *ScaAuthUserDeviceUpdateOne {
|
||||
sauduo.mutation.SetMobile(b)
|
||||
return sauduo
|
||||
}
|
||||
|
||||
// SetNillableMobile sets the "mobile" field if the given value is not nil.
|
||||
func (sauduo *ScaAuthUserDeviceUpdateOne) SetNillableMobile(i *int) *ScaAuthUserDeviceUpdateOne {
|
||||
if i != nil {
|
||||
sauduo.SetMobile(*i)
|
||||
func (sauduo *ScaAuthUserDeviceUpdateOne) SetNillableMobile(b *bool) *ScaAuthUserDeviceUpdateOne {
|
||||
if b != nil {
|
||||
sauduo.SetMobile(*b)
|
||||
}
|
||||
return sauduo
|
||||
}
|
||||
|
||||
// AddMobile adds i to the "mobile" field.
|
||||
func (sauduo *ScaAuthUserDeviceUpdateOne) AddMobile(i int) *ScaAuthUserDeviceUpdateOne {
|
||||
sauduo.mutation.AddMobile(i)
|
||||
return sauduo
|
||||
}
|
||||
|
||||
// SetBot sets the "bot" field.
|
||||
func (sauduo *ScaAuthUserDeviceUpdateOne) SetBot(i int) *ScaAuthUserDeviceUpdateOne {
|
||||
sauduo.mutation.ResetBot()
|
||||
sauduo.mutation.SetBot(i)
|
||||
func (sauduo *ScaAuthUserDeviceUpdateOne) SetBot(b bool) *ScaAuthUserDeviceUpdateOne {
|
||||
sauduo.mutation.SetBot(b)
|
||||
return sauduo
|
||||
}
|
||||
|
||||
// SetNillableBot sets the "bot" field if the given value is not nil.
|
||||
func (sauduo *ScaAuthUserDeviceUpdateOne) SetNillableBot(i *int) *ScaAuthUserDeviceUpdateOne {
|
||||
if i != nil {
|
||||
sauduo.SetBot(*i)
|
||||
func (sauduo *ScaAuthUserDeviceUpdateOne) SetNillableBot(b *bool) *ScaAuthUserDeviceUpdateOne {
|
||||
if b != nil {
|
||||
sauduo.SetBot(*b)
|
||||
}
|
||||
return sauduo
|
||||
}
|
||||
|
||||
// AddBot adds i to the "bot" field.
|
||||
func (sauduo *ScaAuthUserDeviceUpdateOne) AddBot(i int) *ScaAuthUserDeviceUpdateOne {
|
||||
sauduo.mutation.AddBot(i)
|
||||
return sauduo
|
||||
}
|
||||
|
||||
// SetMozilla sets the "mozilla" field.
|
||||
func (sauduo *ScaAuthUserDeviceUpdateOne) SetMozilla(s string) *ScaAuthUserDeviceUpdateOne {
|
||||
sauduo.mutation.SetMozilla(s)
|
||||
@@ -943,16 +909,10 @@ func (sauduo *ScaAuthUserDeviceUpdateOne) sqlSave(ctx context.Context) (_node *S
|
||||
_spec.SetField(scaauthuserdevice.FieldBrowserVersion, field.TypeString, value)
|
||||
}
|
||||
if value, ok := sauduo.mutation.Mobile(); ok {
|
||||
_spec.SetField(scaauthuserdevice.FieldMobile, field.TypeInt, value)
|
||||
}
|
||||
if value, ok := sauduo.mutation.AddedMobile(); ok {
|
||||
_spec.AddField(scaauthuserdevice.FieldMobile, field.TypeInt, value)
|
||||
_spec.SetField(scaauthuserdevice.FieldMobile, field.TypeBool, value)
|
||||
}
|
||||
if value, ok := sauduo.mutation.Bot(); ok {
|
||||
_spec.SetField(scaauthuserdevice.FieldBot, field.TypeInt, value)
|
||||
}
|
||||
if value, ok := sauduo.mutation.AddedBot(); ok {
|
||||
_spec.AddField(scaauthuserdevice.FieldBot, field.TypeInt, value)
|
||||
_spec.SetField(scaauthuserdevice.FieldBot, field.TypeBool, value)
|
||||
}
|
||||
if value, ok := sauduo.mutation.Mozilla(); ok {
|
||||
_spec.SetField(scaauthuserdevice.FieldMozilla, field.TypeString, value)
|
||||
|
@@ -1,3 +1,3 @@
|
||||
package mysql
|
||||
|
||||
//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate --feature privacy,entql --target ./ent ./schema
|
||||
//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate --feature privacy,entql --target ./ent ./model
|
||||
|
@@ -29,7 +29,7 @@ func NewMySQL(url string) *ent.Client {
|
||||
defer client.Close()
|
||||
|
||||
if err = client.Schema.Create(context.Background()); err != nil {
|
||||
log.Panicf("failed creating schema resources: %v", err)
|
||||
log.Panicf("failed creating model resources: %v", err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
package schema
|
||||
package model
|
||||
|
||||
import (
|
||||
"entgo.io/ent"
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"entgo.io/ent/schema/field"
|
||||
)
|
||||
|
||||
// ScaAuthPermissionRule holds the schema definition for the ScaAuthPermissionRule entity.
|
||||
// ScaAuthPermissionRule holds the model definition for the ScaAuthPermissionRule entity.
|
||||
type ScaAuthPermissionRule struct {
|
||||
ent.Schema
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package schema
|
||||
package model
|
||||
|
||||
import (
|
||||
"entgo.io/ent"
|
||||
@@ -8,10 +8,10 @@ import (
|
||||
"entgo.io/ent/schema/edge"
|
||||
"entgo.io/ent/schema/field"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/schema/mixin"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/model/mixin"
|
||||
)
|
||||
|
||||
// ScaAuthRole holds the schema definition for the ScaAuthRole entity.
|
||||
// ScaAuthRole holds the model definition for the ScaAuthRole entity.
|
||||
type ScaAuthRole struct {
|
||||
ent.Schema
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package schema
|
||||
package model
|
||||
|
||||
import (
|
||||
"entgo.io/ent"
|
||||
@@ -9,10 +9,10 @@ import (
|
||||
"entgo.io/ent/schema/field"
|
||||
"entgo.io/ent/schema/index"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/schema/mixin"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/model/mixin"
|
||||
)
|
||||
|
||||
// ScaAuthUser holds the schema definition for the ScaAuthUser entity.
|
||||
// ScaAuthUser holds the model definition for the ScaAuthUser entity.
|
||||
type ScaAuthUser struct {
|
||||
ent.Schema
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package schema
|
||||
package model
|
||||
|
||||
import (
|
||||
"entgo.io/ent"
|
||||
@@ -9,10 +9,10 @@ import (
|
||||
"entgo.io/ent/schema/field"
|
||||
"entgo.io/ent/schema/index"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/schema/mixin"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/model/mixin"
|
||||
)
|
||||
|
||||
// ScaAuthUserDevice holds the schema definition for the ScaAuthUserDevice entity.
|
||||
// ScaAuthUserDevice holds the model definition for the ScaAuthUserDevice entity.
|
||||
type ScaAuthUserDevice struct {
|
||||
ent.Schema
|
||||
}
|
||||
@@ -53,9 +53,9 @@ func (ScaAuthUserDevice) Fields() []ent.Field {
|
||||
field.String("browser_version").
|
||||
MaxLen(20).
|
||||
Comment("浏览器版本"),
|
||||
field.Int("mobile").
|
||||
field.Bool("mobile").
|
||||
Comment("是否为手机 0否1是"),
|
||||
field.Int("bot").
|
||||
field.Bool("bot").
|
||||
Comment("是否为bot 0否1是"),
|
||||
field.String("mozilla").
|
||||
MaxLen(10).
|
@@ -1,4 +1,4 @@
|
||||
package schema
|
||||
package model
|
||||
|
||||
import (
|
||||
"entgo.io/ent"
|
||||
@@ -9,10 +9,10 @@ import (
|
||||
"entgo.io/ent/schema/field"
|
||||
"entgo.io/ent/schema/index"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/schema/mixin"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/model/mixin"
|
||||
)
|
||||
|
||||
// ScaAuthUserSocial holds the schema definition for the ScaAuthUserSocial entity.
|
||||
// ScaAuthUserSocial holds the model definition for the ScaAuthUserSocial entity.
|
||||
type ScaAuthUserSocial struct {
|
||||
ent.Schema
|
||||
}
|
38
app/core/api/repository/redis_session/init.go
Normal file
38
app/core/api/repository/redis_session/init.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package redis_session
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/gob"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/sessions"
|
||||
"github.com/rbcervilla/redisstore/v9"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"github.com/zeromicro/go-zero/core/logc"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/redis_session/types"
|
||||
)
|
||||
|
||||
func NewRedisSession(addr string, password string) *redisstore.RedisStore {
|
||||
client := redis.NewClient(&redis.Options{
|
||||
Addr: addr,
|
||||
Password: password,
|
||||
DB: 0,
|
||||
})
|
||||
store, err := redisstore.NewRedisStore(context.Background(), client)
|
||||
if err != nil {
|
||||
logc.Error(context.Background(), err)
|
||||
}
|
||||
store.KeyPrefix(constant.UserSessionPrefix)
|
||||
store.Options(sessions.Options{
|
||||
Path: "/",
|
||||
// Domain: global.CONFIG.System.Web,
|
||||
MaxAge: 86400 * 7,
|
||||
HttpOnly: true,
|
||||
Secure: true,
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
})
|
||||
gob.Register(types.SessionData{})
|
||||
return store
|
||||
}
|
7
app/core/api/repository/redis_session/types/session.go
Normal file
7
app/core/api/repository/redis_session/types/session.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package types
|
||||
|
||||
// SessionData 返回数据
|
||||
type SessionData struct {
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
UID string `json:"uid"`
|
||||
}
|
12
app/core/api/repository/redisx/init.go
Normal file
12
app/core/api/repository/redisx/init.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package redisx
|
||||
|
||||
import "github.com/redis/go-redis/v9"
|
||||
|
||||
func NewRedis(host, password string, db int) *redis.Client {
|
||||
rdb := redis.NewClient(&redis.Options{
|
||||
Addr: host,
|
||||
Password: password,
|
||||
DB: db,
|
||||
})
|
||||
return rdb
|
||||
}
|
6
app/core/api/repository/redisx/types/redis_token.go
Normal file
6
app/core/api/repository/redisx/types/redis_token.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package types
|
||||
|
||||
type RedisToken struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
UID string `json:"uid"`
|
||||
}
|
BIN
app/core/api/resources/ip2region/ip2region.xdb
Normal file
BIN
app/core/api/resources/ip2region/ip2region.xdb
Normal file
Binary file not shown.
7
app/core/api/resources/language/active.en.toml
Normal file
7
app/core/api/resources/language/active.en.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[captcha]
|
||||
verificationFailure = "verification failure!"
|
||||
[login]
|
||||
invalidAccount = "invalid account!"
|
||||
notFoundAccount = "account not found!"
|
||||
invalidPassword = "invalid password!"
|
||||
loginFailed = "login failed!"
|
7
app/core/api/resources/language/active.zh.toml
Normal file
7
app/core/api/resources/language/active.zh.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[captcha]
|
||||
verificationFailure = "验证失败!"
|
||||
[login]
|
||||
invalidAccount = "无效的账号!"
|
||||
notFoundAccount = "未找到账号!"
|
||||
invalidPassword = "密码错误!"
|
||||
loginFailed = "登录失败!"
|
48603
app/core/api/resources/sensitive/dict1.txt
Normal file
48603
app/core/api/resources/sensitive/dict1.txt
Normal file
File diff suppressed because it is too large
Load Diff
64454
app/core/api/resources/sensitive/dict2.txt
Normal file
64454
app/core/api/resources/sensitive/dict2.txt
Normal file
File diff suppressed because it is too large
Load Diff
170
app/core/api/resources/sensitive/其他词库.txt
Normal file
170
app/core/api/resources/sensitive/其他词库.txt
Normal file
@@ -0,0 +1,170 @@
|
||||
穴海
|
||||
协警
|
||||
纳米比亚
|
||||
专业调查
|
||||
有华龙
|
||||
jq的来
|
||||
电信路
|
||||
党鞭
|
||||
第一夫人
|
||||
黄巨
|
||||
荡尽天下
|
||||
家元自称玉皇大帝
|
||||
主席李世民
|
||||
何祚庥
|
||||
刘刚
|
||||
不要沉默
|
||||
后勤集团
|
||||
食堂涨价
|
||||
发国难财
|
||||
浪漫邂逅
|
||||
红满堂
|
||||
张小洋
|
||||
炸学校
|
||||
子宫
|
||||
叫晶晶的女孩
|
||||
回派
|
||||
社会黑暗
|
||||
国之母
|
||||
国母
|
||||
国姆
|
||||
东方微点
|
||||
震惊全球
|
||||
nowto
|
||||
chengdu
|
||||
徐明
|
||||
六月飞雪
|
||||
暴力虐待
|
||||
暴力袭击
|
||||
天府广场
|
||||
粮荒
|
||||
洗脑班
|
||||
李愚蠢
|
||||
中国猪
|
||||
台湾猪
|
||||
进化不完全的生命体
|
||||
震死他们
|
||||
|
||||
10010
|
||||
10086
|
||||
10159
|
||||
13423205670
|
||||
13725516608
|
||||
13875448369
|
||||
15112886328
|
||||
189
|
||||
6-4tianwang
|
||||
64
|
||||
68170802
|
||||
6a6.net
|
||||
7.31
|
||||
7.310
|
||||
89-64cdjp
|
||||
8945212
|
||||
23条
|
||||
259o
|
||||
381929279
|
||||
3P
|
||||
4-Jun
|
||||
AV
|
||||
BJ
|
||||
CBD
|
||||
CCTV
|
||||
CDMA
|
||||
DICK
|
||||
Dick
|
||||
FLG
|
||||
FOCUSC
|
||||
FUCK
|
||||
Fuck
|
||||
GAMEMASTER
|
||||
GCD
|
||||
GameMaster
|
||||
IP17908
|
||||
KEY_TEXT
|
||||
NMD
|
||||
QQb
|
||||
SM
|
||||
Soccer01.com
|
||||
TMD
|
||||
UltraSurf
|
||||
bignews
|
||||
Bitch
|
||||
boxun
|
||||
Chinaliberal
|
||||
chinamz
|
||||
Chinesenewsnet
|
||||
cnd
|
||||
Creaders
|
||||
dafa
|
||||
Dajiyuan
|
||||
df'd
|
||||
Dfdz
|
||||
die
|
||||
dpp
|
||||
Freechina
|
||||
freedom
|
||||
Freenet
|
||||
fuck
|
||||
fuck your mother
|
||||
hongzhi
|
||||
hrichina
|
||||
huanet
|
||||
hypermart.net
|
||||
incest
|
||||
jiangdongriji
|
||||
l2590803027
|
||||
lihongzhi
|
||||
ma
|
||||
making
|
||||
minghui
|
||||
minghuinews
|
||||
nacb
|
||||
na?ve
|
||||
nmis
|
||||
paper64
|
||||
peacehall
|
||||
piao
|
||||
playboy
|
||||
renminbao
|
||||
renmingbao
|
||||
rfa
|
||||
safeweb
|
||||
sex
|
||||
shit
|
||||
simple
|
||||
svdc
|
||||
taip
|
||||
tibetalk
|
||||
triangle
|
||||
triangleboy
|
||||
txwq.net
|
||||
unixbox
|
||||
ustibet
|
||||
voa
|
||||
voachinese
|
||||
wangce
|
||||
wstaiji
|
||||
www
|
||||
xinsheng
|
||||
yuming
|
||||
yy通讯录
|
||||
zhengjian
|
||||
zhengjianwang
|
||||
zhenshanren
|
||||
zhuanfalu
|
||||
zhuanfalun
|
||||
八九
|
||||
八老
|
||||
fuck
|
||||
duck
|
||||
shit
|
||||
chicken
|
||||
fowl
|
||||
sex
|
||||
sexy
|
||||
prostitute
|
||||
whore
|
||||
harlot
|
||||
hooker
|
||||
gender
|
557
app/core/api/resources/sensitive/反动词库.txt
Normal file
557
app/core/api/resources/sensitive/反动词库.txt
Normal file
@@ -0,0 +1,557 @@
|
||||
腐败中国
|
||||
三个呆婊
|
||||
你办事我放心
|
||||
社会主义灭亡
|
||||
打倒中国
|
||||
打倒共产党
|
||||
打倒共产主义
|
||||
打倒胡锦涛
|
||||
打倒江泽民
|
||||
打倒江主席
|
||||
打倒李鹏
|
||||
打倒罗干
|
||||
打倒温家宝
|
||||
打倒中共
|
||||
打倒朱镕
|
||||
抵制共产党
|
||||
抵制共产主义
|
||||
抵制胡锦涛
|
||||
抵制江泽民
|
||||
抵制江主席
|
||||
抵制李鹏
|
||||
抵制罗干
|
||||
抵制温家宝
|
||||
抵制中共
|
||||
抵制朱镕基
|
||||
灭亡中国
|
||||
亡党亡国
|
||||
粉碎四人帮
|
||||
激流中国
|
||||
特供
|
||||
特贡
|
||||
特共
|
||||
zf大楼
|
||||
殃视
|
||||
贪污腐败
|
||||
强制拆除
|
||||
形式主义
|
||||
政治风波
|
||||
太子党
|
||||
上海帮
|
||||
北京帮
|
||||
清华帮
|
||||
红色贵族
|
||||
权贵集团
|
||||
河蟹社会
|
||||
喝血社会
|
||||
九风
|
||||
9风
|
||||
十七大
|
||||
十7大
|
||||
17da
|
||||
九学
|
||||
9学
|
||||
四风
|
||||
4风
|
||||
双规
|
||||
南街村
|
||||
最淫官员
|
||||
警匪
|
||||
官匪
|
||||
独夫民贼
|
||||
官商勾结
|
||||
城管暴力执法
|
||||
强制捐款
|
||||
毒豺
|
||||
一党执政
|
||||
一党专制
|
||||
一党专政
|
||||
专制政权
|
||||
宪法法院
|
||||
胡平
|
||||
苏晓康
|
||||
贺卫方
|
||||
谭作人
|
||||
焦国标
|
||||
万润南
|
||||
张志新
|
||||
辛灝年
|
||||
高勤荣
|
||||
王炳章
|
||||
高智晟
|
||||
司马璐
|
||||
刘晓竹
|
||||
刘宾雁
|
||||
魏京生
|
||||
寻找林昭的灵魂
|
||||
别梦成灰
|
||||
谁是新中国
|
||||
讨伐中宣部
|
||||
异议人士
|
||||
民运人士
|
||||
启蒙派
|
||||
选国家主席
|
||||
民一主
|
||||
min主
|
||||
民竹
|
||||
民珠
|
||||
民猪
|
||||
chinesedemocracy
|
||||
大赦国际
|
||||
国际特赦
|
||||
da选
|
||||
投公
|
||||
公头
|
||||
宪政
|
||||
平反
|
||||
党章
|
||||
维权
|
||||
昝爱宗
|
||||
宪章
|
||||
08宪
|
||||
08xz
|
||||
抿主
|
||||
敏主
|
||||
人拳
|
||||
人木又
|
||||
人quan
|
||||
renquan
|
||||
中国人权
|
||||
中国新民党
|
||||
群体事件
|
||||
群体性事件
|
||||
上中央
|
||||
去中央
|
||||
讨说法
|
||||
请愿
|
||||
请命
|
||||
公开信
|
||||
联名上书
|
||||
万人大签名
|
||||
万人骚动
|
||||
截访
|
||||
上访
|
||||
shangfang
|
||||
信访
|
||||
访民
|
||||
集合
|
||||
集会
|
||||
组织集体
|
||||
静坐
|
||||
静zuo
|
||||
jing坐
|
||||
示威
|
||||
示wei
|
||||
游行
|
||||
you行
|
||||
油行
|
||||
游xing
|
||||
youxing
|
||||
官逼民反
|
||||
反party
|
||||
反共
|
||||
抗议
|
||||
亢议
|
||||
抵制
|
||||
低制
|
||||
底制
|
||||
di制
|
||||
抵zhi
|
||||
dizhi
|
||||
boycott
|
||||
血书
|
||||
焚烧中国国旗
|
||||
baoluan
|
||||
流血冲突
|
||||
出现暴动
|
||||
发生暴动
|
||||
引起暴动
|
||||
baodong
|
||||
灭共
|
||||
杀毙
|
||||
罢工
|
||||
霸工
|
||||
罢考
|
||||
罢餐
|
||||
霸餐
|
||||
罢参
|
||||
罢饭
|
||||
罢吃
|
||||
罢食
|
||||
罢课
|
||||
罢ke
|
||||
霸课
|
||||
ba课
|
||||
罢教
|
||||
罢学
|
||||
罢运
|
||||
网特
|
||||
网评员
|
||||
网络评论员
|
||||
五毛党
|
||||
五毛们
|
||||
5毛党
|
||||
戒严
|
||||
jieyan
|
||||
jie严
|
||||
戒yan
|
||||
8的平方事件
|
||||
知道64
|
||||
八九年
|
||||
贰拾年
|
||||
2o年
|
||||
20和谐年
|
||||
贰拾周年
|
||||
六四
|
||||
六河蟹四
|
||||
六百度四
|
||||
六和谐四
|
||||
陆四
|
||||
陆肆
|
||||
198964
|
||||
5月35
|
||||
89年春夏之交
|
||||
64惨案
|
||||
64时期
|
||||
64运动
|
||||
4事件
|
||||
四事件
|
||||
北京风波
|
||||
学潮
|
||||
学chao
|
||||
xuechao
|
||||
学百度潮
|
||||
门安天
|
||||
天按门
|
||||
坦克压大学生
|
||||
民主女神
|
||||
历史的伤口
|
||||
高自联
|
||||
北高联
|
||||
血洗京城
|
||||
四二六社论
|
||||
王丹
|
||||
柴玲
|
||||
沈彤
|
||||
封从德
|
||||
王超华
|
||||
王维林
|
||||
吾尔开希
|
||||
吾尔开西
|
||||
侯德健
|
||||
阎明复
|
||||
方励之
|
||||
蒋捷连
|
||||
丁子霖
|
||||
辛灏年
|
||||
蒋彦永
|
||||
严家其
|
||||
陈一咨
|
||||
中华局域网
|
||||
党的喉舌
|
||||
互联网审查
|
||||
当局严密封锁
|
||||
新闻封锁
|
||||
封锁消息
|
||||
爱国者同盟
|
||||
关闭所有论坛
|
||||
网络封锁
|
||||
金盾工程
|
||||
gfw
|
||||
无界浏览
|
||||
无界网络
|
||||
自由门
|
||||
何清涟
|
||||
中国的陷阱
|
||||
汪兆钧
|
||||
记者无疆界
|
||||
境外媒体
|
||||
维基百科
|
||||
纽约时报
|
||||
bbc中文网
|
||||
华盛顿邮报
|
||||
世界日报
|
||||
东森新闻网
|
||||
东森电视
|
||||
星岛日报
|
||||
wikipedia
|
||||
youtube
|
||||
googleblogger
|
||||
美国广播公司
|
||||
英国金融时报
|
||||
自由亚洲
|
||||
自由时报
|
||||
中国时报
|
||||
反分裂
|
||||
威胁论
|
||||
左翼联盟
|
||||
钓鱼岛
|
||||
保钓组织
|
||||
主权
|
||||
弓单
|
||||
火乍
|
||||
木仓
|
||||
石肖
|
||||
核蛋
|
||||
步qiang
|
||||
bao炸
|
||||
爆zha
|
||||
baozha
|
||||
zha药
|
||||
zha弹
|
||||
炸dan
|
||||
炸yao
|
||||
zhadan
|
||||
zhayao
|
||||
hmtd
|
||||
三硝基甲苯
|
||||
六氟化铀
|
||||
炸药配方
|
||||
弹药配方
|
||||
炸弹配方
|
||||
皮箱炸弹
|
||||
火药配方
|
||||
人体炸弹
|
||||
人肉炸弹
|
||||
解放军
|
||||
兵力部署
|
||||
军转
|
||||
军事社
|
||||
8341部队
|
||||
第21集团军
|
||||
七大军区
|
||||
7大军区
|
||||
北京军区
|
||||
沈阳军区
|
||||
济南军区
|
||||
成都军区
|
||||
广州军区
|
||||
南京军区
|
||||
兰州军区
|
||||
颜色革命
|
||||
规模冲突
|
||||
塔利班
|
||||
基地组织
|
||||
恐怖分子
|
||||
恐怖份子
|
||||
三股势力
|
||||
印尼屠华
|
||||
印尼事件
|
||||
蒋公纪念歌
|
||||
马英九
|
||||
mayingjiu
|
||||
李天羽
|
||||
苏贞昌
|
||||
林文漪
|
||||
陈水扁
|
||||
陈s扁
|
||||
陈随便
|
||||
阿扁
|
||||
a扁
|
||||
告全国同胞书
|
||||
台百度湾
|
||||
台完
|
||||
台wan
|
||||
taiwan
|
||||
台弯
|
||||
湾台
|
||||
台湾国
|
||||
台湾共和国
|
||||
台军
|
||||
台独
|
||||
台毒
|
||||
台du
|
||||
taidu
|
||||
twdl
|
||||
一中一台
|
||||
打台湾
|
||||
两岸战争
|
||||
攻占台湾
|
||||
支持台湾
|
||||
进攻台湾
|
||||
占领台湾
|
||||
统一台湾
|
||||
收复台湾
|
||||
登陆台湾
|
||||
解放台湾
|
||||
解放tw
|
||||
解决台湾
|
||||
光复民国
|
||||
台湾独立
|
||||
台湾问题
|
||||
台海问题
|
||||
台海危机
|
||||
台海统一
|
||||
台海大战
|
||||
台海战争
|
||||
台海局势
|
||||
入联
|
||||
入耳关
|
||||
中华联邦
|
||||
国民党
|
||||
x民党
|
||||
民进党
|
||||
青天白日
|
||||
闹独立
|
||||
duli
|
||||
fenlie
|
||||
日本万岁
|
||||
小泽一郎
|
||||
劣等民族
|
||||
汉人
|
||||
汉维
|
||||
维汉
|
||||
维吾
|
||||
吾尔
|
||||
热比娅
|
||||
伊力哈木
|
||||
疆独
|
||||
东突厥斯坦解放组织
|
||||
东突解放组织
|
||||
蒙古分裂分子
|
||||
列确
|
||||
阿旺晋美
|
||||
藏人
|
||||
臧人
|
||||
zang人
|
||||
藏民
|
||||
藏m
|
||||
达赖
|
||||
赖达
|
||||
dalai
|
||||
哒赖
|
||||
dl喇嘛
|
||||
丹增嘉措
|
||||
打砸抢
|
||||
西独
|
||||
藏独
|
||||
葬独
|
||||
臧独
|
||||
藏毒
|
||||
藏du
|
||||
zangdu
|
||||
支持zd
|
||||
藏暴乱
|
||||
藏青会
|
||||
雪山狮子旗
|
||||
拉萨
|
||||
啦萨
|
||||
啦沙
|
||||
啦撒
|
||||
拉sa
|
||||
lasa
|
||||
la萨
|
||||
西藏
|
||||
藏西
|
||||
藏春阁
|
||||
藏獨
|
||||
藏独
|
||||
藏独立
|
||||
藏妇会
|
||||
藏青会
|
||||
藏字石
|
||||
xizang
|
||||
xi藏
|
||||
x藏
|
||||
西z
|
||||
tibet
|
||||
希葬
|
||||
希藏
|
||||
硒藏
|
||||
稀藏
|
||||
西脏
|
||||
西奘
|
||||
西葬
|
||||
西臧
|
||||
援藏
|
||||
bjork
|
||||
王千源
|
||||
安拉
|
||||
回教
|
||||
回族
|
||||
回回
|
||||
回民
|
||||
穆斯林
|
||||
穆罕穆德
|
||||
穆罕默德
|
||||
默罕默德
|
||||
伊斯兰
|
||||
圣战组织
|
||||
清真
|
||||
清zhen
|
||||
qingzhen
|
||||
真主
|
||||
阿拉伯
|
||||
高丽棒子
|
||||
韩国狗
|
||||
满洲第三帝国
|
||||
满狗
|
||||
鞑子
|
||||
江丑闻
|
||||
江嫡系
|
||||
江毒
|
||||
江独裁
|
||||
江蛤蟆
|
||||
江核心
|
||||
江黑心
|
||||
江胡内斗
|
||||
江祸心
|
||||
江家帮
|
||||
江绵恒
|
||||
江派和胡派
|
||||
江派人马
|
||||
江泉集团
|
||||
江人马
|
||||
江三条腿
|
||||
江氏集团
|
||||
江氏家族
|
||||
江氏政治局
|
||||
江氏政治委员
|
||||
江梳头
|
||||
江太上
|
||||
江戏子
|
||||
江系人
|
||||
江系人马
|
||||
江宰民
|
||||
江贼
|
||||
江贼民
|
||||
江主席
|
||||
麻果丸
|
||||
麻将透
|
||||
麻醉弹
|
||||
麻醉狗
|
||||
麻醉枪
|
||||
麻醉槍
|
||||
麻醉药
|
||||
麻醉藥
|
||||
台独
|
||||
台湾版假币
|
||||
台湾独立
|
||||
台湾国
|
||||
台湾应该独立
|
||||
台湾有权独立
|
||||
天灭中共
|
||||
中共帮凶
|
||||
中共保命
|
||||
中共裁
|
||||
中共党文化
|
||||
中共腐败
|
||||
中共的血旗
|
||||
中共的罪恶
|
||||
中共帝国
|
||||
中共独裁
|
||||
中共封锁
|
||||
中共封网
|
||||
中共腐败
|
||||
中共黑
|
||||
中共黑帮
|
||||
中共解体
|
||||
中共近期权力斗争
|
||||
中共恐惧
|
||||
中共权力斗争
|
||||
中共任用
|
||||
中共退党
|
||||
中共洗脑
|
||||
中共邪教
|
||||
中共政治游戏
|
||||
中共邪毒素
|
178
app/core/api/resources/sensitive/暴恐词库.txt
Normal file
178
app/core/api/resources/sensitive/暴恐词库.txt
Normal file
@@ -0,0 +1,178 @@
|
||||
福音会
|
||||
中国教徒
|
||||
统一教
|
||||
观音法门
|
||||
清海无上师
|
||||
盘古
|
||||
李洪志
|
||||
志洪李
|
||||
李宏志
|
||||
轮功
|
||||
法轮
|
||||
轮法功
|
||||
三去车仑
|
||||
氵去车仑
|
||||
发论工
|
||||
法x功
|
||||
法o功
|
||||
法0功
|
||||
法一轮一功
|
||||
轮子功
|
||||
车仑工力
|
||||
法lun
|
||||
fa轮
|
||||
法lg
|
||||
flg
|
||||
fl功
|
||||
falungong
|
||||
大法弟子
|
||||
大纪元
|
||||
dajiyuan
|
||||
明慧网
|
||||
明慧周报
|
||||
正见网
|
||||
新唐人
|
||||
伪火
|
||||
退党
|
||||
tuidang
|
||||
退dang
|
||||
超越红墙
|
||||
自fen
|
||||
真善忍
|
||||
九评
|
||||
9评
|
||||
9ping
|
||||
九ping
|
||||
jiuping
|
||||
藏字石
|
||||
集体自杀
|
||||
自sha
|
||||
zi杀
|
||||
suicide
|
||||
titor
|
||||
逢8必灾
|
||||
逢八必灾
|
||||
逢9必乱
|
||||
逢九必乱
|
||||
朱瑟里诺
|
||||
根达亚文明
|
||||
诺查丹玛斯
|
||||
人类灭亡进程表
|
||||
按照马雅历法
|
||||
推背图
|
||||
推bei图
|
||||
济世灵文
|
||||
诸世纪
|
||||
电狗
|
||||
电话定位器
|
||||
电话拦截器
|
||||
电话窃听
|
||||
电话监
|
||||
电话交友
|
||||
电话追杀系统
|
||||
电击枪
|
||||
电鸡
|
||||
电警棒
|
||||
枪出售
|
||||
枪的制
|
||||
枪货到
|
||||
枪决女犯
|
||||
枪模
|
||||
枪手
|
||||
枪销售
|
||||
枪械制
|
||||
枪子弹
|
||||
售步枪
|
||||
售纯度
|
||||
售单管
|
||||
售弹簧刀
|
||||
售防身
|
||||
售狗子
|
||||
售虎头
|
||||
售火药
|
||||
售假币
|
||||
售健卫
|
||||
售军用
|
||||
售猎枪
|
||||
售氯胺
|
||||
售麻醉
|
||||
售枪支
|
||||
售热武
|
||||
售三棱
|
||||
售手枪
|
||||
售五四
|
||||
售一元硬
|
||||
售子弹
|
||||
售左轮
|
||||
亚砷(酸)酐
|
||||
亚砷酸钾
|
||||
亚砷酸钠
|
||||
亚硒酸
|
||||
亚硒酸二钠
|
||||
亚硒酸镁
|
||||
亚硒酸钠
|
||||
亚硒酸氢钠
|
||||
亚硝酸乙酯
|
||||
亚硝酰乙氧
|
||||
氧化二丁基锡
|
||||
氧化汞
|
||||
氧化铊
|
||||
氧化亚铊
|
||||
氧氯化磷
|
||||
原装弹
|
||||
原子弹方法
|
||||
原子弹清单
|
||||
安眠酮
|
||||
代血浆
|
||||
普萘洛尔
|
||||
呋塞米
|
||||
西布曲明
|
||||
testosterone
|
||||
胰岛素样生长因子
|
||||
促红细胞生成素
|
||||
地西泮
|
||||
尼可刹米
|
||||
甲睾酮
|
||||
adrenaline
|
||||
erythropoietin
|
||||
地奈德
|
||||
莫达非尼
|
||||
氯噻嗪
|
||||
苯巴比妥
|
||||
促性腺激素
|
||||
泼尼松
|
||||
麻黄草
|
||||
雄烯二醇
|
||||
地塞米松
|
||||
tamoxifen
|
||||
strychnine
|
||||
androst
|
||||
新型毒品
|
||||
杜冷丁
|
||||
兴奋剂
|
||||
mdma
|
||||
海洛因
|
||||
海luo因
|
||||
heroin
|
||||
diamorphine
|
||||
diacetylmorphine
|
||||
鸦片
|
||||
阿芙蓉
|
||||
咖啡因
|
||||
cocain
|
||||
三唑仑
|
||||
美沙酮
|
||||
麻古
|
||||
k粉
|
||||
凯他敏
|
||||
ketamine
|
||||
冰毒
|
||||
苯丙胺
|
||||
cannabis
|
||||
大麻
|
||||
爱他死
|
||||
氯胺酮
|
||||
benzodiazepines
|
||||
甲基安非他明
|
||||
吗啡
|
||||
安非他命
|
571
app/core/api/resources/sensitive/民生词库.txt
Normal file
571
app/core/api/resources/sensitive/民生词库.txt
Normal file
@@ -0,0 +1,571 @@
|
||||
打人
|
||||
打人
|
||||
拆迁
|
||||
拆迁
|
||||
纠纷
|
||||
纠纷
|
||||
盗窃
|
||||
盗窃
|
||||
安眠酮
|
||||
代药物毒品类:血浆
|
||||
普萘洛尔
|
||||
呋塞米
|
||||
西布曲明
|
||||
testosterone
|
||||
胰岛素样生长因子
|
||||
促红细胞生成素
|
||||
地西泮
|
||||
尼可刹米
|
||||
甲睾酮
|
||||
adrenaline
|
||||
erythropoietin
|
||||
地奈德
|
||||
莫达非尼
|
||||
氯噻嗪
|
||||
苯巴比妥
|
||||
促性腺激素
|
||||
泼尼松
|
||||
麻黄草
|
||||
雄烯二醇
|
||||
地塞米松
|
||||
tamoxifen
|
||||
strychnine
|
||||
androst
|
||||
新型毒品
|
||||
杜冷丁
|
||||
兴奋剂
|
||||
mdma
|
||||
海洛因
|
||||
海luo因
|
||||
heroin
|
||||
diamorphine
|
||||
diacetylmorphine
|
||||
鸦片
|
||||
阿芙蓉
|
||||
咖啡因
|
||||
cocain
|
||||
三唑仑
|
||||
美沙酮
|
||||
麻古
|
||||
k粉
|
||||
凯他敏
|
||||
ketamine
|
||||
冰毒
|
||||
苯丙胺
|
||||
cannabis
|
||||
大麻
|
||||
爱他死
|
||||
氯胺酮
|
||||
benzodiazepines
|
||||
甲基安非他明
|
||||
安非他命
|
||||
吗啡
|
||||
morphine
|
||||
摇头丸
|
||||
迷药
|
||||
乖乖粉
|
||||
narcotic
|
||||
麻醉药
|
||||
精神药品
|
||||
专业代理
|
||||
帮忙点一下
|
||||
帮忙点下
|
||||
请点击进入
|
||||
详情请进入
|
||||
私人侦探
|
||||
私家侦探
|
||||
针孔摄象
|
||||
调查婚外情
|
||||
信用卡提现
|
||||
无抵押贷款
|
||||
广告代理
|
||||
原音铃声
|
||||
借腹生子
|
||||
找个妈妈
|
||||
找个爸爸
|
||||
代孕妈妈
|
||||
代生孩子
|
||||
代开发票
|
||||
腾讯客服电话
|
||||
销售热线
|
||||
免费订购热线
|
||||
低价出售
|
||||
款到发货
|
||||
回复可见
|
||||
连锁加盟
|
||||
加盟连锁
|
||||
免费二级域名
|
||||
免费使用
|
||||
免费索取
|
||||
蚁力神
|
||||
婴儿汤
|
||||
售肾
|
||||
刻章办
|
||||
买小车
|
||||
套牌车
|
||||
玛雅网
|
||||
电脑传讯
|
||||
视频来源
|
||||
下载速度
|
||||
高清在线
|
||||
全集在线
|
||||
在线播放
|
||||
txt下载
|
||||
六位qq
|
||||
6位qq
|
||||
位的qq
|
||||
个qb
|
||||
送qb
|
||||
用刀横向切腹
|
||||
完全自杀手册
|
||||
四海帮
|
||||
足球投注
|
||||
地下钱庄
|
||||
中国复兴党
|
||||
阿波罗网
|
||||
曾道人
|
||||
六合彩
|
||||
改卷内幕
|
||||
替考试
|
||||
隐形耳机
|
||||
出售答案
|
||||
考中答案
|
||||
答an
|
||||
da案
|
||||
资金周转
|
||||
救市
|
||||
股市圈钱
|
||||
崩盘
|
||||
资金短缺
|
||||
证监会
|
||||
质押贷款
|
||||
小额贷款
|
||||
周小川
|
||||
刘明康
|
||||
尚福林
|
||||
孔丹
|
||||
汉芯造假
|
||||
杨树宽
|
||||
中印边界谈判结果
|
||||
喂奶门
|
||||
摸nai门
|
||||
酒瓶门
|
||||
脱裤门
|
||||
75事件
|
||||
乌鲁木齐
|
||||
新疆骚乱
|
||||
针刺
|
||||
打针
|
||||
食堂涨价
|
||||
饭菜涨价
|
||||
h1n1
|
||||
瘟疫爆发
|
||||
yangjia
|
||||
y佳
|
||||
yang佳
|
||||
杨佳
|
||||
杨j
|
||||
袭警
|
||||
杀警
|
||||
武侯祠
|
||||
川b26931
|
||||
贺立旗
|
||||
周正毅
|
||||
px项目
|
||||
骂四川
|
||||
家l福
|
||||
家le福
|
||||
加了服
|
||||
麦当劳被砸
|
||||
豆腐渣
|
||||
这不是天灾
|
||||
龙小霞
|
||||
震其国土
|
||||
yuce
|
||||
提前预测
|
||||
地震预测
|
||||
隐瞒地震
|
||||
李四光预测
|
||||
蟾蜍迁徙
|
||||
地震来得更猛烈
|
||||
八级地震毫无预报
|
||||
踩踏事故
|
||||
聂树斌
|
||||
万里大造林
|
||||
陈相贵
|
||||
张丹红
|
||||
尹方明
|
||||
李树菲
|
||||
王奉友
|
||||
零八奥运艰
|
||||
惨奥
|
||||
奥晕
|
||||
凹晕
|
||||
懊运
|
||||
懊孕
|
||||
奥孕
|
||||
奥你妈的运
|
||||
反奥
|
||||
628事件
|
||||
weng安
|
||||
wengan
|
||||
翁安
|
||||
瓮安事件
|
||||
化工厂爆炸
|
||||
讨回工资
|
||||
代办发票
|
||||
代办各
|
||||
代办文
|
||||
代办学
|
||||
代办制
|
||||
代辦
|
||||
代表烦
|
||||
代开发票
|
||||
代開
|
||||
代考
|
||||
代理发票
|
||||
代理票据
|
||||
代您考
|
||||
代讨债
|
||||
代写毕
|
||||
代写论文
|
||||
代孕
|
||||
代追债
|
||||
考后付款
|
||||
考机构
|
||||
考考邓
|
||||
考联盟
|
||||
考前答案
|
||||
考前付
|
||||
考前密卷
|
||||
考前预测
|
||||
考试,答案
|
||||
考试,作弊器
|
||||
考试包过
|
||||
考试保
|
||||
考试答案
|
||||
考试机构
|
||||
考试联盟
|
||||
考试枪
|
||||
考试作弊
|
||||
考试作弊器
|
||||
考研考中
|
||||
考中答案
|
||||
透视功能
|
||||
透视镜
|
||||
透视扑
|
||||
透视器
|
||||
透视眼睛
|
||||
透视眼镜
|
||||
透视药
|
||||
透视仪
|
||||
打死经过
|
||||
打死人
|
||||
打砸办公
|
||||
打砸抢
|
||||
安眠酮
|
||||
代血浆
|
||||
普萘洛尔
|
||||
呋塞米
|
||||
西布曲明
|
||||
testosterone
|
||||
胰岛素样生长因子
|
||||
促红细胞生成素
|
||||
地西泮
|
||||
尼可刹米
|
||||
甲睾酮
|
||||
adrenaline
|
||||
erythropoietin
|
||||
地奈德
|
||||
莫达非尼
|
||||
氯噻嗪
|
||||
苯巴比妥
|
||||
促性腺激素
|
||||
泼尼松
|
||||
麻黄草
|
||||
雄烯二醇
|
||||
地塞米松
|
||||
tamoxifen
|
||||
strychnine
|
||||
androst
|
||||
新型毒品
|
||||
杜冷丁
|
||||
兴奋剂
|
||||
mdma
|
||||
海洛因
|
||||
海luo因
|
||||
heroin
|
||||
diamorphine
|
||||
diacetylmorphine
|
||||
鸦片
|
||||
阿芙蓉
|
||||
咖啡因
|
||||
cocain
|
||||
三唑仑
|
||||
美沙酮
|
||||
麻古
|
||||
k粉
|
||||
凯他敏
|
||||
ketamine
|
||||
冰毒
|
||||
苯丙胺
|
||||
cannabis
|
||||
大麻
|
||||
爱他死
|
||||
氯胺酮
|
||||
benzodiazepines
|
||||
甲基安非他明
|
||||
安非他命
|
||||
吗啡
|
||||
KC短信
|
||||
KC嘉年华
|
||||
短信广告
|
||||
短信群发
|
||||
短信群发器
|
||||
小6灵通
|
||||
短信商务广告
|
||||
段录定
|
||||
无界浏览
|
||||
无界浏览器
|
||||
无界
|
||||
无网界
|
||||
无网界浏览
|
||||
无帮国
|
||||
KC提示
|
||||
KC网站
|
||||
UP8新势力
|
||||
白皮书
|
||||
UP新势力
|
||||
移民
|
||||
易达网络卡
|
||||
安魂网
|
||||
罢工
|
||||
罢课
|
||||
纽崔莱七折
|
||||
手机复制
|
||||
手机铃声
|
||||
网关
|
||||
神通加持法
|
||||
全1球通
|
||||
如6意通
|
||||
清仓
|
||||
灵动卡
|
||||
答案卫星接收机
|
||||
高薪养廉
|
||||
考后付款
|
||||
佳静安定片
|
||||
航空母舰
|
||||
航空售票
|
||||
号码百事通
|
||||
考前发放
|
||||
成本价
|
||||
诚信通手机商城
|
||||
高利贷
|
||||
联4通
|
||||
黑庄
|
||||
黑手党
|
||||
黑车
|
||||
联通贵宾卡
|
||||
联总
|
||||
联总这声传单
|
||||
联总之声传单
|
||||
高息贷款
|
||||
高干子弟
|
||||
恭喜你的号码
|
||||
恭喜您的号码
|
||||
高干子女
|
||||
各个银行全称
|
||||
各种发票
|
||||
高官
|
||||
高官互调
|
||||
高官子女
|
||||
喝一送一
|
||||
卡号
|
||||
复制
|
||||
监听王
|
||||
传单
|
||||
旦科
|
||||
钓鱼岛
|
||||
钓鱼台
|
||||
当官靠后台
|
||||
党校安插亲信
|
||||
传九促三
|
||||
客户端非法字符
|
||||
刻章
|
||||
大麻树脂
|
||||
大麻油
|
||||
大法
|
||||
大法弟子
|
||||
dpp大法
|
||||
fa lun
|
||||
falu
|
||||
发抡
|
||||
发抡功
|
||||
洗脑
|
||||
下法轮
|
||||
发轮
|
||||
发伦
|
||||
发伦功
|
||||
发仑
|
||||
发沦
|
||||
发纶
|
||||
发论
|
||||
发论功
|
||||
发论公
|
||||
发正念
|
||||
发囵
|
||||
发愣
|
||||
发瞟
|
||||
罚抡
|
||||
罚伦
|
||||
罚仑
|
||||
罚沦
|
||||
罚纶
|
||||
罚囵
|
||||
筏抡
|
||||
筏轮
|
||||
筏伦
|
||||
筏仑
|
||||
筏沦
|
||||
筏纶
|
||||
筏论
|
||||
筏囵
|
||||
伐抡
|
||||
伐轮
|
||||
伐伦
|
||||
伐仑
|
||||
伐沦
|
||||
伐论
|
||||
伐囵
|
||||
乏抡
|
||||
乏轮
|
||||
乏伦
|
||||
乏仑
|
||||
乏沦
|
||||
乏纶
|
||||
乏论
|
||||
乏囵
|
||||
阀抡
|
||||
阀伦
|
||||
阀仑
|
||||
阀沦
|
||||
阀纶
|
||||
阀论
|
||||
阀囵
|
||||
法 轮 功
|
||||
法*功
|
||||
法.轮.功
|
||||
法L功
|
||||
法lun功
|
||||
法功
|
||||
法会
|
||||
法抡
|
||||
法抡功
|
||||
法轮
|
||||
法轮大法
|
||||
法轮佛法
|
||||
法轮功
|
||||
法伦
|
||||
法仑
|
||||
法沦
|
||||
法纶
|
||||
法论
|
||||
法十轮十功
|
||||
法西斯
|
||||
法院
|
||||
法正
|
||||
法谪
|
||||
法谪功
|
||||
法輪
|
||||
法囵
|
||||
法愣
|
||||
珐.輪功
|
||||
珐抡
|
||||
珐轮
|
||||
珐伦
|
||||
珐仑
|
||||
珐沦
|
||||
五不
|
||||
五不争鸣论坛
|
||||
五出三进
|
||||
五套功法
|
||||
邝锦文
|
||||
垡抡
|
||||
垡轮
|
||||
垡伦
|
||||
垡仑
|
||||
垡沦
|
||||
垡纶
|
||||
垡论
|
||||
垡囵
|
||||
茳澤民
|
||||
荭志
|
||||
闳志
|
||||
闵维方
|
||||
氵去
|
||||
氵去车仑工力
|
||||
转法轮
|
||||
砝抡
|
||||
砝轮
|
||||
砝伦
|
||||
砝仑
|
||||
砝沦
|
||||
砝纶
|
||||
真、善、忍
|
||||
真理教
|
||||
真善美
|
||||
真善忍
|
||||
砝论
|
||||
砝囵
|
||||
泓志
|
||||
屙民
|
||||
珐纶
|
||||
珐论
|
||||
珐囵
|
||||
falun
|
||||
Falundafa
|
||||
fa轮
|
||||
Flg
|
||||
弟子
|
||||
地下教会
|
||||
炼功
|
||||
梦网洪志
|
||||
轮大
|
||||
抡功
|
||||
轮功
|
||||
伦功
|
||||
摩门教
|
||||
三水法轮
|
||||
三唑仑
|
||||
天皇
|
||||
天怒
|
||||
天葬
|
||||
车臣
|
||||
达赖
|
||||
功法
|
||||
讲法
|
||||
基督
|
||||
基督教
|
||||
护法
|
||||
回教
|
||||
教徒
|
||||
功友
|
||||
大师
|
||||
达赖喇嘛
|
||||
虹志
|
||||
鸿志
|
||||
洪传
|
||||
贯通两极法
|
||||
光祖
|
||||
洪吟
|
||||
洪哲胜
|
||||
洪志
|
||||
宏法
|
||||
观世音
|
||||
宏志
|
||||
弘志
|
||||
古兰经
|
||||
红志
|
||||
车库
|
||||
经文
|
||||
车仑
|
929
app/core/api/resources/sensitive/色情词库.txt
Normal file
929
app/core/api/resources/sensitive/色情词库.txt
Normal file
@@ -0,0 +1,929 @@
|
||||
爱女人
|
||||
爱液
|
||||
按摩棒
|
||||
拔出来
|
||||
爆草
|
||||
包二奶
|
||||
暴干
|
||||
暴奸
|
||||
暴乳
|
||||
爆乳
|
||||
暴淫
|
||||
屄
|
||||
被插
|
||||
被操
|
||||
被干
|
||||
逼奸
|
||||
仓井空
|
||||
插暴
|
||||
操逼
|
||||
操黑
|
||||
操烂
|
||||
肏你
|
||||
肏死
|
||||
操死
|
||||
操我
|
||||
厕奴
|
||||
插比
|
||||
插b
|
||||
插逼
|
||||
插进
|
||||
插你
|
||||
插我
|
||||
插阴
|
||||
潮吹
|
||||
潮喷
|
||||
成人dv
|
||||
成人电影
|
||||
成人论坛
|
||||
成人小说
|
||||
成人电
|
||||
成人电影
|
||||
成人卡通
|
||||
成人聊
|
||||
成人片
|
||||
成人视
|
||||
成人图
|
||||
成人文
|
||||
成人小
|
||||
成人电影
|
||||
成人论坛
|
||||
成人色情
|
||||
成人网站
|
||||
成人文学
|
||||
成人小说
|
||||
艳情小说
|
||||
成人游戏
|
||||
吃精
|
||||
赤裸
|
||||
抽插
|
||||
扌由插
|
||||
抽一插
|
||||
春药
|
||||
大波
|
||||
大力抽送
|
||||
大乳
|
||||
荡妇
|
||||
荡女
|
||||
盗撮
|
||||
多人轮
|
||||
发浪
|
||||
放尿
|
||||
肥逼
|
||||
粉穴
|
||||
封面女郎
|
||||
风月大陆
|
||||
干死你
|
||||
干穴
|
||||
肛交
|
||||
肛门
|
||||
龟头
|
||||
裹本
|
||||
国产av
|
||||
好嫩
|
||||
豪乳
|
||||
黑逼
|
||||
后庭
|
||||
后穴
|
||||
虎骑
|
||||
花花公子
|
||||
换妻俱乐部
|
||||
黄片
|
||||
几吧
|
||||
鸡吧
|
||||
鸡巴
|
||||
鸡奸
|
||||
寂寞男
|
||||
寂寞女
|
||||
妓女
|
||||
激情
|
||||
集体淫
|
||||
奸情
|
||||
叫床
|
||||
脚交
|
||||
金鳞岂是池中物
|
||||
金麟岂是池中物
|
||||
精液
|
||||
就去日
|
||||
巨屌
|
||||
菊花洞
|
||||
菊门
|
||||
巨奶
|
||||
巨乳
|
||||
菊穴
|
||||
开苞
|
||||
口爆
|
||||
口活
|
||||
口交
|
||||
口射
|
||||
口淫
|
||||
裤袜
|
||||
狂操
|
||||
狂插
|
||||
浪逼
|
||||
浪妇
|
||||
浪叫
|
||||
浪女
|
||||
狼友
|
||||
聊性
|
||||
流淫
|
||||
铃木麻
|
||||
凌辱
|
||||
漏乳
|
||||
露b
|
||||
乱交
|
||||
乱伦
|
||||
轮暴
|
||||
轮操
|
||||
轮奸
|
||||
裸陪
|
||||
买春
|
||||
美逼
|
||||
美少妇
|
||||
美乳
|
||||
美腿
|
||||
美穴
|
||||
美幼
|
||||
秘唇
|
||||
迷奸
|
||||
密穴
|
||||
蜜穴
|
||||
蜜液
|
||||
摸奶
|
||||
摸胸
|
||||
母奸
|
||||
奈美
|
||||
奶子
|
||||
男奴
|
||||
内射
|
||||
嫩逼
|
||||
嫩女
|
||||
嫩穴
|
||||
捏弄
|
||||
女优
|
||||
炮友
|
||||
砲友
|
||||
喷精
|
||||
屁眼
|
||||
品香堂
|
||||
前凸后翘
|
||||
强jian
|
||||
强暴
|
||||
强奸处女
|
||||
情趣用品
|
||||
情色
|
||||
拳交
|
||||
全裸
|
||||
群交
|
||||
惹火身材
|
||||
人妻
|
||||
人兽
|
||||
日逼
|
||||
日烂
|
||||
肉棒
|
||||
肉逼
|
||||
肉唇
|
||||
肉洞
|
||||
肉缝
|
||||
肉棍
|
||||
肉茎
|
||||
肉具
|
||||
揉乳
|
||||
肉穴
|
||||
肉欲
|
||||
乳爆
|
||||
乳房
|
||||
乳沟
|
||||
乳交
|
||||
乳头
|
||||
三级片
|
||||
骚逼
|
||||
骚比
|
||||
骚女
|
||||
骚水
|
||||
骚穴
|
||||
色逼
|
||||
色界
|
||||
色猫
|
||||
色盟
|
||||
色情网站
|
||||
色区
|
||||
色色
|
||||
色诱
|
||||
色欲
|
||||
色b
|
||||
少年阿宾
|
||||
少修正
|
||||
射爽
|
||||
射颜
|
||||
食精
|
||||
释欲
|
||||
兽奸
|
||||
兽交
|
||||
手淫
|
||||
兽欲
|
||||
熟妇
|
||||
熟母
|
||||
熟女
|
||||
爽片
|
||||
爽死我了
|
||||
双臀
|
||||
死逼
|
||||
丝袜
|
||||
丝诱
|
||||
松岛枫
|
||||
酥痒
|
||||
汤加丽
|
||||
套弄
|
||||
体奸
|
||||
体位
|
||||
舔脚
|
||||
舔阴
|
||||
调教
|
||||
偷欢
|
||||
偷拍
|
||||
推油
|
||||
脱内裤
|
||||
文做
|
||||
我就色
|
||||
无码
|
||||
舞女
|
||||
无修正
|
||||
吸精
|
||||
夏川纯
|
||||
相奸
|
||||
小逼
|
||||
校鸡
|
||||
小穴
|
||||
小xue
|
||||
写真
|
||||
性感妖娆
|
||||
性感诱惑
|
||||
性虎
|
||||
性饥渴
|
||||
性技巧
|
||||
性交
|
||||
性奴
|
||||
性虐
|
||||
性息
|
||||
性欲
|
||||
胸推
|
||||
穴口
|
||||
学生妹
|
||||
穴图
|
||||
亚情
|
||||
颜射
|
||||
阳具
|
||||
杨思敏
|
||||
要射了
|
||||
夜勤病栋
|
||||
一本道
|
||||
一夜欢
|
||||
一夜情
|
||||
一ye情
|
||||
阴部
|
||||
淫虫
|
||||
阴唇
|
||||
淫荡
|
||||
阴道
|
||||
淫电影
|
||||
阴阜
|
||||
淫妇
|
||||
淫河
|
||||
阴核
|
||||
阴户
|
||||
淫贱
|
||||
淫叫
|
||||
淫教师
|
||||
阴茎
|
||||
阴精
|
||||
淫浪
|
||||
淫媚
|
||||
淫糜
|
||||
淫魔
|
||||
淫母
|
||||
淫女
|
||||
淫虐
|
||||
淫妻
|
||||
淫情
|
||||
淫色
|
||||
淫声浪语
|
||||
淫兽学园
|
||||
淫书
|
||||
淫术炼金士
|
||||
淫水
|
||||
淫娃
|
||||
淫威
|
||||
淫亵
|
||||
淫样
|
||||
淫液
|
||||
淫照
|
||||
阴b
|
||||
应召
|
||||
幼交
|
||||
幼男
|
||||
幼女
|
||||
欲火
|
||||
欲女
|
||||
玉女心经
|
||||
玉蒲团
|
||||
玉乳
|
||||
欲仙欲死
|
||||
玉穴
|
||||
援交
|
||||
原味内衣
|
||||
援助交际
|
||||
张筱雨
|
||||
招鸡
|
||||
招妓
|
||||
中年美妇
|
||||
抓胸
|
||||
自拍
|
||||
自慰
|
||||
作爱
|
||||
18禁
|
||||
99bb
|
||||
a4u
|
||||
a4y
|
||||
adult
|
||||
amateur
|
||||
anal
|
||||
a片
|
||||
fuck
|
||||
gay片
|
||||
g点
|
||||
g片
|
||||
hardcore
|
||||
h动画
|
||||
h动漫
|
||||
incest
|
||||
porn
|
||||
secom
|
||||
sexinsex
|
||||
sm女王
|
||||
xiao77
|
||||
xing伴侣
|
||||
tokyohot
|
||||
yin荡
|
||||
贱人
|
||||
装b
|
||||
大sb
|
||||
傻逼
|
||||
傻b
|
||||
煞逼
|
||||
煞笔
|
||||
刹笔
|
||||
傻比
|
||||
沙比
|
||||
欠干
|
||||
婊子养的
|
||||
我日你
|
||||
我操
|
||||
我草
|
||||
卧艹
|
||||
卧槽
|
||||
爆你菊
|
||||
艹你
|
||||
cao你
|
||||
你他妈
|
||||
真他妈
|
||||
别他吗
|
||||
草你吗
|
||||
草你丫
|
||||
操你妈
|
||||
擦你妈
|
||||
操你娘
|
||||
操他妈
|
||||
日你妈
|
||||
干你妈
|
||||
干你娘
|
||||
娘西皮
|
||||
狗操
|
||||
狗草
|
||||
狗杂种
|
||||
狗日的
|
||||
操你祖宗
|
||||
操你全家
|
||||
操你大爷
|
||||
妈逼
|
||||
你麻痹
|
||||
麻痹的
|
||||
妈了个逼
|
||||
马勒
|
||||
狗娘养
|
||||
贱比
|
||||
贱b
|
||||
下贱
|
||||
死全家
|
||||
全家死光
|
||||
全家不得好死
|
||||
全家死绝
|
||||
白痴
|
||||
无耻
|
||||
sb
|
||||
杀b
|
||||
你吗b
|
||||
你妈的
|
||||
婊子
|
||||
贱货
|
||||
人渣
|
||||
混蛋
|
||||
媚外
|
||||
和弦
|
||||
兼职
|
||||
限量
|
||||
铃声
|
||||
性伴侣
|
||||
男公关
|
||||
火辣
|
||||
精子
|
||||
射精
|
||||
诱奸
|
||||
强奸
|
||||
做爱
|
||||
性爱
|
||||
发生关系
|
||||
按摩
|
||||
快感
|
||||
处男
|
||||
猛男
|
||||
少妇
|
||||
屌
|
||||
屁股
|
||||
下体
|
||||
a片
|
||||
内裤
|
||||
浑圆
|
||||
咪咪
|
||||
发情
|
||||
刺激
|
||||
白嫩
|
||||
粉嫩
|
||||
兽性
|
||||
风骚
|
||||
呻吟
|
||||
sm
|
||||
阉割
|
||||
高潮
|
||||
裸露
|
||||
不穿
|
||||
一丝不挂
|
||||
脱光
|
||||
干你
|
||||
干死
|
||||
我干
|
||||
裙中性运动
|
||||
乱奸
|
||||
乱伦
|
||||
乱伦类
|
||||
乱伦小
|
||||
伦理大
|
||||
伦理电影
|
||||
伦理毛
|
||||
伦理片
|
||||
裸聊
|
||||
裸聊网
|
||||
裸体写真
|
||||
裸舞视
|
||||
裸照
|
||||
美女裸体
|
||||
美女写真
|
||||
美女上门
|
||||
美艳少妇
|
||||
妹按摩
|
||||
妹上门
|
||||
迷幻药
|
||||
迷幻藥
|
||||
迷昏口
|
||||
迷昏药
|
||||
迷昏藥
|
||||
迷魂香
|
||||
迷魂药
|
||||
迷魂藥
|
||||
迷奸粉
|
||||
迷奸药
|
||||
迷情粉
|
||||
迷情水
|
||||
迷情药
|
||||
迷药
|
||||
迷藥
|
||||
谜奸药
|
||||
骚妇
|
||||
骚货
|
||||
骚浪
|
||||
骚女
|
||||
骚嘴
|
||||
色电影
|
||||
色妹妹
|
||||
色情表演
|
||||
色情电影
|
||||
色情服务
|
||||
色情图片
|
||||
色情小说
|
||||
色情影片
|
||||
色情表演
|
||||
色情电影
|
||||
色情服务
|
||||
色情片
|
||||
色视频
|
||||
色小说
|
||||
性伴侣
|
||||
性服务
|
||||
性福情
|
||||
性感少
|
||||
性伙伴
|
||||
性交
|
||||
性交视频
|
||||
性交图片
|
||||
性奴
|
||||
性奴集中营
|
||||
性虐
|
||||
阴唇
|
||||
阴道
|
||||
阴蒂
|
||||
阴户
|
||||
阴间来电
|
||||
阴茎
|
||||
阴茎增大
|
||||
阴茎助勃
|
||||
阴毛
|
||||
陰唇
|
||||
陰道
|
||||
陰戶
|
||||
淫荡
|
||||
淫荡美女
|
||||
淫荡视频
|
||||
淫荡照片
|
||||
淫乱
|
||||
淫靡
|
||||
淫魔
|
||||
淫魔舞
|
||||
淫女
|
||||
淫情女
|
||||
淫肉
|
||||
淫騷妹
|
||||
淫兽
|
||||
淫兽学
|
||||
淫水
|
||||
淫穴
|
||||
morphine
|
||||
摇头丸
|
||||
迷药
|
||||
乖乖粉
|
||||
narcotic
|
||||
麻醉药
|
||||
精神药品
|
||||
爱女人
|
||||
爱液
|
||||
按摩棒
|
||||
拔出来
|
||||
爆草
|
||||
包二奶
|
||||
暴干
|
||||
暴奸
|
||||
暴乳
|
||||
爆乳
|
||||
暴淫
|
||||
屄
|
||||
被操
|
||||
被插
|
||||
被干
|
||||
逼奸
|
||||
仓井空
|
||||
插暴
|
||||
操逼
|
||||
操黑
|
||||
操烂
|
||||
肏你
|
||||
肏死
|
||||
操死
|
||||
操我
|
||||
厕奴
|
||||
插比
|
||||
插b
|
||||
插逼
|
||||
插进
|
||||
插你
|
||||
插我
|
||||
插阴
|
||||
潮吹
|
||||
潮喷
|
||||
成人电影
|
||||
成人论坛
|
||||
成人色情
|
||||
成人网站
|
||||
成人文学
|
||||
成人小说
|
||||
艳情小说
|
||||
成人游戏
|
||||
吃精
|
||||
赤裸
|
||||
抽插
|
||||
扌由插
|
||||
抽一插
|
||||
春药
|
||||
大波
|
||||
大力抽送
|
||||
大乳
|
||||
荡妇
|
||||
荡女
|
||||
盗撮
|
||||
多人轮
|
||||
发浪
|
||||
放尿
|
||||
肥逼
|
||||
粉穴
|
||||
封面女郎
|
||||
风月大陆
|
||||
干死你
|
||||
干穴
|
||||
肛交
|
||||
肛门
|
||||
龟头
|
||||
裹本
|
||||
国产av
|
||||
好嫩
|
||||
豪乳
|
||||
黑逼
|
||||
后庭
|
||||
后穴
|
||||
虎骑
|
||||
花花公子
|
||||
换妻俱乐部
|
||||
黄片
|
||||
几吧
|
||||
鸡吧
|
||||
鸡巴
|
||||
鸡奸
|
||||
寂寞男
|
||||
寂寞女
|
||||
妓女
|
||||
激情
|
||||
集体淫
|
||||
奸情
|
||||
叫床
|
||||
脚交
|
||||
金鳞岂是池中物
|
||||
金麟岂是池中物
|
||||
精液
|
||||
就去日
|
||||
巨屌
|
||||
菊花洞
|
||||
菊门
|
||||
巨奶
|
||||
巨乳
|
||||
菊穴
|
||||
开苞
|
||||
口爆
|
||||
口活
|
||||
口交
|
||||
口射
|
||||
口淫
|
||||
裤袜
|
||||
狂操
|
||||
狂插
|
||||
浪逼
|
||||
浪妇
|
||||
浪叫
|
||||
浪女
|
||||
狼友
|
||||
聊性
|
||||
流淫
|
||||
铃木麻
|
||||
凌辱
|
||||
漏乳
|
||||
露b
|
||||
乱交
|
||||
乱伦
|
||||
轮暴
|
||||
轮操
|
||||
轮奸
|
||||
裸陪
|
||||
买春
|
||||
美逼
|
||||
美少妇
|
||||
美乳
|
||||
美腿
|
||||
美穴
|
||||
美幼
|
||||
秘唇
|
||||
迷奸
|
||||
密穴
|
||||
蜜穴
|
||||
蜜液
|
||||
摸奶
|
||||
摸胸
|
||||
母奸
|
||||
奈美
|
||||
奶子
|
||||
男奴
|
||||
内射
|
||||
嫩逼
|
||||
嫩女
|
||||
嫩穴
|
||||
捏弄
|
||||
女优
|
||||
炮友
|
||||
砲友
|
||||
喷精
|
||||
屁眼
|
||||
品香堂
|
||||
前凸后翘
|
||||
强jian
|
||||
强暴
|
||||
强奸处女
|
||||
情趣用品
|
||||
情色
|
||||
拳交
|
||||
全裸
|
||||
群交
|
||||
惹火身材
|
||||
人妻
|
||||
人兽
|
||||
日逼
|
||||
日烂
|
||||
肉棒
|
||||
肉逼
|
||||
肉唇
|
||||
肉洞
|
||||
肉缝
|
||||
肉棍
|
||||
肉茎
|
||||
肉具
|
||||
揉乳
|
||||
肉穴
|
||||
肉欲
|
||||
乳爆
|
||||
乳房
|
||||
乳沟
|
||||
乳交
|
||||
乳头
|
||||
三级片
|
||||
骚逼
|
||||
骚比
|
||||
骚女
|
||||
骚水
|
||||
骚穴
|
||||
色逼
|
||||
色界
|
||||
色猫
|
||||
色盟
|
||||
色情网站
|
||||
色区
|
||||
色色
|
||||
色诱
|
||||
色欲
|
||||
色b
|
||||
少年阿宾
|
||||
少修正
|
||||
射爽
|
||||
射颜
|
||||
食精
|
||||
释欲
|
||||
兽奸
|
||||
兽交
|
||||
手淫
|
||||
兽欲
|
||||
熟妇
|
||||
熟母
|
||||
熟女
|
||||
爽片
|
||||
爽死我了
|
||||
双臀
|
||||
死逼
|
||||
丝袜
|
||||
丝诱
|
||||
松岛枫
|
||||
酥痒
|
||||
汤加丽
|
||||
套弄
|
||||
体奸
|
||||
体位
|
||||
舔脚
|
||||
舔阴
|
||||
调教
|
||||
偷欢
|
||||
偷拍
|
||||
推油
|
||||
脱内裤
|
||||
文做
|
||||
我就色
|
||||
无码
|
||||
舞女
|
||||
无修正
|
||||
吸精
|
||||
夏川纯
|
||||
相奸
|
||||
小逼
|
||||
校鸡
|
||||
小穴
|
||||
小xue
|
||||
写真
|
||||
性感妖娆
|
||||
性感诱惑
|
||||
性虎
|
||||
性饥渴
|
||||
性技巧
|
||||
性交
|
||||
性奴
|
||||
性虐
|
||||
性息
|
||||
性欲
|
||||
胸推
|
||||
穴口
|
||||
学生妹
|
||||
穴图
|
||||
亚情
|
||||
颜射
|
||||
阳具
|
||||
杨思敏
|
||||
要射了
|
||||
夜勤病栋
|
||||
一本道
|
||||
一夜欢
|
||||
一夜情
|
||||
一ye情
|
||||
阴部
|
||||
淫虫
|
||||
阴唇
|
||||
淫荡
|
||||
阴道
|
||||
淫电影
|
||||
阴阜
|
||||
淫妇
|
||||
淫河
|
||||
阴核
|
||||
阴户
|
||||
淫贱
|
||||
淫叫
|
||||
淫教师
|
||||
阴茎
|
||||
阴精
|
||||
淫浪
|
||||
淫媚
|
||||
淫糜
|
||||
淫魔
|
||||
淫母
|
||||
淫女
|
||||
淫虐
|
||||
淫妻
|
||||
淫情
|
||||
淫色
|
||||
淫声浪语
|
||||
淫兽学园
|
||||
淫书
|
||||
淫术炼金士
|
||||
淫水
|
||||
淫娃
|
||||
淫威
|
||||
淫亵
|
||||
淫样
|
||||
淫液
|
||||
淫照
|
||||
阴b
|
||||
应召
|
||||
幼交
|
||||
幼男
|
||||
幼女
|
||||
欲火
|
||||
欲女
|
||||
玉女心经
|
||||
玉蒲团
|
||||
玉乳
|
||||
欲仙欲死
|
||||
玉穴
|
||||
援交
|
||||
原味内衣
|
||||
援助交际
|
||||
张筱雨
|
||||
招鸡
|
||||
招妓
|
||||
中年美妇
|
||||
抓胸
|
||||
自拍
|
||||
自慰
|
||||
作爱
|
||||
18禁
|
||||
99bb
|
||||
a4u
|
||||
a4y
|
||||
adult
|
||||
amateur
|
||||
anal
|
||||
a片
|
||||
fuck
|
||||
gay片
|
||||
g点
|
||||
g片
|
||||
hardcore
|
||||
h动画
|
||||
h动漫
|
||||
incest
|
||||
porn
|
||||
secom
|
||||
sexinsex
|
||||
sm女王
|
||||
xiao77
|
||||
xing伴侣
|
||||
tokyohot
|
||||
yin荡
|
1064
app/core/api/resources/sensitive/补充词库.txt
Normal file
1064
app/core/api/resources/sensitive/补充词库.txt
Normal file
File diff suppressed because it is too large
Load Diff
244
app/core/api/resources/sensitive/贪腐词库.txt
Normal file
244
app/core/api/resources/sensitive/贪腐词库.txt
Normal file
@@ -0,0 +1,244 @@
|
||||
腐败
|
||||
贪污
|
||||
gcd
|
||||
共贪党
|
||||
gongchandang
|
||||
阿共
|
||||
共一产一党
|
||||
产党共
|
||||
公产党
|
||||
工产党
|
||||
共c党
|
||||
共x党
|
||||
供产
|
||||
共铲
|
||||
共惨
|
||||
供铲党
|
||||
供铲谠
|
||||
供铲裆
|
||||
共残党
|
||||
共残主义
|
||||
共产主义的幽灵
|
||||
拱铲
|
||||
老共
|
||||
中珙
|
||||
中gong
|
||||
gc党
|
||||
贡挡
|
||||
gong党
|
||||
g产
|
||||
狗产蛋
|
||||
共残裆
|
||||
恶党
|
||||
邪党
|
||||
共产专制
|
||||
共产王朝
|
||||
裆中央
|
||||
土共
|
||||
土g
|
||||
共狗
|
||||
g匪
|
||||
共匪
|
||||
仇共
|
||||
共产党腐败
|
||||
共产党专制
|
||||
共产党的报应
|
||||
共产党的末日
|
||||
共产党专制
|
||||
communistparty
|
||||
症腐
|
||||
政腐
|
||||
政付
|
||||
正府
|
||||
政俯
|
||||
政f
|
||||
zhengfu
|
||||
政zhi
|
||||
挡中央
|
||||
档中央
|
||||
中国zf
|
||||
中央zf
|
||||
国wu院
|
||||
中华帝国
|
||||
gong和
|
||||
大陆官方
|
||||
北京政权
|
||||
刘志军
|
||||
张曙
|
||||
刘志军
|
||||
买别墅
|
||||
玩女人
|
||||
贪20亿
|
||||
许宗衡
|
||||
贪财物
|
||||
李启红
|
||||
贪腐财富
|
||||
落马
|
||||
高官名单
|
||||
陈希同
|
||||
贪污
|
||||
玩忽职守
|
||||
有期徒刑
|
||||
陈良宇
|
||||
受贿罪
|
||||
滥用职权
|
||||
有期徒刑
|
||||
没收个人财产
|
||||
成克杰
|
||||
死刑
|
||||
程维高
|
||||
严重违纪
|
||||
开除党籍
|
||||
撤销职务
|
||||
刘方仁
|
||||
无期徒刑
|
||||
倪献策
|
||||
徇私舞弊
|
||||
梁湘
|
||||
以权谋私
|
||||
撤职。
|
||||
李嘉廷
|
||||
死刑缓期
|
||||
张国光
|
||||
韩桂芝
|
||||
宋平顺
|
||||
自杀
|
||||
黄瑶
|
||||
双规
|
||||
陈绍基
|
||||
判处死刑
|
||||
剥夺政治权利终身
|
||||
没收个人全部财产
|
||||
石兆彬
|
||||
侯伍杰
|
||||
王昭耀
|
||||
剥夺政治权利
|
||||
杜世成
|
||||
沈图
|
||||
叛逃美国
|
||||
罗云光
|
||||
起诉
|
||||
张辛泰
|
||||
李效时
|
||||
边少斌
|
||||
徐鹏航
|
||||
违纪
|
||||
收受股票
|
||||
王乐毅
|
||||
李纪周
|
||||
郑光迪
|
||||
田凤山。
|
||||
邱晓华
|
||||
郑筱萸
|
||||
孙鹤龄
|
||||
蓝田造假案
|
||||
于幼军
|
||||
留党察看
|
||||
何洪达
|
||||
朱志刚
|
||||
杨汇泉
|
||||
官僚主义
|
||||
徐炳松
|
||||
托乎提沙比尔
|
||||
王宝森
|
||||
经济犯罪
|
||||
畏罪自杀。
|
||||
陈水文
|
||||
孟庆平
|
||||
胡长清
|
||||
朱川
|
||||
许运鸿
|
||||
丘广钟
|
||||
刘知炳
|
||||
丛福奎
|
||||
王怀忠
|
||||
巨额财产
|
||||
来源不明罪
|
||||
李达昌
|
||||
刘长贵
|
||||
王钟麓
|
||||
阿曼哈吉
|
||||
付晓光
|
||||
自动辞
|
||||
刘克田
|
||||
吕德彬
|
||||
刘维明
|
||||
双开
|
||||
刘志华
|
||||
孙瑜
|
||||
李堂堂
|
||||
韩福才 青海
|
||||
欧阳德 广东
|
||||
韦泽芳 海南
|
||||
铁英 北京
|
||||
辛业江 海南
|
||||
于飞 广东
|
||||
姜殿武 河北
|
||||
秦昌典 重庆
|
||||
范广举 黑龙江
|
||||
张凯广东
|
||||
王厚宏海南
|
||||
陈维席安徽
|
||||
王有杰河南
|
||||
王武龙江苏
|
||||
米凤君吉林
|
||||
宋勇辽宁
|
||||
张家盟浙江
|
||||
马烈孙宁夏
|
||||
黄纪诚北京
|
||||
常征贵州
|
||||
王式惠重庆
|
||||
周文吉
|
||||
王庆录广西
|
||||
潘广田山东
|
||||
朱作勇甘肃
|
||||
孙善武河南
|
||||
宋晨光江西
|
||||
梁春禄广西政协
|
||||
鲁家善 中国交通
|
||||
金德琴 中信
|
||||
李大强 神华
|
||||
吴文英 纺织
|
||||
查克明 华能
|
||||
朱小华光大
|
||||
高严 国家电力
|
||||
王雪冰
|
||||
林孔兴
|
||||
刘金宝
|
||||
张恩照
|
||||
陈同海
|
||||
康日新
|
||||
王益
|
||||
张春江
|
||||
洪清源
|
||||
平义杰
|
||||
李恩潮
|
||||
孙小虹
|
||||
陈忠
|
||||
慕绥新
|
||||
田凤岐
|
||||
麦崇楷
|
||||
柴王群
|
||||
吴振汉
|
||||
张秋阳
|
||||
徐衍东
|
||||
徐发 黑龙江
|
||||
张宗海
|
||||
丁鑫发
|
||||
徐国健
|
||||
李宝金
|
||||
单平
|
||||
段义和
|
||||
荆福生
|
||||
陈少勇
|
||||
黄松有
|
||||
皮黔生
|
||||
王华元
|
||||
王守业
|
||||
刘连昆
|
||||
孙晋美
|
||||
邵松高
|
||||
肖怀枢
|
||||
刘广智 空军
|
||||
姬胜德 总参
|
||||
廖伯年 北京
|
53308
app/core/api/resources/sensitive/零时-Tencent.txt
Normal file
53308
app/core/api/resources/sensitive/零时-Tencent.txt
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user