├── run.sh ├── external ├── agent │ └── ja-netfilter.zip ├── data │ ├── product.json │ └── plugin.json └── certificate │ └── root.key ├── config.toml ├── config └── ConfigType.go ├── Dockerfile ├── helper ├── Products.go ├── License.go ├── Types.go ├── Certificate.go ├── Refresh.go ├── Util.go └── Agent.go ├── .gitignore ├── LICENSE ├── main.go ├── README.md ├── templates ├── articles.html └── index.html ├── go.mod ├── router.go ├── static ├── js │ ├── index.js │ └── jquery.js └── css │ └── index.css └── go.sum /run.sh: -------------------------------------------------------------------------------- 1 | docker rm jetbrains-help 2 | docker run -itd -p 8080:8080 --name jetbrains-help luxcis/jetbrains-help-go -------------------------------------------------------------------------------- /external/agent/ja-netfilter.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Luxcis/Jetbrains-Helper-Go/HEAD/external/agent/ja-netfilter.zip -------------------------------------------------------------------------------- /config.toml: -------------------------------------------------------------------------------- 1 | Mode = "debug" 2 | 3 | [License] 4 | LicenseName = "Azurlane" 5 | AssigneeName = "Yamato" 6 | ExpiryDate = "2030-12-31" -------------------------------------------------------------------------------- /config/ConfigType.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | var Conf Config 4 | 5 | type Config struct { 6 | Mode string `required:"true" default:"release"` 7 | License License `required:"true"` 8 | } 9 | type License struct { 10 | LicenseName string `required:"true" default:"Azurlane"` 11 | AssigneeName string `required:"true" default:"Yamato"` 12 | ExpiryDate string `required:"true" default:"2030-12-31"` 13 | } 14 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:latest AS builder 2 | WORKDIR /go/src/app 3 | COPY . . 4 | RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main . 5 | 6 | FROM alpine:latest 7 | WORKDIR /app/ 8 | COPY --from=builder /go/src/app/main . 9 | COPY --from=builder /go/src/app/config.toml . 10 | COPY --from=builder /go/src/app/external ./external 11 | COPY --from=builder /go/src/app/static ./static 12 | COPY --from=builder /go/src/app/templates ./templates 13 | CMD ["./main"] 14 | EXPOSE 8080 -------------------------------------------------------------------------------- /helper/Products.go: -------------------------------------------------------------------------------- 1 | package helper 2 | 3 | import ( 4 | "log" 5 | ) 6 | 7 | var Products []ProductCache 8 | var Plugins []PluginCache 9 | 10 | func InitProducts() { 11 | log.Println("ProductCache context init loading...") 12 | err := ReadJson(products, &Products) 13 | if err != nil { 14 | log.Fatalf("Product初始化失败: %v", err) 15 | return 16 | } 17 | } 18 | 19 | func InitPlugins() { 20 | log.Println("PluginCache context init loading...") 21 | err := ReadJson(plugins, &Plugins) 22 | if err != nil { 23 | log.Fatalf("Plugin初始化失败: %v", err) 24 | return 25 | } 26 | } 27 | 28 | const ( 29 | products = "external/data/product.json" 30 | plugins = "external/data/plugin.json" 31 | ) 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Example user template template 2 | ### Example user template 3 | 4 | # IntelliJ project files 5 | .idea 6 | *.iml 7 | out 8 | gen 9 | ### Go template 10 | # If you prefer the allow list template instead of the deny list, see community template: 11 | # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore 12 | # 13 | # Binaries for programs and plugins 14 | *.exe 15 | *.exe~ 16 | *.dll 17 | *.so 18 | *.dylib 19 | 20 | # Test binary, built with `go test -c` 21 | *.test 22 | 23 | # Output of the go coverage tool, specifically when used with LiteIDE 24 | *.out 25 | 26 | # Dependency directories (remove the comment below to include it) 27 | # vendor/ 28 | 29 | # Go workspace file 30 | go.work 31 | 32 | external/agent/ja-netfilter 33 | external/agent/ja-netfilter.zip 34 | ca.crt 35 | private.key 36 | public.key 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 NotoChen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /helper/License.go: -------------------------------------------------------------------------------- 1 | package helper 2 | 3 | import ( 4 | "encoding/base64" 5 | "encoding/json" 6 | "github.com/google/uuid" 7 | "strings" 8 | ) 9 | 10 | func GenerateLicense(licensesName, assigneeName, expiryDate string, productCodeSet []string) (string, error) { 11 | licenseID := uuid.New().String() 12 | licenseID = strings.Replace(licenseID, "-", "", -1) 13 | var products []Product 14 | for _, code := range productCodeSet { 15 | products = append(products, Product{ 16 | Code: code, 17 | FallbackDate: expiryDate, 18 | PaidUpTo: expiryDate, 19 | }) 20 | } 21 | licensePart := LicensePart{ 22 | LicenseID: licenseID, 23 | LicenseeName: licensesName, 24 | AssigneeName: assigneeName, 25 | Products: products, 26 | Metadata: "0120230914PSAX000005", 27 | } 28 | 29 | licensePartJSON, err := json.Marshal(licensePart) 30 | if err != nil { 31 | return "", err 32 | } 33 | licensePartBase64 := base64.StdEncoding.EncodeToString(licensePartJSON) 34 | privateKey := readRSAPrivateKey(privateKeyFileName) 35 | // publicKey := readRSAPublicKey(publicKeyFileName) 36 | signatureBase64 := signWithRSA(privateKey, licensePartJSON) 37 | cert := readX509Certificate(certFileName) 38 | certBase64 := base64.StdEncoding.EncodeToString(cert.Raw) 39 | println(signatureBase64) 40 | return licenseID + "-" + licensePartBase64 + "-" + signatureBase64 + "-" + certBase64, nil 41 | } 42 | -------------------------------------------------------------------------------- /external/data/product.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "All In One", 4 | "productCode": "", 5 | "iconClass": "icon-al" 6 | }, 7 | { 8 | "name": "IntelliJ IDEA", 9 | "productCode": "II,PCWMP,PSI", 10 | "iconClass": "icon-ii" 11 | }, 12 | { 13 | "name": "PhpStorm", 14 | "productCode": "PS,PCWMP,PSI", 15 | "iconClass": "icon-ps" 16 | }, 17 | { 18 | "name": "AppCode", 19 | "productCode": "AC,PCWMP,PSI", 20 | "iconClass": "icon-ac" 21 | }, 22 | { 23 | "name": "DataGrip", 24 | "productCode": "DB,PSI,PDB", 25 | "iconClass": "icon-db" 26 | }, 27 | { 28 | "name": "RubyMine", 29 | "productCode": "RM,PCWMP,PSI", 30 | "iconClass": "icon-rm" 31 | }, 32 | { 33 | "name": "WebStorm", 34 | "productCode": "WS,PCWMP,PSI", 35 | "iconClass": "icon-ws" 36 | }, 37 | { 38 | "name": "Rider", 39 | "productCode": "RD,PDB,PSI,PCWMP", 40 | "iconClass": "icon-rd" 41 | }, 42 | { 43 | "name": "CLion", 44 | "productCode": "CL,PSI,PCWMP", 45 | "iconClass": "icon-cl" 46 | }, 47 | { 48 | "name": "PyCharm", 49 | "productCode": "PC,PSI,PCWMP", 50 | "iconClass": "icon-pc" 51 | }, 52 | { 53 | "name": "GoLand", 54 | "productCode": "GO,PSI,PCWMP", 55 | "iconClass": "icon-go" 56 | }, 57 | { 58 | "name": "DataSpell", 59 | "productCode": "DS,PSI,PDB,PCWMP", 60 | "iconClass": "icon-ds" 61 | }, 62 | { 63 | "name": "dotMemory", 64 | "productCode": "DM", 65 | "iconClass": "icon-dm" 66 | } 67 | ] 68 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "Jetbrain-Helper/config" 5 | "Jetbrain-Helper/helper" 6 | "github.com/fsnotify/fsnotify" 7 | "github.com/gin-gonic/gin" 8 | "github.com/robfig/cron/v3" 9 | "github.com/spf13/viper" 10 | "log" 11 | "time" 12 | ) 13 | 14 | func init() { 15 | viper.SetConfigName("config") 16 | viper.SetConfigType("toml") 17 | viper.AddConfigPath(".") 18 | err := viper.ReadInConfig() 19 | if err != nil { 20 | log.Fatalf("配置文件读取失败: %v", err) 21 | } 22 | err = viper.Unmarshal(&config.Conf) 23 | if err != nil { 24 | log.Fatalf("配置文件类型转换失败: %v", err) 25 | } 26 | // 监听配置文件修改 27 | viper.WatchConfig() 28 | viper.OnConfigChange(func(e fsnotify.Event) { 29 | err := viper.Unmarshal(&config.Conf) 30 | if err != nil { 31 | log.Printf("配置文件类型转换失败: %v\n", err) 32 | return 33 | } 34 | log.Printf("配置文件修改(%s): %s\n", time.Now().Format("2006-01-01 15:04:05"), e.Name) 35 | }) 36 | helper.InitProducts() 37 | helper.InitPlugins() 38 | helper.InitCertificate() 39 | helper.InitAgent() 40 | } 41 | 42 | func main() { 43 | gin.SetMode(config.Conf.Mode) 44 | r := gin.Default() 45 | r.Static("/assets", "./static") 46 | r.LoadHTMLGlob("templates/*") 47 | r.GET("/", index) 48 | r.GET("/search", search) 49 | r.POST("/generateLicense", generateLicense) 50 | r.GET("/ja-netfilter", download) 51 | startCron() 52 | err := r.Run("0.0.0.0:8080") 53 | if err != nil { 54 | log.Fatalf("服务启动失败: %v", err) 55 | } 56 | } 57 | 58 | func startCron() { 59 | c := cron.New() 60 | _, err := c.AddFunc("0 0 12 * *", helper.RefreshJsonFile) 61 | if err != nil { 62 | log.Fatalf("定时任务添加失败: %v", err) 63 | } else { 64 | log.Println("定时重启启动成功") 65 | } 66 | c.Start() 67 | } 68 | -------------------------------------------------------------------------------- /external/certificate/root.key: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIFOzCCAyOgAwIBAgIJANJssYOyg3nhMA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNV 3 | BAMMDUpldFByb2ZpbGUgQ0EwHhcNMTUxMDAyMTEwMDU2WhcNNDUxMDI0MTEwMDU2 4 | WjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMIICIjANBgkqhkiG9w0BAQEFAAOC 5 | Ag8AMIICCgKCAgEA0tQuEA8784NabB1+T2XBhpB+2P1qjewHiSajAV8dfIeWJOYG 6 | y+ShXiuedj8rL8VCdU+yH7Ux/6IvTcT3nwM/E/3rjJIgLnbZNerFm15Eez+XpWBl 7 | m5fDBJhEGhPc89Y31GpTzW0vCLmhJ44XwvYPntWxYISUrqeR3zoUQrCEp1C6mXNX 8 | EpqIGIVbJ6JVa/YI+pwbfuP51o0ZtF2rzvgfPzKtkpYQ7m7KgA8g8ktRXyNrz8bo 9 | iwg7RRPeqs4uL/RK8d2KLpgLqcAB9WDpcEQzPWegbDrFO1F3z4UVNH6hrMfOLGVA 10 | xoiQhNFhZj6RumBXlPS0rmCOCkUkWrDr3l6Z3spUVgoeea+QdX682j6t7JnakaOw 11 | jzwY777SrZoi9mFFpLVhfb4haq4IWyKSHR3/0BlWXgcgI6w6LXm+V+ZgLVDON52F 12 | LcxnfftaBJz2yclEwBohq38rYEpb+28+JBvHJYqcZRaldHYLjjmb8XXvf2MyFeXr 13 | SopYkdzCvzmiEJAewrEbPUaTllogUQmnv7Rv9sZ9jfdJ/cEn8e7GSGjHIbnjV2ZM 14 | Q9vTpWjvsT/cqatbxzdBo/iEg5i9yohOC9aBfpIHPXFw+fEj7VLvktxZY6qThYXR 15 | Rus1WErPgxDzVpNp+4gXovAYOxsZak5oTV74ynv1aQ93HSndGkKUE/qA/JECAwEA 16 | AaOBhzCBhDAdBgNVHQ4EFgQUo562SGdCEjZBvW3gubSgUouX8bMwSAYDVR0jBEEw 17 | P4AUo562SGdCEjZBvW3gubSgUouX8bOhHKQaMBgxFjAUBgNVBAMMDUpldFByb2Zp 18 | bGUgQ0GCCQDSbLGDsoN54TAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkq 19 | hkiG9w0BAQsFAAOCAgEAjrPAZ4xC7sNiSSqh69s3KJD3Ti4etaxcrSnD7r9rJYpK 20 | BMviCKZRKFbLv+iaF5JK5QWuWdlgA37ol7mLeoF7aIA9b60Ag2OpgRICRG79QY7o 21 | uLviF/yRMqm6yno7NYkGLd61e5Huu+BfT459MWG9RVkG/DY0sGfkyTHJS5xrjBV6 22 | hjLG0lf3orwqOlqSNRmhvn9sMzwAP3ILLM5VJC5jNF1zAk0jrqKz64vuA8PLJZlL 23 | S9TZJIYwdesCGfnN2AETvzf3qxLcGTF038zKOHUMnjZuFW1ba/12fDK5GJ4i5y+n 24 | fDWVZVUDYOPUixEZ1cwzmf9Tx3hR8tRjMWQmHixcNC8XEkVfztID5XeHtDeQ+uPk 25 | X+jTDXbRb+77BP6n41briXhm57AwUI3TqqJFvoiFyx5JvVWG3ZqlVaeU/U9e0gxn 26 | 8qyR+ZA3BGbtUSDDs8LDnE67URzK+L+q0F2BC758lSPNB2qsJeQ63bYyzf0du3wB 27 | /gb2+xJijAvscU3KgNpkxfGklvJD/oDUIqZQAnNcHe7QEf8iG2WqaMJIyXZlW3me 28 | 0rn+cgvxHPt6N4EBh5GgNZR4l0eaFEV+fxVsydOQYo1RIyFMXtafFBqQl6DDxujl 29 | FeU3FZ+Bcp12t7dlM4E0/sS1XdL47CfGVj4Bp+/VbF862HmkAbd7shs7sDQkHbU= 30 | -----END CERTIFICATE----- 31 | -------------------------------------------------------------------------------- /helper/Types.go: -------------------------------------------------------------------------------- 1 | package helper 2 | 3 | type ProductCache struct { 4 | Name string `json:"name"` 5 | ProductCode string `json:"productCode"` 6 | IconClass string `json:"iconClass"` 7 | } 8 | 9 | type PluginCache struct { 10 | Id int `json:"id"` 11 | Name string `json:"name"` 12 | ProductCode string `json:"productCode"` 13 | PricingModel string `json:"pricingModel"` 14 | Icon string `json:"icon"` 15 | } 16 | 17 | type PluginInfo struct { 18 | ID int `json:"id"` 19 | PurchaseInfo PurchaseInfo `json:"purchaseInfo"` 20 | } 21 | 22 | type PurchaseInfo struct { 23 | ProductCode string `json:"productCode"` 24 | } 25 | 26 | type PluginList struct { 27 | Plugins []Plugin `json:"plugins"` 28 | Total int `json:"total"` 29 | } 30 | 31 | type Plugin struct { 32 | Id int `json:"id"` 33 | Name string `json:"name"` 34 | Preview string `json:"preview"` 35 | Downloads int `json:"downloads"` 36 | PricingModel string `json:"pricingModel"` 37 | Organization string `json:"organization"` 38 | Icon string `json:"icon"` 39 | PreviewImage string `json:"previewImage"` 40 | Rating float64 `json:"rating"` 41 | VendorInfo VendorInfo `json:"vendorInfo"` 42 | } 43 | 44 | type VendorInfo struct { 45 | Name string `json:"name"` 46 | IsVerified bool `json:"isVerified"` 47 | } 48 | 49 | type LicensePart struct { 50 | LicenseID string `json:"licenseId"` 51 | LicenseeName string `json:"licenseeName"` 52 | AssigneeName string `json:"assigneeName"` 53 | Products []Product `json:"products"` 54 | Metadata string `json:"metadata"` 55 | } 56 | 57 | type Product struct { 58 | Code string `json:"code"` 59 | FallbackDate string `json:"fallbackDate"` 60 | PaidUpTo string `json:"paidUpTo"` 61 | } 62 | 63 | type GenerateLicenseReqBody struct { 64 | LicenseName string `json:"licenseName"` 65 | AssigneeName string `json:"assigneeName"` 66 | ExpiryDate string `json:"expiryDate"` 67 | ProductCode string `json:"productCode"` 68 | } 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Jetbrains-Help-Go

2 | 3 | ``` 4 | ██╗███████╗████████╗██████╗ ██████╗ █████╗ ██╗███╗ ██╗███████╗ ██╗ ██╗███████╗██╗ ██████╗ ██████╗ ██████╗ 5 | ██║██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██╔══██╗██║████╗ ██║██╔════╝ ██║ ██║██╔════╝██║ ██╔══██╗ ██╔════╝ ██╔═══██╗ 6 | ██║█████╗ ██║ ██████╔╝██████╔╝███████║██║██╔██╗ ██║███████╗█████╗███████║█████╗ ██║ ██████╔╝█████╗██║ ███╗██║ ██║ 7 | ██ ██║██╔══╝ ██║ ██╔══██╗██╔══██╗██╔══██║██║██║╚██╗██║╚════██║╚════╝██╔══██║██╔══╝ ██║ ██╔═══╝ ╚════╝██║ ██║██║ ██║ 8 | ╚█████╔╝███████╗ ██║ ██████╔╝██║ ██║██║ ██║██║██║ ╚████║███████║ ██║ ██║███████╗███████╗██║ ╚██████╔╝╚██████╔╝ 9 | ╚════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝╚══════╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═════╝ ╚═════╝ 10 | ``` 11 | 12 |

13 | 14 | 15 |

16 | 17 |

18 | 19 |

20 | 21 |

22 | 23 | 24 |

25 | 26 |

27 | 28 |

29 | 30 | # 功能 31 | 32 | | 功能 | DID | 33 | |:-------------------------|:---:| 34 | | Jetbrains全产品支持 | ✅ | 35 | | Jetbrains全插件支持 | ✅ | 36 | | 插件库全自动订阅官网更新 | ✅ | 37 | | 公私钥/证书, 自动生成管理 | ✅ | 38 | | power.conf文件自动配置 | ✅ | 39 | | ja-netfilter.zip自动打包 | ✅ | 40 | | 自定义License Show | ✅ | 41 | | 支持实时搜索 | ✅ | 42 | | 插件默认按名称排序 | ✅ | 43 | | 支持local/jar/dockerfile运行 | ✅ | 44 | | 单码全家桶激活支持 | ✅ | 45 | | …… | ☑️ | -------------------------------------------------------------------------------- /helper/Certificate.go: -------------------------------------------------------------------------------- 1 | package helper 2 | 3 | import ( 4 | "crypto/rand" 5 | "crypto/rsa" 6 | "crypto/x509" 7 | "crypto/x509/pkix" 8 | "log" 9 | "math/big" 10 | "time" 11 | ) 12 | 13 | const ( 14 | rootKeyFileName = "external/certificate/root.key" 15 | privateKeyFileName = "external/certificate/private.key" 16 | publicKeyFileName = "external/certificate/public.key" 17 | certFileName = "external/certificate/ca.crt" 18 | ) 19 | 20 | func InitCertificate() { 21 | log.Println("Certificate context init loading...") 22 | if !FileExists(privateKeyFileName) || !FileExists(publicKeyFileName) || !FileExists(certFileName) { 23 | log.Println("Certificate context generate loading...") 24 | generateCertificate() 25 | log.Println("Certificate context generate success!") 26 | } 27 | log.Println("Certificate context init success!") 28 | } 29 | 30 | func generateCertificate() { 31 | privateKey, err := rsa.GenerateKey(rand.Reader, 4096) 32 | if err != nil { 33 | log.Fatalf("Failed to generate RSA key pair: %v", err) 34 | } 35 | 36 | publicKeyBytes, err := x509.MarshalPKIXPublicKey(&privateKey.PublicKey) 37 | if err != nil { 38 | log.Fatalf("Failed to marshal public key: %v", err) 39 | } 40 | writePemFile(publicKeyFileName, "PUBLIC KEY", publicKeyBytes) 41 | 42 | privateKeyBytes, err := x509.MarshalPKCS8PrivateKey(privateKey) 43 | if err != nil { 44 | log.Fatalf("Failed to marshal private key: %v", err) 45 | } 46 | writePemFile(privateKeyFileName, "PRIVATE KEY", privateKeyBytes) 47 | 48 | serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128)) 49 | if err != nil { 50 | log.Fatalf("Failed to generate serial number: %v", err) 51 | } 52 | 53 | certTemplate := x509.Certificate{ 54 | SerialNumber: serialNumber, 55 | Subject: pkix.Name{ 56 | CommonName: "JetProfile CA", 57 | }, 58 | NotBefore: time.Now().Add(-24 * time.Hour), 59 | NotAfter: time.Now().AddDate(100, 0, 0), 60 | KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, 61 | } 62 | 63 | certBytes, err := x509.CreateCertificate(rand.Reader, &certTemplate, &certTemplate, &privateKey.PublicKey, privateKey) 64 | if err != nil { 65 | log.Fatalf("Failed to create certificate: %v", err) 66 | } 67 | writePemFile(certFileName, "CERTIFICATE", certBytes) 68 | } 69 | -------------------------------------------------------------------------------- /templates/articles.html: -------------------------------------------------------------------------------- 1 | {{define "articles"}} 2 | {{range .products}} 3 |
4 |
5 |
6 |
7 | 8 |
9 |
10 |
11 |
12 |
13 |

14 | {{.Name}} 15 |

16 |

18 | ********************************************************************************************************************************************************* 19 |

20 |
21 |
22 |
23 |
24 | {{end}} 25 | {{range .plugins}} 26 |
28 |
29 |
30 |
31 | 33 |
34 |
35 |
36 |
37 |
38 |

{{.Name}}

39 |

41 | ********************************************************************************************************************************************************* 42 |

43 |
44 |
45 |
46 |
47 | {{end}} 48 | {{end}} -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module Jetbrain-Helper 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/fsnotify/fsnotify v1.7.0 7 | github.com/gin-gonic/gin v1.9.1 8 | github.com/google/uuid v1.6.0 9 | github.com/mholt/archiver/v3 v3.5.1 10 | github.com/robfig/cron/v3 v3.0.1 11 | github.com/spf13/viper v1.18.2 12 | ) 13 | 14 | require ( 15 | github.com/andybalholm/brotli v1.0.1 // indirect 16 | github.com/bytedance/sonic v1.11.5 // indirect 17 | github.com/bytedance/sonic/loader v0.1.1 // indirect 18 | github.com/cloudwego/base64x v0.1.3 // indirect 19 | github.com/cloudwego/iasm v0.2.0 // indirect 20 | github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect 21 | github.com/gabriel-vasile/mimetype v1.4.3 // indirect 22 | github.com/gin-contrib/sse v0.1.0 // indirect 23 | github.com/go-playground/locales v0.14.1 // indirect 24 | github.com/go-playground/universal-translator v0.18.1 // indirect 25 | github.com/go-playground/validator/v10 v10.19.0 // indirect 26 | github.com/goccy/go-json v0.10.2 // indirect 27 | github.com/golang/snappy v0.0.2 // indirect 28 | github.com/hashicorp/hcl v1.0.0 // indirect 29 | github.com/json-iterator/go v1.1.12 // indirect 30 | github.com/klauspost/compress v1.17.0 // indirect 31 | github.com/klauspost/cpuid/v2 v2.2.7 // indirect 32 | github.com/klauspost/pgzip v1.2.5 // indirect 33 | github.com/leodido/go-urn v1.4.0 // indirect 34 | github.com/magiconair/properties v1.8.7 // indirect 35 | github.com/mattn/go-isatty v0.0.20 // indirect 36 | github.com/mitchellh/mapstructure v1.5.0 // indirect 37 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 38 | github.com/modern-go/reflect2 v1.0.2 // indirect 39 | github.com/nwaples/rardecode v1.1.0 // indirect 40 | github.com/pelletier/go-toml/v2 v2.2.1 // indirect 41 | github.com/pierrec/lz4/v4 v4.1.2 // indirect 42 | github.com/sagikazarmark/locafero v0.4.0 // indirect 43 | github.com/sagikazarmark/slog-shim v0.1.0 // indirect 44 | github.com/sourcegraph/conc v0.3.0 // indirect 45 | github.com/spf13/afero v1.11.0 // indirect 46 | github.com/spf13/cast v1.6.0 // indirect 47 | github.com/spf13/pflag v1.0.5 // indirect 48 | github.com/subosito/gotenv v1.6.0 // indirect 49 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 50 | github.com/ugorji/go/codec v1.2.12 // indirect 51 | github.com/ulikunitz/xz v0.5.9 // indirect 52 | github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect 53 | go.uber.org/atomic v1.9.0 // indirect 54 | go.uber.org/multierr v1.9.0 // indirect 55 | golang.org/x/arch v0.7.0 // indirect 56 | golang.org/x/crypto v0.22.0 // indirect 57 | golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect 58 | golang.org/x/net v0.24.0 // indirect 59 | golang.org/x/sys v0.19.0 // indirect 60 | golang.org/x/text v0.14.0 // indirect 61 | google.golang.org/protobuf v1.33.0 // indirect 62 | gopkg.in/ini.v1 v1.67.0 // indirect 63 | gopkg.in/yaml.v3 v3.0.1 // indirect 64 | ) 65 | -------------------------------------------------------------------------------- /router.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "Jetbrain-Helper/config" 5 | "Jetbrain-Helper/helper" 6 | "github.com/gin-gonic/gin" 7 | "io" 8 | "net/http" 9 | "strconv" 10 | "strings" 11 | ) 12 | 13 | func index(c *gin.Context) { 14 | c.HTML(http.StatusOK, "index.html", gin.H{ 15 | "products": helper.Products, 16 | "plugins": helper.Plugins, 17 | "defaults": config.Conf.License, 18 | }) 19 | } 20 | 21 | func search(c *gin.Context) { 22 | var filteredProductList []helper.ProductCache 23 | var filteredPluginList []helper.PluginCache 24 | search := c.Query("search") 25 | if search != "" { 26 | for _, productCache := range helper.Products { 27 | if strings.Contains(strings.ToLower(productCache.Name), strings.ToLower(search)) { 28 | filteredProductList = append(filteredProductList, productCache) 29 | } 30 | } 31 | for _, pluginCache := range helper.Plugins { 32 | if strings.Contains(strings.ToLower(pluginCache.Name), strings.ToLower(search)) { 33 | filteredPluginList = append(filteredPluginList, pluginCache) 34 | } 35 | } 36 | } else { 37 | filteredProductList = helper.Products 38 | filteredPluginList = helper.Plugins 39 | } 40 | c.HTML(http.StatusOK, "articles", gin.H{ 41 | "products": filteredProductList, 42 | "plugins": filteredPluginList, 43 | "defaults": config.Conf.License, 44 | }) 45 | } 46 | 47 | func generateLicense(c *gin.Context) { 48 | var req helper.GenerateLicenseReqBody 49 | if err := c.ShouldBindJSON(&req); err != nil { 50 | c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) 51 | return 52 | } 53 | var productCodeSet []string 54 | if req.ProductCode == "" { 55 | var productCodeList []string 56 | for _, product := range helper.Products { 57 | if product.ProductCode != "" { 58 | productCodeList = append(productCodeList, strings.Split(product.ProductCode, ",")...) 59 | } 60 | } 61 | for _, plugin := range helper.Plugins { 62 | if plugin.ProductCode != "" { 63 | productCodeList = append(productCodeList, plugin.ProductCode) 64 | } 65 | } 66 | } else { 67 | productCodeSet = append(productCodeSet, strings.Split(req.ProductCode, ",")...) 68 | } 69 | license, err := helper.GenerateLicense( 70 | req.LicenseName, 71 | req.AssigneeName, 72 | req.ExpiryDate, 73 | productCodeSet, 74 | ) 75 | if err != nil { 76 | c.String(http.StatusInternalServerError, err.Error()) 77 | } else { 78 | c.String(http.StatusOK, license) 79 | } 80 | } 81 | 82 | func download(c *gin.Context) { 83 | file := helper.OpenFile(helper.JaNetfilterZipFile) 84 | fileStat, err := file.Stat() 85 | if err != nil { 86 | c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get file info"}) 87 | return 88 | } 89 | c.Header("Content-Disposition", "attachment; filename=ja-netfilter.zip") 90 | c.Header("Content-Type", "application/octet-stream") 91 | c.Header("Content-Length", strconv.FormatInt(fileStat.Size(), 10)) 92 | // 将文件内容复制到响应主体 93 | _, err = io.Copy(c.Writer, file) 94 | if err != nil { 95 | c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to download file"}) 96 | return 97 | } 98 | 99 | c.Status(http.StatusOK) 100 | } 101 | -------------------------------------------------------------------------------- /helper/Refresh.go: -------------------------------------------------------------------------------- 1 | package helper 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "log" 7 | "net/http" 8 | "os" 9 | ) 10 | 11 | const ( 12 | PluginBasicUrl = "https://plugins.jetbrains.com" 13 | PluginListUrl = "/api/searchPlugins?max=10000&offset=0&orderBy=name" 14 | PluginInfoUrl = "/api/plugins/" 15 | ) 16 | 17 | func RefreshJsonFile() { 18 | log.Println("Init or Refresh plugin context from 'JetBrains.com' loading...") 19 | plugins, err := pluginList() 20 | if err != nil { 21 | log.Printf("Plugin context init or refresh failed: %v\n", err) 22 | return 23 | } 24 | 25 | filteredPlugins := pluginListFilter(plugins) 26 | pluginCaches := pluginConversion(filteredPlugins) 27 | 28 | overrideJsonFile(pluginCaches) 29 | 30 | log.Println("Init or Refresh plugin context success !") 31 | } 32 | 33 | func overrideJsonFile(pluginCaches []PluginCache) { 34 | Plugins = append(Plugins, pluginCaches...) 35 | 36 | jsonStr, err := json.Marshal(Plugins) 37 | if err != nil { 38 | log.Fatalf("%s File write failed: %v\n", plugins, err) 39 | return 40 | } 41 | 42 | err = os.WriteFile(plugins, jsonStr, 0644) 43 | if err != nil { 44 | log.Fatalf("%s File write failed: %v\n", plugins, err) 45 | return 46 | } 47 | } 48 | 49 | func pluginList() (PluginList, error) { 50 | resp, err := http.Get(PluginListUrl) 51 | if err != nil { 52 | return PluginList{}, err 53 | } 54 | defer resp.Body.Close() 55 | 56 | if resp.StatusCode != http.StatusOK { 57 | return PluginList{}, fmt.Errorf("The request failed = %d", resp.StatusCode) 58 | } 59 | 60 | var pluginList PluginList 61 | err = json.NewDecoder(resp.Body).Decode(&pluginList) 62 | if err != nil { 63 | return PluginList{}, err 64 | } 65 | 66 | return pluginList, nil 67 | } 68 | 69 | func pluginListFilter(pluginList PluginList) []Plugin { 70 | filteredPlugins := []Plugin{} 71 | for _, plugin := range pluginList.Plugins { 72 | if !contains(plugin.Id) && plugin.PricingModel != "FREE" { 73 | filteredPlugins = append(filteredPlugins, plugin) 74 | } 75 | } 76 | return filteredPlugins 77 | } 78 | 79 | func contains(pluginId int) bool { 80 | for _, plugin := range Plugins { 81 | if plugin.Id == pluginId { 82 | return true 83 | } 84 | } 85 | return false 86 | } 87 | 88 | func pluginConversion(pluginList []Plugin) []PluginCache { 89 | pluginCaches := []PluginCache{} 90 | for _, plugin := range pluginList { 91 | info, err := pluginInfo(plugin.Id) 92 | if err != nil { 93 | log.Printf("Failed to get plugin info: %v\n", err) 94 | continue 95 | } 96 | cache := PluginCache{ 97 | Id: plugin.Id, 98 | ProductCode: info.PurchaseInfo.ProductCode, 99 | Name: plugin.Name, 100 | PricingModel: plugin.PricingModel, 101 | Icon: PluginBasicUrl + plugin.Icon, 102 | } 103 | pluginCaches = append(pluginCaches, cache) 104 | } 105 | return pluginCaches 106 | } 107 | 108 | func pluginInfo(pluginId int) (PluginInfo, error) { 109 | resp, err := http.Get(PluginInfoUrl + fmt.Sprint(pluginId)) 110 | if err != nil { 111 | return PluginInfo{}, err 112 | } 113 | defer resp.Body.Close() 114 | 115 | if resp.StatusCode != http.StatusOK { 116 | return PluginInfo{}, fmt.Errorf("The request failed = %d", resp.StatusCode) 117 | } 118 | 119 | var pluginInfo PluginInfo 120 | err = json.NewDecoder(resp.Body).Decode(&pluginInfo) 121 | if err != nil { 122 | return PluginInfo{}, err 123 | } 124 | 125 | return pluginInfo, nil 126 | } 127 | -------------------------------------------------------------------------------- /static/js/index.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | // Set default headers for AJAX requests 3 | $.ajaxSetup({ 4 | headers: { 5 | 'Content-Type': 'application/json' 6 | } 7 | }); 8 | 9 | // Function to handle submission of license information 10 | window.submitLicenseInfo = function () { 11 | let licenseInfo = { 12 | licenseeName: $('#licenseeName').val(), 13 | assigneeName: $('#assigneeName').val(), 14 | expiryDate: $('#expiryDate').val() 15 | }; 16 | localStorage.setItem('licenseInfo', JSON.stringify(licenseInfo)); 17 | $('#mask, #form').hide(); 18 | }; 19 | 20 | // Function to handle search input 21 | $('#search').on('input', function (e) { 22 | $("#product-list").load('/search?search=' + e.target.value); 23 | }); 24 | 25 | // Function to show license form 26 | window.showLicenseForm = function () { 27 | let licenseInfo = JSON.parse(localStorage.getItem('licenseInfo')); 28 | $('#licenseeName').val(licenseInfo?.licenseeName || '碧蓝航线'); 29 | $('#assigneeName').val(licenseInfo?.assigneeName || '大和'); 30 | $('#expiryDate').val(licenseInfo?.expiryDate || '2030-12-31'); 31 | $('#mask, #form').show(); 32 | }; 33 | 34 | // Function to show VM options 35 | window.showVmoptins = function () { 36 | $('#config').val("-javaagent:/(Your Path)/ja-netfilter/ja-netfilter.jar\n" + 37 | "--add-opens=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED\n" + 38 | "--add-opens=java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED") 39 | $('#mask, #vmoptions').show(); 40 | }; 41 | 42 | // Function to copy license 43 | window.copyLicense = async function (e) { 44 | while (localStorage.getItem('licenseInfo') === null) { 45 | showLicenseForm(); 46 | await new Promise(r => setTimeout(r, 1000)); 47 | } 48 | let licenseInfo = JSON.parse(localStorage.getItem('licenseInfo')); 49 | let productCode = $(e).closest('.card').data('productCodes'); 50 | let data = { 51 | "licenseName": licenseInfo.licenseeName, 52 | "assigneeName": licenseInfo.assigneeName, 53 | "expiryDate": licenseInfo.expiryDate, 54 | "productCode": productCode, 55 | }; 56 | $.post('/generateLicense', JSON.stringify(data)) 57 | .then(response => { 58 | copyText(response) 59 | .then(() => { 60 | e.setAttribute('data-content', 'Copied!'); 61 | }) 62 | .catch(() => { 63 | e.setAttribute('data-content', 'Copy failed!'); 64 | }) 65 | .finally(() => { 66 | setTimeout(() => { 67 | e.setAttribute('data-content', 'Copy to clipboard'); 68 | }, 2000); 69 | }); 70 | }) 71 | .catch(() => { 72 | e.setAttribute('data-content', 'Copy failed!'); 73 | setTimeout(() => { 74 | e.setAttribute('data-content', 'Copy to clipboard'); 75 | }, 2000); 76 | }); 77 | }; 78 | 79 | // Function to copy text to clipboard 80 | const copyText = async (val) => { 81 | if (navigator.clipboard && navigator.permissions) { 82 | await navigator.clipboard.writeText(val); 83 | return "The activation code has been copied"; 84 | } else { 85 | console.log(val); 86 | return "The system does not support it, please go to the console to copy it manually"; 87 | } 88 | }; 89 | 90 | }); 91 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Jetbrains-Help 8 | 9 | 10 | 11 | 12 |
13 |

14 | 🇨🇳 Download ja-netfilter.zip , and configure 15 | your JetBrains's vmoptions!
16 | 🇨🇳 Also you can Refill license information to customizer your license!
17 | 🇨🇳 Please note that this page is only developed and used by 18 | {{.defaults.LicenseName}} 19 | / 20 | {{.defaults.AssigneeName}} 21 | personally! 22 | 23 |

24 |
25 | 26 |
27 |
28 |
29 | {{block "articles" .}} 30 | {{end}} 31 |
32 | 34 | 59 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /helper/Util.go: -------------------------------------------------------------------------------- 1 | package helper 2 | 3 | import ( 4 | "crypto" 5 | "crypto/ecdsa" 6 | "crypto/rand" 7 | "crypto/rsa" 8 | "crypto/sha1" 9 | "crypto/x509" 10 | "encoding/base64" 11 | "encoding/json" 12 | "encoding/pem" 13 | "errors" 14 | "log" 15 | "os" 16 | ) 17 | 18 | func ReadJson(path string, payload interface{}) error { 19 | content, err := os.ReadFile(path) 20 | if err != nil { 21 | return err 22 | } 23 | err = json.Unmarshal(content, &payload) 24 | if err != nil { 25 | return err 26 | } 27 | return nil 28 | } 29 | 30 | func OpenFile(path string) *os.File { 31 | file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0600) 32 | if err != nil { 33 | log.Fatalf("Failed to open or create file: %v", err) 34 | } 35 | return file 36 | } 37 | 38 | func FileExists(path string) bool { 39 | _, err := os.Stat(path) 40 | return !os.IsNotExist(err) 41 | } 42 | 43 | func readRSAPublicKey(file string) *rsa.PublicKey { 44 | key, err := readPemKey(file) 45 | if err != nil { 46 | log.Fatalf("无法解析公钥: %v", err) 47 | } 48 | pk := key.(*rsa.PublicKey) 49 | return pk 50 | } 51 | 52 | func readRSAPrivateKey(file string) *rsa.PrivateKey { 53 | key, err := readPemKey(file) 54 | if err != nil { 55 | log.Fatalf("无法解析私钥: %v", err) 56 | } 57 | pk := key.(*rsa.PrivateKey) 58 | return pk 59 | } 60 | 61 | func readX509Certificate(file string) *x509.Certificate { 62 | key, err := readPemKey(file) 63 | if err != nil { 64 | log.Fatalf("无法解析私钥: %v", err) 65 | } 66 | ck := key.(*x509.Certificate) 67 | return ck 68 | } 69 | 70 | func readPemKey(file string) (interface{}, error) { 71 | keyData, err := os.ReadFile(file) 72 | if err != nil { 73 | return nil, err 74 | } 75 | 76 | block, _ := pem.Decode(keyData) 77 | if block == nil { 78 | return nil, errors.New("failed to decode PEM block containing key") 79 | } 80 | 81 | switch block.Type { 82 | case "EC PRIVATE KEY": 83 | key, err := x509.ParseECPrivateKey(block.Bytes) 84 | if err != nil { 85 | key, err := x509.ParsePKCS8PrivateKey(block.Bytes) 86 | if err != nil { 87 | return nil, err 88 | } 89 | switch key := key.(type) { 90 | case *ecdsa.PrivateKey: 91 | return key, nil 92 | default: 93 | return nil, errors.New("unsupported private key type") 94 | } 95 | } 96 | return key, nil 97 | case "RSA PRIVATE KEY": 98 | key, err := x509.ParsePKCS1PrivateKey(block.Bytes) 99 | if err != nil { 100 | return nil, err 101 | } 102 | return key, nil 103 | case "PRIVATE KEY": 104 | key, err := x509.ParsePKCS8PrivateKey(block.Bytes) 105 | if err != nil { 106 | return nil, err 107 | } 108 | switch key := key.(type) { 109 | case *rsa.PrivateKey, *ecdsa.PrivateKey: 110 | return key, nil 111 | default: 112 | return nil, errors.New("unknown private key type") 113 | } 114 | case "EC PUBLIC KEY", "PUBLIC KEY": 115 | key, err := x509.ParsePKIXPublicKey(block.Bytes) 116 | if err != nil { 117 | return nil, err 118 | } 119 | switch key := key.(type) { 120 | case *ecdsa.PublicKey, *rsa.PublicKey: 121 | return key, nil 122 | default: 123 | return nil, errors.New("unknown public key type") 124 | } 125 | case "CERTIFICATE": 126 | cert, err := x509.ParseCertificate(block.Bytes) 127 | if err != nil { 128 | return nil, err 129 | } 130 | return cert, nil 131 | default: 132 | return nil, errors.New("unrecognized key type: " + block.Type) 133 | } 134 | } 135 | 136 | func writePemFile(fileName string, pemType string, bytes []byte) { 137 | file, err := os.Create(fileName) 138 | if err != nil { 139 | log.Fatalf("Failed to create file: %v", err) 140 | } 141 | defer func(file *os.File) { 142 | err := file.Close() 143 | if err != nil { 144 | log.Fatalf("Failed to close data to PEM file: %v", err) 145 | } 146 | }(file) 147 | 148 | pemBlock := &pem.Block{ 149 | Type: pemType, 150 | Bytes: bytes, 151 | } 152 | if err := pem.Encode(file, pemBlock); err != nil { 153 | log.Fatalf("Failed to write data to PEM file: %v", err) 154 | } 155 | } 156 | 157 | func signWithRSA(privateKey *rsa.PrivateKey, data []byte) string { 158 | // 对数据进行SHA1哈希 159 | hash := sha1.New() 160 | _, err := hash.Write(data) 161 | if err != nil { 162 | log.Fatalf("哈希计算失败: %v", err) 163 | } 164 | hashed := hash.Sum(nil) 165 | sign, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA1, hashed) 166 | if err != nil { 167 | log.Fatalf("Failed to sign: %v", err) 168 | } 169 | signature := base64.StdEncoding.EncodeToString(sign) 170 | return signature 171 | } 172 | -------------------------------------------------------------------------------- /helper/Agent.go: -------------------------------------------------------------------------------- 1 | package helper 2 | 3 | import ( 4 | "archive/zip" 5 | "crypto/rsa" 6 | "fmt" 7 | "github.com/mholt/archiver/v3" 8 | "io" 9 | "log" 10 | "math/big" 11 | "os" 12 | "path/filepath" 13 | "strings" 14 | ) 15 | 16 | const ( 17 | JaNetfilterFilePath = "external/agent/ja-netfilter" 18 | JaNetfilterZipFile = JaNetfilterFilePath + ".zip" 19 | powerConfFileName = JaNetfilterFilePath + "/config/power.conf" 20 | ) 21 | 22 | var jaNetfilterZipFile *os.File 23 | 24 | func InitAgent() { 25 | log.Println("Agent context init loading...") 26 | jaNetfilterZipFile, _ = getFileOrCreate(JaNetfilterZipFile) 27 | 28 | if _, err := os.Stat(JaNetfilterFilePath); os.IsNotExist(err) { 29 | unzipJaNetfilter() 30 | if !powerConfHasInit() { 31 | log.Println("Agent config init loading...") 32 | loadPowerConf() 33 | zipJaNetfilter() 34 | log.Println("Agent config init success!") 35 | } 36 | } 37 | log.Println("Agent context init success!") 38 | } 39 | 40 | func getFileOrCreate(fileName string) (*os.File, error) { 41 | return os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0600) 42 | } 43 | 44 | func powerConfHasInit() bool { 45 | data, err := os.ReadFile(powerConfFileName) 46 | if err != nil { 47 | log.Fatalf("Error reading file: %v", err) 48 | } 49 | powerConfStr := string(data) 50 | return strings.Contains(powerConfStr, "[Result]") && strings.Contains(powerConfStr, "EQUAL,") 51 | } 52 | 53 | func loadPowerConf() { 54 | ruleValue := generatePowerConfigRule() 55 | configStr := generatePowerConfigStr(ruleValue) 56 | overridePowerConfFileContent(configStr) 57 | } 58 | 59 | func generatePowerConfigRule() string { 60 | crt := readX509Certificate(certFileName) 61 | publicKey := readRSAPublicKey(publicKeyFileName) 62 | rootPublicKey := readX509Certificate(rootKeyFileName) 63 | 64 | x := new(big.Int).SetBytes(crt.Signature) 65 | y := big.NewInt(int64(publicKey.E)) 66 | z := rootPublicKey.PublicKey.(*rsa.PublicKey).N 67 | r := new(big.Int).Exp(x, y, publicKey.N) 68 | return fmt.Sprintf("EQUAL,%s,%s,%s->%s", x, y, z, r) 69 | } 70 | 71 | func generatePowerConfigStr(ruleValue string) string { 72 | return "[Result]\n" + ruleValue 73 | } 74 | 75 | func overridePowerConfFileContent(configStr string) { 76 | if err := os.WriteFile(powerConfFileName, []byte(configStr), 0644); err != nil { 77 | log.Fatalf("Error writing file: %v", err) 78 | } 79 | } 80 | 81 | func unzipJaNetfilter() { 82 | if err := archiver.Unarchive(jaNetfilterZipFile.Name(), JaNetfilterFilePath); err != nil { 83 | log.Fatalf("Failed to unzip file: %v", err) 84 | } 85 | } 86 | 87 | func zipJaNetfilter() { 88 | // 检查是否已存在同名的 zip 文件 89 | if _, err := os.Stat(JaNetfilterZipFile); err == nil { 90 | // 如果存在,重命名之前的文件 91 | newName := JaNetfilterFilePath + "_old.zip" 92 | err := os.Rename(JaNetfilterZipFile, newName) 93 | if err != nil { 94 | fmt.Println("Failed to rename existing zip file:", err) 95 | return 96 | } 97 | defer func(name string) { 98 | err := os.Remove(name) 99 | if err != nil { 100 | log.Fatalf("Failed to remove existing zip file: %v", err) 101 | } 102 | }(newName) // 在压缩完成后删除旧的 zip 文件 103 | fmt.Println("Existing zip file renamed to:", newName) 104 | } 105 | 106 | // 创建一个新的 zip 文件 107 | zipFile, err := os.Create(JaNetfilterZipFile) 108 | if err != nil { 109 | fmt.Println(err) 110 | return 111 | } 112 | defer func(zipFile *os.File) { 113 | err := zipFile.Close() 114 | if err != nil { 115 | if err != nil { 116 | log.Fatalf("Failed to close data to zip file: %v", err) 117 | } 118 | } 119 | }(zipFile) 120 | 121 | // 创建一个 zip.Writer 122 | zipWriter := zip.NewWriter(zipFile) 123 | defer func(zipWriter *zip.Writer) { 124 | err := zipWriter.Close() 125 | if err != nil { 126 | log.Fatalf("Failed to close data to zip writer: %v", err) 127 | } 128 | }(zipWriter) 129 | 130 | // 递归地压缩目录中的文件 131 | err = filepath.Walk(JaNetfilterFilePath, func(filePath string, info os.FileInfo, err error) error { 132 | if err != nil { 133 | return err 134 | } 135 | 136 | // 跳过.DS_Store文件 137 | if strings.HasSuffix(info.Name(), ".DS_Store") { 138 | return nil 139 | } 140 | 141 | // 获取文件头信息 142 | header, err := zip.FileInfoHeader(info) 143 | if err != nil { 144 | return err 145 | } 146 | 147 | // 设置文件名 148 | header.Name, err = filepath.Rel(JaNetfilterFilePath, filePath) 149 | if err != nil { 150 | return err 151 | } 152 | 153 | // 在 Windows 下修复 zip 文件中的路径分隔符 154 | header.Name = strings.ReplaceAll(header.Name, "\\", "/") 155 | 156 | // 如果是目录,只添加目录名到 zip 文件中 157 | if info.IsDir() { 158 | header.Name += "/" 159 | } 160 | 161 | // 创建一个 zip 文件中的新文件 162 | writer, err := zipWriter.CreateHeader(header) 163 | if err != nil { 164 | return err 165 | } 166 | 167 | // 如果是文件,将文件内容拷贝到 zip 文件中 168 | if !info.IsDir() { 169 | file, err := os.Open(filePath) 170 | if err != nil { 171 | return err 172 | } 173 | defer func(file *os.File) { 174 | err := file.Close() 175 | if err != nil { 176 | log.Fatalf("Failed to close data to zip file: %v", err) 177 | } 178 | }(file) 179 | 180 | _, err = io.Copy(writer, file) 181 | if err != nil { 182 | return err 183 | } 184 | } 185 | 186 | return nil 187 | }) 188 | 189 | if err != nil { 190 | fmt.Println(err) 191 | return 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /static/css/index.css: -------------------------------------------------------------------------------- 1 | .form { 2 | background-color: #15172b; 3 | border-radius: 20px; 4 | box-sizing: border-box; 5 | height: 500px; 6 | padding: 20px; 7 | width: 320px; 8 | } 9 | 10 | .title { 11 | color: #eee; 12 | font-family: sans-serif; 13 | font-size: 36px; 14 | font-weight: 600; 15 | margin-top: 30px; 16 | } 17 | 18 | .subtitle { 19 | color: #eee; 20 | font-family: sans-serif; 21 | font-size: 16px; 22 | font-weight: 600; 23 | margin-top: 10px; 24 | } 25 | 26 | .input-container { 27 | height: 50px; 28 | position: relative; 29 | width: 100%; 30 | } 31 | 32 | .ic1 { 33 | margin-top: 40px; 34 | } 35 | 36 | .ic2 { 37 | margin-top: 30px; 38 | } 39 | 40 | .input { 41 | background-color: #303245; 42 | border-radius: 12px; 43 | border: 0; 44 | box-sizing: border-box; 45 | color: #eee; 46 | font-size: 18px; 47 | height: 100%; 48 | outline: 0; 49 | padding: 4px 20px 0; 50 | width: 100%; 51 | } 52 | 53 | .cut { 54 | background-color: #15172b; 55 | border-radius: 10px; 56 | height: 20px; 57 | left: 20px; 58 | position: absolute; 59 | top: -20px; 60 | transform: translateY(0); 61 | transition: transform 200ms; 62 | width: 76px; 63 | } 64 | 65 | .cut-short { 66 | width: 50px; 67 | } 68 | 69 | .input:focus ~ .cut, 70 | .input:not(:placeholder-shown) ~ .cut { 71 | transform: translateY(8px); 72 | } 73 | 74 | .placeholder { 75 | color: #65657b; 76 | font-family: sans-serif; 77 | left: 20px; 78 | line-height: 14px; 79 | pointer-events: none; 80 | position: absolute; 81 | transform-origin: 0 50%; 82 | transition: transform 200ms, color 200ms; 83 | top: 20px; 84 | } 85 | 86 | .input:focus ~ .placeholder, 87 | .input:not(:placeholder-shown) ~ .placeholder { 88 | transform: translateY(-30px) translateX(10px) scale(0.75); 89 | } 90 | 91 | .input:not(:placeholder-shown) ~ .placeholder { 92 | color: #808097; 93 | } 94 | 95 | .input:focus ~ .placeholder { 96 | color: #dc2f55; 97 | } 98 | 99 | .submit { 100 | background-color: #08d; 101 | border-radius: 12px; 102 | border: 0; 103 | box-sizing: border-box; 104 | color: #eee; 105 | cursor: pointer; 106 | font-size: 18px; 107 | height: 50px; 108 | margin-top: 38px; 109 | text-align: center; 110 | width: 100%; 111 | } 112 | 113 | .submit:active { 114 | background-color: #06b; 115 | } 116 | 117 | :root { 118 | --text-grey: #9e9e9e; 119 | --text-main: rgba(0, 0, 0, 0.87); 120 | --spacing: 4px; 121 | --size: 64px; 122 | --radius: 1.5rem; 123 | --accent: #5380f7; 124 | --text-sm: 0.875rem; 125 | --main-bg: #fff; 126 | --card-bg: #fff; 127 | --hover-color: #eee; 128 | --border-color: rgba(0, 0, 0, 0.05); 129 | --grey-400: rgba(0, 0, 0, 0.04); 130 | --grey-600: rgba(0, 0, 0, 0.06); 131 | } 132 | 133 | @media (prefers-color-scheme: dark) { 134 | :root { 135 | --main-bg: rgb(0, 0, 0); 136 | --card-bg: rgb(31, 34, 38); 137 | --text-main: #d9d9d9; 138 | --text-grey: #6e767d; 139 | --accent: #1d9bf0; 140 | --hover-color: rgba(255, 255, 255, 0.07); 141 | --border-color: #4b4648; 142 | } 143 | } 144 | 145 | body { 146 | font-size: 1rem; 147 | line-height: 1.5; 148 | word-wrap: break-word; 149 | font-kerning: normal; 150 | font-family: 'Gotham SSm A', 'Gotham SSm B', 'Arial Unicode MS', Helvetica, sans-serif; 151 | margin: 0; 152 | padding: 0; 153 | -webkit-font-smoothing: antialiased; 154 | background-color: var(--main-bg); 155 | } 156 | 157 | * ul, * ol { 158 | list-style: none; 159 | padding: 0; 160 | margin: 0; 161 | } 162 | 163 | *[role='button'], button { 164 | cursor: pointer; 165 | } 166 | 167 | .color-primary { 168 | color: var(--text-main); 169 | } 170 | 171 | 172 | .mt-0 { 173 | margin-top: 0; 174 | } 175 | 176 | 177 | .radius-1 { 178 | border-radius: var(--radius); 179 | } 180 | 181 | .px-6 { 182 | padding-left: calc(var(--spacing) * 6); 183 | padding-right: calc(var(--spacing) * 6); 184 | } 185 | 186 | .py-6 { 187 | padding-left: calc(var(--spacing) * 6); 188 | padding-right: calc(var(--spacing) * 6); 189 | } 190 | 191 | .py-10 { 192 | padding-top: calc(var(--spacing) * 10); 193 | padding-bottom: calc(var(--spacing) * 10); 194 | } 195 | 196 | .pd-6 { 197 | padding: calc(var(--spacing) * 6); 198 | } 199 | 200 | 201 | .pt-1 { 202 | padding-top: var(--spacing); 203 | } 204 | 205 | .pb-0 { 206 | padding-bottom: 0; 207 | } 208 | 209 | .overflow-hidden { 210 | overflow: hidden; 211 | } 212 | 213 | .flex { 214 | display: flex; 215 | } 216 | 217 | .justify-between { 218 | justify-content: space-between; 219 | } 220 | 221 | .justify-center { 222 | justify-content: center; 223 | } 224 | 225 | 226 | .items-center { 227 | align-items: center; 228 | } 229 | 230 | .shrink-0 { 231 | flex-shrink: 0; 232 | } 233 | 234 | .text-grey { 235 | color: var(--text-grey); 236 | } 237 | 238 | .text-sm { 239 | font-size: 0.875rem; 240 | } 241 | 242 | .bg-card { 243 | background-color: var(--card-bg); 244 | } 245 | 246 | .truncate { 247 | /* display: -webkit-box; */ 248 | /* -webkit-box-orient: vertical; */ 249 | /* -webkit-line-clamp: var(--line, 3); */ 250 | /* overflow: hidden; */ 251 | } 252 | 253 | .truncate-1 { 254 | --line: 1; 255 | } 256 | 257 | .overflow-ellipsis { 258 | text-overflow: ellipsis; 259 | } 260 | 261 | .z-grid { 262 | display: grid; 263 | grid-gap: var(--gutter, 1rem); 264 | grid-template-columns: repeat(auto-fill, minmax(min(var(--space, 10rem), 100%), 1fr)); 265 | } 266 | 267 | 268 | .card { 269 | box-shadow: rgb(0 0 0 / 30%) 0 8px 40px -12px; 270 | border-radius: 1.5rem; 271 | transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1) 0ms; 272 | width: 90%; 273 | position: relative; 274 | overflow: visible; 275 | background-color: var(--card-bg); 276 | margin: 0 auto; 277 | } 278 | 279 | .card:hover { 280 | transform: translateY(-2px); 281 | } 282 | 283 | .card:hover .mask { 284 | bottom: -1.5rem; 285 | } 286 | 287 | .card:hover .mask-c-1 { 288 | bottom: -2.5rem; 289 | } 290 | 291 | .container { 292 | padding-top: calc(var(--spacing) * 10); 293 | } 294 | 295 | .container p { 296 | position: relative; 297 | cursor: pointer; 298 | transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; 299 | } 300 | 301 | .container p::after { 302 | content: attr(data-content); 303 | position: absolute; 304 | transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; 305 | color: transparent; 306 | top: 0; 307 | left: 0; 308 | width: 100%; 309 | height: 100%; 310 | display: flex; 311 | align-items: center; 312 | justify-content: center; 313 | border-radius: var(--radius); 314 | } 315 | 316 | .container p:hover { 317 | color: transparent; 318 | } 319 | 320 | .container p:hover::after { 321 | color: var(--text-main); 322 | background-color: var(--hover-color); 323 | } 324 | 325 | .toggle li { 326 | z-index: 99; 327 | position: relative; 328 | background: transparent; 329 | padding: 0 20px; 330 | color: var(--text-main); 331 | transition: background-color 250ms ease-out; 332 | } 333 | 334 | .toggle li:hover { 335 | background-color: var(--hover-color); 336 | } 337 | 338 | .toggle li.active a { 339 | color: var(--accent); 340 | } 341 | 342 | .toggle li:first-child { 343 | border-top-left-radius: var(--text-sm); 344 | border-top-right-radius: var(--text-sm); 345 | } 346 | 347 | .toggle li:last-child { 348 | border-bottom-left-radius: var(--text-sm); 349 | border-bottom-right-radius: var(--text-sm); 350 | } 351 | 352 | .toggle li:last-child a { 353 | border-bottom: 0; 354 | } 355 | 356 | .toggle li a { 357 | display: block; 358 | border-bottom: 1px solid var(--border-color); 359 | padding: 16px 0; 360 | color: inherit; 361 | text-decoration: none; 362 | white-space: nowrap; 363 | } 364 | 365 | .icon { 366 | background-image: url('../images/icons.svg?t=4567'); 367 | background-size: 64px; 368 | background-position-x: 0; 369 | } 370 | 371 | .icon-al { 372 | background-position-y: -1728px; 373 | } 374 | 375 | .icon-ii { 376 | background-position-y: -448px; 377 | } 378 | 379 | .icon-ps { 380 | background-position-y: -512px; 381 | } 382 | 383 | .icon-ac { 384 | background-position-y: -192px; 385 | } 386 | 387 | .icon-db { 388 | background-position-y: -320px; 389 | } 390 | 391 | .icon-rm { 392 | background-position-y: -896px; 393 | } 394 | 395 | .icon-ws { 396 | background-position-y: -960px; 397 | } 398 | 399 | .icon-rd { 400 | background-position-y: -832px; 401 | } 402 | 403 | .icon-cl { 404 | background-position-y: -256px; 405 | } 406 | 407 | .icon-pc { 408 | background-position-y: -576px; 409 | } 410 | 411 | .icon-go { 412 | background-position-y: -384px; 413 | } 414 | 415 | .icon-ds { 416 | background-position-y: -1792px; 417 | } 418 | 419 | .icon-dc { 420 | background-position-y: -1408px; 421 | } 422 | 423 | .icon-dpn { 424 | background-position-y: -1536px; 425 | } 426 | 427 | .icon-dm { 428 | background-position-y: -1472px; 429 | } 430 | 431 | .mask { 432 | transition: 0.2s; 433 | position: absolute; 434 | z-index: -1; 435 | width: 88%; 436 | height: 100%; 437 | bottom: 0; 438 | border-radius: 1.5rem; 439 | background-color: var(--grey-600); 440 | left: 50%; 441 | transform: translateX(-50%); 442 | } 443 | 444 | .mask-c-1 { 445 | bottom: 0; 446 | width: 72%; 447 | background-color: var(--grey-400); 448 | } 449 | 450 | .avatar-wrapper { 451 | position: relative; 452 | width: var(--size); 453 | height: var(--size); 454 | font-size: 1.25rem; 455 | user-select: none; 456 | transform: translateY(50%); 457 | } 458 | 459 | .avatar-wrapper img, .avatar-wrapper .icon { 460 | width: 100%; 461 | height: 100%; 462 | margin: 0; 463 | background-color: var(--card-bg); 464 | color: transparent; 465 | object-fit: cover; 466 | text-align: center; 467 | text-indent: 10000px; 468 | } 469 | 470 | 471 | header.tip a { 472 | color: var(--accent); 473 | text-decoration: none; 474 | } 475 | 476 | header.tip p { 477 | word-break: break-word; 478 | word-wrap: break-word; 479 | } 480 | 481 | 482 | main hr { 483 | margin: 0; 484 | padding: 0; 485 | background: var(--border-color); 486 | height: 1px; 487 | border: none; 488 | } 489 | 490 | footer { 491 | --_size: 40px; 492 | padding-top: var(--_size); 493 | width: 96%; 494 | margin: calc(var(--spacing) * 10) auto 0; 495 | padding-bottom: var(--_size); 496 | border-top: 1px solid var(--border-color); 497 | -moz-box-align: center; 498 | -webkit-box-pack: justify; 499 | } 500 | 501 | footer .lt-panel p:nth-of-type(1) { 502 | color: inherit; 503 | } 504 | 505 | header.tip { 506 | top: 2.3%; 507 | background-color: var(--card-bg); 508 | color: var(--text-main); 509 | z-index: 99; 510 | width: 80%; 511 | margin: 0 auto; 512 | border-radius: 16px; 513 | box-shadow: rgb(0 0 0 / 30%) 0 8px 40px -12px; 514 | transition: transform 250ms ease, box-shadow 250ms ease; 515 | } 516 | 517 | .sticky { 518 | position: sticky; 519 | } 520 | 521 | 522 | .parent { 523 | position: relative; 524 | } 525 | 526 | .search { 527 | width: 300px; 528 | height: 40px; 529 | border-radius: 18px; 530 | outline: none; 531 | /*border: 1px solid #ccc;*/ 532 | padding-left: 20px; 533 | /*position: absolute;*/ 534 | } -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc= 2 | github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= 3 | github.com/bytedance/sonic v1.11.5 h1:G00FYjjqll5iQ1PYXynbg/hyzqBqavH8Mo9/oTopd9k= 4 | github.com/bytedance/sonic v1.11.5/go.mod h1:X2PC2giUdj/Cv2lliWFLk6c/DUQok5rViJSemeB0wDw= 5 | github.com/bytedance/sonic/loader v0.1.0/go.mod h1:UmRT+IRTGKz/DAkzcEGzyVqQFJ7H9BqwBO3pm9H/+HY= 6 | github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= 7 | github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= 8 | github.com/cloudwego/base64x v0.1.3 h1:b5J/l8xolB7dyDTTmhJP2oTs5LdrjyrUFuNxdfq5hAg= 9 | github.com/cloudwego/base64x v0.1.3/go.mod h1:1+1K5BUHIQzyapgpF7LwvOGAEDicKtt1umPV+aN8pi8= 10 | github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= 11 | github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= 12 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 13 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 14 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= 15 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 16 | github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY= 17 | github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s= 18 | github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= 19 | github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= 20 | github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= 21 | github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= 22 | github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= 23 | github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= 24 | github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= 25 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 26 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 27 | github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= 28 | github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= 29 | github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= 30 | github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 31 | github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= 32 | github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= 33 | github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= 34 | github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= 35 | github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4= 36 | github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= 37 | github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= 38 | github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= 39 | github.com/golang/snappy v0.0.2 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw= 40 | github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 41 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 42 | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= 43 | github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 44 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 45 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 46 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 47 | github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= 48 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= 49 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 50 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 51 | github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= 52 | github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= 53 | github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= 54 | github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= 55 | github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= 56 | github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= 57 | github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= 58 | github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= 59 | github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= 60 | github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= 61 | github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= 62 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 63 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 64 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 65 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 66 | github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= 67 | github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= 68 | github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= 69 | github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= 70 | github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 71 | github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 72 | github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo= 73 | github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= 74 | github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= 75 | github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 76 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 77 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 78 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 79 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 80 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 81 | github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ= 82 | github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= 83 | github.com/pelletier/go-toml/v2 v2.2.1 h1:9TA9+T8+8CUCO2+WYnDLCgrYi9+omqKXyjDtosvtEhg= 84 | github.com/pelletier/go-toml/v2 v2.2.1/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= 85 | github.com/pierrec/lz4/v4 v4.1.2 h1:qvY3YFXRQE/XB8MlLzJH7mSzBs74eA2gg52YTk6jUPM= 86 | github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= 87 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 88 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= 89 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 90 | github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= 91 | github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= 92 | github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= 93 | github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= 94 | github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= 95 | github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= 96 | github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= 97 | github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= 98 | github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= 99 | github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= 100 | github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= 101 | github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= 102 | github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= 103 | github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= 104 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 105 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 106 | github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= 107 | github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= 108 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 109 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 110 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 111 | github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= 112 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 113 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 114 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 115 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 116 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 117 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 118 | github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 119 | github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 120 | github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= 121 | github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= 122 | github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= 123 | github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= 124 | github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= 125 | github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= 126 | github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= 127 | github.com/ulikunitz/xz v0.5.9 h1:RsKRIA2MO8x56wkkcd3LbtcE/uMszhb6DpRf+3uwa3I= 128 | github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= 129 | github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= 130 | github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= 131 | go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= 132 | go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= 133 | go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= 134 | go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= 135 | golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= 136 | golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= 137 | golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= 138 | golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= 139 | golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= 140 | golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= 141 | golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= 142 | golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= 143 | golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= 144 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 145 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 146 | golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= 147 | golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 148 | golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= 149 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 150 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 151 | google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= 152 | google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 153 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 154 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= 155 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 156 | gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= 157 | gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 158 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 159 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 160 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 161 | nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= 162 | rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= 163 | -------------------------------------------------------------------------------- /external/data/plugin.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 9269, 4 | "productCode": "PAEMIDE", 5 | "name": "AEM IDE", 6 | "pricingModel": "PAID", 7 | "icon": "https://plugins.jetbrains.com/files/9269/503057/icon/pluginIcon.svg" 8 | }, 9 | { 10 | "id": 9863, 11 | "productCode": "PAEM", 12 | "name": "AEM Support", 13 | "pricingModel": "PAID", 14 | "icon": "https://plugins.jetbrains.com/files/9863/509753/icon/pluginIcon.svg" 15 | }, 16 | { 17 | "id": 21263, 18 | "productCode": "PAICODING", 19 | "name": "AI Coding", 20 | "pricingModel": "PAID", 21 | "icon": "https://plugins.jetbrains.com/files/21263/513630/icon/pluginIcon.svg" 22 | }, 23 | { 24 | "id": 21289, 25 | "productCode": "PCAICOMMITAPP", 26 | "name": "AICommit", 27 | "pricingModel": "PAID", 28 | "icon": "https://plugins.jetbrains.com/files/21289/504423/icon/pluginIcon.svg" 29 | }, 30 | { 31 | "id": 12408, 32 | "productCode": "PBISAA", 33 | "name": "Android Antidecompiler", 34 | "pricingModel": "PAID", 35 | "icon": "https://plugins.jetbrains.com/files/12408/229970/icon/pluginIcon.svg" 36 | }, 37 | { 38 | "id": 15456, 39 | "productCode": "PAPH", 40 | "name": "Android Package Helper", 41 | "pricingModel": "PAID", 42 | "icon": "https://plugins.jetbrains.com/files/15456/104869/icon/pluginIcon.svg" 43 | }, 44 | { 45 | "id": 13156, 46 | "productCode": "PWIFIADB", 47 | "name": "Android WiFiADB", 48 | "pricingModel": "PAID", 49 | "icon": "https://plugins.jetbrains.com/files/13156/154275/icon/pluginIcon.svg" 50 | }, 51 | { 52 | "id": 9707, 53 | "productCode": "PANSIHIGHLIGHT", 54 | "name": "ANSI Highlighter Premium", 55 | "pricingModel": "PAID", 56 | "icon": "https://plugins.jetbrains.com/files/9707/518674/icon/pluginIcon.svg" 57 | }, 58 | { 59 | "id": 18357, 60 | "productCode": "PCDAPIRUNNER", 61 | "name": "API Runner", 62 | "pricingModel": "PAID", 63 | "icon": "https://plugins.jetbrains.com/files/18357/269544/icon/pluginIcon.svg" 64 | }, 65 | { 66 | "id": 16682, 67 | "productCode": "PAPPLETRUNNER", 68 | "name": "Applet Runner", 69 | "pricingModel": "FREEMIUM", 70 | "icon": "https://plugins.jetbrains.com/files/16682/506565/icon/pluginIcon.svg" 71 | }, 72 | { 73 | "id": 21566, 74 | "productCode": "PARMADILLO", 75 | "name": "Armadillo", 76 | "pricingModel": "FREEMIUM", 77 | "icon": "https://plugins.jetbrains.com/files/21566/354792/icon/pluginIcon.svg" 78 | }, 79 | { 80 | "id": 17699, 81 | "productCode": "PASTOCK", 82 | "name": "AStock", 83 | "pricingModel": "PAID", 84 | "icon": "https://plugins.jetbrains.com/files/17699/468853/icon/pluginIcon.svg" 85 | }, 86 | { 87 | "id": 13016, 88 | "productCode": "PATOMONEDARK", 89 | "name": "Atom One Dark By Mayke", 90 | "pricingModel": "PAID", 91 | "icon": "https://plugins.jetbrains.com/files/13016/122178/icon/pluginIcon.svg" 92 | }, 93 | { 94 | "id": 14088, 95 | "productCode": "PGOLANGCODESUGG", 96 | "name": "Auto GOLang Code Suggestions", 97 | "pricingModel": "PAID", 98 | "icon": "https://plugins.jetbrains.com/files/14088/191484/icon/pluginIcon.svg" 99 | }, 100 | { 101 | "id": 14070, 102 | "productCode": "PJAVACODESUGG", 103 | "name": "Auto Java Code Suggestions", 104 | "pricingModel": "PAID", 105 | "icon": "https://plugins.jetbrains.com/files/14070/191711/icon/pluginIcon.svg" 106 | }, 107 | { 108 | "id": 14166, 109 | "productCode": "PJSCODESUGG", 110 | "name": "Auto Javascript Code Suggestions", 111 | "pricingModel": "PAID", 112 | "icon": "https://plugins.jetbrains.com/files/14166/191485/icon/pluginIcon.svg" 113 | }, 114 | { 115 | "id": 14167, 116 | "productCode": "PPHPCODESUGG", 117 | "name": "Auto PHP Code Suggestions", 118 | "pricingModel": "PAID", 119 | "icon": "https://plugins.jetbrains.com/files/14167/191710/icon/pluginIcon.svg" 120 | }, 121 | { 122 | "id": 14594, 123 | "productCode": "PPYCODESUGG", 124 | "name": "Auto Python Code Suggestions", 125 | "pricingModel": "PAID", 126 | "icon": "https://plugins.jetbrains.com/files/14594/190896/icon/pluginIcon.svg" 127 | }, 128 | { 129 | "id": 14089, 130 | "productCode": "PRUBYCODESUGG", 131 | "name": "Auto Ruby Code Suggestions", 132 | "pricingModel": "PAID", 133 | "icon": "https://plugins.jetbrains.com/files/14089/191482/icon/pluginIcon.svg" 134 | }, 135 | { 136 | "id": 10904, 137 | "productCode": "PBRWJV", 138 | "name": "AutoCode for Java", 139 | "pricingModel": "PAID", 140 | "icon": "https://plugins.jetbrains.com" 141 | }, 142 | { 143 | "id": 23577, 144 | "productCode": "PAUTOLOG", 145 | "name": "AutoLog", 146 | "pricingModel": "PAID", 147 | "icon": "https://plugins.jetbrains.com/files/23577/473858/icon/pluginIcon.svg" 148 | }, 149 | { 150 | "id": 14742, 151 | "productCode": "PAWSLAMBDADEPLR", 152 | "name": "AWS Lambda Deployer", 153 | "pricingModel": "PAID", 154 | "icon": "https://plugins.jetbrains.com" 155 | }, 156 | { 157 | "id": 22319, 158 | "productCode": "PAZD", 159 | "name": "Azd", 160 | "pricingModel": "PAID", 161 | "icon": "https://plugins.jetbrains.com/files/22319/517134/icon/pluginIcon.svg" 162 | }, 163 | { 164 | "id": 22194, 165 | "productCode": "PAZURECODING", 166 | "name": "Azure Coding", 167 | "pricingModel": "PAID", 168 | "icon": "https://plugins.jetbrains.com/files/22194/355932/icon/pluginIcon.svg" 169 | }, 170 | { 171 | "id": 13841, 172 | "productCode": "PBASHSUPPORTPRO", 173 | "name": "BashSupport Pro", 174 | "pricingModel": "PAID", 175 | "icon": "https://plugins.jetbrains.com/files/13841/514417/icon/pluginIcon.svg" 176 | }, 177 | { 178 | "id": 12895, 179 | "productCode": "PBETTERHIGHLIGH", 180 | "name": "Better Highlights", 181 | "pricingModel": "FREEMIUM", 182 | "icon": "https://plugins.jetbrains.com/files/12895/514904/icon/pluginIcon.svg" 183 | }, 184 | { 185 | "id": 13538, 186 | "productCode": "PCREVIEW", 187 | "name": "Bitbucket Pull Requests", 188 | "pricingModel": "PAID", 189 | "icon": "https://plugins.jetbrains.com/files/13538/516839/icon/pluginIcon.svg" 190 | }, 191 | { 192 | "id": 16222, 193 | "productCode": "PBITRISECI", 194 | "name": "Bitrise Dashboard", 195 | "pricingModel": "PAID", 196 | "icon": "https://plugins.jetbrains.com/files/16222/463944/icon/pluginIcon.svg" 197 | }, 198 | { 199 | "id": 20061, 200 | "productCode": "PBREWBUNDLE", 201 | "name": "Brew Bundle", 202 | "pricingModel": "PAID", 203 | "icon": "https://plugins.jetbrains.com/files/20061/471756/icon/pluginIcon.svg" 204 | }, 205 | { 206 | "id": 20985, 207 | "productCode": "PBUILDMON", 208 | "name": "Build Monitor", 209 | "pricingModel": "FREEMIUM", 210 | "icon": "https://plugins.jetbrains.com/files/20985/452340/icon/pluginIcon.svg" 211 | }, 212 | { 213 | "id": 17692, 214 | "productCode": "PCAPELASTIC", 215 | "name": "Cap-Elasticsearch", 216 | "pricingModel": "PAID", 217 | "icon": "https://plugins.jetbrains.com/files/17692/256059/icon/pluginIcon.svg" 218 | }, 219 | { 220 | "id": 17785, 221 | "productCode": "PCAPREDIS", 222 | "name": "Cap-Redis", 223 | "pricingModel": "PAID", 224 | "icon": "https://plugins.jetbrains.com/files/17785/256060/icon/pluginIcon.svg" 225 | }, 226 | { 227 | "id": 21314, 228 | "productCode": "PCHATGPTCODING", 229 | "name": "ChatGPT Coding", 230 | "pricingModel": "PAID", 231 | "icon": "https://plugins.jetbrains.com/files/21314/346162/icon/pluginIcon.svg" 232 | }, 233 | { 234 | "id": 19114, 235 | "productCode": "PCIINTG", 236 | "name": "CIclone", 237 | "pricingModel": "PAID", 238 | "icon": "https://plugins.jetbrains.com/files/19114/472822/icon/pluginIcon.svg" 239 | }, 240 | { 241 | "id": 15458, 242 | "productCode": "PCIRCLECI", 243 | "name": "CircleCI Dashboard", 244 | "pricingModel": "PAID", 245 | "icon": "https://plugins.jetbrains.com/files/15458/463945/icon/pluginIcon.svg" 246 | }, 247 | { 248 | "id": 22813, 249 | "productCode": "PCITRIC", 250 | "name": "Citric", 251 | "pricingModel": "PAID", 252 | "icon": "https://plugins.jetbrains.com/files/22813/515382/icon/pluginIcon.svg" 253 | }, 254 | { 255 | "id": 23887, 256 | "productCode": "PCLAI", 257 | "name": "CLAi", 258 | "pricingModel": "PAID", 259 | "icon": "https://plugins.jetbrains.com/files/23887/515259/icon/pluginIcon.svg" 260 | }, 261 | { 262 | "id": 12869, 263 | "productCode": "PCMAKEPLUS", 264 | "name": "CMake Plus", 265 | "pricingModel": "PAID", 266 | "icon": "https://plugins.jetbrains.com/files/12869/496990/icon/pluginIcon.svg" 267 | }, 268 | { 269 | "id": 17501, 270 | "productCode": "PISCRATCH", 271 | "name": "Code Note: In IDE Note-Taking, Project Notes", 272 | "pricingModel": "PAID", 273 | "icon": "https://plugins.jetbrains.com/files/17501/509149/icon/pluginIcon.svg" 274 | }, 275 | { 276 | "id": 18394, 277 | "productCode": "PCODEREFACTORAI", 278 | "name": "Code Refactor AI", 279 | "pricingModel": "PAID", 280 | "icon": "https://plugins.jetbrains.com/files/18394/153532/icon/pluginIcon.svg" 281 | }, 282 | { 283 | "id": 14896, 284 | "productCode": "PCWMP", 285 | "name": "Code With Me", 286 | "pricingModel": "FREEMIUM", 287 | "icon": "https://plugins.jetbrains.com" 288 | }, 289 | { 290 | "id": 19097, 291 | "productCode": "PWGCODECREATOR", 292 | "name": "codeCreator", 293 | "pricingModel": "FREEMIUM", 294 | "icon": "https://plugins.jetbrains.com" 295 | }, 296 | { 297 | "id": 19578, 298 | "productCode": "PCODEKITS", 299 | "name": "CodeKits", 300 | "pricingModel": "FREEMIUM", 301 | "icon": "https://plugins.jetbrains.com/files/19578/302019/icon/pluginIcon.svg" 302 | }, 303 | { 304 | "id": 10811, 305 | "productCode": "PCODEMRBASE", 306 | "name": "CodeMR", 307 | "pricingModel": "PAID", 308 | "icon": "https://plugins.jetbrains.com/files/10811/186959/icon/pluginIcon.svg" 309 | }, 310 | { 311 | "id": 14104, 312 | "productCode": "PVCS", 313 | "name": "commit-template", 314 | "pricingModel": "PAID", 315 | "icon": "https://plugins.jetbrains.com/files/14104/250600/icon/pluginIcon.svg" 316 | }, 317 | { 318 | "id": 20293, 319 | "productCode": "PCONNECTUI", 320 | "name": "Connect Api", 321 | "pricingModel": "FREEMIUM", 322 | "icon": "https://plugins.jetbrains.com/files/20293/452254/icon/pluginIcon.svg" 323 | }, 324 | { 325 | "id": 21857, 326 | "productCode": "PCUEFY", 327 | "name": "Cuefy", 328 | "pricingModel": "PAID", 329 | "icon": "https://plugins.jetbrains.com/files/21857/428708/icon/pluginIcon.svg" 330 | }, 331 | { 332 | "id": 23561, 333 | "productCode": "PDATABASEBUDDY", 334 | "name": "Database Buddy", 335 | "pricingModel": "PAID", 336 | "icon": "https://plugins.jetbrains.com/files/23561/474923/icon/pluginIcon.svg" 337 | }, 338 | { 339 | "id": 16861, 340 | "productCode": "PDATABASE", 341 | "name": "Database Helper", 342 | "pricingModel": "PAID", 343 | "icon": "https://plugins.jetbrains.com/files/16861/500171/icon/pluginIcon.svg" 344 | }, 345 | { 346 | "id": 19161, 347 | "productCode": "PDBDATABASETOOL", 348 | "name": "Database Tool", 349 | "pricingModel": "PAID", 350 | "icon": "https://plugins.jetbrains.com/files/19161/514290/icon/pluginIcon.svg" 351 | }, 352 | { 353 | "id": 10925, 354 | "productCode": "PDB", 355 | "name": "Database Tools and SQL for WebStorm", 356 | "pricingModel": "PAID", 357 | "icon": "https://plugins.jetbrains.com/files/10925/511241/icon/pluginIcon.svg" 358 | }, 359 | { 360 | "id": 22472, 361 | "productCode": "PDATAGRAPH", 362 | "name": "DataGraph - JSON, YAML, XML Visualization", 363 | "pricingModel": "FREEMIUM", 364 | "icon": "https://plugins.jetbrains.com/files/22472/503936/icon/pluginIcon.svg" 365 | }, 366 | { 367 | "id": 11461, 368 | "productCode": "DC", 369 | "name": "dotCover", 370 | "pricingModel": "PAID", 371 | "icon": "https://plugins.jetbrains.com/files/11461/81836/icon/META-INF_pluginIcon.svg" 372 | }, 373 | { 374 | "id": 11462, 375 | "productCode": "DPN", 376 | "name": "dotTrace", 377 | "pricingModel": "PAID", 378 | "icon": "https://plugins.jetbrains.com/files/11462/81835/icon/META-INF_pluginIcon.svg" 379 | }, 380 | { 381 | "id": 18896, 382 | "productCode": "PDYNAMODB", 383 | "name": "DynamoDB", 384 | "pricingModel": "PAID", 385 | "icon": "https://plugins.jetbrains.com/files/18896/503820/icon/pluginIcon.svg" 386 | }, 387 | { 388 | "id": 14512, 389 | "productCode": "PELASTICSEARCH", 390 | "name": "Elasticsearch", 391 | "pricingModel": "PAID", 392 | "icon": "https://plugins.jetbrains.com/files/14512/511081/icon/pluginIcon.svg" 393 | }, 394 | { 395 | "id": 18209, 396 | "productCode": "PELSA", 397 | "name": "ElasticSearch-Admin", 398 | "pricingModel": "PAID", 399 | "icon": "https://plugins.jetbrains.com" 400 | }, 401 | { 402 | "id": 18663, 403 | "productCode": "PEXCELEDITOR", 404 | "name": "ExcelEditor", 405 | "pricingModel": "FREEMIUM", 406 | "icon": "https://plugins.jetbrains.com/files/18663/510865/icon/pluginIcon.svg" 407 | }, 408 | { 409 | "id": 15379, 410 | "productCode": "PGODRUNNER", 411 | "name": "Execution God Recorder", 412 | "pricingModel": "PAID", 413 | "icon": "https://plugins.jetbrains.com/files/15379/102175/icon/pluginIcon.svg" 414 | }, 415 | { 416 | "id": 20238, 417 | "productCode": "PEXTENSION", 418 | "name": "Extensions Manager", 419 | "pricingModel": "PAID", 420 | "icon": "https://plugins.jetbrains.com/files/20238/308627/icon/pluginIcon.svg" 421 | }, 422 | { 423 | "id": 11058, 424 | "productCode": "PEXTRAICONS", 425 | "name": "Extra Icons", 426 | "pricingModel": "PAID", 427 | "icon": "https://plugins.jetbrains.com/files/11058/516273/icon/pluginIcon.svg" 428 | }, 429 | { 430 | "id": 23927, 431 | "productCode": "PEXTRAIDETWEAKS", 432 | "name": "Extra IDE Tweaks", 433 | "pricingModel": "PAID", 434 | "icon": "https://plugins.jetbrains.com/files/23927/515986/icon/pluginIcon.svg" 435 | }, 436 | { 437 | "id": 16988, 438 | "productCode": "PFASTREQUEST", 439 | "name": "Fast Request - API Buddy", 440 | "pricingModel": "PAID", 441 | "icon": "https://plugins.jetbrains.com/files/16988/498000/icon/pluginIcon.svg" 442 | }, 443 | { 444 | "id": 18971, 445 | "productCode": "PFASTSHELL", 446 | "name": "FastShell", 447 | "pricingModel": "FREEMIUM", 448 | "icon": "https://plugins.jetbrains.com/files/18971/200999/icon/pluginIcon.svg" 449 | }, 450 | { 451 | "id": 23146, 452 | "productCode": "PFEIGNHELPER", 453 | "name": "Feign-Helper", 454 | "pricingModel": "PAID", 455 | "icon": "https://plugins.jetbrains.com/files/23146/473643/icon/pluginIcon.svg" 456 | }, 457 | { 458 | "id": 16217, 459 | "productCode": "PFUZYFIPC", 460 | "name": "Find In Files (Favorites)", 461 | "pricingModel": "PAID", 462 | "icon": "https://plugins.jetbrains.com/files/16217/518682/icon/pluginIcon.svg" 463 | }, 464 | { 465 | "id": 23609, 466 | "productCode": "PFIREBASE", 467 | "name": "Firebase Firestore", 468 | "pricingModel": "PAID", 469 | "icon": "https://plugins.jetbrains.com/files/23609/503413/icon/pluginIcon.svg" 470 | }, 471 | { 472 | "id": 15189, 473 | "productCode": "PFIREHIGHLIGHT", 474 | "name": "Firebase Rules", 475 | "pricingModel": "PAID", 476 | "icon": "https://plugins.jetbrains.com/files/15189/471752/icon/pluginIcon.svg" 477 | }, 478 | { 479 | "id": 23685, 480 | "productCode": "PSCIPIOFTL", 481 | "name": "Flexible Freemarker", 482 | "pricingModel": "PAID", 483 | "icon": "https://plugins.jetbrains.com/files/23685/483800/icon/pluginIcon.svg" 484 | }, 485 | { 486 | "id": 14718, 487 | "productCode": "PFLUTTER", 488 | "name": "Flutter Storm", 489 | "pricingModel": "PAID", 490 | "icon": "https://plugins.jetbrains.com/files/14718/367205/icon/pluginIcon.svg" 491 | }, 492 | { 493 | "id": 13086, 494 | "productCode": "PGDOC", 495 | "name": "Generate Document", 496 | "pricingModel": "PAID", 497 | "icon": "https://plugins.jetbrains.com/files/13086/499172/icon/pluginIcon.svg" 498 | }, 499 | { 500 | "id": 22971, 501 | "productCode": "PGENSETANDSET", 502 | "name": "GenerateSetAndGet", 503 | "pricingModel": "PAID", 504 | "icon": "https://plugins.jetbrains.com/files/22971/467619/icon/pluginIcon.svg" 505 | }, 506 | { 507 | "id": 20319, 508 | "productCode": "PGERRYAURORA", 509 | "name": "Gerry Aurora", 510 | "pricingModel": "PAID", 511 | "icon": "https://plugins.jetbrains.com/files/20319/435418/icon/pluginIcon.svg" 512 | }, 513 | { 514 | "id": 20246, 515 | "productCode": "PGERRYCHERRY", 516 | "name": "Gerry Cherry", 517 | "pricingModel": "PAID", 518 | "icon": "https://plugins.jetbrains.com/files/20246/435417/icon/pluginIcon.svg" 519 | }, 520 | { 521 | "id": 20247, 522 | "productCode": "PGERRYCOFFEE", 523 | "name": "Gerry Coffee", 524 | "pricingModel": "PAID", 525 | "icon": "https://plugins.jetbrains.com/files/20247/435420/icon/pluginIcon.svg" 526 | }, 527 | { 528 | "id": 20049, 529 | "productCode": "PGERRYCYBERPUNK", 530 | "name": "Gerry Cyberpunk", 531 | "pricingModel": "PAID", 532 | "icon": "https://plugins.jetbrains.com/files/20049/435415/icon/pluginIcon.svg" 533 | }, 534 | { 535 | "id": 20236, 536 | "productCode": "PGERRYNATURE", 537 | "name": "Gerry Nature", 538 | "pricingModel": "PAID", 539 | "icon": "https://plugins.jetbrains.com/files/20236/435419/icon/pluginIcon.svg" 540 | }, 541 | { 542 | "id": 20075, 543 | "productCode": "PGERRYSPACE", 544 | "name": "Gerry Space", 545 | "pricingModel": "PAID", 546 | "icon": "https://plugins.jetbrains.com/files/20075/435416/icon/pluginIcon.svg" 547 | }, 548 | { 549 | "id": 19668, 550 | "productCode": "PGERRYTHEMESPRO", 551 | "name": "Gerry Themes Pro", 552 | "pricingModel": "PAID", 553 | "icon": "https://plugins.jetbrains.com/files/19668/517943/icon/pluginIcon.svg" 554 | }, 555 | { 556 | "id": 10083, 557 | "productCode": "PGITSCOPE", 558 | "name": "Git Scope", 559 | "pricingModel": "PAID", 560 | "icon": "https://plugins.jetbrains.com/files/10083/396420/icon/pluginIcon.svg" 561 | }, 562 | { 563 | "id": 23813, 564 | "productCode": "PGITWORKTREE", 565 | "name": "Git Worktree", 566 | "pricingModel": "FREEMIUM", 567 | "icon": "https://plugins.jetbrains.com/files/23813/493642/icon/pluginIcon.svg" 568 | }, 569 | { 570 | "id": 14056, 571 | "productCode": "PGITFLOWPLUS", 572 | "name": "GitFlowPlus", 573 | "pricingModel": "FREEMIUM", 574 | "icon": "https://plugins.jetbrains.com/files/14056/506220/icon/pluginIcon.svg" 575 | }, 576 | { 577 | "id": 20144, 578 | "productCode": "PGITHUBCI", 579 | "name": "Github CI Dashboard", 580 | "pricingModel": "PAID", 581 | "icon": "https://plugins.jetbrains.com/files/20144/463946/icon/pluginIcon.svg" 582 | }, 583 | { 584 | "id": 15457, 585 | "productCode": "PGITLABCI", 586 | "name": "Gitlab CI Pipeline Dashboard", 587 | "pricingModel": "PAID", 588 | "icon": "https://plugins.jetbrains.com/files/15457/463947/icon/pluginIcon.svg" 589 | }, 590 | { 591 | "id": 22202, 592 | "productCode": "PGITLABCICD", 593 | "name": "GitLab CICD - Pipelines \u0026 Jobs, Builds Run Cancel Retry View Log", 594 | "pricingModel": "PAID", 595 | "icon": "https://plugins.jetbrains.com/files/22202/517828/icon/pluginIcon.svg" 596 | }, 597 | { 598 | "id": 18689, 599 | "productCode": "PGITLAB", 600 | "name": "GitLab Merge Requests", 601 | "pricingModel": "PAID", 602 | "icon": "https://plugins.jetbrains.com/files/18689/516838/icon/pluginIcon.svg" 603 | }, 604 | { 605 | "id": 7499, 606 | "productCode": "PGITTOOLBOX", 607 | "name": "GitToolBox", 608 | "pricingModel": "FREEMIUM", 609 | "icon": "https://plugins.jetbrains.com/files/7499/512954/icon/pluginIcon.svg" 610 | }, 611 | { 612 | "id": 19906, 613 | "productCode": "PGOPARSER", 614 | "name": "GoParser", 615 | "pricingModel": "PAID", 616 | "icon": "https://plugins.jetbrains.com/files/19906/293012/icon/pluginIcon.svg" 617 | }, 618 | { 619 | "id": 20411, 620 | "productCode": "PWXUFQYRHZCRSEO", 621 | "name": "Gorm", 622 | "pricingModel": "PAID", 623 | "icon": "https://plugins.jetbrains.com/files/20411/502598/icon/pluginIcon.svg" 624 | }, 625 | { 626 | "id": 22035, 627 | "productCode": "PGPTASSISTANT", 628 | "name": "GPT Assistant", 629 | "pricingModel": "PAID", 630 | "icon": "https://plugins.jetbrains.com/files/22035/510722/icon/pluginIcon.svg" 631 | }, 632 | { 633 | "id": 15535, 634 | "productCode": "PHEROKU", 635 | "name": "Heroku Dashboard", 636 | "pricingModel": "PAID", 637 | "icon": "https://plugins.jetbrains.com/files/15535/463948/icon/pluginIcon.svg" 638 | }, 639 | { 640 | "id": 7525, 641 | "productCode": "PHYBRISCOMMERCE", 642 | "name": "Hybris Integration", 643 | "pricingModel": "PAID", 644 | "icon": "https://plugins.jetbrains.com/files/7525/517492/icon/pluginIcon.svg" 645 | }, 646 | { 647 | "id": 12634, 648 | "productCode": "PIEDIS", 649 | "name": "Iedis 2", 650 | "pricingModel": "PAID", 651 | "icon": "https://plugins.jetbrains.com/files/12634/167816/icon/pluginIcon.svg" 652 | }, 653 | { 654 | "id": 22459, 655 | "productCode": "PIMAGETOVECTOR", 656 | "name": "ImageToVector", 657 | "pricingModel": "PAID", 658 | "icon": "https://plugins.jetbrains.com/files/22459/376877/icon/pluginIcon.svg" 659 | }, 660 | { 661 | "id": 23859, 662 | "productCode": "PINTELLIPHP", 663 | "name": "IntelliPHP - AI Autocomplete for PHP", 664 | "pricingModel": "PAID", 665 | "icon": "https://plugins.jetbrains.com/files/23859/505657/icon/pluginIcon.svg" 666 | }, 667 | { 668 | "id": 20526, 669 | "productCode": "PWAUFKYVHQCRXEO", 670 | "name": "IoGame", 671 | "pricingModel": "PAID", 672 | "icon": "https://plugins.jetbrains.com/files/20526/468605/icon/pluginIcon.svg" 673 | }, 674 | { 675 | "id": 11560, 676 | "productCode": "PBISJ", 677 | "name": "Java Antidecompiler", 678 | "pricingModel": "PAID", 679 | "icon": "https://plugins.jetbrains.com/files/11560/367010/icon/pluginIcon.svg" 680 | }, 681 | { 682 | "id": 10828, 683 | "productCode": "PJDCLEANREAD", 684 | "name": "JavaDoc Clean Read", 685 | "pricingModel": "PAID", 686 | "icon": "https://plugins.jetbrains.com/files/10828/375796/icon/pluginIcon.svg" 687 | }, 688 | { 689 | "id": 20888, 690 | "productCode": "PWXUQQYVOXCRSEO", 691 | "name": "JavaOrm", 692 | "pricingModel": "PAID", 693 | "icon": "https://plugins.jetbrains.com/files/20888/438337/icon/pluginIcon.svg" 694 | }, 695 | { 696 | "id": 14557, 697 | "productCode": "PVISUALGC", 698 | "name": "JDK VisualGC", 699 | "pricingModel": "FREEMIUM", 700 | "icon": "https://plugins.jetbrains.com/files/14557/453632/icon/pluginIcon.svg" 701 | }, 702 | { 703 | "id": 22282, 704 | "productCode": "AIP", 705 | "name": "JetBrains AI Assistant", 706 | "pricingModel": "FREEMIUM", 707 | "icon": "https://plugins.jetbrains.com/files/22282/515367/icon/pluginIcon.svg" 708 | }, 709 | { 710 | "id": 21173, 711 | "productCode": "PJETCLIENT", 712 | "name": "JetClient - The Ultimate REST Client", 713 | "pricingModel": "FREEMIUM", 714 | "icon": "https://plugins.jetbrains.com/files/21173/515501/icon/pluginIcon.svg" 715 | }, 716 | { 717 | "id": 9238, 718 | "productCode": "PJETFORCER", 719 | "name": "JetForcer | The Smartest Force.com IDE", 720 | "pricingModel": "PAID", 721 | "icon": "https://plugins.jetbrains.com" 722 | }, 723 | { 724 | "id": 12621, 725 | "productCode": "PJFORMDESIGNER", 726 | "name": "JFormDesigner (Marketplace Edition)", 727 | "pricingModel": "PAID", 728 | "icon": "https://plugins.jetbrains.com/files/12621/516265/icon/pluginIcon.svg" 729 | }, 730 | { 731 | "id": 23812, 732 | "productCode": "PJMETERPLUGINSM", 733 | "name": "JMeter Plugins Manager", 734 | "pricingModel": "PAID", 735 | "icon": "https://plugins.jetbrains.com/files/23812/492356/icon/pluginIcon.svg" 736 | }, 737 | { 738 | "id": 23855, 739 | "productCode": "PJMETERRUNNER", 740 | "name": "JMeter Runner", 741 | "pricingModel": "PAID", 742 | "icon": "https://plugins.jetbrains.com/files/23855/494217/icon/pluginIcon.svg" 743 | }, 744 | { 745 | "id": 15242, 746 | "productCode": "PJPASQL", 747 | "name": "JPA SQL", 748 | "pricingModel": "FREEMIUM", 749 | "icon": "https://plugins.jetbrains.com/files/15242/510410/icon/pluginIcon.svg" 750 | }, 751 | { 752 | "id": 23360, 753 | "productCode": "PJQEXPRESS", 754 | "name": "jqExpress", 755 | "pricingModel": "PAID", 756 | "icon": "https://plugins.jetbrains.com/files/23360/492713/icon/pluginIcon.svg" 757 | }, 758 | { 759 | "id": 22597, 760 | "productCode": "POXYJSONSCHGEN", 761 | "name": "JSON Schema Generator", 762 | "pricingModel": "PAID", 763 | "icon": "https://plugins.jetbrains.com/files/22597/471041/icon/pluginIcon.svg" 764 | }, 765 | { 766 | "id": 23554, 767 | "productCode": "POXYJSONDIAGRAM", 768 | "name": "JSON Schema Visualizer/Editor", 769 | "pricingModel": "PAID", 770 | "icon": "https://plugins.jetbrains.com/files/23554/503415/icon/pluginIcon.svg" 771 | }, 772 | { 773 | "id": 20297, 774 | "productCode": "POXYJSONCONVERT", 775 | "name": "JSON-YAML-XML Converter", 776 | "pricingModel": "PAID", 777 | "icon": "https://plugins.jetbrains.com/files/20297/472486/icon/pluginIcon.svg" 778 | }, 779 | { 780 | "id": 18975, 781 | "productCode": "PJSONNETEMLSUP", 782 | "name": "Jsonnet Pro", 783 | "pricingModel": "PAID", 784 | "icon": "https://plugins.jetbrains.com/files/18975/458972/icon/pluginIcon.svg" 785 | }, 786 | { 787 | "id": 19297, 788 | "productCode": "PJSONTOANYLANGU", 789 | "name": "JsonToAnyLanguage", 790 | "pricingModel": "FREEMIUM", 791 | "icon": "https://plugins.jetbrains.com/files/19297/351202/icon/pluginIcon.svg" 792 | }, 793 | { 794 | "id": 14393, 795 | "productCode": "PJSONTOTS", 796 | "name": "JsonToTypeScript", 797 | "pricingModel": "FREEMIUM", 798 | "icon": "https://plugins.jetbrains.com/files/14393/321300/icon/pluginIcon.svg" 799 | }, 800 | { 801 | "id": 22284, 802 | "productCode": "PKAFKA", 803 | "name": "Kafka Client", 804 | "pricingModel": "PAID", 805 | "icon": "https://plugins.jetbrains.com/files/22284/428744/icon/pluginIcon.svg" 806 | }, 807 | { 808 | "id": 20111, 809 | "productCode": "PKAFKAIDE", 810 | "name": "Kafkaide", 811 | "pricingModel": "PAID", 812 | "icon": "https://plugins.jetbrains.com/files/20111/425515/icon/pluginIcon.svg" 813 | }, 814 | { 815 | "id": 18286, 816 | "productCode": "PKSEXPLORER", 817 | "name": "KS-Explorer", 818 | "pricingModel": "PAID", 819 | "icon": "https://plugins.jetbrains.com/files/18286/518701/icon/pluginIcon.svg" 820 | }, 821 | { 822 | "id": 13441, 823 | "productCode": "PLARAVEL", 824 | "name": "Laravel Idea", 825 | "pricingModel": "PAID", 826 | "icon": "https://plugins.jetbrains.com/files/13441/507406/icon/pluginIcon.svg" 827 | }, 828 | { 829 | "id": 19661, 830 | "productCode": "PLATTEPRO", 831 | "name": "Latte Pro", 832 | "pricingModel": "PAID", 833 | "icon": "https://plugins.jetbrains.com/files/19661/440924/icon/pluginIcon.svg" 834 | }, 835 | { 836 | "id": 15405, 837 | "productCode": "PLEDGER", 838 | "name": "Ledger CLI", 839 | "pricingModel": "PAID", 840 | "icon": "https://plugins.jetbrains.com/files/15405/458942/icon/pluginIcon.svg" 841 | }, 842 | { 843 | "id": 17166, 844 | "productCode": "PLEP", 845 | "name": "LeetCode Editor Pro", 846 | "pricingModel": "PAID", 847 | "icon": "https://plugins.jetbrains.com/files/17166/502109/icon/pluginIcon.svg" 848 | }, 849 | { 850 | "id": 22223, 851 | "productCode": "PLOCALSTACK", 852 | "name": "LocalStack Integrator", 853 | "pricingModel": "FREEMIUM", 854 | "icon": "https://plugins.jetbrains.com/files/22223/518671/icon/pluginIcon.svg" 855 | }, 856 | { 857 | "id": 20554, 858 | "productCode": "PMAGE", 859 | "name": "Magento and Adobe Commerce PhpStorm by Atwix", 860 | "pricingModel": "FREEMIUM", 861 | "icon": "https://plugins.jetbrains.com/files/20554/505887/icon/pluginIcon.svg" 862 | }, 863 | { 864 | "id": 23556, 865 | "productCode": "PSCIPIOMGNL", 866 | "name": "Magnolia CMS Integration", 867 | "pricingModel": "PAID", 868 | "icon": "https://plugins.jetbrains.com/files/23556/483799/icon/pluginIcon.svg" 869 | }, 870 | { 871 | "id": 17688, 872 | "productCode": "PRSMGNL", 873 | "name": "Magnolia YAML Assistant", 874 | "pricingModel": "FREEMIUM", 875 | "icon": "https://plugins.jetbrains.com/files/17688/511232/icon/pluginIcon.svg" 876 | }, 877 | { 878 | "id": 8006, 879 | "productCode": "PMATERIALUI", 880 | "name": "Material Theme UI", 881 | "pricingModel": "FREEMIUM", 882 | "icon": "https://plugins.jetbrains.com/files/8006/518563/icon/pluginIcon.svg" 883 | }, 884 | { 885 | "id": 19308, 886 | "productCode": "PMATERIALCUSTOM", 887 | "name": "Material Theme UI Custom Theme", 888 | "pricingModel": "PAID", 889 | "icon": "https://plugins.jetbrains.com/files/19308/384272/icon/pluginIcon.svg" 890 | }, 891 | { 892 | "id": 19250, 893 | "productCode": "PMATERIALEXTRAS", 894 | "name": "Material Theme UI Extras", 895 | "pricingModel": "PAID", 896 | "icon": "https://plugins.jetbrains.com/files/19250/384271/icon/pluginIcon.svg" 897 | }, 898 | { 899 | "id": 17456, 900 | "productCode": "PMATERIALHC", 901 | "name": "Material Theme UI High Contrast", 902 | "pricingModel": "PAID", 903 | "icon": "https://plugins.jetbrains.com/files/17456/384270/icon/pluginIcon.svg" 904 | }, 905 | { 906 | "id": 19309, 907 | "productCode": "PMATERIALLANG", 908 | "name": "Material Theme UI Language Additions", 909 | "pricingModel": "PAID", 910 | "icon": "https://plugins.jetbrains.com/files/19309/384269/icon/pluginIcon.svg" 911 | }, 912 | { 913 | "id": 19310, 914 | "productCode": "PMATERIALFRAME", 915 | "name": "Material Theme UI Project Frame", 916 | "pricingModel": "PAID", 917 | "icon": "https://plugins.jetbrains.com/files/19310/385745/icon/pluginIcon.svg" 918 | }, 919 | { 920 | "id": 13615, 921 | "productCode": "PMRINTEGEE", 922 | "name": "Merge Request Integration EE - Code Review for GitLab", 923 | "pricingModel": "PAID", 924 | "icon": "https://plugins.jetbrains.com/files/13615/113000/icon/pluginIcon.svg" 925 | }, 926 | { 927 | "id": 23687, 928 | "productCode": "PMICRONAUTLAUNC", 929 | "name": "Micronaut Launch", 930 | "pricingModel": "PAID", 931 | "icon": "https://plugins.jetbrains.com/files/23687/478379/icon/pluginIcon.svg" 932 | }, 933 | { 934 | "id": 13720, 935 | "productCode": "PMINBATIS", 936 | "name": "MinBatis", 937 | "pricingModel": "PAID", 938 | "icon": "https://plugins.jetbrains.com/files/13720/116149/icon/pluginIcon.svg" 939 | }, 940 | { 941 | "id": 23999, 942 | "productCode": "PMONGODB", 943 | "name": "Mongo DB", 944 | "pricingModel": "PAID", 945 | "icon": "https://plugins.jetbrains.com/files/23999/518250/icon/pluginIcon.svg" 946 | }, 947 | { 948 | "id": 20761, 949 | "productCode": "PMONGOEXPERT", 950 | "name": "Mongo Expert", 951 | "pricingModel": "PAID", 952 | "icon": "https://plugins.jetbrains.com/files/20761/510302/icon/pluginIcon.svg" 953 | }, 954 | { 955 | "id": 17465, 956 | "productCode": "PCDMQTTCLIENT", 957 | "name": "MQTT Client", 958 | "pricingModel": "PAID", 959 | "icon": "https://plugins.jetbrains.com/files/17465/308433/icon/pluginIcon.svg" 960 | }, 961 | { 962 | "id": 13905, 963 | "productCode": "PMYBATISLOG", 964 | "name": "MyBatis Log", 965 | "pricingModel": "PAID", 966 | "icon": "https://plugins.jetbrains.com/files/13905/447241/icon/pluginIcon.svg" 967 | }, 968 | { 969 | "id": 18389, 970 | "productCode": "PMBCODEHELPPRO", 971 | "name": "Mybatis Smart Code Help Pro", 972 | "pricingModel": "FREEMIUM", 973 | "icon": "https://plugins.jetbrains.com/files/18389/516824/icon/pluginIcon.svg" 974 | }, 975 | { 976 | "id": 23478, 977 | "productCode": "PMYBATISCODE", 978 | "name": "MybatisCode", 979 | "pricingModel": "PAID", 980 | "icon": "https://plugins.jetbrains.com/files/23478/472229/icon/pluginIcon.svg" 981 | }, 982 | { 983 | "id": 14522, 984 | "productCode": "PMYBATISHELPER", 985 | "name": "MyBatisCodeHelperPro (Marketplace Edition)", 986 | "pricingModel": "PAID", 987 | "icon": "https://plugins.jetbrains.com/files/14522/510194/icon/pluginIcon.svg" 988 | }, 989 | { 990 | "id": 22655, 991 | "productCode": "PMYSQLPROXY", 992 | "name": "MySQL Proxy", 993 | "pricingModel": "FREEMIUM", 994 | "icon": "https://plugins.jetbrains.com/files/22655/436599/icon/pluginIcon.svg" 995 | }, 996 | { 997 | "id": 18387, 998 | "productCode": "PNEONPRO", 999 | "name": "NEON Nette Support", 1000 | "pricingModel": "PAID", 1001 | "icon": "https://plugins.jetbrains.com/files/18387/479200/icon/pluginIcon.svg" 1002 | }, 1003 | { 1004 | "id": 19977, 1005 | "productCode": "PNETLIFY", 1006 | "name": "Netlify Dashboard", 1007 | "pricingModel": "PAID", 1008 | "icon": "https://plugins.jetbrains.com/files/19977/463949/icon/pluginIcon.svg" 1009 | }, 1010 | { 1011 | "id": 19963, 1012 | "productCode": "PNEXTSKETCH", 1013 | "name": "NextSketch", 1014 | "pricingModel": "PAID", 1015 | "icon": "https://plugins.jetbrains.com/files/19963/272018/icon/pluginIcon.svg" 1016 | }, 1017 | { 1018 | "id": 20805, 1019 | "productCode": "PNEXTSKETCHTWO", 1020 | "name": "NextSketch2", 1021 | "pricingModel": "PAID", 1022 | "icon": "https://plugins.jetbrains.com/files/20805/308349/icon/pluginIcon.svg" 1023 | }, 1024 | { 1025 | "id": 23765, 1026 | "productCode": "PNFLUTTER", 1027 | "name": "NFlutter", 1028 | "pricingModel": "PAID", 1029 | "icon": "https://plugins.jetbrains.com/files/23765/492994/icon/pluginIcon.svg" 1030 | }, 1031 | { 1032 | "id": 18280, 1033 | "productCode": "PNGINX", 1034 | "name": "Nginx Configuration Pro", 1035 | "pricingModel": "PAID", 1036 | "icon": "https://plugins.jetbrains.com/files/18280/239000/icon/pluginIcon.svg" 1037 | }, 1038 | { 1039 | "id": 19205, 1040 | "productCode": "PNGROK", 1041 | "name": "Ngrok", 1042 | "pricingModel": "FREEMIUM", 1043 | "icon": "https://plugins.jetbrains.com/files/19205/510423/icon/pluginIcon.svg" 1044 | }, 1045 | { 1046 | "id": 21833, 1047 | "productCode": "PNOSQLNAVMDB", 1048 | "name": "NoSQL Navigator For MongoDB", 1049 | "pricingModel": "PAID", 1050 | "icon": "https://plugins.jetbrains.com/files/21833/433051/icon/pluginIcon.svg" 1051 | }, 1052 | { 1053 | "id": 22128, 1054 | "productCode": "PNPMPACKAGEJSON", 1055 | "name": "NPM Package Json", 1056 | "pricingModel": "PAID", 1057 | "icon": "https://plugins.jetbrains.com/files/22128/451192/icon/pluginIcon.svg" 1058 | }, 1059 | { 1060 | "id": 13499, 1061 | "productCode": "PODOO", 1062 | "name": "Odoo", 1063 | "pricingModel": "PAID", 1064 | "icon": "https://plugins.jetbrains.com/files/13499/512679/icon/pluginIcon.svg" 1065 | }, 1066 | { 1067 | "id": 13151, 1068 | "productCode": "POFFICEFLOOR", 1069 | "name": "OfficeFloor", 1070 | "pricingModel": "PAID", 1071 | "icon": "https://plugins.jetbrains.com/files/13151/131867/icon/pluginIcon.svg" 1072 | }, 1073 | { 1074 | "id": 19889, 1075 | "productCode": "POPENAPICRUDWIZ", 1076 | "name": "OpenAPI CRUD Wizard", 1077 | "pricingModel": "FREEMIUM", 1078 | "icon": "https://plugins.jetbrains.com/files/19889/478359/icon/pluginIcon.svg" 1079 | }, 1080 | { 1081 | "id": 12887, 1082 | "productCode": "POPENAPI", 1083 | "name": "OpenAPI Editor", 1084 | "pricingModel": "PAID", 1085 | "icon": "https://plugins.jetbrains.com/files/12887/512174/icon/pluginIcon.svg" 1086 | }, 1087 | { 1088 | "id": 14371, 1089 | "productCode": "PIMAGEVIEWER", 1090 | "name": "OpenCV Image Viewer", 1091 | "pricingModel": "FREEMIUM", 1092 | "icon": "https://plugins.jetbrains.com/files/14371/480879/icon/pluginIcon.svg" 1093 | }, 1094 | { 1095 | "id": 12626, 1096 | "productCode": "PORCHIDE", 1097 | "name": "OrchidE - Ansible Language Support", 1098 | "pricingModel": "PAID", 1099 | "icon": "https://plugins.jetbrains.com" 1100 | }, 1101 | { 1102 | "id": 19660, 1103 | "productCode": "PAWSQLADVISOR", 1104 | "name": "PawSQL Advisor,SQL Audit/Rewrite/Index Advice,Tune SQL by Clicks", 1105 | "pricingModel": "PAID", 1106 | "icon": "https://plugins.jetbrains.com/files/19660/502106/icon/pluginIcon.svg" 1107 | }, 1108 | { 1109 | "id": 17440, 1110 | "productCode": "PHPBUILDER", 1111 | "name": "PHP Data Object Generator", 1112 | "pricingModel": "FREEMIUM", 1113 | "icon": "https://plugins.jetbrains.com/files/17440/458368/icon/pluginIcon.svg" 1114 | }, 1115 | { 1116 | "id": 18981, 1117 | "productCode": "PPHPHOUDINI", 1118 | "name": "PHP Houdini", 1119 | "pricingModel": "PAID", 1120 | "icon": "https://plugins.jetbrains.com/files/18981/271233/icon/pluginIcon.svg" 1121 | }, 1122 | { 1123 | "id": 16935, 1124 | "productCode": "PHPEAPLUGIN", 1125 | "name": "Php Inspections (EA Ultimate)", 1126 | "pricingModel": "PAID", 1127 | "icon": "https://plugins.jetbrains.com" 1128 | }, 1129 | { 1130 | "id": 14821, 1131 | "productCode": "PPUMLSTUDIO", 1132 | "name": "PlantUML Studio", 1133 | "pricingModel": "PAID", 1134 | "icon": "https://plugins.jetbrains.com/files/14821/172312/icon/pluginIcon.svg" 1135 | }, 1136 | { 1137 | "id": 13733, 1138 | "productCode": "PPOJOTOJSONSCH", 1139 | "name": "POJO to JSON Schema", 1140 | "pricingModel": "PAID", 1141 | "icon": "https://plugins.jetbrains.com/files/13733/95154/icon/pluginIcon.svg" 1142 | }, 1143 | { 1144 | "id": 22429, 1145 | "productCode": "PPOLARISTOMCATS", 1146 | "name": "Polaris Tomcat Server", 1147 | "pricingModel": "PAID", 1148 | "icon": "https://plugins.jetbrains.com/files/22429/506445/icon/pluginIcon.svg" 1149 | }, 1150 | { 1151 | "id": 21361, 1152 | "productCode": "POLYBPMNGDNEXT", 1153 | "name": "PolyBPMN visualizer", 1154 | "pricingModel": "PAID", 1155 | "icon": "https://plugins.jetbrains.com/files/21361/479001/icon/pluginIcon.svg" 1156 | }, 1157 | { 1158 | "id": 14434, 1159 | "productCode": "PQMLEDITOR", 1160 | "name": "QmlEditor", 1161 | "pricingModel": "PAID", 1162 | "icon": "https://plugins.jetbrains.com/files/14434/314029/icon/pluginIcon.svg" 1163 | }, 1164 | { 1165 | "id": 16405, 1166 | "productCode": "PQTSQSSEDITOR", 1167 | "name": "Qt Style Sheets Editor", 1168 | "pricingModel": "PAID", 1169 | "icon": "https://plugins.jetbrains.com/files/16405/193379/icon/pluginIcon.svg" 1170 | }, 1171 | { 1172 | "id": 19027, 1173 | "productCode": "PQUARKUSHELPER", 1174 | "name": "Quarkus Assistant", 1175 | "pricingModel": "PAID", 1176 | "icon": "https://plugins.jetbrains.com/files/19027/477162/icon/pluginIcon.svg" 1177 | }, 1178 | { 1179 | "id": 18269, 1180 | "productCode": "PQUERYFLAG", 1181 | "name": "QueryFlag", 1182 | "pricingModel": "PAID", 1183 | "icon": "https://plugins.jetbrains.com/files/18269/508126/icon/pluginIcon.svg" 1184 | }, 1185 | { 1186 | "id": 10080, 1187 | "productCode": "PRAINBOWBRACKET", 1188 | "name": "Rainbow Brackets", 1189 | "pricingModel": "FREEMIUM", 1190 | "icon": "https://plugins.jetbrains.com/files/10080/509542/icon/pluginIcon.svg" 1191 | }, 1192 | { 1193 | "id": 19316, 1194 | "productCode": "PRANCHER", 1195 | "name": "Rancher", 1196 | "pricingModel": "PAID", 1197 | "icon": "https://plugins.jetbrains.com/files/19316/367013/icon/pluginIcon.svg" 1198 | }, 1199 | { 1200 | "id": 13838, 1201 | "productCode": "PRDFANDSPARQL", 1202 | "name": "RDF and SPARQL", 1203 | "pricingModel": "PAID", 1204 | "icon": "https://plugins.jetbrains.com/files/13838/499816/icon/pluginIcon.svg" 1205 | }, 1206 | { 1207 | "id": 9564, 1208 | "productCode": "PRNCONSOLE", 1209 | "name": "React Native Console", 1210 | "pricingModel": "PAID", 1211 | "icon": "https://plugins.jetbrains.com/files/9564/514551/icon/pluginIcon.svg" 1212 | }, 1213 | { 1214 | "id": 12820, 1215 | "productCode": "PREDIS", 1216 | "name": "Redis", 1217 | "pricingModel": "PAID", 1218 | "icon": "https://plugins.jetbrains.com/files/12820/433300/icon/pluginIcon.svg" 1219 | }, 1220 | { 1221 | "id": 19360, 1222 | "productCode": "PREDISCLIHELPER", 1223 | "name": "Redis Client", 1224 | "pricingModel": "PAID", 1225 | "icon": "https://plugins.jetbrains.com/files/19360/479210/icon/pluginIcon.svg" 1226 | }, 1227 | { 1228 | "id": 15722, 1229 | "productCode": "PREDISMANAGER", 1230 | "name": "Redis Manager", 1231 | "pricingModel": "PAID", 1232 | "icon": "https://plugins.jetbrains.com/files/15722/270538/icon/pluginIcon.svg" 1233 | }, 1234 | { 1235 | "id": 19599, 1236 | "productCode": "PREDISS", 1237 | "name": "Redis Operator", 1238 | "pricingModel": "PAID", 1239 | "icon": "https://plugins.jetbrains.com/files/19599/518569/icon/pluginIcon.svg" 1240 | }, 1241 | { 1242 | "id": 16160, 1243 | "productCode": "PREDISTOOLS", 1244 | "name": "Redis-Cli", 1245 | "pricingModel": "PAID", 1246 | "icon": "https://plugins.jetbrains.com/files/16160/286263/icon/pluginIcon.svg" 1247 | }, 1248 | { 1249 | "id": 15433, 1250 | "productCode": "PREGEXTOOL", 1251 | "name": "Regex Tool", 1252 | "pricingModel": "PAID", 1253 | "icon": "https://plugins.jetbrains.com/files/15433/510718/icon/pluginIcon.svg" 1254 | }, 1255 | { 1256 | "id": 14723, 1257 | "productCode": "PRESTKIT", 1258 | "name": "RestfulBox", 1259 | "pricingModel": "FREEMIUM", 1260 | "icon": "https://plugins.jetbrains.com/files/14723/464469/icon/pluginIcon.svg" 1261 | }, 1262 | { 1263 | "id": 22726, 1264 | "productCode": "PRETROFITASSIT", 1265 | "name": "Retrofit Assistant", 1266 | "pricingModel": "PAID", 1267 | "icon": "https://plugins.jetbrains.com/files/22726/514538/icon/pluginIcon.svg" 1268 | }, 1269 | { 1270 | "id": 22428, 1271 | "productCode": "PWXUQRYTOXCRSEO", 1272 | "name": "RustTool", 1273 | "pricingModel": "PAID", 1274 | "icon": "https://plugins.jetbrains.com/files/22428/513930/icon/pluginIcon.svg" 1275 | }, 1276 | { 1277 | "id": 13668, 1278 | "productCode": "PSFCC", 1279 | "name": "Salesforce B2C Commerce (SFCC)", 1280 | "pricingModel": "PAID", 1281 | "icon": "https://plugins.jetbrains.com/files/13668/510847/icon/pluginIcon.svg" 1282 | }, 1283 | { 1284 | "id": 22748, 1285 | "productCode": "PSCHEMAREGVIEW", 1286 | "name": "Schema Registry Viewer", 1287 | "pricingModel": "PAID", 1288 | "icon": "https://plugins.jetbrains.com/files/22748/496140/icon/pluginIcon.svg" 1289 | }, 1290 | { 1291 | "id": 12108, 1292 | "productCode": "PSCIPIO", 1293 | "name": "Scipio ERP Integration", 1294 | "pricingModel": "PAID", 1295 | "icon": "https://plugins.jetbrains.com/files/12108/478355/icon/pluginIcon.svg" 1296 | }, 1297 | { 1298 | "id": 19556, 1299 | "productCode": "PSCREENCODEPRO", 1300 | "name": "ScreenCodePro", 1301 | "pricingModel": "PAID", 1302 | "icon": "https://plugins.jetbrains.com/files/19556/198086/icon/pluginIcon.svg" 1303 | }, 1304 | { 1305 | "id": 22232, 1306 | "productCode": "PSENTRY", 1307 | "name": "Sentry", 1308 | "pricingModel": "FREEMIUM", 1309 | "icon": "https://plugins.jetbrains.com/files/22232/514906/icon/pluginIcon.svg" 1310 | }, 1311 | { 1312 | "id": 15945, 1313 | "productCode": "PSENTRYINTEG", 1314 | "name": "Sentry Integration", 1315 | "pricingModel": "PAID", 1316 | "icon": "https://plugins.jetbrains.com/files/15945/111527/icon/pluginIcon.svg" 1317 | }, 1318 | { 1319 | "id": 8286, 1320 | "productCode": "PSEQUENCEDIAGRA", 1321 | "name": "SequenceDiagram", 1322 | "pricingModel": "FREEMIUM", 1323 | "icon": "https://plugins.jetbrains.com/files/8286/485614/icon/pluginIcon.svg" 1324 | }, 1325 | { 1326 | "id": 23115, 1327 | "productCode": "PSEQDIAORG", 1328 | "name": "SequenceDiagram.org", 1329 | "pricingModel": "PAID", 1330 | "icon": "https://plugins.jetbrains.com/files/23115/485275/icon/pluginIcon.svg" 1331 | }, 1332 | { 1333 | "id": 14437, 1334 | "productCode": "PSI", 1335 | "name": "Shared Project Indexes", 1336 | "pricingModel": "PAID", 1337 | "icon": "https://plugins.jetbrains.com/files/14437/508994/icon/pluginIcon.svg" 1338 | }, 1339 | { 1340 | "id": 7410, 1341 | "productCode": "PSWPLUGIN", 1342 | "name": "Shopware", 1343 | "pricingModel": "PAID", 1344 | "icon": "https://plugins.jetbrains.com/files/7410/167127/icon/pluginIcon.svg" 1345 | }, 1346 | { 1347 | "id": 18151, 1348 | "productCode": "PBEANCONVERTER", 1349 | "name": "Simple Object Copy", 1350 | "pricingModel": "PAID", 1351 | "icon": "https://plugins.jetbrains.com" 1352 | }, 1353 | { 1354 | "id": 20243, 1355 | "productCode": "PSKOL", 1356 | "name": "Skol", 1357 | "pricingModel": "PAID", 1358 | "icon": "https://plugins.jetbrains.com/files/20243/518236/icon/pluginIcon.svg" 1359 | }, 1360 | { 1361 | "id": 14053, 1362 | "productCode": "PSMARTJUMP", 1363 | "name": "Smart Jump", 1364 | "pricingModel": "PAID", 1365 | "icon": "https://plugins.jetbrains.com/files/14053/274462/icon/pluginIcon.svg" 1366 | }, 1367 | { 1368 | "id": 20565, 1369 | "productCode": "PTAILWINDTOOLS", 1370 | "name": "Snippet Toolkit for Tailwind CSS", 1371 | "pricingModel": "PAID", 1372 | "icon": "https://plugins.jetbrains.com/files/20565/502104/icon/pluginIcon.svg" 1373 | }, 1374 | { 1375 | "id": 23743, 1376 | "productCode": "PSOTERISECURITY", 1377 | "name": "Soteri Secret Scanner", 1378 | "pricingModel": "PAID", 1379 | "icon": "https://plugins.jetbrains.com/files/23743/484143/icon/pluginIcon.svg" 1380 | }, 1381 | { 1382 | "id": 22318, 1383 | "productCode": "PSOURCESYNCPRO", 1384 | "name": "Source Synchronizer Pro", 1385 | "pricingModel": "PAID", 1386 | "icon": "https://plugins.jetbrains.com/files/22318/503948/icon/pluginIcon.svg" 1387 | }, 1388 | { 1389 | "id": 14338, 1390 | "productCode": "PSPARQL", 1391 | "name": "SPARQL", 1392 | "pricingModel": "PAID", 1393 | "icon": "https://plugins.jetbrains.com/files/14338/165810/icon/pluginIcon.svg" 1394 | }, 1395 | { 1396 | "id": 22635, 1397 | "productCode": "PSPEECHTOTEXT", 1398 | "name": "Speech-To-Text (AWS Transcribe)", 1399 | "pricingModel": "PAID", 1400 | "icon": "https://plugins.jetbrains.com/files/22635/388024/icon/pluginIcon.svg" 1401 | }, 1402 | { 1403 | "id": 18622, 1404 | "productCode": "PSPRINGBOOTIDEA", 1405 | "name": "Spring Boot Helper", 1406 | "pricingModel": "PAID", 1407 | "icon": "https://plugins.jetbrains.com/files/18622/472683/icon/pluginIcon.svg" 1408 | }, 1409 | { 1410 | "id": 22304, 1411 | "productCode": "PSRCODEGEN", 1412 | "name": "Spring Rest Code Generator", 1413 | "pricingModel": "PAID", 1414 | "icon": "https://plugins.jetbrains.com/files/22304/391163/icon/pluginIcon.svg" 1415 | }, 1416 | { 1417 | "id": 15574, 1418 | "productCode": "PFLYINSKYZJBZ", 1419 | "name": "spring-assistant-@valueToYml", 1420 | "pricingModel": "PAID", 1421 | "icon": "https://plugins.jetbrains.com/files/15574/412050/icon/pluginIcon.svg" 1422 | }, 1423 | { 1424 | "id": 20534, 1425 | "productCode": "PSQLFLUFFLINTER", 1426 | "name": "Sqlfluff Linter (Ultimate Edition)", 1427 | "pricingModel": "PAID", 1428 | "icon": "https://plugins.jetbrains.com/files/20534/502715/icon/pluginIcon.svg" 1429 | }, 1430 | { 1431 | "id": 22742, 1432 | "productCode": "PSQLFORMATTER", 1433 | "name": "SQLFormatter", 1434 | "pricingModel": "PAID", 1435 | "icon": "https://plugins.jetbrains.com" 1436 | }, 1437 | { 1438 | "id": 22713, 1439 | "productCode": "PDBSSH", 1440 | "name": "SSH Tool", 1441 | "pricingModel": "PAID", 1442 | "icon": "https://plugins.jetbrains.com/files/22713/516730/icon/pluginIcon.svg" 1443 | }, 1444 | { 1445 | "id": 15851, 1446 | "productCode": "PSTORMSECTIONS", 1447 | "name": "StormSections", 1448 | "pricingModel": "FREEMIUM", 1449 | "icon": "https://plugins.jetbrains.com/files/15851/449282/icon/pluginIcon.svg" 1450 | }, 1451 | { 1452 | "id": 14482, 1453 | "productCode": "PSTRKER", 1454 | "name": "Stryker", 1455 | "pricingModel": "FREEMIUM", 1456 | "icon": "https://plugins.jetbrains.com/files/14482/134911/icon/pluginIcon.svg" 1457 | }, 1458 | { 1459 | "id": 23458, 1460 | "productCode": "PSWISSKITCONVER", 1461 | "name": "SwissKit Converter", 1462 | "pricingModel": "PAID", 1463 | "icon": "https://plugins.jetbrains.com/files/23458/469170/icon/pluginIcon.svg" 1464 | }, 1465 | { 1466 | "id": 7219, 1467 | "productCode": "PSYMFONYPLUGIN", 1468 | "name": "Symfony Support", 1469 | "pricingModel": "FREEMIUM", 1470 | "icon": "https://plugins.jetbrains.com/files/7219/514919/icon/pluginIcon.svg" 1471 | }, 1472 | { 1473 | "id": 10695, 1474 | "productCode": "PVLOG", 1475 | "name": "SystemVerilog", 1476 | "pricingModel": "PAID", 1477 | "icon": "https://plugins.jetbrains.com/files/10695/163626/icon/pluginIcon.svg" 1478 | }, 1479 | { 1480 | "id": 14203, 1481 | "productCode": "PSVERILOG", 1482 | "name": "SystemVerilog Studio", 1483 | "pricingModel": "PAID", 1484 | "icon": "https://plugins.jetbrains.com" 1485 | }, 1486 | { 1487 | "id": 22685, 1488 | "productCode": "PNEKOCAT", 1489 | "name": "TamaCat the Embedded Internet Browser", 1490 | "pricingModel": "FREEMIUM", 1491 | "icon": "https://plugins.jetbrains.com/files/22685/456002/icon/pluginIcon.svg" 1492 | }, 1493 | { 1494 | "id": 18857, 1495 | "productCode": "PTERMINAL", 1496 | "name": "Terminal Pro", 1497 | "pricingModel": "FREEMIUM", 1498 | "icon": "https://plugins.jetbrains.com/files/18857/505301/icon/pluginIcon.svg" 1499 | }, 1500 | { 1501 | "id": 20050, 1502 | "productCode": "PTLDRAI", 1503 | "name": "TLDR", 1504 | "pricingModel": "FREEMIUM", 1505 | "icon": "https://plugins.jetbrains.com/files/20050/394140/icon/pluginIcon.svg" 1506 | }, 1507 | { 1508 | "id": 14384, 1509 | "productCode": "PTOOLSET", 1510 | "name": "Toolset", 1511 | "pricingModel": "FREEMIUM", 1512 | "icon": "https://plugins.jetbrains.com/files/14384/497387/icon/pluginIcon.svg" 1513 | }, 1514 | { 1515 | "id": 20683, 1516 | "productCode": "PTRAVISCI", 1517 | "name": "Travis CI Dashboard", 1518 | "pricingModel": "PAID", 1519 | "icon": "https://plugins.jetbrains.com/files/20683/463950/icon/pluginIcon.svg" 1520 | }, 1521 | { 1522 | "id": 18232, 1523 | "productCode": "PDJANGOTPLPEP", 1524 | "name": "Typed Django Template", 1525 | "pricingModel": "FREEMIUM", 1526 | "icon": "https://plugins.jetbrains.com/files/18232/370564/icon/pluginIcon.svg" 1527 | }, 1528 | { 1529 | "id": 19675, 1530 | "productCode": "PUNIAPPSUPPORT", 1531 | "name": "Uniapp Support", 1532 | "pricingModel": "PAID", 1533 | "icon": "https://plugins.jetbrains.com/files/19675/450668/icon/pluginIcon.svg" 1534 | }, 1535 | { 1536 | "id": 21813, 1537 | "productCode": "PVERILOGLANGUAG", 1538 | "name": "Verilog Language Support", 1539 | "pricingModel": "PAID", 1540 | "icon": "https://plugins.jetbrains.com/files/21813/472208/icon/pluginIcon.svg" 1541 | }, 1542 | { 1543 | "id": 23086, 1544 | "productCode": "PVOQAL", 1545 | "name": "Voqal Assistant", 1546 | "pricingModel": "PAID", 1547 | "icon": "https://plugins.jetbrains.com/files/23086/518244/icon/pluginIcon.svg" 1548 | }, 1549 | { 1550 | "id": 18860, 1551 | "productCode": "PWIREMOCHA", 1552 | "name": "WireMocha", 1553 | "pricingModel": "PAID", 1554 | "icon": "https://plugins.jetbrains.com/files/18860/517127/icon/pluginIcon.svg" 1555 | }, 1556 | { 1557 | "id": 7232, 1558 | "productCode": "PWLANG", 1559 | "name": "Wolfram Language", 1560 | "pricingModel": "PAID", 1561 | "icon": "https://plugins.jetbrains.com/files/7232/476166/icon/pluginIcon.svg" 1562 | }, 1563 | { 1564 | "id": 18425, 1565 | "productCode": "PXSDVISUALIZER", 1566 | "name": "XSD / WSDL Visualizer", 1567 | "pricingModel": "PAID", 1568 | "icon": "https://plugins.jetbrains.com/files/18425/515020/icon/pluginIcon.svg" 1569 | }, 1570 | { 1571 | "id": 19024, 1572 | "productCode": "POXYXSDJSONSCH", 1573 | "name": "XSD to JSON Schema", 1574 | "pricingModel": "FREEMIUM", 1575 | "icon": "https://plugins.jetbrains.com/files/19024/472499/icon/pluginIcon.svg" 1576 | }, 1577 | { 1578 | "id": 9739, 1579 | "productCode": "PYAOQIANGBPMN", 1580 | "name": "Yaoqiang BPMN Editor", 1581 | "pricingModel": "PAID", 1582 | "icon": "https://plugins.jetbrains.com" 1583 | }, 1584 | { 1585 | "id": 23693, 1586 | "productCode": "PYIIFRAMEWORK", 1587 | "name": "Yii2 Framework Support", 1588 | "pricingModel": "PAID", 1589 | "icon": "https://plugins.jetbrains.com/files/23693/504334/icon/pluginIcon.svg" 1590 | }, 1591 | { 1592 | "id": 12437, 1593 | "productCode": "PZENUML", 1594 | "name": "ZenUML Support", 1595 | "pricingModel": "FREEMIUM", 1596 | "icon": "https://plugins.jetbrains.com/files/12437/466910/icon/pluginIcon.svg" 1597 | }, 1598 | { 1599 | "id": 15773, 1600 | "productCode": "PZEROCODE", 1601 | "name": "Zerocode Scenario Helper", 1602 | "pricingModel": "PAID", 1603 | "icon": "https://plugins.jetbrains.com/files/15773/155295/icon/pluginIcon.svg" 1604 | }, 1605 | { 1606 | "id": 18341, 1607 | "productCode": "PZKA", 1608 | "name": "Zookeeper-Admin", 1609 | "pricingModel": "PAID", 1610 | "icon": "https://plugins.jetbrains.com" 1611 | } 1612 | ] 1613 | -------------------------------------------------------------------------------- /static/js/jquery.js: -------------------------------------------------------------------------------- 1 | /*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */ 2 | !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0