├── 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 |
12 |
13 |
14 | {{.Name}}
15 |
16 |
18 | *********************************************************************************************************************************************************
19 |
20 |
21 |
22 |
23 |
24 | {{end}}
25 | {{range .plugins}}
26 |
28 |
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 |
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