commit 15cf0ebd49167262868019b626294fed2bf350b0 Author: Jonas Plum Date: Mon Dec 13 00:39:15 2021 +0100 Release catalyst diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..6dcc315 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,93 @@ +name: CI +on: + push: { branches: [ main ] } + pull_request: + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + test: + name: Test + runs-on: ubuntu-latest + env: { GIN_MODE: test } + steps: + - uses: actions/setup-go@v2 + with: { go-version: '1.17' } + - uses: actions/setup-node@v2 + with: { node-version: '14' } + - uses: actions/checkout@v2 + - run: | + mkdir -p ui/dist/img + touch ui/dist/index.html ui/dist/favicon.ico ui/dist/manifest.json ui/dist/img/fake.png + - run: docker-compose up -d + working-directory: dev + - name: Install ArangoDB + run: | + curl -OL https://download.arangodb.com/arangodb34/DEBIAN/Release.key + sudo apt-key add Release.key + sudo apt-add-repository 'deb https://download.arangodb.com/arangodb34/DEBIAN/ /' + sudo apt-get update -y && sudo apt-get -y install arangodb3 + - run: go test -coverprofile=cover.out -coverpkg=./... ./... + - run: go tool cover -func=cover.out + + build-npm: + name: Build npm + runs-on: ubuntu-latest + steps: + - uses: actions/setup-node@v2 + with: { node-version: '14' } + - uses: actions/checkout@v2 + - run: yarn install && yarn build + working-directory: ui + - uses: actions/upload-artifact@v2 + with: { name: ui, path: ui/dist, retention-days: 1 } + + build: + name: Build + runs-on: ubuntu-latest + needs: [ build-npm, test ] + steps: + - uses: actions/setup-go@v2 + with: { go-version: '1.17' } + - uses: actions/checkout@v2 + - uses: actions/download-artifact@v2 + with: { name: ui, path: ui/dist } + - run: go build -o catalyst ./cmd/catalyst/. + - uses: docker/login-action@v1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Version + if: ${{ github.ref != '' }} + run: | + echo ${{ github.ref }} + echo ${{ github.ref }} > VERSION + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v3 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + - uses: docker/build-push-action@v2 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + # deploy: + # name: Deploy + # runs-on: self-hosted + # needs: [ build ] + # steps: + # - uses: actions/checkout@v2 + # - uses: docker/login-action@v1 + # with: + # registry: ${{ env.REGISTRY }} + # username: ${{ github.actor }} + # password: ${{ secrets.GITHUB_TOKEN }} + # - run: docker-compose -f docker-compose.yml -f docker-compose.demo.yml pull + # - run: docker-compose -f docker-compose.yml -f docker-compose.demo.yml up -d --remove-orphans --force-recreate + # - run: docker-compose -f docker-compose.yml -f docker-compose.demo.yml restart diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..db5a5bf --- /dev/null +++ b/.gitignore @@ -0,0 +1,86 @@ +.idea +.antlr + +.DS_Store +uploads +gen + +*.bleve + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ +venv/ +.venv/ +.python-version +.pytest_cache + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +#Ipython Notebook +.ipynb_checkpoints + +# npm +wwwroot/*.js +typings +dist +node_modules + +profile.cov + +generated/caql/parser/*.interp +generated/caql/parser/*.tokens diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0215c30 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM ubuntu:18.04 + +RUN apt-get update -y && apt-get -y install curl gnupg2 software-properties-common +RUN curl -OL https://download.arangodb.com/arangodb34/DEBIAN/Release.key +RUN apt-key add Release.key +RUN apt-add-repository 'deb https://download.arangodb.com/arangodb34/DEBIAN/ /' +RUN apt-get update -y && apt-get -y install arangodb3 + +COPY catalyst /app/catalyst +CMD /app/catalyst + +EXPOSE 8000 diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..f2e44fe --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,104 @@ +Copyright (c) 2021-present Jonas Plum + +Portions of this software are licensed as follows: + +* All third party components incorporated into Catalyst are licensed under the + original license provided by the owner of the applicable component. Those + files contain a license notice on top of the file and are listed in the + [NOTICE](NOTICE) file. +* Content outside of the above mentioned files above is + available under the "Elastic License 2.0" license as defined below. + +# Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..3172bf2 --- /dev/null +++ b/NOTICE @@ -0,0 +1,16 @@ +The following components are included in this product: + +Badgerodon Collections +https://github.com/badgerodon/collections +Copyright (c) 2012 Caleb Doxsey +Licensed under the MIT License + +go-toposort +https://github.com/philopon/go-toposort +Copyright (c) 2017 Hirotomo Moriwaki +Licensed under the MIT License + +The Go programming language +https://go.dev/ +Copyright (c) 2009 The Go Authors +See https://go.dev/LICENSE for license details. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7f02e7c --- /dev/null +++ b/README.md @@ -0,0 +1,78 @@ +

+ Screenshot of the playbook part of a ticket + Catalyst

+

Speed up your reactions

+

+Website +- +The Catalyst Handbook (Documentation) +- +Try online (user: bob, password: bob) +

+ +Catalyst is an incident response platform or SOAR (Security Orchestration, Automation and Response) system. It can help +you to automate your alert handling and incident response procedures. + +## Features + +### Ticket (Alert & Incident) Management + +![Screenshot of a ticket](docs/screenshots/ticket.png) + +Tickets are the core of Catalyst. They represent alerts, incidents, forensics +investigations, threat hunts or any other event you want to handle in your +organisation. + +## Ticket Templates + +
+ Screenshot of the playbook part of a ticket +
+ +Templates define the custom information for tickets. The core information for +tickets like title, creation date or closing status is kept quite minimal and other +information like criticality, description or MITRE ATT&CK information can be +added individually. + +## Conditional Custom Fields + +
+ Screenshot of the playbook part of a ticket + Screenshot of the playbook part of a ticket +
+ +Custom Fields can be dependent on each other. So if you, for example choose +"malware" as an incident type a custom field ask you to define it further as +ransomware, worm, etc. which a "phishing" incident would ask for the number +of received mails in that campaign. + +## Playbooks + +
+ Screenshot of the playbook part of a ticket +
+ +Playbooks represent processes that can be attached to tickets. Playbooks can +contain manual and automated tasks. Complex workflows with different workflow +branches, parallel tasks and task dependencies can be modeled. + +## Automations + +
+ Screenshot of the playbook part of a ticket +
+ +Automations are scripts that automate tasks or enrich artifacts. Automations are +run in their own Docker containers. This enables them to be created in different +scripting languages and run securely in their own environment. + +## Users + +
+ Screenshot of the playbook part of a ticket +
+ +Catalyst has two different types of users, normal users accessing the platform +via OIDC authentication and API keys for external script. A +fine-grained access model is available for both types and allows to define +possible actions for each user. diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..cb676de --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.0.0-dev diff --git a/auth.go b/auth.go new file mode 100644 index 0000000..be32591 --- /dev/null +++ b/auth.go @@ -0,0 +1,403 @@ +package catalyst + +import ( + "context" + "crypto/sha256" + "encoding/base64" + "fmt" + "log" + "math/rand" + "net/http" + "strings" + "time" + + "github.com/coreos/go-oidc/v3/oidc" + "github.com/gin-contrib/sessions" + "github.com/gin-gonic/gin" + "golang.org/x/oauth2" + + "github.com/SecurityBrewery/catalyst/database" + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/hooks" + "github.com/SecurityBrewery/catalyst/role" +) + +type AuthConfig struct { + OIDCIssuer string + OAuth2 *oauth2.Config + + OIDCClaimUsername string + OIDCClaimEmail string + // OIDCClaimGroups string + OIDCClaimName string + AuthBlockNew bool + AuthDefaultRoles []role.Role + + provider *oidc.Provider +} + +func (c *AuthConfig) Verifier(ctx context.Context) (*oidc.IDTokenVerifier, error) { + if c.provider == nil { + err := c.Load(ctx) + if err != nil { + return nil, err + } + } + return c.provider.Verifier(&oidc.Config{SkipClientIDCheck: true}), nil +} + +func (c *AuthConfig) Load(ctx context.Context) error { + provider, err := oidc.NewProvider(ctx, c.OIDCIssuer) + if err != nil { + return err + } + c.provider = provider + c.OAuth2.Endpoint = provider.Endpoint() + + return nil +} + +const ( + SessionName = "catalyst-session" + stateSession = "state" + userSession = "user" +) + +func Authenticate(db *database.Database, config *AuthConfig) gin.HandlerFunc { + return func(ctx *gin.Context) { + iss := config.OIDCIssuer + + keyHeader := ctx.Request.Header.Get("PRIVATE-TOKEN") + if keyHeader != "" { + keyAuth(db, keyHeader)(ctx) + return + } + + authHeader := ctx.Request.Header.Get("User") + + if authHeader != "" { + bearerAuth(db, authHeader, iss, config)(ctx) + return + } + sessionAuth(db, config)(ctx) + } +} + +func oidcCtx(ctx *gin.Context) (context.Context, context.CancelFunc) { + /* + if config.TLSCertFile != "" && config.TLSKeyFile != "" { + cert, err := tls.LoadX509KeyPair(config.TLSCertFile, config.TLSKeyFile) + if err != nil { + return nil, err + } + + rootCAs, _ := x509.SystemCertPool() + if rootCAs == nil { + rootCAs = x509.NewCertPool() + } + for _, c := range cert.Certificate { + rootCAs.AppendCertsFromPEM(c) + } + + return oidc.ClientContext(ctx, &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + RootCAs: rootCAs, + InsecureSkipVerify: true, + }, + }, + }), nil + } + */ + cctx, cancel := context.WithTimeout(ctx, time.Minute) + return cctx, cancel +} + +func bearerAuth(db *database.Database, authHeader string, iss string, config *AuthConfig) func(ctx *gin.Context) { + return func(ctx *gin.Context) { + if !strings.HasPrefix(authHeader, "Bearer ") { + ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "no bearer token"}) + return + } + + oidcCtx, cancel := oidcCtx(ctx) + defer cancel() + + verifier, err := config.Verifier(oidcCtx) + if err != nil { + ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "could not verify: " + err.Error()}) + return + } + authToken, err := verifier.Verify(oidcCtx, authHeader[7:]) + if err != nil { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("could not verify bearer token: %v", err)}) + return + } + + var claims map[string]interface{} + if err := authToken.Claims(&claims); err != nil { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("failed to parse claims: %v", err)}) + return + } + + // if claims.Iss != iss { + // ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "wrong issuer"}) + // return + // } + + session := sessions.Default(ctx) + session.Set(userSession, claims) + if err = session.Save(); err != nil { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, fmt.Sprintf("could not set session: %v", err)) + return + } + + if err = setContextClaims(ctx, db, claims, config); err != nil { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("could not load user: %s", err)}) + return + } + ctx.Next() + } +} + +func keyAuth(db *database.Database, keyHeader string) func(ctx *gin.Context) { + return func(ctx *gin.Context) { + h := fmt.Sprintf("%x", sha256.Sum256([]byte(keyHeader))) + + key, err := db.UserByHash(ctx, h) + if err != nil { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("could not verify private token: %v", err)}) + return + } + + setContextUser(ctx, key, db.Hooks) + + ctx.Next() + } +} + +func sessionAuth(db *database.Database, config *AuthConfig) func(ctx *gin.Context) { + return func(ctx *gin.Context) { + session := sessions.Default(ctx) + + user := session.Get(userSession) + if user == nil { + redirectToLogin(ctx, session, config.OAuth2) + + return + } + + claims, ok := user.(map[string]interface{}) + if !ok { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "claims not in session"}) + return + } + + if err := setContextClaims(ctx, db, claims, config); err != nil { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("could not load user: %s", err)}) + return + } + + ctx.Next() + } +} + +func setContextClaims(ctx *gin.Context, db *database.Database, claims map[string]interface{}, config *AuthConfig) error { + newUser, newSetting, err := mapUserAndSettings(claims, config) + if err != nil { + return err + } + + if _, ok := busdb.UserFromContext(ctx); !ok { + busdb.SetContext(ctx, &models.UserResponse{ID: "auth", Roles: []string{role.Admin}, Apikey: false, Blocked: false}) + } + + user, err := db.UserGetOrCreate(ctx, newUser) + if err != nil { + return err + } + + _, err = db.UserDataGetOrCreate(ctx, newUser.ID, newSetting) + if err != nil { + return err + } + + setContextUser(ctx, user, db.Hooks) + return nil +} + +func setContextUser(ctx *gin.Context, user *models.UserResponse, hooks *hooks.Hooks) { + groups, err := hooks.GetGroups(ctx, user.ID) + if err == nil { + busdb.SetGroupContext(ctx, groups) + } + + busdb.SetContext(ctx, user) +} + +func mapUserAndSettings(claims map[string]interface{}, config *AuthConfig) (*models.UserForm, *models.UserData, error) { + // handle Bearer tokens + // if typ, ok := claims["typ"]; ok && typ == "Bearer" { + // return &models.User{ + // Username: "bot", + // Blocked: false, + // Email: pointer.String("bot@example.org"), + // Roles: []string{"user:read", "settings:read", "ticket", "backup:read", "backup:restore"}, + // Name: pointer.String("Bot"), + // }, nil + // } + + username, err := getString(claims, config.OIDCClaimUsername) + if err != nil { + return nil, nil, err + } + email, err := getString(claims, config.OIDCClaimEmail) + if err != nil { + email = "" + } + + name, err := getString(claims, config.OIDCClaimName) + if err != nil { + name = "" + } + + return &models.UserForm{ + ID: username, + Blocked: config.AuthBlockNew, + Roles: role.Strings(config.AuthDefaultRoles), + }, &models.UserData{ + Email: &email, + Name: &name, + }, nil +} + +func getString(m map[string]interface{}, key string) (string, error) { + if v, ok := m[key]; ok { + if s, ok := v.(string); ok { + return s, nil + } + return "", fmt.Errorf("mapping of %s failed, wrong type (%T)", key, v) + } + + return "", fmt.Errorf("mapping of %s failed, missing value", key) +} + +func redirectToLogin(ctx *gin.Context, session sessions.Session, oauth2Config *oauth2.Config) { + state, err := state() + if err != nil { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "generating state failed"}) + return + } + session.Set(stateSession, state) + err = session.Save() + if err != nil { + log.Println(err) + } + + ctx.Redirect(http.StatusFound, oauth2Config.AuthCodeURL(state)) + log.Println("abort", ctx.Request.URL.String()) + ctx.Abort() +} + +func AuthorizeBlockedUser(ctx *gin.Context) { + user, ok := busdb.UserFromContext(ctx) + if !ok { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "no user in context"}) + return + } + + if user.Blocked { + ctx.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "user is blocked"}) + return + } + + ctx.Next() +} + +func AuthorizeRole(roles []role.Role) gin.HandlerFunc { + return func(ctx *gin.Context) { + user, ok := busdb.UserFromContext(ctx) + if !ok { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "no user in context"}) + return + } + + if !role.UserHasRoles(user, roles) { + ctx.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": fmt.Sprintf("missing role %s has %s", roles, user.Roles)}) + return + } + + ctx.Next() + } +} + +func callback(config *AuthConfig) gin.HandlerFunc { + return func(ctx *gin.Context) { + session := sessions.Default(ctx) + + state := session.Get(stateSession) + if state == "" { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "state missing"}) + return + } + + if state != ctx.Query("state") { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "state mismatch"}) + return + } + + oauth2Token, err := config.OAuth2.Exchange(ctx, ctx.Query("code")) + if err != nil { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": gin.H{"error": fmt.Sprintf("oauth2 exchange failed: %s", err)}}) + return + } + + // Extract the ID Token from OAuth2 token. + rawIDToken, ok := oauth2Token.Extra("id_token").(string) + if !ok { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "missing id token"}) + return + } + + oidcCtx, cancel := oidcCtx(ctx) + defer cancel() + + verifier, err := config.Verifier(oidcCtx) + if err != nil { + ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "could not verify: " + err.Error()}) + return + } + + // Parse and verify ID Token payload. + idToken, err := verifier.Verify(oidcCtx, rawIDToken) + if err != nil { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "token verification failed: " + err.Error()}) + return + } + + // Extract custom claims + var claims map[string]interface{} + if err := idToken.Claims(&claims); err != nil { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "claim extraction failed"}) + return + } + + session.Set(userSession, claims) + err = session.Save() + if err != nil { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("could not save session %s", err)}) + return + } + + ctx.Redirect(http.StatusFound, "/") + } +} + +func state() (string, error) { + rnd := make([]byte, 32) + if _, err := rand.Read(rnd); err != nil { + return "", err + } + return base64.URLEncoding.EncodeToString(rnd), nil +} diff --git a/automation/automation.go b/automation/automation.go new file mode 100644 index 0000000..1cd2053 --- /dev/null +++ b/automation/automation.go @@ -0,0 +1,26 @@ +package automation + +import ( + "context" + "log" + + "github.com/SecurityBrewery/catalyst/bus" + "github.com/SecurityBrewery/catalyst/database" + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/role" +) + +func New(apiurl, apikey string, bus *bus.Bus, db *database.Database) error { + if err := jobAutomation(jobContext(), apiurl, apikey, bus, db); err != nil { + log.Fatal(err) + } + + return resultAutomation(bus, db) +} + +func jobContext() context.Context { + // TODO: change roles? + bot := &models.UserResponse{ID: "bot", Roles: []string{role.Admin}} + return busdb.UserContext(context.Background(), bot) +} diff --git a/automation/docker.go b/automation/docker.go new file mode 100644 index 0000000..c92b223 --- /dev/null +++ b/automation/docker.go @@ -0,0 +1,186 @@ +package automation + +import ( + "archive/tar" + "bufio" + "bytes" + "context" + "fmt" + "io" + "log" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/client" + "github.com/docker/docker/pkg/stdcopy" + + "github.com/SecurityBrewery/catalyst/database" +) + +func createContainer(ctx context.Context, image, script, data string) (string, string, error) { + cli, err := client.NewClientWithOpts(client.FromEnv) + if err != nil { + return "", "", err + } + + logs, err := pullImage(ctx, cli, image) + if err != nil { + return "", logs, err + } + + config := &container.Config{ + Image: image, Cmd: []string{"/script", data}, WorkingDir: "/home", + AttachStderr: true, AttachStdout: true, + } + resp, err := cli.ContainerCreate(ctx, config, nil, nil, "") + if err != nil { + return "", logs, err + } + + if err := copyFile(ctx, cli, "/script", script, resp.ID); err != nil { + return "", logs, err + } + + return resp.ID, logs, nil +} + +func pullImage(ctx context.Context, cli *client.Client, image string) (string, error) { + reader, err := cli.ImagePull(ctx, image, types.ImagePullOptions{}) + if err != nil { + return "", err + } + defer reader.Close() + + buf := &bytes.Buffer{} + _, err = io.Copy(buf, reader) + return buf.String(), err +} + +func copyFile(ctx context.Context, cli *client.Client, path string, contentString string, id string) error { + tarBuf := &bytes.Buffer{} + tw := tar.NewWriter(tarBuf) + if err := tw.WriteHeader(&tar.Header{Name: path, Mode: 0755, Size: int64(len(contentString))}); err != nil { + return err + } + + if _, err := tw.Write([]byte(contentString)); err != nil { + return err + } + + if err := tw.Close(); err != nil { + return err + } + + if err := cli.CopyToContainer(ctx, id, "/", tarBuf, types.CopyToContainerOptions{}); err != nil { + return err + } + + return nil +} + +func runDocker(ctx context.Context, jobID, containerID string, db *database.Database) (stdout []byte, stderr []byte, err error) { + cli, err := client.NewClientWithOpts(client.FromEnv) + if err != nil { + return nil, nil, err + } + + defer cli.ContainerRemove(ctx, containerID, types.ContainerRemoveOptions{Force: true}) + + if err := cli.ContainerStart(ctx, containerID, types.ContainerStartOptions{}); err != nil { + return nil, nil, err + } + + stderrBuf, err := streamStdErr(ctx, cli, jobID, containerID, db) + if err != nil { + return nil, nil, err + } + + if err := waitForContainer(ctx, cli, containerID, stderrBuf); err != nil { + return nil, nil, err + } + + output, err := getStdOut(ctx, cli, containerID) + if err != nil { + log.Println(err) + } + + return output.Bytes(), stderrBuf.Bytes(), nil +} + +func streamStdErr(ctx context.Context, cli *client.Client, jobID, containerID string, db *database.Database) (*bytes.Buffer, error) { + stderrBuf := &bytes.Buffer{} + containerLogs, err := cli.ContainerLogs(ctx, containerID, types.ContainerLogsOptions{ShowStderr: true, Follow: true}) + if err != nil { + return nil, err + } + go func() { + err := scanLines(ctx, jobID, containerLogs, stderrBuf, db) + if err != nil { + log.Println(err) + return + } + if err := containerLogs.Close(); err != nil { + log.Println(err) + return + } + }() + return stderrBuf, nil +} + +func scanLines(ctx context.Context, jobID string, input io.ReadCloser, output io.Writer, db *database.Database) error { + r, w := io.Pipe() + go func() { + _, err := stdcopy.StdCopy(w, w, input) + if err != nil { + log.Println(err) + return + } + if err := w.Close(); err != nil { + log.Println(err) + return + } + }() + s := bufio.NewScanner(r) + for s.Scan() { + b := s.Bytes() + output.Write(b) + output.Write([]byte("\n")) + + if err := db.JobLogAppend(ctx, jobID, string(b)+"\n"); err != nil { + log.Println(err) + continue + } + } + return s.Err() +} + +func waitForContainer(ctx context.Context, cli *client.Client, containerID string, stderrBuf *bytes.Buffer) error { + statusCh, errCh := cli.ContainerWait(ctx, containerID, container.WaitConditionNotRunning) + select { + case err := <-errCh: + if err != nil { + return err + } + case exitStatus := <-statusCh: + if exitStatus.StatusCode != 0 { + return fmt.Errorf("container returned status code %d: stderr: %s", exitStatus.StatusCode, stderrBuf.String()) + } + } + return nil +} + +func getStdOut(ctx context.Context, cli *client.Client, containerID string) (*bytes.Buffer, error) { + output := &bytes.Buffer{} + containerLogs, err := cli.ContainerLogs(ctx, containerID, types.ContainerLogsOptions{ShowStdout: true, Follow: true}) + if err != nil { + return nil, err + } + defer containerLogs.Close() + + _, err = stdcopy.StdCopy(output, output, containerLogs) + if err != nil { + return nil, err + } + + return output, nil +} diff --git a/automation/job.go b/automation/job.go new file mode 100644 index 0000000..fe98daa --- /dev/null +++ b/automation/job.go @@ -0,0 +1,116 @@ +package automation + +import ( + "encoding/json" + "fmt" + "log" + + "golang.org/x/net/context" + + "github.com/SecurityBrewery/catalyst/bus" + "github.com/SecurityBrewery/catalyst/database" + "github.com/SecurityBrewery/catalyst/generated/models" +) + +func jobAutomation(ctx context.Context, apiurl, apikey string, catalystBus *bus.Bus, db *database.Database) error { + return catalystBus.SubscribeJob(func(automationMsg *bus.JobMsg) { + job, err := db.JobCreate(ctx, automationMsg.ID, &models.JobForm{ + Automation: automationMsg.Automation, + Payload: automationMsg.Message.Payload, + Origin: automationMsg.Origin, + }) + if err != nil { + log.Println(err) + return + } + + automation, err := db.AutomationGet(ctx, automationMsg.Automation) + if err != nil { + log.Println(err) + return + } + + if automation.Script == "" { + log.Println("automation is empty") + return + } + + if automationMsg.Message.Secrets == nil { + automationMsg.Message.Secrets = map[string]string{} + } + automationMsg.Message.Secrets["catalyst_apikey"] = apikey + automationMsg.Message.Secrets["catalyst_apiurl"] = apiurl + + scriptMessage, _ := json.Marshal(automationMsg.Message) + + containerID, logs, err := createContainer(ctx, automation.Image, automation.Script, string(scriptMessage)) + if err != nil { + log.Println(err) + return + } + + if _, err := db.JobUpdate(ctx, automationMsg.ID, &models.Job{ + Automation: job.Automation, + Container: &containerID, + Origin: job.Origin, + Output: job.Output, + Log: &logs, + Payload: job.Payload, + Status: job.Status, + }); err != nil { + log.Println(err) + return + } + + var result map[string]interface{} + + stdout, _, err := runDocker(ctx, automationMsg.ID, containerID, db) + if err != nil { + result = map[string]interface{}{"error": fmt.Sprintf("error running script %s %s", err, string(stdout))} + } else { + var data map[string]interface{} + if err := json.Unmarshal(stdout, &data); err != nil { + result = map[string]interface{}{"error": string(stdout)} + } else { + result = data + } + } + + if err := catalystBus.PublishResult(automationMsg.Automation, result, automationMsg.Origin); err != nil { + log.Println(err) + } + + if err := db.JobComplete(ctx, automationMsg.ID, result); err != nil { + log.Println(err) + return + } + }) +} + +/* +func getAutomation(automationID string, config *Config) (*models.AutomationResponse, error) { + req, err := http.NewRequest(http.MethodGet, config.CatalystAPIUrl+"/automations/"+automationID, nil) + if err != nil { + return nil, err + } + + req.Header.Set("PRIVATE-TOKEN", config.CatalystAPIKey) + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + b, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + var automation models.AutomationResponse + if err := json.Unmarshal(b, &automation); err != nil { + return nil, err + } + return &automation, nil +} +*/ diff --git a/automation/result.go b/automation/result.go new file mode 100644 index 0000000..a7e5ff6 --- /dev/null +++ b/automation/result.go @@ -0,0 +1,38 @@ +package automation + +import ( + "log" + + "github.com/SecurityBrewery/catalyst/bus" + "github.com/SecurityBrewery/catalyst/database" + "github.com/SecurityBrewery/catalyst/generated/models" +) + +func resultAutomation(catalystBus *bus.Bus, db *database.Database) error { + return catalystBus.SubscribeResult(func(resultMsg *bus.ResultMsg) { + if resultMsg.Target != nil { + ctx := jobContext() + switch { + case resultMsg.Target.TaskOrigin != nil: + if _, err := db.TaskComplete( + ctx, + resultMsg.Target.TaskOrigin.TicketId, + resultMsg.Target.TaskOrigin.PlaybookId, + resultMsg.Target.TaskOrigin.TaskId, + resultMsg.Data, + ); err != nil { + log.Println(err) + } + case resultMsg.Target.ArtifactOrigin != nil: + enrichment := &models.EnrichmentForm{ + Data: resultMsg.Data, + Name: resultMsg.Automation, + } + _, err := db.EnrichArtifact(ctx, resultMsg.Target.ArtifactOrigin.TicketId, resultMsg.Target.ArtifactOrigin.Artifact, enrichment) + if err != nil { + log.Println(err) + } + } + } + }) +} diff --git a/backup.go b/backup.go new file mode 100644 index 0000000..141994c --- /dev/null +++ b/backup.go @@ -0,0 +1,149 @@ +package catalyst + +import ( + "archive/zip" + "bytes" + "io" + "io/fs" + "log" + "net/http" + "os" + "os/exec" + "path" + "strings" + + "github.com/aws/aws-sdk-go/service/s3" + "github.com/gin-gonic/gin" + + "github.com/SecurityBrewery/catalyst/database" + "github.com/SecurityBrewery/catalyst/storage" +) + +func BackupHandler(catalystStorage *storage.Storage, c *database.Config) gin.HandlerFunc { + return func(context *gin.Context) { + context.Header("Content-Disposition", "attachment; filename=backup.zip") + context.Header("Content-Type", "application/zip") + err := Backup(catalystStorage, c, context.Writer) + if err != nil { + log.Println(err) + context.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + } + } +} + +type WriterAtBuffer struct { + bytes.Buffer +} + +func (fw WriterAtBuffer) WriteAt(p []byte, offset int64) (n int, err error) { + return fw.Write(p) +} + +func Backup(catalystStorage *storage.Storage, c *database.Config, writer io.Writer) error { + archive := zip.NewWriter(writer) + defer archive.Close() + + archive.SetComment(GetVersion()) + + // S3 + if err := backupS3(catalystStorage, archive); err != nil { + return err + } + + // Arango + return backupArango(c, archive) +} + +func backupS3(catalystStorage *storage.Storage, archive *zip.Writer) error { + buckets, err := catalystStorage.S3().ListBuckets(nil) + if err != nil { + return err + } + for _, bucket := range buckets.Buckets { + objects, err := catalystStorage.S3().ListObjectsV2(&s3.ListObjectsV2Input{ + Bucket: bucket.Name, + }) + if err != nil { + return err + } + + for _, content := range objects.Contents { + rbuf := &WriterAtBuffer{} + _, err := catalystStorage.Downloader().Download(rbuf, &s3.GetObjectInput{ + Bucket: bucket.Name, + Key: content.Key, + }) + if err != nil { + return err + } + + a, err := archive.Create(path.Join("minio", *bucket.Name, *content.Key)) + if err != nil { + return err + } + + if _, err := io.Copy(a, rbuf); err != nil { + return err + } + } + } + return nil +} + +func backupArango(c *database.Config, archive *zip.Writer) error { + dir, err := os.MkdirTemp("", "catalyst-backup") + if err != nil { + return err + } + defer os.RemoveAll(dir) + + if err := arangodump(dir, c); err != nil { + return err + } + + return zipDump(dir, archive) +} + +func zipDump(dir string, archive *zip.Writer) error { + fsys := os.DirFS(dir) + return fs.WalkDir(fsys, ".", func(p string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + + if d.IsDir() { + return nil + } + + a, err := archive.Create(path.Join("arango", p)) + if err != nil { + return err + } + + f, err := fsys.Open(p) + if err != nil { + return err + } + + if _, err := io.Copy(a, f); err != nil { + return err + } + return nil + }) +} + +func arangodump(dir string, config *database.Config) error { + host := strings.Replace(config.Host, "http", "tcp", 1) + + name := config.Name + if config.Name == "" { + name = database.Name + } + args := []string{ + "--output-directory", dir, "--server.endpoint", host, + "--server.username", config.User, "--server.password", config.Password, + "--server.database", name, + } + cmd := exec.Command("arangodump", args...) + return cmd.Run() +} diff --git a/bus/bus.go b/bus/bus.go new file mode 100644 index 0000000..6492552 --- /dev/null +++ b/bus/bus.go @@ -0,0 +1,139 @@ +package bus + +import ( + "encoding/json" + "log" + + "github.com/arangodb/go-driver" + emitter "github.com/emitter-io/go/v2" + + "github.com/SecurityBrewery/catalyst/generated/models" +) + +const ( + channelUpdate = "data" + channelJob = "job" + channelResult = "result" +) + +type Bus struct { + config *Config + client *emitter.Client +} + +type Config struct { + Host string + Key string + resultBusKey string + jobBusKey string + dataBusKey string + APIUrl string +} + +type JobMsg struct { + ID string `json:"id"` + Automation string `json:"automation"` + Origin *models.Origin `json:"origin"` + Message *models.Message `json:"message"` +} + +type ResultMsg struct { + Automation string `json:"automation"` + Data map[string]interface{} `json:"data,omitempty"` + Target *models.Origin `json:"target"` +} + +func New(c *Config) (*Bus, error) { + client, err := emitter.Connect(c.Host, func(_ *emitter.Client, msg emitter.Message) { + log.Printf("received: '%s' topic: '%s'\n", msg.Payload(), msg.Topic()) + }) + if err != nil { + return nil, err + } + + c.dataBusKey, err = client.GenerateKey(c.Key, channelUpdate+"/", "rwls", 0) + if err != nil { + return nil, err + } + c.jobBusKey, err = client.GenerateKey(c.Key, channelJob+"/", "rwls", 0) + if err != nil { + return nil, err + } + c.resultBusKey, err = client.GenerateKey(c.Key, channelResult+"/", "rwls", 0) + if err != nil { + return nil, err + } + + return &Bus{config: c, client: client}, err +} + +func (b *Bus) PublishUpdate(ids []driver.DocumentID) error { + return b.jsonPublish(ids, channelUpdate, b.config.dataBusKey) +} + +func (b *Bus) PublishJob(id, automation string, payload interface{}, context *models.Context, origin *models.Origin) error { + return b.jsonPublish(&JobMsg{ + ID: id, + Automation: automation, + Origin: origin, + Message: &models.Message{ + Context: context, + Payload: payload, + }, + }, channelJob, b.config.jobBusKey) +} + +func (b *Bus) PublishResult(automation string, data map[string]interface{}, target *models.Origin) error { + return b.jsonPublish(&ResultMsg{Automation: automation, Data: data, Target: target}, channelResult, b.config.resultBusKey) +} + +func (b *Bus) jsonPublish(msg interface{}, channel, key string) error { + payload, err := json.Marshal(msg) + if err != nil { + return err + } + + return b.client.Publish(key, channel, payload) +} + +func (b *Bus) SubscribeUpdate(f func(ids []driver.DocumentID)) error { + return b.safeSubscribe(b.config.dataBusKey, channelUpdate, func(c *emitter.Client, m emitter.Message) { + var msg []driver.DocumentID + if err := json.Unmarshal(m.Payload(), &msg); err != nil { + log.Println(err) + return + } + go f(msg) + }) +} + +func (b *Bus) SubscribeJob(f func(msg *JobMsg)) error { + return b.safeSubscribe(b.config.jobBusKey, channelJob, func(c *emitter.Client, m emitter.Message) { + var msg JobMsg + if err := json.Unmarshal(m.Payload(), &msg); err != nil { + log.Println(err) + return + } + go f(&msg) + }) +} + +func (b *Bus) SubscribeResult(f func(msg *ResultMsg)) error { + return b.safeSubscribe(b.config.resultBusKey, channelResult, func(c *emitter.Client, m emitter.Message) { + var msg ResultMsg + if err := json.Unmarshal(m.Payload(), &msg); err != nil { + log.Println(err) + return + } + go f(&msg) + }) +} + +func (b *Bus) safeSubscribe(key, channel string, handler func(c *emitter.Client, m emitter.Message)) error { + defer func() { + if r := recover(); r != nil { + log.Printf("Recovered %s in channel %s\n", r, channel) + } + }() + return b.client.Subscribe(key, channel, handler) +} diff --git a/caql/blevebuilder.go b/caql/blevebuilder.go new file mode 100644 index 0000000..4faf1f8 --- /dev/null +++ b/caql/blevebuilder.go @@ -0,0 +1,182 @@ +package caql + +import ( + "errors" + "fmt" + "strconv" + + "github.com/SecurityBrewery/catalyst/generated/caql/parser" +) + +var TooComplexError = errors.New("unsupported features for index queries, use advanced search instead") + +type bleveBuilder struct { + *parser.BaseCAQLParserListener + stack []string + err error +} + +// push is a helper function for pushing new node to the listener Stack. +func (s *bleveBuilder) push(i string) { + s.stack = append(s.stack, i) +} + +// pop is a helper function for poping a node from the listener Stack. +func (s *bleveBuilder) pop() (n string) { + // Check that we have nodes in the stack. + size := len(s.stack) + if size < 1 { + panic(ErrStack) + } + + // Pop the last value from the Stack. + n, s.stack = s.stack[size-1], s.stack[:size-1] + + return +} + +func (s *bleveBuilder) binaryPop() (interface{}, interface{}) { + right, left := s.pop(), s.pop() + return left, right +} + +// ExitExpression is called when production expression is exited. +func (s *bleveBuilder) ExitExpression(ctx *parser.ExpressionContext) { + switch { + case ctx.Value_literal() != nil: + // pass + case ctx.Reference() != nil: + // pass + case ctx.Operator_unary() != nil: + s.err = TooComplexError + return + + case ctx.T_PLUS() != nil: + fallthrough + case ctx.T_MINUS() != nil: + fallthrough + case ctx.T_TIMES() != nil: + fallthrough + case ctx.T_DIV() != nil: + fallthrough + case ctx.T_MOD() != nil: + s.err = TooComplexError + return + + case ctx.T_RANGE() != nil: + s.err = TooComplexError + return + + case ctx.T_LT() != nil && ctx.GetEq_op() == nil: + left, right := s.binaryPop() + s.push(fmt.Sprintf("%s:<%s", left, right)) + case ctx.T_GT() != nil && ctx.GetEq_op() == nil: + left, right := s.binaryPop() + s.push(fmt.Sprintf("%s:>%s", left, right)) + case ctx.T_LE() != nil && ctx.GetEq_op() == nil: + left, right := s.binaryPop() + s.push(fmt.Sprintf("%s:<=%s", left, right)) + case ctx.T_GE() != nil && ctx.GetEq_op() == nil: + left, right := s.binaryPop() + s.push(fmt.Sprintf("%s:>=%s", left, right)) + + case ctx.T_IN() != nil && ctx.GetEq_op() == nil: + s.err = TooComplexError + return + + case ctx.T_EQ() != nil && ctx.GetEq_op() == nil: + left, right := s.binaryPop() + s.push(fmt.Sprintf("%s:%s", left, right)) + case ctx.T_NE() != nil && ctx.GetEq_op() == nil: + left, right := s.binaryPop() + s.push(fmt.Sprintf("-%s:%s", left, right)) + + case ctx.T_ALL() != nil && ctx.GetEq_op() != nil: + fallthrough + case ctx.T_ANY() != nil && ctx.GetEq_op() != nil: + fallthrough + case ctx.T_NONE() != nil && ctx.GetEq_op() != nil: + s.err = TooComplexError + return + + case ctx.T_ALL() != nil && ctx.T_NOT() != nil && ctx.T_IN() != nil: + fallthrough + case ctx.T_ANY() != nil && ctx.T_NOT() != nil && ctx.T_IN() != nil: + fallthrough + case ctx.T_NONE() != nil && ctx.T_NOT() != nil && ctx.T_IN() != nil: + s.err = TooComplexError + return + + case ctx.T_LIKE() != nil: + s.err = errors.New("index queries are like queries by default") + return + + case ctx.T_REGEX_MATCH() != nil: + left, right := s.binaryPop() + if ctx.T_NOT() != nil { + s.err = TooComplexError + return + } else { + s.push(fmt.Sprintf("%s:/%s/", left, right)) + } + case ctx.T_REGEX_NON_MATCH() != nil: + s.err = errors.New("index query cannot contain regex non matches, use advanced search instead") + return + + case ctx.T_AND() != nil: + left, right := s.binaryPop() + s.push(fmt.Sprintf("%s %s", left, right)) + case ctx.T_OR() != nil: + s.err = errors.New("index query cannot contain OR, use advanced search instead") + return + + case ctx.T_QUESTION() != nil && len(ctx.AllExpression()) == 3: + s.err = errors.New("index query cannot contain ternary operations, use advanced search instead") + return + case ctx.T_QUESTION() != nil && len(ctx.AllExpression()) == 2: + s.err = errors.New("index query cannot contain ternary operations, use advanced search instead") + return + + default: + panic("unknown expression") + } +} + +// ExitReference is called when production reference is exited. +func (s *bleveBuilder) ExitReference(ctx *parser.ReferenceContext) { + switch { + case ctx.DOT() != nil: + reference := s.pop() + + s.push(fmt.Sprintf("%s.%s", reference, ctx.T_STRING().GetText())) + case ctx.T_STRING() != nil: + s.push(ctx.T_STRING().GetText()) + case ctx.Compound_value() != nil: + s.err = TooComplexError + return + case ctx.Function_call() != nil: + s.err = TooComplexError + return + case ctx.T_OPEN() != nil: + s.err = TooComplexError + return + case ctx.T_ARRAY_OPEN() != nil: + s.err = TooComplexError + return + default: + panic(fmt.Sprintf("unexpected value: %s", ctx.GetText())) + } +} + +// ExitValue_literal is called when production value_literal is exited. +func (s *bleveBuilder) ExitValue_literal(ctx *parser.Value_literalContext) { + if ctx.T_QUOTED_STRING() != nil { + st, err := unquote(ctx.GetText()) + if err != nil { + panic(err) + } + s.push(strconv.Quote(st)) + } else { + s.push(ctx.GetText()) + } +} diff --git a/caql/blevebuilder_test.go b/caql/blevebuilder_test.go new file mode 100644 index 0000000..edc453e --- /dev/null +++ b/caql/blevebuilder_test.go @@ -0,0 +1,50 @@ +package caql + +import ( + "testing" +) + +func TestBleveBuilder(t *testing.T) { + tests := []struct { + name string + saql string + wantBleve string + wantParseErr bool + wantRebuildErr bool + }{ + {name: "Search 1", saql: `"Bob"`, wantBleve: `"Bob"`}, + {name: "Search 2", saql: `"Bob" AND title == 'Name'`, wantBleve: `"Bob" title:"Name"`}, + {name: "Search 3", saql: `"Bob" OR title == 'Name'`, wantRebuildErr: true}, + {name: "Search 4", saql: `title == 'malware' AND 'wannacry'`, wantBleve: `title:"malware" "wannacry"`}, + } + for _, tt := range tests { + parser := &Parser{} + + t.Run(tt.name, func(t *testing.T) { + expr, err := parser.Parse(tt.saql) + if (err != nil) != tt.wantParseErr { + t.Errorf("Parse() error = %v, wantErr %v", err, tt.wantParseErr) + if expr != nil { + t.Error(expr.String()) + } + return + } + if err != nil { + return + } + + got, err := expr.BleveString() + if (err != nil) != tt.wantRebuildErr { + t.Error(expr.String()) + t.Errorf("String() error = %v, wantErr %v", err, tt.wantParseErr) + return + } + if err != nil { + return + } + if got != tt.wantBleve { + t.Errorf("String() got = %v, want %v", got, tt.wantBleve) + } + }) + } +} diff --git a/caql/builder.go b/caql/builder.go new file mode 100644 index 0000000..e31c9c8 --- /dev/null +++ b/caql/builder.go @@ -0,0 +1,317 @@ +package caql + +import ( + "fmt" + "strconv" + "strings" + + "github.com/SecurityBrewery/catalyst/generated/caql/parser" +) + +type Searcher interface { + Search(term string) (ids []string, err error) +} + +type aqlBuilder struct { + *parser.BaseCAQLParserListener + searcher Searcher + stack []string + prefix string +} + +// push is a helper function for pushing new node to the listener Stack. +func (s *aqlBuilder) push(i string) { + s.stack = append(s.stack, i) +} + +// pop is a helper function for poping a node from the listener Stack. +func (s *aqlBuilder) pop() (n string) { + // Check that we have nodes in the stack. + size := len(s.stack) + if size < 1 { + panic(ErrStack) + } + + // Pop the last value from the Stack. + n, s.stack = s.stack[size-1], s.stack[:size-1] + + return +} + +func (s *aqlBuilder) binaryPop() (string, string) { + right, left := s.pop(), s.pop() + return left, right +} + +// ExitExpression is called when production expression is exited. +func (s *aqlBuilder) ExitExpression(ctx *parser.ExpressionContext) { + switch { + case ctx.Value_literal() != nil: + if ctx.GetParent().GetParent() == nil { + s.push(s.toBoolString(s.pop())) + } + case ctx.Reference() != nil: + ref := s.pop() + if ref == "d.id" { + s.push("d._key") + } else { + s.push(ref) + } + // pass + case ctx.Operator_unary() != nil: + s.push(s.toBoolString(s.pop())) + + case ctx.T_PLUS() != nil: + left, right := s.binaryPop() + s.push(fmt.Sprintf("%s + %s", left, right)) + case ctx.T_MINUS() != nil: + left, right := s.binaryPop() + s.push(fmt.Sprintf("%s - %s", left, right)) + case ctx.T_TIMES() != nil: + left, right := s.binaryPop() + s.push(fmt.Sprintf("%s * %s", left, right)) + case ctx.T_DIV() != nil: + left, right := s.binaryPop() + s.push(fmt.Sprintf("%s / %s", left, right)) + case ctx.T_MOD() != nil: + left, right := s.binaryPop() + s.push(fmt.Sprintf("%s %% %s", left, right)) + + case ctx.T_RANGE() != nil: + left, right := s.binaryPop() + s.push(fmt.Sprintf("%s..%s", left, right)) + + case ctx.T_LT() != nil && ctx.GetEq_op() == nil: + left, right := s.binaryPop() + s.push(fmt.Sprintf("%s < %s", left, right)) + case ctx.T_GT() != nil && ctx.GetEq_op() == nil: + left, right := s.binaryPop() + s.push(fmt.Sprintf("%s > %s", left, right)) + case ctx.T_LE() != nil && ctx.GetEq_op() == nil: + left, right := s.binaryPop() + s.push(fmt.Sprintf("%s <= %s", left, right)) + case ctx.T_GE() != nil && ctx.GetEq_op() == nil: + left, right := s.binaryPop() + s.push(fmt.Sprintf("%s >= %s", left, right)) + + case ctx.T_IN() != nil && ctx.GetEq_op() == nil: + left, right := s.binaryPop() + if ctx.T_NOT() != nil { + s.push(fmt.Sprintf("%s NOT IN %s", left, right)) + } else { + s.push(fmt.Sprintf("%s IN %s", left, right)) + } + + case ctx.T_EQ() != nil && ctx.GetEq_op() == nil: + left, right := s.binaryPop() + s.push(fmt.Sprintf("%s == %s", left, right)) + case ctx.T_NE() != nil && ctx.GetEq_op() == nil: + left, right := s.binaryPop() + s.push(fmt.Sprintf("%s != %s", left, right)) + + case ctx.T_ALL() != nil && ctx.GetEq_op() != nil: + right, left := s.pop(), s.pop() + s.push(fmt.Sprintf("%s ALL %s %s", left, ctx.GetEq_op().GetText(), right)) + case ctx.T_ANY() != nil && ctx.GetEq_op() != nil: + right, left := s.pop(), s.pop() + s.push(fmt.Sprintf("%s ANY %s %s", left, ctx.GetEq_op().GetText(), right)) + case ctx.T_NONE() != nil && ctx.GetEq_op() != nil: + right, left := s.pop(), s.pop() + s.push(fmt.Sprintf("%s NONE %s %s", left, ctx.GetEq_op().GetText(), right)) + + case ctx.T_ALL() != nil && ctx.T_NOT() != nil && ctx.T_IN() != nil: + right, left := s.pop(), s.pop() + s.push(fmt.Sprintf("%s ALL IN %s", left, right)) + case ctx.T_ANY() != nil && ctx.T_NOT() != nil && ctx.T_IN() != nil: + right, left := s.pop(), s.pop() + s.push(fmt.Sprintf("%s ANY IN %s", left, right)) + case ctx.T_NONE() != nil && ctx.T_NOT() != nil && ctx.T_IN() != nil: + right, left := s.pop(), s.pop() + s.push(fmt.Sprintf("%s NONE IN %s", left, right)) + + case ctx.T_LIKE() != nil: + left, right := s.binaryPop() + if ctx.T_NOT() != nil { + s.push(fmt.Sprintf("%s NOT LIKE %s", left, right)) + } else { + s.push(fmt.Sprintf("%s LIKE %s", left, right)) + } + case ctx.T_REGEX_MATCH() != nil: + left, right := s.binaryPop() + if ctx.T_NOT() != nil { + s.push(fmt.Sprintf("%s NOT =~ %s", left, right)) + } else { + s.push(fmt.Sprintf("%s =~ %s", left, right)) + } + case ctx.T_REGEX_NON_MATCH() != nil: + left, right := s.binaryPop() + if ctx.T_NOT() != nil { + s.push(fmt.Sprintf("%s NOT !~ %s", left, right)) + } else { + s.push(fmt.Sprintf("%s !~ %s", left, right)) + } + + case ctx.T_AND() != nil: + left, right := s.binaryPop() + left = s.toBoolString(left) + right = s.toBoolString(right) + s.push(fmt.Sprintf("%s AND %s", left, right)) + case ctx.T_OR() != nil: + left, right := s.binaryPop() + left = s.toBoolString(left) + right = s.toBoolString(right) + s.push(fmt.Sprintf("%s OR %s", left, right)) + + case ctx.T_QUESTION() != nil && len(ctx.AllExpression()) == 3: + right, middle, left := s.pop(), s.pop(), s.pop() + s.push(fmt.Sprintf("%s ? %s : %s", left, middle, right)) + case ctx.T_QUESTION() != nil && len(ctx.AllExpression()) == 2: + right, left := s.pop(), s.pop() + s.push(fmt.Sprintf("%s ? : %s", left, right)) + + default: + panic("unknown expression") + } +} + +func (s *aqlBuilder) toBoolString(v string) string { + _, err := unquote(v) + if err == nil { + ids, err := s.searcher.Search(v) + if err != nil { + panic("invalid search " + err.Error()) + } + return fmt.Sprintf(`d._key IN ["%s"]`, strings.Join(ids, `","`)) + } + return v +} + +// ExitOperator_unary is called when production operator_unary is exited. +func (s *aqlBuilder) ExitOperator_unary(ctx *parser.Operator_unaryContext) { + value := s.pop() + switch { + case ctx.T_PLUS() != nil: + s.push(value) + case ctx.T_MINUS() != nil: + s.push(fmt.Sprintf("-%s", value)) + case ctx.T_NOT() != nil: + s.push(fmt.Sprintf("NOT %s", value)) + default: + panic(fmt.Sprintf("unexpected operation: %s", ctx.GetText())) + } +} + +// ExitReference is called when production reference is exited. +func (s *aqlBuilder) ExitReference(ctx *parser.ReferenceContext) { + switch { + case ctx.DOT() != nil: + reference := s.pop() + if s.prefix != "" && !strings.HasPrefix(reference, s.prefix) { + reference = s.prefix + reference + } + s.push(fmt.Sprintf("%s.%s", reference, ctx.T_STRING().GetText())) + case ctx.T_STRING() != nil: + reference := ctx.T_STRING().GetText() + if s.prefix != "" && !strings.HasPrefix(reference, s.prefix) { + reference = s.prefix + reference + } + s.push(reference) + case ctx.Compound_value() != nil: + // pass + case ctx.Function_call() != nil: + // pass + case ctx.T_OPEN() != nil: + s.push(fmt.Sprintf("(%s)", s.pop())) + case ctx.T_ARRAY_OPEN() != nil: + key := s.pop() + reference := s.pop() + + s.push(fmt.Sprintf("%s[%s]", reference, key)) + default: + panic(fmt.Sprintf("unexpected value: %s", ctx.GetText())) + } +} + +// ExitCompound_value is called when production compound_value is exited. +func (s *aqlBuilder) ExitCompound_value(ctx *parser.Compound_valueContext) { + // pass +} + +// ExitFunction_call is called when production function_call is exited. +func (s *aqlBuilder) ExitFunction_call(ctx *parser.Function_callContext) { + var array []string + for range ctx.AllExpression() { + // prepend element + array = append([]string{s.pop()}, array...) + } + parameter := strings.Join(array, ", ") + + if !stringSliceContains(functionNames, strings.ToUpper(ctx.T_STRING().GetText())) { + panic("unknown function") + } + + s.push(fmt.Sprintf("%s(%s)", strings.ToUpper(ctx.T_STRING().GetText()), parameter)) +} + +// ExitValue_literal is called when production value_literal is exited. +func (s *aqlBuilder) ExitValue_literal(ctx *parser.Value_literalContext) { + if ctx.T_QUOTED_STRING() != nil { + st, err := unquote(ctx.GetText()) + if err != nil { + panic(err) + } + s.push(strconv.Quote(st)) + } else { + s.push(ctx.GetText()) + } +} + +// ExitArray is called when production array is exited. +func (s *aqlBuilder) ExitArray(ctx *parser.ArrayContext) { + var elements []string + for range ctx.AllExpression() { + // elements = append(elements, s.pop()) + elements = append([]string{s.pop()}, elements...) + } + s.push("[" + strings.Join(elements, ", ") + "]") +} + +// ExitObject is called when production object is exited. +func (s *aqlBuilder) ExitObject(ctx *parser.ObjectContext) { + var elements []string + for range ctx.AllObject_element() { + key, value := s.pop(), s.pop() + + elements = append([]string{fmt.Sprintf("%s: %v", key, value)}, elements...) + } + // s.push(object) + s.push("{" + strings.Join(elements, ", ") + "}") +} + +// ExitObject_element is called when production object_element is exited. +func (s *aqlBuilder) ExitObject_element(ctx *parser.Object_elementContext) { + switch { + case ctx.T_STRING() != nil: + s.push(ctx.GetText()) + s.push(ctx.GetText()) + case ctx.Object_element_name() != nil, ctx.T_ARRAY_OPEN() != nil: + key, value := s.pop(), s.pop() + + s.push(key) + s.push(value) + default: + panic(fmt.Sprintf("unexpected value: %s", ctx.GetText())) + } +} + +// ExitObject_element_name is called when production object_element_name is exited. +func (s *aqlBuilder) ExitObject_element_name(ctx *parser.Object_element_nameContext) { + switch { + case ctx.T_STRING() != nil: + s.push(ctx.T_STRING().GetText()) + case ctx.T_QUOTED_STRING() != nil: + s.push(ctx.T_QUOTED_STRING().GetText()) + default: + panic(fmt.Sprintf("unexpected value: %s", ctx.GetText())) + } +} diff --git a/caql/errors.go b/caql/errors.go new file mode 100644 index 0000000..40acff6 --- /dev/null +++ b/caql/errors.go @@ -0,0 +1,8 @@ +package caql + +import "errors" + +var ( + ErrStack = errors.New("unexpected operator stack") + ErrUndefined = errors.New("variable not defined") +) diff --git a/caql/function.go b/caql/function.go new file mode 100644 index 0000000..88b4216 --- /dev/null +++ b/caql/function.go @@ -0,0 +1,750 @@ +package caql + +import ( + "errors" + "fmt" + "math" + "math/rand" + "sort" + "strings" + "unicode/utf8" + + "github.com/imdario/mergo" + + "github.com/SecurityBrewery/catalyst/generated/caql/parser" +) + +func (s *aqlInterpreter) function(ctx *parser.Function_callContext) { + switch strings.ToUpper(ctx.T_STRING().GetText()) { + + default: + s.appendErrors(errors.New("unknown function")) + + // Array https://www.arangodb.com/docs/stable/aql/functions-array.html + case "APPEND": + u := false + if len(ctx.AllExpression()) == 3 { + u = s.pop().(bool) + } + seen := map[interface{}]bool{} + values, anyArray := s.pop().([]interface{}), s.pop().([]interface{}) + + if u { + for _, e := range anyArray { + seen[e] = true + } + } + + for _, e := range values { + _, ok := seen[e] + if !ok || !u { + seen[e] = true + anyArray = append(anyArray, e) + } + } + s.push(anyArray) + case "COUNT_DISTINCT", "COUNT_UNIQUE": + count := 0 + seen := map[interface{}]bool{} + array := s.pop().([]interface{}) + for _, e := range array { + _, ok := seen[e] + if !ok { + seen[e] = true + count += 1 + } + } + s.push(float64(count)) + case "FIRST": + array := s.pop().([]interface{}) + if len(array) == 0 { + s.push(nil) + } else { + s.push(array[0]) + } + // case "FLATTEN": + // case "INTERLEAVE": + case "INTERSECTION": + iset := New(s.pop().([]interface{})...) + + for i := 1; i < len(ctx.AllExpression()); i++ { + iset = iset.Intersection(New(s.pop().([]interface{})...)) + } + + s.push(iset.Values()) + // case "JACCARD": + case "LAST": + array := s.pop().([]interface{}) + if len(array) == 0 { + s.push(nil) + } else { + s.push(array[len(array)-1]) + } + case "COUNT", "LENGTH": + switch v := s.pop().(type) { + case nil: + s.push(float64(0)) + case bool: + if v { + s.push(float64(1)) + } else { + s.push(float64(0)) + } + case float64: + s.push(float64(len(fmt.Sprint(v)))) + case string: + s.push(float64(utf8.RuneCountInString(v))) + case []interface{}: + s.push(float64(len(v))) + case map[string]interface{}: + s.push(float64(len(v))) + default: + panic("unknown type") + } + case "MINUS": + var sets []*Set + for i := 0; i < len(ctx.AllExpression()); i++ { + sets = append(sets, New(s.pop().([]interface{})...)) + } + + iset := sets[len(sets)-1] + // for i := len(sets)-1; i > 0; i-- { + for i := 0; i < len(sets)-1; i++ { + iset = iset.Minus(sets[i]) + } + + s.push(iset.Values()) + case "NTH": + pos := s.pop().(float64) + array := s.pop().([]interface{}) + if int(pos) >= len(array) || pos < 0 { + s.push(nil) + } else { + s.push(array[int64(pos)]) + } + // case "OUTERSECTION": + // array := s.pop().([]interface{}) + // union := New(array...) + // intersection := New(s.pop().([]interface{})...) + // for i := 1; i < len(ctx.AllExpression()); i++ { + // array = s.pop().([]interface{}) + // union = union.Union(New(array...)) + // intersection = intersection.Intersection(New(array...)) + // } + // s.push(union.Minus(intersection).Values()) + case "POP": + array := s.pop().([]interface{}) + s.push(array[:len(array)-1]) + case "POSITION", "CONTAINS_ARRAY": + returnIndex := false + if len(ctx.AllExpression()) == 3 { + returnIndex = s.pop().(bool) + } + search := s.pop() + array := s.pop().([]interface{}) + + for idx, e := range array { + if e == search { + if returnIndex { + s.push(float64(idx)) + } else { + s.push(true) + } + } + } + + if returnIndex { + s.push(float64(-1)) + } else { + s.push(false) + } + case "PUSH": + u := false + if len(ctx.AllExpression()) == 3 { + u = s.pop().(bool) + } + element := s.pop() + array := s.pop().([]interface{}) + + if u && contains(array, element) { + s.push(array) + } else { + s.push(append(array, element)) + } + case "REMOVE_NTH": + position := s.pop().(float64) + anyArray := s.pop().([]interface{}) + + if position < 0 { + position = float64(len(anyArray) + int(position)) + } + + result := []interface{}{} + for idx, e := range anyArray { + if idx != int(position) { + result = append(result, e) + } + } + s.push(result) + case "REPLACE_NTH": + defaultPaddingValue := "" + if len(ctx.AllExpression()) == 4 { + defaultPaddingValue = s.pop().(string) + } + replaceValue := s.pop().(string) + position := s.pop().(float64) + anyArray := s.pop().([]interface{}) + + if position < 0 { + position = float64(len(anyArray) + int(position)) + if position < 0 { + position = 0 + } + } + + switch { + case int(position) < len(anyArray): + anyArray[int(position)] = replaceValue + case int(position) == len(anyArray): + anyArray = append(anyArray, replaceValue) + default: + if defaultPaddingValue == "" { + panic("missing defaultPaddingValue") + } + for len(anyArray) < int(position) { + anyArray = append(anyArray, defaultPaddingValue) + } + anyArray = append(anyArray, replaceValue) + } + + s.push(anyArray) + case "REMOVE_VALUE": + limit := math.Inf(1) + if len(ctx.AllExpression()) == 3 { + limit = s.pop().(float64) + } + value := s.pop() + array := s.pop().([]interface{}) + result := []interface{}{} + for idx, e := range array { + if e != value || float64(idx) > limit { + result = append(result, e) + } + } + s.push(result) + case "REMOVE_VALUES": + values := s.pop().([]interface{}) + array := s.pop().([]interface{}) + result := []interface{}{} + for _, e := range array { + if !contains(values, e) { + result = append(result, e) + } + } + s.push(result) + case "REVERSE": + array := s.pop().([]interface{}) + var reverse []interface{} + for _, e := range array { + reverse = append([]interface{}{e}, reverse...) + } + s.push(reverse) + case "SHIFT": + s.push(s.pop().([]interface{})[1:]) + case "SLICE": + length := float64(-1) + full := true + if len(ctx.AllExpression()) == 3 { + length = s.pop().(float64) + full = false + } + start := int64(s.pop().(float64)) + array := s.pop().([]interface{}) + + if start < 0 { + start = int64(len(array)) + start + } + if full { + length = float64(int64(len(array)) - start) + } + + end := int64(0) + if length < 0 { + end = int64(len(array)) + int64(length) + } else { + end = start + int64(length) + } + s.push(array[start:end]) + case "SORTED": + array := s.pop().([]interface{}) + sort.Slice(array, func(i, j int) bool { return lt(array[i], array[j]) }) + s.push(array) + case "SORTED_UNIQUE": + array := s.pop().([]interface{}) + sort.Slice(array, func(i, j int) bool { return lt(array[i], array[j]) }) + s.push(unique(array)) + case "UNION": + array := s.pop().([]interface{}) + + for i := 1; i < len(ctx.AllExpression()); i++ { + array = append(array, s.pop().([]interface{})...) + } + + sort.Slice(array, func(i, j int) bool { return lt(array[i], array[j]) }) + s.push(array) + case "UNION_DISTINCT": + iset := New(s.pop().([]interface{})...) + + for i := 1; i < len(ctx.AllExpression()); i++ { + iset = iset.Union(New(s.pop().([]interface{})...)) + } + + s.push(unique(iset.Values())) + case "UNIQUE": + s.push(unique(s.pop().([]interface{}))) + case "UNSHIFT": + u := false + if len(ctx.AllExpression()) == 3 { + u = s.pop().(bool) + } + element := s.pop() + array := s.pop().([]interface{}) + if u && contains(array, element) { + s.push(array) + } else { + s.push(append([]interface{}{element}, array...)) + } + + // Bit https://www.arangodb.com/docs/stable/aql/functions-bit.html + // case "BIT_AND": + // case "BIT_CONSTRUCT": + // case "BIT_DECONSTRUCT": + // case "BIT_FROM_STRING": + // case "BIT_NEGATE": + // case "BIT_OR": + // case "BIT_POPCOUNT": + // case "BIT_SHIFT_LEFT": + // case "BIT_SHIFT_RIGHT": + // case "BIT_TEST": + // case "BIT_TO_STRING": + // case "BIT_XOR": + + // Date https://www.arangodb.com/docs/stable/aql/functions-date.html + // case "DATE_NOW": + // case "DATE_ISO8601": + // case "DATE_TIMESTAMP": + // case "IS_DATESTRING": + + // case "DATE_DAYOFWEEK": + // case "DATE_YEAR": + // case "DATE_MONTH": + // case "DATE_DAY": + // case "DATE_HOUR": + // case "DATE_MINUTE": + // case "DATE_SECOND": + // case "DATE_MILLISECOND": + + // case "DATE_DAYOFYEAR": + // case "DATE_ISOWEEK": + // case "DATE_LEAPYEAR": + // case "DATE_QUARTER": + // case "DATE_DAYS_IN_MONTH": + // case "DATE_TRUNC": + // case "DATE_ROUND": + // case "DATE_FORMAT": + + // case "DATE_ADD": + // case "DATE_SUBTRACT": + // case "DATE_DIFF": + // case "DATE_COMPARE": + + // Document https://www.arangodb.com/docs/stable/aql/functions-document.html + case "ATTRIBUTES": + if len(ctx.AllExpression()) == 3 { + s.pop() // always sort + } + removeInternal := false + if len(ctx.AllExpression()) >= 2 { + removeInternal = s.pop().(bool) + } + var keys []interface{} + for k := range s.pop().(map[string]interface{}) { + isInternalKey := strings.HasPrefix(k, "_") + if !removeInternal || !isInternalKey { + keys = append(keys, k) + } + } + sort.Slice(keys, func(i, j int) bool { return lt(keys[i], keys[j]) }) + s.push(keys) + // case "COUNT": + case "HAS": + right, left := s.pop(), s.pop() + _, ok := left.(map[string]interface{})[right.(string)] + s.push(ok) + // case "KEEP": + // case "LENGTH": + // case "MATCHES": + case "MERGE": + var docs []map[string]interface{} + if len(ctx.AllExpression()) == 1 { + for _, doc := range s.pop().([]interface{}) { + docs = append([]map[string]interface{}{doc.(map[string]interface{})}, docs...) + } + } else { + for i := 0; i < len(ctx.AllExpression()); i++ { + docs = append(docs, s.pop().(map[string]interface{})) + } + } + + doc := docs[len(docs)-1] + for i := len(docs) - 2; i >= 0; i-- { + for k, v := range docs[i] { + doc[k] = v + } + } + s.push(doc) + case "MERGE_RECURSIVE": + var doc map[string]interface{} + for i := 0; i < len(ctx.AllExpression()); i++ { + err := mergo.Merge(&doc, s.pop().(map[string]interface{})) + if err != nil { + panic(err) + } + } + s.push(doc) + // case "PARSE_IDENTIFIER": + // case "TRANSLATE": + // case "UNSET": + // case "UNSET_RECURSIVE": + case "VALUES": + removeInternal := false + if len(ctx.AllExpression()) == 2 { + removeInternal = s.pop().(bool) + } + var values []interface{} + for k, v := range s.pop().(map[string]interface{}) { + isInternalKey := strings.HasPrefix(k, "_") + if !removeInternal || !isInternalKey { + values = append(values, v) + } + } + sort.Slice(values, func(i, j int) bool { return lt(values[i], values[j]) }) + s.push(values) + // case "ZIP": + + // Numeric https://www.arangodb.com/docs/stable/aql/functions-numeric.html + case "ABS": + s.push(math.Abs(s.pop().(float64))) + case "ACOS": + v := s.pop().(float64) + asin := math.Acos(v) + if v > 1 || v < -1 { + s.push(nil) + } else { + s.push(asin) + } + case "ASIN": + v := s.pop().(float64) + asin := math.Asin(v) + if v > 1 || v < -1 { + s.push(nil) + } else { + s.push(asin) + } + case "ATAN": + s.push(math.Atan(s.pop().(float64))) + case "ATAN2": + s.push(math.Atan2(s.pop().(float64), s.pop().(float64))) + case "AVERAGE", "AVG": + count := 0 + sum := float64(0) + array := s.pop().([]interface{}) + for _, element := range array { + if element != nil { + count += 1 + sum += toNumber(element) + } + } + if count == 0 { + s.push(nil) + } else { + s.push(sum / float64(count)) + } + case "CEIL": + s.push(math.Ceil(s.pop().(float64))) + case "COS": + s.push(math.Cos(s.pop().(float64))) + case "DEGREES": + s.push(s.pop().(float64) * 180 / math.Pi) + case "EXP": + s.push(math.Exp(s.pop().(float64))) + case "EXP2": + s.push(math.Exp2(s.pop().(float64))) + case "FLOOR": + s.push(math.Floor(s.pop().(float64))) + case "LOG": + l := math.Log(s.pop().(float64)) + if l <= 0 { + s.push(nil) + } else { + s.push(l) + } + case "LOG2": + l := math.Log2(s.pop().(float64)) + if l <= 0 { + s.push(nil) + } else { + s.push(l) + } + case "LOG10": + l := math.Log10(s.pop().(float64)) + if l <= 0 { + s.push(nil) + } else { + s.push(l) + } + case "MAX": + var set bool + var max float64 + array := s.pop().([]interface{}) + for _, element := range array { + if element != nil { + if !set || toNumber(element) > max { + max = toNumber(element) + set = true + } + } + } + if set { + s.push(max) + } else { + s.push(nil) + } + case "MEDIAN": + array := s.pop().([]interface{}) + var numbers []float64 + for _, element := range array { + if f, ok := element.(float64); ok { + numbers = append(numbers, f) + } + } + + sort.Float64s(numbers) // sort the numbers + + middlePos := len(numbers) / 2 + + switch { + case len(numbers) == 0: + s.push(nil) + case len(numbers)%2 == 1: + s.push(numbers[middlePos]) + default: + s.push((numbers[middlePos-1] + numbers[middlePos]) / 2) + } + case "MIN": + var set bool + var min float64 + array := s.pop().([]interface{}) + for _, element := range array { + if element != nil { + if !set || toNumber(element) < min { + min = toNumber(element) + set = true + } + } + } + if set { + s.push(min) + } else { + s.push(nil) + } + // case "PERCENTILE": + case "PI": + s.push(math.Pi) + case "POW": + right, left := s.pop(), s.pop() + s.push(math.Pow(left.(float64), right.(float64))) + case "PRODUCT": + product := float64(1) + array := s.pop().([]interface{}) + for _, element := range array { + if element != nil { + product *= toNumber(element) + } + } + s.push(product) + case "RADIANS": + s.push(s.pop().(float64) * math.Pi / 180) + case "RAND": + s.push(rand.Float64()) + case "RANGE": + var array []interface{} + var start, end, step float64 + if len(ctx.AllExpression()) == 2 { + right, left := s.pop(), s.pop() + start = math.Trunc(left.(float64)) + end = math.Trunc(right.(float64)) + step = 1 + } else { + middle, right, left := s.pop(), s.pop(), s.pop() + start = left.(float64) + end = right.(float64) + step = middle.(float64) + } + for i := start; i <= end; i += step { + array = append(array, i) + } + s.push(array) + case "ROUND": + x := s.pop().(float64) + t := math.Trunc(x) + if math.Abs(x-t) == 0.5 { + s.push(x + 0.5) + } else { + s.push(math.Round(x)) + } + case "SIN": + s.push(math.Sin(s.pop().(float64))) + case "SQRT": + s.push(math.Sqrt(s.pop().(float64))) + // case "STDDEV_POPULATION": + // case "STDDEV_SAMPLE": + // case "STDDEV": + case "SUM": + sum := float64(0) + array := s.pop().([]interface{}) + for _, element := range array { + sum += toNumber(element) + } + s.push(sum) + case "TAN": + s.push(math.Tan(s.pop().(float64))) + // case "VARIANCE_POPULATION", "VARIANCE": + // case "VARIANCE_SAMPLE": + + // String https://www.arangodb.com/docs/stable/aql/functions-string.html + // case "CHAR_LENGTH": + // case "CONCAT": + // case "CONCAT_SEPARATOR": + // case "CONTAINS": + // case "CRC32": + // case "ENCODE_URI_COMPONENT": + // case "FIND_FIRST": + // case "FIND_LAST": + // case "FNV64": + // case "IPV4_FROM_NUMBER": + // case "IPV4_TO_NUMBER": + // case "IS_IPV4": + // case "JSON_PARSE": + // case "JSON_STRINGIFY": + // case "LEFT": + // case "LENGTH": + // case "LEVENSHTEIN_DISTANCE": + // case "LIKE": + case "LOWER": + s.push(strings.ToLower(s.pop().(string))) + // case "LTRIM": + // case "MD5": + // case "NGRAM_POSITIONAL_SIMILARITY": + // case "NGRAM_SIMILARITY": + // case "RANDOM_TOKEN": + // case "REGEX_MATCHES": + // case "REGEX_SPLIT": + // case "REGEX_TEST": + // case "REGEX_REPLACE": + // case "REVERSE": + // case "RIGHT": + // case "RTRIM": + // case "SHA1": + // case "SHA512": + // case "SOUNDEX": + // case "SPLIT": + // case "STARTS_WITH": + // case "SUBSTITUTE": + // case "SUBSTRING": + // case "TOKENS": + // case "TO_BASE64": + // case "TO_HEX": + // case "TRIM": + case "UPPER": + s.push(strings.ToUpper(s.pop().(string))) + // case "UUID": + + // Type cast https://www.arangodb.com/docs/stable/aql/functions-type-cast.html + case "TO_BOOL": + s.push(toBool(s.pop())) + case "TO_NUMBER": + s.push(toNumber(s.pop())) + // case "TO_STRING": + // case "TO_ARRAY": + // case "TO_LIST": + + // case "IS_NULL": + // case "IS_BOOL": + // case "IS_NUMBER": + // case "IS_STRING": + // case "IS_ARRAY": + // case "IS_LIST": + // case "IS_OBJECT": + // case "IS_DOCUMENT": + // case "IS_DATESTRING": + // case "IS_IPV4": + // case "IS_KEY": + // case "TYPENAME": + + } +} + +func unique(array []interface{}) []interface{} { + seen := map[interface{}]bool{} + var filtered []interface{} + for _, e := range array { + _, ok := seen[e] + if !ok { + seen[e] = true + filtered = append(filtered, e) + } + } + return filtered +} + +func contains(values []interface{}, e interface{}) bool { + for _, v := range values { + if e == v { + return true + } + } + return false +} + +func stringSliceContains(values []string, e string) bool { + for _, v := range values { + if e == v { + return true + } + } + return false +} + +var functionNames = []string{ + "APPEND", "COUNT_DISTINCT", "COUNT_UNIQUE", "FIRST", "FLATTEN", "INTERLEAVE", "INTERSECTION", "JACCARD", "LAST", + "COUNT", "LENGTH", "MINUS", "NTH", "OUTERSECTION", "POP", "POSITION", "CONTAINS_ARRAY", "PUSH", "REMOVE_NTH", + "REPLACE_NTH", "REMOVE_VALUE", "REMOVE_VALUES", "REVERSE", "SHIFT", "SLICE", "SORTED", "SORTED_UNIQUE", "UNION", + "UNION_DISTINCT", "UNIQUE", "UNSHIFT", "BIT_AND", "BIT_CONSTRUCT", "BIT_DECONSTRUCT", "BIT_FROM_STRING", + "BIT_NEGATE", "BIT_OR", "BIT_POPCOUNT", "BIT_SHIFT_LEFT", "BIT_SHIFT_RIGHT", "BIT_TEST", "BIT_TO_STRING", + "BIT_XOR", "DATE_NOW", "DATE_ISO8601", "DATE_TIMESTAMP", "IS_DATESTRING", "DATE_DAYOFWEEK", "DATE_YEAR", + "DATE_MONTH", "DATE_DAY", "DATE_HOUR", "DATE_MINUTE", "DATE_SECOND", "DATE_MILLISECOND", "DATE_DAYOFYEAR", + "DATE_ISOWEEK", "DATE_LEAPYEAR", "DATE_QUARTER", "DATE_DAYS_IN_MONTH", "DATE_TRUNC", "DATE_ROUND", "DATE_FORMAT", + "DATE_ADD", "DATE_SUBTRACT", "DATE_DIFF", "DATE_COMPARE", "ATTRIBUTES", "COUNT", "HAS", "KEEP", "LENGTH", + "MATCHES", "MERGE", "MERGE_RECURSIVE", "PARSE_IDENTIFIER", "TRANSLATE", "UNSET", "UNSET_RECURSIVE", "VALUES", + "ZIP", "ABS", "ACOS", "ASIN", "ATAN", "ATAN2", "AVERAGE", "AVG", "CEIL", "COS", "DEGREES", "EXP", "EXP2", "FLOOR", + "LOG", "LOG2", "LOG10", "MAX", "MEDIAN", "MIN", "PERCENTILE", "PI", "POW", "PRODUCT", "RADIANS", "RAND", "RANGE", + "ROUND", "SIN", "SQRT", "STDDEV_POPULATION", "STDDEV_SAMPLE", "STDDEV", "SUM", "TAN", "VARIANCE_POPULATION", + "VARIANCE", "VARIANCE_SAMPLE", "CHAR_LENGTH", "CONCAT", "CONCAT_SEPARATOR", "CONTAINS", "CRC32", + "ENCODE_URI_COMPONENT", "FIND_FIRST", "FIND_LAST", "FNV64", "IPV4_FROM_NUMBER", "IPV4_TO_NUMBER", "IS_IPV4", + "JSON_PARSE", "JSON_STRINGIFY", "LEFT", "LENGTH", "LEVENSHTEIN_DISTANCE", "LIKE", "LOWER", "LTRIM", "MD5", + "NGRAM_POSITIONAL_SIMILARITY", "NGRAM_SIMILARITY", "RANDOM_TOKEN", "REGEX_MATCHES", "REGEX_SPLIT", "REGEX_TEST", + "REGEX_REPLACE", "REVERSE", "RIGHT", "RTRIM", "SHA1", "SHA512", "SOUNDEX", "SPLIT", "STARTS_WITH", "SUBSTITUTE", + "SUBSTRING", "TOKENS", "TO_BASE64", "TO_HEX", "TRIM", "UPPER", "UUID", "TO_BOOL", "TO_NUMBER", "TO_STRING", + "TO_ARRAY", "TO_LIST", "IS_NULL", "IS_BOOL", "IS_NUMBER", "IS_STRING", "IS_ARRAY", "IS_LIST", "IS_OBJECT", + "IS_DOCUMENT", "IS_DATESTRING", "IS_IPV4", "IS_KEY", "TYPENAME"} diff --git a/caql/function_test.go b/caql/function_test.go new file mode 100644 index 0000000..dcbea87 --- /dev/null +++ b/caql/function_test.go @@ -0,0 +1,380 @@ +package caql + +import ( + "encoding/json" + "math" + "reflect" + "testing" +) + +func TestFunctions(t *testing.T) { + tests := []struct { + name string + saql string + wantRebuild string + wantValue interface{} + wantParseErr bool + wantRebuildErr bool + wantEvalErr bool + values string + }{ + // https://www.arangodb.com/docs/3.7/aql/functions-array.html + {name: "APPEND", saql: `APPEND([1, 2, 3], [5, 6, 9])`, wantRebuild: `APPEND([1, 2, 3], [5, 6, 9])`, wantValue: jsonParse(`[1, 2, 3, 5, 6, 9]`)}, + {name: "APPEND", saql: `APPEND([1, 2, 3], [3, 4, 5, 2, 9], true)`, wantRebuild: `APPEND([1, 2, 3], [3, 4, 5, 2, 9], true)`, wantValue: jsonParse(`[1, 2, 3, 4, 5, 9]`)}, + {name: "COUNT_DISTINCT", saql: `COUNT_DISTINCT([1, 2, 3])`, wantRebuild: `COUNT_DISTINCT([1, 2, 3])`, wantValue: 3}, + {name: "COUNT_DISTINCT", saql: `COUNT_DISTINCT(["yes", "no", "yes", "sauron", "no", "yes"])`, wantRebuild: `COUNT_DISTINCT(["yes", "no", "yes", "sauron", "no", "yes"])`, wantValue: 3}, + {name: "FIRST", saql: `FIRST([1, 2, 3])`, wantRebuild: `FIRST([1, 2, 3])`, wantValue: 1}, + {name: "FIRST", saql: `FIRST([])`, wantRebuild: `FIRST([])`, wantValue: nil}, + // {name: "FLATTEN", saql: `FLATTEN([1, 2, [3, 4], 5, [6, 7], [8, [9, 10]]])`, wantRebuild: `FLATTEN([1, 2, [3, 4], 5, [6, 7], [8, [9, 10]]])`, wantValue:}, + // {name: "FLATTEN", saql: `FLATTEN([1, 2, [3, 4], 5, [6, 7], [8, [9, 10]]], 2)`, wantRebuild: `FLATTEN([1, 2, [3, 4], 5, [6, 7], [8, [9, 10]]], 2)`, wantValue:}, + // {name: "INTERLEAVE", saql: `INTERLEAVE([1, 1, 1], [2, 2, 2], [3, 3, 3])`, wantRebuild: `INTERLEAVE([1, 1, 1], [2, 2, 2], [3, 3, 3])`, wantValue:}, + // {name: "INTERLEAVE", saql: `INTERLEAVE([1], [2, 2], [3, 3, 3])`, wantRebuild: `INTERLEAVE([1], [2, 2], [3, 3, 3])`, wantValue:}, + {name: "INTERSECTION", saql: `INTERSECTION([1,2,3,4,5], [2,3,4,5,6], [3,4,5,6,7])`, wantRebuild: `INTERSECTION([1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7])`, wantValue: jsonParse(`[3, 4, 5]`)}, + {name: "INTERSECTION", saql: `INTERSECTION([2,4,6], [8,10,12], [14,16,18])`, wantRebuild: `INTERSECTION([2, 4, 6], [8, 10, 12], [14, 16, 18])`, wantValue: jsonParse(`[]`)}, + // {name: "JACCARD", saql: `JACCARD([1,2,3,4], [3,4,5,6])`, wantRebuild: `JACCARD([1,2,3,4], [3,4,5,6])`, wantValue: 0.3333333333333333}, + // {name: "JACCARD", saql: `JACCARD([1,1,2,2,2,3], [2,2,3,4])`, wantRebuild: `JACCARD([1,1,2,2,2,3], [2,2,3,4])`, wantValue: 0.5}, + // {name: "JACCARD", saql: `JACCARD([1,2,3], [])`, wantRebuild: `JACCARD([1, 2, 3], [])`, wantValue: 0}, + // {name: "JACCARD", saql: `JACCARD([], [])`, wantRebuild: `JACCARD([], [])`, wantValue: 1}, + {name: "LAST", saql: `LAST([1,2,3,4,5])`, wantRebuild: `LAST([1, 2, 3, 4, 5])`, wantValue: 5}, + {name: "LENGTH", saql: `LENGTH("🥑")`, wantRebuild: `LENGTH("🥑")`, wantValue: 1}, + {name: "LENGTH", saql: `LENGTH(1234)`, wantRebuild: `LENGTH(1234)`, wantValue: 4}, + {name: "LENGTH", saql: `LENGTH([1,2,3,4,5,6,7])`, wantRebuild: `LENGTH([1, 2, 3, 4, 5, 6, 7])`, wantValue: 7}, + {name: "LENGTH", saql: `LENGTH(false)`, wantRebuild: `LENGTH(false)`, wantValue: 0}, + {name: "LENGTH", saql: `LENGTH({a:1, b:2, c:3, d:4, e:{f:5,g:6}})`, wantRebuild: `LENGTH({a: 1, b: 2, c: 3, d: 4, e: {f: 5, g: 6}})`, wantValue: 5}, + {name: "MINUS", saql: `MINUS([1,2,3,4], [3,4,5,6], [5,6,7,8])`, wantRebuild: `MINUS([1, 2, 3, 4], [3, 4, 5, 6], [5, 6, 7, 8])`, wantValue: jsonParse(`[1, 2]`)}, + {name: "NTH", saql: `NTH(["foo", "bar", "baz"], 2)`, wantRebuild: `NTH(["foo", "bar", "baz"], 2)`, wantValue: "baz"}, + {name: "NTH", saql: `NTH(["foo", "bar", "baz"], 3)`, wantRebuild: `NTH(["foo", "bar", "baz"], 3)`, wantValue: nil}, + {name: "NTH", saql: `NTH(["foo", "bar", "baz"], -1)`, wantRebuild: `NTH(["foo", "bar", "baz"], -1)`, wantValue: nil}, + // {name: "OUTERSECTION", saql: `OUTERSECTION([1, 2, 3], [2, 3, 4], [3, 4, 5])`, wantRebuild: `OUTERSECTION([1, 2, 3], [2, 3, 4], [3, 4, 5])`, wantValue: jsonParse(`[1, 5]`)}, + {name: "POP", saql: `POP([1, 2, 3, 4])`, wantRebuild: `POP([1, 2, 3, 4])`, wantValue: jsonParse(`[1, 2, 3]`)}, + {name: "POP", saql: `POP([1])`, wantRebuild: `POP([1])`, wantValue: jsonParse(`[]`)}, + {name: "POSITION", saql: `POSITION([2,4,6,8], 4)`, wantRebuild: `POSITION([2, 4, 6, 8], 4)`, wantValue: true}, + {name: "POSITION", saql: `POSITION([2,4,6,8], 4, true)`, wantRebuild: `POSITION([2, 4, 6, 8], 4, true)`, wantValue: 1}, + {name: "PUSH", saql: `PUSH([1, 2, 3], 4)`, wantRebuild: `PUSH([1, 2, 3], 4)`, wantValue: jsonParse(`[1, 2, 3, 4]`)}, + {name: "PUSH", saql: `PUSH([1, 2, 2, 3], 2, true)`, wantRebuild: `PUSH([1, 2, 2, 3], 2, true)`, wantValue: jsonParse(`[1, 2, 2, 3]`)}, + {name: "REMOVE_NTH", saql: `REMOVE_NTH(["a", "b", "c", "d", "e"], 1)`, wantRebuild: `REMOVE_NTH(["a", "b", "c", "d", "e"], 1)`, wantValue: jsonParse(`["a", "c", "d", "e"]`)}, + {name: "REMOVE_NTH", saql: `REMOVE_NTH(["a", "b", "c", "d", "e"], -2)`, wantRebuild: `REMOVE_NTH(["a", "b", "c", "d", "e"], -2)`, wantValue: jsonParse(`["a", "b", "c", "e"]`)}, + {name: "REPLACE_NTH", saql: `REPLACE_NTH(["a", "b", "c"], 1 , "z")`, wantRebuild: `REPLACE_NTH(["a", "b", "c"], 1, "z")`, wantValue: jsonParse(`["a", "z", "c"]`)}, + {name: "REPLACE_NTH", saql: `REPLACE_NTH(["a", "b", "c"], 3 , "z")`, wantRebuild: `REPLACE_NTH(["a", "b", "c"], 3, "z")`, wantValue: jsonParse(`["a", "b", "c", "z"]`)}, + {name: "REPLACE_NTH", saql: `REPLACE_NTH(["a", "b", "c"], 6, "z", "y")`, wantRebuild: `REPLACE_NTH(["a", "b", "c"], 6, "z", "y")`, wantValue: jsonParse(`["a", "b", "c", "y", "y", "y", "z"]`)}, + {name: "REPLACE_NTH", saql: `REPLACE_NTH(["a", "b", "c"], -1, "z")`, wantRebuild: `REPLACE_NTH(["a", "b", "c"], -1, "z")`, wantValue: jsonParse(`["a", "b", "z"]`)}, + {name: "REPLACE_NTH", saql: `REPLACE_NTH(["a", "b", "c"], -9, "z")`, wantRebuild: `REPLACE_NTH(["a", "b", "c"], -9, "z")`, wantValue: jsonParse(`["z", "b", "c"]`)}, + {name: "REMOVE_VALUE", saql: `REMOVE_VALUE(["a", "b", "b", "a", "c"], "a")`, wantRebuild: `REMOVE_VALUE(["a", "b", "b", "a", "c"], "a")`, wantValue: jsonParse(`["b", "b", "c"]`)}, + {name: "REMOVE_VALUE", saql: `REMOVE_VALUE(["a", "b", "b", "a", "c"], "a", 1)`, wantRebuild: `REMOVE_VALUE(["a", "b", "b", "a", "c"], "a", 1)`, wantValue: jsonParse(`["b", "b", "a", "c"]`)}, + {name: "REMOVE_VALUES", saql: `REMOVE_VALUES(["a", "a", "b", "c", "d", "e", "f"], ["a", "f", "d"])`, wantRebuild: `REMOVE_VALUES(["a", "a", "b", "c", "d", "e", "f"], ["a", "f", "d"])`, wantValue: jsonParse(`["b", "c", "e"]`)}, + {name: "REVERSE", saql: `REVERSE ([2,4,6,8,10])`, wantRebuild: `REVERSE([2, 4, 6, 8, 10])`, wantValue: jsonParse(`[10, 8, 6, 4, 2]`)}, + {name: "SHIFT", saql: `SHIFT([1, 2, 3, 4])`, wantRebuild: `SHIFT([1, 2, 3, 4])`, wantValue: jsonParse(`[2, 3, 4]`)}, + {name: "SHIFT", saql: `SHIFT([1])`, wantRebuild: `SHIFT([1])`, wantValue: jsonParse(`[]`)}, + {name: "SLICE", saql: `SLICE([1, 2, 3, 4, 5], 0, 1)`, wantRebuild: `SLICE([1, 2, 3, 4, 5], 0, 1)`, wantValue: jsonParse(`[1]`)}, + {name: "SLICE", saql: `SLICE([1, 2, 3, 4, 5], 1, 2)`, wantRebuild: `SLICE([1, 2, 3, 4, 5], 1, 2)`, wantValue: jsonParse(`[2, 3]`)}, + {name: "SLICE", saql: `SLICE([1, 2, 3, 4, 5], 3)`, wantRebuild: `SLICE([1, 2, 3, 4, 5], 3)`, wantValue: jsonParse(`[4, 5]`)}, + {name: "SLICE", saql: `SLICE([1, 2, 3, 4, 5], 1, -1)`, wantRebuild: `SLICE([1, 2, 3, 4, 5], 1, -1)`, wantValue: jsonParse(`[2, 3, 4]`)}, + {name: "SLICE", saql: `SLICE([1, 2, 3, 4, 5], 0, -2)`, wantRebuild: `SLICE([1, 2, 3, 4, 5], 0, -2)`, wantValue: jsonParse(`[1, 2, 3]`)}, + {name: "SLICE", saql: `SLICE([1, 2, 3, 4, 5], -3, 2)`, wantRebuild: `SLICE([1, 2, 3, 4, 5], -3, 2)`, wantValue: jsonParse(`[3, 4]`)}, + {name: "SORTED", saql: `SORTED([8,4,2,10,6])`, wantRebuild: `SORTED([8, 4, 2, 10, 6])`, wantValue: jsonParse(`[2, 4, 6, 8, 10]`)}, + {name: "SORTED_UNIQUE", saql: `SORTED_UNIQUE([8,4,2,10,6,2,8,6,4])`, wantRebuild: `SORTED_UNIQUE([8, 4, 2, 10, 6, 2, 8, 6, 4])`, wantValue: jsonParse(`[2, 4, 6, 8, 10]`)}, + {name: "UNION", saql: `UNION([1, 2, 3], [1, 2])`, wantRebuild: `UNION([1, 2, 3], [1, 2])`, wantValue: jsonParse(`[1, 1, 2, 2, 3]`)}, + {name: "UNION_DISTINCT", saql: `UNION_DISTINCT([1, 2, 3], [1, 2])`, wantRebuild: `UNION_DISTINCT([1, 2, 3], [1, 2])`, wantValue: jsonParse(`[1, 2, 3]`)}, + {name: "UNIQUE", saql: `UNIQUE([1,2,2,3,3,3,4,4,4,4,5,5,5,5,5])`, wantRebuild: `UNIQUE([1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5])`, wantValue: jsonParse(`[1, 2, 3, 4, 5]`)}, + {name: "UNSHIFT", saql: `UNSHIFT([1, 2, 3], 4)`, wantRebuild: `UNSHIFT([1, 2, 3], 4)`, wantValue: jsonParse(`[4, 1, 2, 3]`)}, + {name: "UNSHIFT", saql: `UNSHIFT([1, 2, 3], 2, true)`, wantRebuild: `UNSHIFT([1, 2, 3], 2, true)`, wantValue: jsonParse(`[1, 2, 3]`)}, + + // https://www.arangodb.com/docs/3.7/aql/functions-bit.html + // {name: "BIT_CONSTRUCT", saql: `BIT_CONSTRUCT([1, 2, 3])`, wantRebuild: `BIT_CONSTRUCT([1, 2, 3])`, wantValue: 14}, + // {name: "BIT_CONSTRUCT", saql: `BIT_CONSTRUCT([0, 4, 8])`, wantRebuild: `BIT_CONSTRUCT([0, 4, 8])`, wantValue: 273}, + // {name: "BIT_CONSTRUCT", saql: `BIT_CONSTRUCT([0, 1, 10, 31])`, wantRebuild: `BIT_CONSTRUCT([0, 1, 10, 31])`, wantValue: 2147484675}, + // {name: "BIT_DECONSTRUCT", saql: `BIT_DECONSTRUCT(14)`, wantRebuild: `BIT_DECONSTRUCT(14) `, wantValue: []interface{}{1, 2, 3}}, + // {name: "BIT_DECONSTRUCT", saql: `BIT_DECONSTRUCT(273)`, wantRebuild: `BIT_DECONSTRUCT(273)`, wantValue: []interface{}{0, 4, 8}}, + // {name: "BIT_DECONSTRUCT", saql: `BIT_DECONSTRUCT(2147484675)`, wantRebuild: `BIT_DECONSTRUCT(2147484675)`, wantValue: []interface{}{0, 1, 10, 31}}, + // {name: "BIT_FROM_STRING", saql: `BIT_FROM_STRING("0111")`, wantRebuild: `BIT_FROM_STRING("0111")`, wantValue: 7}, + // {name: "BIT_FROM_STRING", saql: `BIT_FROM_STRING("000000000000010")`, wantRebuild: `BIT_FROM_STRING("000000000000010")`, wantValue: 2}, + // {name: "BIT_FROM_STRING", saql: `BIT_FROM_STRING("11010111011101")`, wantRebuild: `BIT_FROM_STRING("11010111011101")`, wantValue: 13789}, + // {name: "BIT_FROM_STRING", saql: `BIT_FROM_STRING("100000000000000000000")`, wantRebuild: `BIT_FROM_STRING("100000000000000000000")`, wantValue: 1048756}, + // {name: "BIT_NEGATE", saql: `BIT_NEGATE(0, 8)`, wantRebuild: `BIT_NEGATE(0, 8)`, wantValue: 255}, + // {name: "BIT_NEGATE", saql: `BIT_NEGATE(0, 10)`, wantRebuild: `BIT_NEGATE(0, 10)`, wantValue: 1023}, + // {name: "BIT_NEGATE", saql: `BIT_NEGATE(3, 4)`, wantRebuild: `BIT_NEGATE(3, 4)`, wantValue: 12}, + // {name: "BIT_NEGATE", saql: `BIT_NEGATE(446359921, 32)`, wantRebuild: `BIT_NEGATE(446359921, 32)`, wantValue: 3848607374}, + // {name: "BIT_OR", saql: `BIT_OR([1, 4, 8, 16])`, wantRebuild: `BIT_OR([1, 4, 8, 16])`, wantValue: 29}, + // {name: "BIT_OR", saql: `BIT_OR([3, 7, 63])`, wantRebuild: `BIT_OR([3, 7, 63])`, wantValue: 63}, + // {name: "BIT_OR", saql: `BIT_OR([255, 127, null, 63])`, wantRebuild: `BIT_OR([255, 127, null, 63])`, wantValue: 255}, + // {name: "BIT_OR", saql: `BIT_OR(255, 127)`, wantRebuild: `BIT_OR(255, 127)`, wantValue: 255}, + // {name: "BIT_OR", saql: `BIT_OR("foo")`, wantRebuild: `BIT_OR("foo")`, wantValue: nil}, + // {name: "BIT_POPCOUNT", saql: `BIT_POPCOUNT(0)`, wantRebuild: `BIT_POPCOUNT(0)`, wantValue: 0}, + // {name: "BIT_POPCOUNT", saql: `BIT_POPCOUNT(255)`, wantRebuild: `BIT_POPCOUNT(255)`, wantValue: 8}, + // {name: "BIT_POPCOUNT", saql: `BIT_POPCOUNT(69399252)`, wantRebuild: `BIT_POPCOUNT(69399252)`, wantValue: 12}, + // {name: "BIT_POPCOUNT", saql: `BIT_POPCOUNT("foo")`, wantRebuild: `BIT_POPCOUNT("foo")`, wantValue: nil}, + // {name: "BIT_SHIFT_LEFT", saql: `BIT_SHIFT_LEFT(0, 1, 8)`, wantRebuild: `BIT_SHIFT_LEFT(0, 1, 8)`, wantValue: 0}, + // {name: "BIT_SHIFT_LEFT", saql: `BIT_SHIFT_LEFT(7, 1, 16)`, wantRebuild: `BIT_SHIFT_LEFT(7, 1, 16)`, wantValue: 14}, + // {name: "BIT_SHIFT_LEFT", saql: `BIT_SHIFT_LEFT(2, 10, 16)`, wantRebuild: `BIT_SHIFT_LEFT(2, 10, 16)`, wantValue: 2048}, + // {name: "BIT_SHIFT_LEFT", saql: `BIT_SHIFT_LEFT(878836, 16, 32)`, wantRebuild: `BIT_SHIFT_LEFT(878836, 16, 32)`, wantValue: 1760821248}, + // {name: "BIT_SHIFT_RIGHT", saql: `BIT_SHIFT_RIGHT(0, 1, 8)`, wantRebuild: `BIT_SHIFT_RIGHT(0, 1, 8)`, wantValue: 0}, + // {name: "BIT_SHIFT_RIGHT", saql: `BIT_SHIFT_RIGHT(33, 1, 16)`, wantRebuild: `BIT_SHIFT_RIGHT(33, 1, 16)`, wantValue: 16}, + // {name: "BIT_SHIFT_RIGHT", saql: `BIT_SHIFT_RIGHT(65536, 13, 16)`, wantRebuild: `BIT_SHIFT_RIGHT(65536, 13, 16)`, wantValue: 8}, + // {name: "BIT_SHIFT_RIGHT", saql: `BIT_SHIFT_RIGHT(878836, 4, 32)`, wantRebuild: `BIT_SHIFT_RIGHT(878836, 4, 32)`, wantValue: 54927}, + // {name: "BIT_TEST", saql: `BIT_TEST(0, 3)`, wantRebuild: `BIT_TEST(0, 3)`, wantValue: false}, + // {name: "BIT_TEST", saql: `BIT_TEST(255, 0)`, wantRebuild: `BIT_TEST(255, 0)`, wantValue: true}, + // {name: "BIT_TEST", saql: `BIT_TEST(7, 2)`, wantRebuild: `BIT_TEST(7, 2)`, wantValue: true}, + // {name: "BIT_TEST", saql: `BIT_TEST(255, 8)`, wantRebuild: `BIT_TEST(255, 8)`, wantValue: false}, + // {name: "BIT_TO_STRING", saql: `BIT_TO_STRING(7, 4)`, wantRebuild: `BIT_TO_STRING(7, 4)`, wantValue: "0111"}, + // {name: "BIT_TO_STRING", saql: `BIT_TO_STRING(255, 8)`, wantRebuild: `BIT_TO_STRING(255, 8)`, wantValue: "11111111"}, + // {name: "BIT_TO_STRING", saql: `BIT_TO_STRING(60, 8)`, wantRebuild: `BIT_TO_STRING(60, 8)`, wantValue: "00011110"}, + // {name: "BIT_TO_STRING", saql: `BIT_TO_STRING(1048576, 32)`, wantRebuild: `BIT_TO_STRING(1048576, 32)`, wantValue: "00000000000100000000000000000000"}, + // {name: "BIT_XOR", saql: `BIT_XOR([1, 4, 8, 16])`, wantRebuild: `BIT_XOR([1, 4, 8, 16])`, wantValue: 29}, + // {name: "BIT_XOR", saql: `BIT_XOR([3, 7, 63])`, wantRebuild: `BIT_XOR([3, 7, 63])`, wantValue: 59}, + // {name: "BIT_XOR", saql: `BIT_XOR([255, 127, null, 63])`, wantRebuild: `BIT_XOR([255, 127, null, 63])`, wantValue: 191}, + // {name: "BIT_XOR", saql: `BIT_XOR(255, 257)`, wantRebuild: `BIT_XOR(255, 257)`, wantValue: 510}, + // {name: "BIT_XOR", saql: `BIT_XOR("foo")`, wantRebuild: `BIT_XOR("foo")`, wantValue: nil}, + + // https://www.arangodb.com/docs/3.7/aql/functions-date.html + // DATE_TIMESTAMP("2014-05-07T14:19:09.522") + // DATE_TIMESTAMP("2014-05-07T14:19:09.522Z") + // DATE_TIMESTAMP("2014-05-07 14:19:09.522") + // DATE_TIMESTAMP("2014-05-07 14:19:09.522Z") + // DATE_TIMESTAMP(2014, 5, 7, 14, 19, 9, 522) + // DATE_TIMESTAMP(1399472349522) + // DATE_ISO8601("2014-05-07T14:19:09.522Z") + // DATE_ISO8601("2014-05-07 14:19:09.522Z") + // DATE_ISO8601(2014, 5, 7, 14, 19, 9, 522) + // DATE_ISO8601(1399472349522) + // {name: "DATE_TIMESTAMP", saql: `DATE_TIMESTAMP(2016, 12, -1)`, wantRebuild: `DATE_TIMESTAMP(2016, 12, -1)`, wantValue: nil}, + // {name: "DATE_TIMESTAMP", saql: `DATE_TIMESTAMP(2016, 2, 32)`, wantRebuild: `DATE_TIMESTAMP(2016, 2, 32)`, wantValue: 1456963200000}, + // {name: "DATE_TIMESTAMP", saql: `DATE_TIMESTAMP(1970, 1, 1, 26)`, wantRebuild: `DATE_TIMESTAMP(1970, 1, 1, 26)`, wantValue: 93600000}, + // {name: "DATE_TRUNC", saql: `DATE_TRUNC('2017-02-03', 'month')`, wantRebuild: `DATE_TRUNC('2017-02-03', 'month')`, wantValue: "2017-02-01T00:00:00.000Z"}, + // {name: "DATE_TRUNC", saql: `DATE_TRUNC('2017-02-03 04:05:06', 'hours')`, wantRebuild: `DATE_TRUNC('2017-02-03 04:05:06', 'hours')`, wantValue: "2017-02-03 04:00:00.000Z"}, + // {name: "DATE_ROUND", saql: `DATE_ROUND('2000-04-28T11:11:11.111Z', 1, 'day')`, wantRebuild: `DATE_ROUND('2000-04-28T11:11:11.111Z', 1, 'day')`, wantValue: "2000-04-28T00:00:00.000Z"}, + // {name: "DATE_ROUND", saql: `DATE_ROUND('2000-04-10T11:39:29Z', 15, 'minutes')`, wantRebuild: `DATE_ROUND('2000-04-10T11:39:29Z', 15, 'minutes')`, wantValue: "2000-04-10T11:30:00.000Z"}, + // {name: "DATE_FORMAT", saql: `DATE_FORMAT(DATE_NOW(), "%q/%yyyy")`, wantRebuild: `DATE_FORMAT(DATE_NOW(), "%q/%yyyy")`}, + // {name: "DATE_FORMAT", saql: `DATE_FORMAT(DATE_NOW(), "%dd.%mm.%yyyy %hh:%ii:%ss,%fff")`, wantRebuild: `DATE_FORMAT(DATE_NOW(), "%dd.%mm.%yyyy %hh:%ii:%ss,%fff")`, wantValue: "18.09.2015 15:30:49,374"}, + // {name: "DATE_FORMAT", saql: `DATE_FORMAT("1969", "Summer of '%yy")`, wantRebuild: `DATE_FORMAT("1969", "Summer of '%yy")`, wantValue: "Summer of '69"}, + // {name: "DATE_FORMAT", saql: `DATE_FORMAT("2016", "%%l = %l")`, wantRebuild: `DATE_FORMAT("2016", "%%l = %l")`, wantValue: "%l = 1"}, + // {name: "DATE_FORMAT", saql: `DATE_FORMAT("2016-03-01", "%xxx%")`, wantRebuild: `DATE_FORMAT("2016-03-01", "%xxx%")`, wantValue: "063, trailing % ignored"}, + // {name: "DATE_ADD", saql: `DATE_ADD(DATE_NOW(), -1, "day")`, wantRebuild: `DATE_ADD(DATE_NOW(), -1, "day")`, wantValue: "yesterday; also see DATE_SUBTRACT()"}, + // {name: "DATE_ADD", saql: `DATE_ADD(DATE_NOW(), 3, "months")`, wantRebuild: `DATE_ADD(DATE_NOW(), 3, "months")`, wantValue: "in three months"}, + // {name: "DATE_ADD", saql: `DATE_ADD(DATE_ADD("2015-04-01", 5, "years"), 1, "month")`, wantRebuild: `DATE_ADD(DATE_ADD("2015-04-01", 5, "years"), 1, "month")`, wantValue: "May 1st 2020"}, + // {name: "DATE_ADD", saql: `DATE_ADD("2015-04-01", 12*5 + 1, "months")`, wantRebuild: `DATE_ADD("2015-04-01", 12*5 + 1, "months")`, wantValue: "also May 1st 2020"}, + // {name: "DATE_ADD", saql: `DATE_ADD(DATE_TIMESTAMP(DATE_YEAR(DATE_NOW()), 12, 24), -4, "years")`, wantRebuild: `DATE_ADD(DATE_TIMESTAMP(DATE_YEAR(DATE_NOW()), 12, 24), -4, "years")`, wantValue: "Christmas four years ago"}, + // {name: "DATE_ADD", saql: `DATE_ADD(DATE_ADD("2016-02", "month", 1), -1, "day")`, wantRebuild: `DATE_ADD(DATE_ADD("2016-02", "month", 1), -1, "day")`, wantValue: "last day of February (29th, because 2016 is a leap year!)"}, + // {name: "DATE_ADD", saql: `DATE_ADD(DATE_NOW(), "P1Y")`, wantRebuild: `DATE_ADD(DATE_NOW(), "P1Y")`}, + // {name: "DATE_ADD", saql: `DATE_ADD(DATE_NOW(), "P3M2W")`, wantRebuild: `DATE_ADD(DATE_NOW(), "P3M2W")`}, + // {name: "DATE_ADD", saql: `DATE_ADD(DATE_NOW(), "P5DT26H")`, wantRebuild: `DATE_ADD(DATE_NOW(), "P5DT26H")`}, + // {name: "DATE_ADD", saql: `DATE_ADD("2000-01-01", "PT4H")`, wantRebuild: `DATE_ADD("2000-01-01", "PT4H")`}, + // {name: "DATE_ADD", saql: `DATE_ADD("2000-01-01", "PT30M44.4S"`, wantRebuild: `DATE_ADD("2000-01-01", "PT30M44.4S"`}, + // {name: "DATE_ADD", saql: `DATE_ADD("2000-01-01", "P1Y2M3W4DT5H6M7.89S"`, wantRebuild: `DATE_ADD("2000-01-01", "P1Y2M3W4DT5H6M7.89S"`}, + // {name: "DATE_SUBTRACT", saql: `DATE_SUBTRACT(DATE_NOW(), 1, "day")`, wantRebuild: `DATE_SUBTRACT(DATE_NOW(), 1, "day")`}, + // {name: "DATE_SUBTRACT", saql: `DATE_SUBTRACT(DATE_TIMESTAMP(DATE_YEAR(DATE_NOW()), 12, 24), 4, "years")`, wantRebuild: `DATE_SUBTRACT(DATE_TIMESTAMP(DATE_YEAR(DATE_NOW()), 12, 24), 4, "years")`}, + // {name: "DATE_SUBTRACT", saql: `DATE_SUBTRACT(DATE_ADD("2016-02", "month", 1), 1, "day")`, wantRebuild: `DATE_SUBTRACT(DATE_ADD("2016-02", "month", 1), 1, "day")`}, + // {name: "DATE_SUBTRACT", saql: `DATE_SUBTRACT(DATE_NOW(), "P4D")`, wantRebuild: `DATE_SUBTRACT(DATE_NOW(), "P4D")`}, + // {name: "DATE_SUBTRACT", saql: `DATE_SUBTRACT(DATE_NOW(), "PT1H3M")`, wantRebuild: `DATE_SUBTRACT(DATE_NOW(), "PT1H3M")`}, + // DATE_COMPARE("1985-04-04", DATE_NOW(), "months", "days") + // DATE_COMPARE("1984-02-29", DATE_NOW(), "months", "days") + // DATE_COMPARE("2001-01-01T15:30:45.678Z", "2001-01-01T08:08:08.008Z", "years", "days") + + // https://www.arangodb.com/docs/3.7/aql/functions-document.html + {name: "ATTRIBUTES", saql: `ATTRIBUTES({"foo": "bar", "_key": "123", "_custom": "yes"})`, wantRebuild: `ATTRIBUTES({"foo": "bar", "_key": "123", "_custom": "yes"})`, wantValue: jsonParse(`["_custom", "_key", "foo"]`)}, + {name: "ATTRIBUTES", saql: `ATTRIBUTES({"foo": "bar", "_key": "123", "_custom": "yes"}, true)`, wantRebuild: `ATTRIBUTES({"foo": "bar", "_key": "123", "_custom": "yes"}, true)`, wantValue: jsonParse(`["foo"]`)}, + {name: "ATTRIBUTES", saql: `ATTRIBUTES({"foo": "bar", "_key": "123", "_custom": "yes"}, false, true)`, wantRebuild: `ATTRIBUTES({"foo": "bar", "_key": "123", "_custom": "yes"}, false, true)`, wantValue: jsonParse(`["_custom", "_key", "foo"]`)}, + {name: "HAS", saql: `HAS({name: "Jane"}, "name")`, wantRebuild: `HAS({name: "Jane"}, "name")`, wantValue: true}, + {name: "HAS", saql: `HAS({name: "Jane"}, "age")`, wantRebuild: `HAS({name: "Jane"}, "age")`, wantValue: false}, + {name: "HAS", saql: `HAS({name: null}, "name")`, wantRebuild: `HAS({name: null}, "name")`, wantValue: true}, + // KEEP(doc, "firstname", "name", "likes") + // KEEP(doc, ["firstname", "name", "likes"]) + // MATCHES({name: "jane", age: 27, active: true}, {age: 27, active: true}) + // MATCHES({"test": 1}, [{"test": 1, "foo": "bar"}, {"foo": 1}, {"test": 1}], true) + {name: "MERGE", saql: `MERGE({"user1": {"name": "Jane"}}, {"user2": {"name": "Tom"}})`, wantRebuild: `MERGE({"user1": {"name": "Jane"}}, {"user2": {"name": "Tom"}})`, wantValue: jsonParse(`{"user1": {"name": "Jane"}, "user2": {"name": "Tom"}}`)}, + {name: "MERGE", saql: `MERGE({"users": {"name": "Jane"}}, {"users": {"name": "Tom"}})`, wantRebuild: `MERGE({"users": {"name": "Jane"}}, {"users": {"name": "Tom"}})`, wantValue: jsonParse(`{"users": {"name": "Tom"}}`)}, + {name: "MERGE", saql: `MERGE([{foo: "bar"}, {quux: "quetzalcoatl", ruled: true}, {bar: "baz", foo: "done"}])`, wantRebuild: `MERGE([{foo: "bar"}, {quux: "quetzalcoatl", ruled: true}, {bar: "baz", foo: "done"}])`, wantValue: jsonParse(`{"foo": "done", "quux": "quetzalcoatl", "ruled": true, "bar": "baz"}`)}, + {name: "MERGE_RECURSIVE", saql: `MERGE_RECURSIVE({"user-1": {"name": "Jane", "livesIn": {"city": "LA"}}}, {"user-1": {"age": 42, "livesIn": {"state": "CA"}}})`, wantRebuild: `MERGE_RECURSIVE({"user-1": {"name": "Jane", "livesIn": {"city": "LA"}}}, {"user-1": {"age": 42, "livesIn": {"state": "CA"}}})`, wantValue: jsonParse(`{"user-1": {"name": "Jane", "livesIn": {"city": "LA", "state": "CA"}, "age": 42}}`)}, + // {name: "TRANSLATE", saql: `TRANSLATE("FR", {US: "United States", UK: "United Kingdom", FR: "France"})`, wantRebuild: `TRANSLATE("FR", {US: "United States", UK: "United Kingdom", FR: "France"})`, wantValue: "France"}, + // {name: "TRANSLATE", saql: `TRANSLATE(42, {foo: "bar", bar: "baz"})`, wantRebuild: `TRANSLATE(42, {foo: "bar", bar: "baz"})`, wantValue: 42}, + // {name: "TRANSLATE", saql: `TRANSLATE(42, {foo: "bar", bar: "baz"}, "not found!")`, wantRebuild: `TRANSLATE(42, {foo: "bar", bar: "baz"}, "not found!")`, wantValue: "not found!"}, + // UNSET(doc, "_id", "_key", "foo", "bar") + // UNSET(doc, ["_id", "_key", "foo", "bar"]) + // UNSET_RECURSIVE(doc, "_id", "_key", "foo", "bar") + // UNSET_RECURSIVE(doc, ["_id", "_key", "foo", "bar"]) + {name: "VALUES", saql: `VALUES({"_key": "users/jane", "name": "Jane", "age": 35})`, wantRebuild: `VALUES({"_key": "users/jane", "name": "Jane", "age": 35})`, wantValue: jsonParse(`[35, "Jane", "users/jane"]`)}, + {name: "VALUES", saql: `VALUES({"_key": "users/jane", "name": "Jane", "age": 35}, true)`, wantRebuild: `VALUES({"_key": "users/jane", "name": "Jane", "age": 35}, true)`, wantValue: jsonParse(`[35, "Jane"]`)}, + // {name: "ZIP", saql: `ZIP(["name", "active", "hobbies"], ["some user", true, ["swimming", "riding"]])`, wantRebuild: `ZIP(["name", "active", "hobbies"], ["some user", true, ["swimming", "riding"]])`, wantValue: jsonParse(`{"name": "some user", "active": true, "hobbies": ["swimming", "riding"]}`)}, + + // https://www.arangodb.com/docs/3.7/aql/functions-numeric.html + {name: "ABS", saql: `ABS(-5)`, wantRebuild: `ABS(-5)`, wantValue: 5}, + {name: "ABS", saql: `ABS(+5)`, wantRebuild: `ABS(5)`, wantValue: 5}, + {name: "ABS", saql: `ABS(3.5)`, wantRebuild: `ABS(3.5)`, wantValue: 3.5}, + {name: "ACOS", saql: `ACOS(-1)`, wantRebuild: `ACOS(-1)`, wantValue: 3.141592653589793}, + {name: "ACOS", saql: `ACOS(0)`, wantRebuild: `ACOS(0)`, wantValue: 1.5707963267948966}, + {name: "ACOS", saql: `ACOS(1)`, wantRebuild: `ACOS(1)`, wantValue: 0}, + {name: "ACOS", saql: `ACOS(2)`, wantRebuild: `ACOS(2)`, wantValue: nil}, + {name: "ASIN", saql: `ASIN(1)`, wantRebuild: `ASIN(1)`, wantValue: 1.5707963267948966}, + {name: "ASIN", saql: `ASIN(0)`, wantRebuild: `ASIN(0)`, wantValue: 0}, + {name: "ASIN", saql: `ASIN(-1)`, wantRebuild: `ASIN(-1)`, wantValue: -1.5707963267948966}, + {name: "ASIN", saql: `ASIN(2)`, wantRebuild: `ASIN(2)`, wantValue: nil}, + {name: "ATAN", saql: `ATAN(-1)`, wantRebuild: `ATAN(-1)`, wantValue: -0.7853981633974483}, + {name: "ATAN", saql: `ATAN(0)`, wantRebuild: `ATAN(0)`, wantValue: 0}, + {name: "ATAN", saql: `ATAN(10)`, wantRebuild: `ATAN(10)`, wantValue: 1.4711276743037347}, + {name: "AVERAGE", saql: `AVERAGE([5, 2, 9, 2])`, wantRebuild: `AVERAGE([5, 2, 9, 2])`, wantValue: 4.5}, + {name: "AVERAGE", saql: `AVERAGE([-3, -5, 2])`, wantRebuild: `AVERAGE([-3, -5, 2])`, wantValue: -2}, + {name: "AVERAGE", saql: `AVERAGE([999, 80, 4, 4, 4, 3, 3, 3])`, wantRebuild: `AVERAGE([999, 80, 4, 4, 4, 3, 3, 3])`, wantValue: 137.5}, + {name: "CEIL", saql: `CEIL(2.49)`, wantRebuild: `CEIL(2.49)`, wantValue: 3}, + {name: "CEIL", saql: `CEIL(2.50)`, wantRebuild: `CEIL(2.50)`, wantValue: 3}, + {name: "CEIL", saql: `CEIL(-2.50)`, wantRebuild: `CEIL(-2.50)`, wantValue: -2}, + {name: "CEIL", saql: `CEIL(-2.51)`, wantRebuild: `CEIL(-2.51)`, wantValue: -2}, + {name: "COS", saql: `COS(1)`, wantRebuild: `COS(1)`, wantValue: 0.5403023058681398}, + {name: "COS", saql: `COS(0)`, wantRebuild: `COS(0)`, wantValue: 1}, + {name: "COS", saql: `COS(-3.141592653589783)`, wantRebuild: `COS(-3.141592653589783)`, wantValue: -1}, + {name: "COS", saql: `COS(RADIANS(45))`, wantRebuild: `COS(RADIANS(45))`, wantValue: 0.7071067811865476}, + {name: "DEGREES", saql: `DEGREES(0.7853981633974483)`, wantRebuild: `DEGREES(0.7853981633974483)`, wantValue: 45}, + {name: "DEGREES", saql: `DEGREES(0)`, wantRebuild: `DEGREES(0)`, wantValue: 0}, + {name: "DEGREES", saql: `DEGREES(3.141592653589793)`, wantRebuild: `DEGREES(3.141592653589793)`, wantValue: 180}, + {name: "EXP", saql: `EXP(1)`, wantRebuild: `EXP(1)`, wantValue: 2.718281828459045}, + {name: "EXP", saql: `EXP(10)`, wantRebuild: `EXP(10)`, wantValue: 22026.46579480671}, + {name: "EXP", saql: `EXP(0)`, wantRebuild: `EXP(0)`, wantValue: 1}, + {name: "EXP2", saql: `EXP2(16)`, wantRebuild: `EXP2(16)`, wantValue: 65536}, + {name: "EXP2", saql: `EXP2(1)`, wantRebuild: `EXP2(1)`, wantValue: 2}, + {name: "EXP2", saql: `EXP2(0)`, wantRebuild: `EXP2(0)`, wantValue: 1}, + {name: "FLOOR", saql: `FLOOR(2.49)`, wantRebuild: `FLOOR(2.49)`, wantValue: 2}, + {name: "FLOOR", saql: `FLOOR(2.50)`, wantRebuild: `FLOOR(2.50)`, wantValue: 2}, + {name: "FLOOR", saql: `FLOOR(-2.50)`, wantRebuild: `FLOOR(-2.50)`, wantValue: -3}, + {name: "FLOOR", saql: `FLOOR(-2.51)`, wantRebuild: `FLOOR(-2.51)`, wantValue: -3}, + {name: "LOG", saql: `LOG(2.718281828459045)`, wantRebuild: `LOG(2.718281828459045)`, wantValue: 1}, + {name: "LOG", saql: `LOG(10)`, wantRebuild: `LOG(10)`, wantValue: 2.302585092994046}, + {name: "LOG", saql: `LOG(0)`, wantRebuild: `LOG(0)`, wantValue: nil}, + {name: "LOG2", saql: `LOG2(1024)`, wantRebuild: `LOG2(1024)`, wantValue: 10}, + {name: "LOG2", saql: `LOG2(8)`, wantRebuild: `LOG2(8)`, wantValue: 3}, + {name: "LOG2", saql: `LOG2(0)`, wantRebuild: `LOG2(0)`, wantValue: nil}, + {name: "LOG10", saql: `LOG10(10000)`, wantRebuild: `LOG10(10000)`, wantValue: 4}, + {name: "LOG10", saql: `LOG10(10)`, wantRebuild: `LOG10(10)`, wantValue: 1}, + {name: "LOG10", saql: `LOG10(0)`, wantRebuild: `LOG10(0)`, wantValue: nil}, + {name: "MAX", saql: `MAX([5, 9, -2, null, 1])`, wantRebuild: `MAX([5, 9, -2, null, 1])`, wantValue: 9}, + {name: "MAX", saql: `MAX([null, null])`, wantRebuild: `MAX([null, null])`, wantValue: nil}, + {name: "MEDIAN", saql: `MEDIAN([1, 2, 3])`, wantRebuild: `MEDIAN([1, 2, 3])`, wantValue: 2}, + {name: "MEDIAN", saql: `MEDIAN([1, 2, 3, 4])`, wantRebuild: `MEDIAN([1, 2, 3, 4])`, wantValue: 2.5}, + {name: "MEDIAN", saql: `MEDIAN([4, 2, 3, 1])`, wantRebuild: `MEDIAN([4, 2, 3, 1])`, wantValue: 2.5}, + {name: "MEDIAN", saql: `MEDIAN([999, 80, 4, 4, 4, 3, 3, 3])`, wantRebuild: `MEDIAN([999, 80, 4, 4, 4, 3, 3, 3])`, wantValue: 4}, + {name: "MIN", saql: `MIN([5, 9, -2, null, 1])`, wantRebuild: `MIN([5, 9, -2, null, 1])`, wantValue: -2}, + {name: "MIN", saql: `MIN([null, null])`, wantRebuild: `MIN([null, null])`, wantValue: nil}, + // {name: "PERCENTILE", saql: `PERCENTILE([1, 2, 3, 4], 50)`, wantRebuild: `PERCENTILE([1, 2, 3, 4], 50)`, wantValue: 2}, + // {name: "PERCENTILE", saql: `PERCENTILE([1, 2, 3, 4], 50, "rank")`, wantRebuild: `PERCENTILE([1, 2, 3, 4], 50, "rank")`, wantValue: 2}, + // {name: "PERCENTILE", saql: `PERCENTILE([1, 2, 3, 4], 50, "interpolation")`, wantRebuild: `PERCENTILE([1, 2, 3, 4], 50, "interpolation")`, wantValue: 2.5}, + {name: "PI", saql: `PI()`, wantRebuild: `PI()`, wantValue: 3.141592653589793}, + {name: "POW", saql: `POW(2, 4)`, wantRebuild: `POW(2, 4)`, wantValue: 16}, + {name: "POW", saql: `POW(5, -1)`, wantRebuild: `POW(5, -1)`, wantValue: 0.2}, + {name: "POW", saql: `POW(5, 0)`, wantRebuild: `POW(5, 0)`, wantValue: 1}, + {name: "PRODUCT", saql: `PRODUCT([1, 2, 3, 4])`, wantRebuild: `PRODUCT([1, 2, 3, 4])`, wantValue: 24}, + {name: "PRODUCT", saql: `PRODUCT([null, -5, 6])`, wantRebuild: `PRODUCT([null, -5, 6])`, wantValue: -30}, + {name: "PRODUCT", saql: `PRODUCT([])`, wantRebuild: `PRODUCT([])`, wantValue: 1}, + {name: "RADIANS", saql: `RADIANS(180)`, wantRebuild: `RADIANS(180)`, wantValue: 3.141592653589793}, + {name: "RADIANS", saql: `RADIANS(90)`, wantRebuild: `RADIANS(90)`, wantValue: 1.5707963267948966}, + {name: "RADIANS", saql: `RADIANS(0)`, wantRebuild: `RADIANS(0)`, wantValue: 0}, + // {name: "RAND", saql: `RAND()`, wantRebuild: `RAND()`, wantValue: 0.3503170117504508}, + // {name: "RAND", saql: `RAND()`, wantRebuild: `RAND()`, wantValue: 0.6138226173882478}, + {name: "RANGE", saql: `RANGE(1, 4)`, wantRebuild: `RANGE(1, 4)`, wantValue: []interface{}{float64(1), float64(2), float64(3), float64(4)}}, + {name: "RANGE", saql: `RANGE(1, 4, 2)`, wantRebuild: `RANGE(1, 4, 2)`, wantValue: []interface{}{float64(1), float64(3)}}, + {name: "RANGE", saql: `RANGE(1, 4, 3)`, wantRebuild: `RANGE(1, 4, 3)`, wantValue: []interface{}{float64(1), float64(4)}}, + {name: "RANGE", saql: `RANGE(1.5, 2.5)`, wantRebuild: `RANGE(1.5, 2.5)`, wantValue: []interface{}{float64(1), float64(2)}}, + {name: "RANGE", saql: `RANGE(1.5, 2.5, 1)`, wantRebuild: `RANGE(1.5, 2.5, 1)`, wantValue: []interface{}{1.5, 2.5}}, + {name: "RANGE", saql: `RANGE(1.5, 2.5, 0.5)`, wantRebuild: `RANGE(1.5, 2.5, 0.5)`, wantValue: []interface{}{1.5, 2.0, 2.5}}, + {name: "RANGE", saql: `RANGE(-0.75, 1.1, 0.5)`, wantRebuild: `RANGE(-0.75, 1.1, 0.5)`, wantValue: []interface{}{-0.75, -0.25, 0.25, 0.75}}, + {name: "ROUND", saql: `ROUND(2.49)`, wantRebuild: `ROUND(2.49)`, wantValue: 2}, + {name: "ROUND", saql: `ROUND(2.50)`, wantRebuild: `ROUND(2.50)`, wantValue: 3}, + {name: "ROUND", saql: `ROUND(-2.50)`, wantRebuild: `ROUND(-2.50)`, wantValue: -2}, + {name: "ROUND", saql: `ROUND(-2.51)`, wantRebuild: `ROUND(-2.51)`, wantValue: -3}, + {name: "SQRT", saql: `SQRT(9)`, wantRebuild: `SQRT(9)`, wantValue: 3}, + {name: "SQRT", saql: `SQRT(2)`, wantRebuild: `SQRT(2)`, wantValue: 1.4142135623730951}, + {name: "POW", saql: `POW(4096, 1/4)`, wantRebuild: `POW(4096, 1 / 4)`, wantValue: 8}, + {name: "POW", saql: `POW(27, 1/3)`, wantRebuild: `POW(27, 1 / 3)`, wantValue: 3}, + {name: "POW", saql: `POW(9, 1/2)`, wantRebuild: `POW(9, 1 / 2)`, wantValue: 3}, + // {name: "STDDEV_POPULATION", saql: `STDDEV_POPULATION([1, 3, 6, 5, 2])`, wantRebuild: `STDDEV_POPULATION([1, 3, 6, 5, 2])`, wantValue: 1.854723699099141}, + // {name: "STDDEV_SAMPLE", saql: `STDDEV_SAMPLE([1, 3, 6, 5, 2])`, wantRebuild: `STDDEV_SAMPLE([1, 3, 6, 5, 2])`, wantValue: 2.0736441353327724}, + {name: "SUM", saql: `SUM([1, 2, 3, 4])`, wantRebuild: `SUM([1, 2, 3, 4])`, wantValue: 10}, + {name: "SUM", saql: `SUM([null, -5, 6])`, wantRebuild: `SUM([null, -5, 6])`, wantValue: 1}, + {name: "SUM", saql: `SUM([])`, wantRebuild: `SUM([])`, wantValue: 0}, + {name: "TAN", saql: `TAN(10)`, wantRebuild: `TAN(10)`, wantValue: 0.6483608274590866}, + {name: "TAN", saql: `TAN(5)`, wantRebuild: `TAN(5)`, wantValue: -3.380515006246586}, + {name: "TAN", saql: `TAN(0)`, wantRebuild: `TAN(0)`, wantValue: 0}, + // {name: "VARIANCE_POPULATION", saql: `VARIANCE_POPULATION([1, 3, 6, 5, 2])`, wantRebuild: `VARIANCE_POPULATION([1, 3, 6, 5, 2])`, wantValue: 3.4400000000000004}, + // {name: "VARIANCE_SAMPLE", saql: `VARIANCE_SAMPLE([1, 3, 6, 5, 2])`, wantRebuild: `VARIANCE_SAMPLE([1, 3, 6, 5, 2])`, wantValue: 4.300000000000001}, + + // Errors + {name: "Function Error 1", saql: "UNKNOWN(value)", wantRebuild: "UNKNOWN(value)", wantRebuildErr: true, wantEvalErr: true, values: `{"value": true}`}, + {name: "Function Error 2", saql: "ABS(value, value2)", wantRebuild: "ABS(value, value2)", wantEvalErr: true, values: `{"value": true, "value2": false}`}, + {name: "Function Error 3", saql: `ABS("abs")`, wantRebuild: `ABS("abs")`, wantEvalErr: true}, + } + for _, tt := range tests { + parser := &Parser{} + + t.Run(tt.name, func(t *testing.T) { + expr, err := parser.Parse(tt.saql) + if (err != nil) != tt.wantParseErr { + t.Errorf("Parse() error = %v, wantErr %v", err, tt.wantParseErr) + if expr != nil { + t.Error(expr.String()) + } + return + } + if err != nil { + return + } + + got, err := expr.String() + if (err != nil) != tt.wantRebuildErr { + t.Error(expr.String()) + t.Errorf("String() error = %v, wantErr %v", err, tt.wantParseErr) + return + } + if err != nil { + return + } + if got != tt.wantRebuild { + t.Errorf("String() got = %v, want %v", got, tt.wantRebuild) + } + + var myJson map[string]interface{} + if tt.values != "" { + err = json.Unmarshal([]byte(tt.values), &myJson) + if err != nil { + t.Fatal(err) + } + } + + value, err := expr.Eval(myJson) + if (err != nil) != tt.wantEvalErr { + t.Error(expr.String()) + t.Errorf("Parse() error = %v, wantErr %v", err, tt.wantParseErr) + return + } + if err != nil { + return + } + + wantValue := tt.wantValue + if i, ok := wantValue.(int); ok { + wantValue = float64(i) + } + + valueFloat, ok := value.(float64) + wantValueFloat, ok2 := wantValue.(float64) + if ok && ok2 { + if math.Abs(valueFloat-wantValueFloat) > 0.0001 { + t.Error(expr.String()) + t.Errorf("Eval() got = %T %#v, want %T %#v", value, value, wantValue, wantValue) + } + } else { + if !reflect.DeepEqual(value, wantValue) { + t.Error(expr.String()) + t.Errorf("Eval() got = %T %#v, want %T %#v", value, value, wantValue, wantValue) + } + } + }) + } +} + +func jsonParse(s string) interface{} { + if s == "" { + return nil + } + var j interface{} + err := json.Unmarshal([]byte(s), &j) + if err != nil { + panic(s + err.Error()) + } + return j +} diff --git a/caql/interpreter.go b/caql/interpreter.go new file mode 100644 index 0000000..fce3685 --- /dev/null +++ b/caql/interpreter.go @@ -0,0 +1,355 @@ +package caql + +import ( + "fmt" + "strconv" + "strings" + + "github.com/SecurityBrewery/catalyst/generated/caql/parser" +) + +type aqlInterpreter struct { + *parser.BaseCAQLParserListener + values map[string]interface{} + stack []interface{} + errs []error +} + +// push is a helper function for pushing new node to the listener Stack. +func (s *aqlInterpreter) push(i interface{}) { + s.stack = append(s.stack, i) +} + +// pop is a helper function for poping a node from the listener Stack. +func (s *aqlInterpreter) pop() (n interface{}) { + // Check that we have nodes in the stack. + size := len(s.stack) + if size < 1 { + s.appendErrors(ErrStack) + return + } + + // Pop the last value from the Stack. + n, s.stack = s.stack[size-1], s.stack[:size-1] + + return +} + +func (s *aqlInterpreter) binaryPop() (interface{}, interface{}) { + right, left := s.pop(), s.pop() + return left, right +} + +// ExitExpression is called when production expression is exited. +func (s *aqlInterpreter) ExitExpression(ctx *parser.ExpressionContext) { + switch { + case ctx.Value_literal() != nil: + // pass + case ctx.Reference() != nil: + // pass + case ctx.Operator_unary() != nil: + // pass + + case ctx.T_PLUS() != nil: + s.push(plus(s.binaryPop())) + case ctx.T_MINUS() != nil: + s.push(minus(s.binaryPop())) + + case ctx.T_TIMES() != nil: + s.push(times(s.binaryPop())) + case ctx.T_DIV() != nil: + s.push(div(s.binaryPop())) + case ctx.T_MOD() != nil: + s.push(mod(s.binaryPop())) + + case ctx.T_RANGE() != nil: + s.push(aqlrange(s.binaryPop())) + + case ctx.T_LT() != nil && ctx.GetEq_op() == nil: + s.push(lt(s.binaryPop())) + case ctx.T_GT() != nil && ctx.GetEq_op() == nil: + s.push(gt(s.binaryPop())) + case ctx.T_LE() != nil && ctx.GetEq_op() == nil: + s.push(le(s.binaryPop())) + case ctx.T_GE() != nil && ctx.GetEq_op() == nil: + s.push(ge(s.binaryPop())) + + case ctx.T_IN() != nil && ctx.GetEq_op() == nil: + s.push(maybeNot(ctx, in(s.binaryPop()))) + + case ctx.T_EQ() != nil && ctx.GetEq_op() == nil: + s.push(eq(s.binaryPop())) + case ctx.T_NE() != nil && ctx.GetEq_op() == nil: + s.push(ne(s.binaryPop())) + + case ctx.T_ALL() != nil && ctx.GetEq_op() != nil: + right, left := s.pop(), s.pop() + s.push(all(left.([]interface{}), getOp(ctx.GetEq_op().GetTokenType()), right)) + case ctx.T_ANY() != nil && ctx.GetEq_op() != nil: + right, left := s.pop(), s.pop() + s.push(any(left.([]interface{}), getOp(ctx.GetEq_op().GetTokenType()), right)) + case ctx.T_NONE() != nil && ctx.GetEq_op() != nil: + right, left := s.pop(), s.pop() + s.push(none(left.([]interface{}), getOp(ctx.GetEq_op().GetTokenType()), right)) + + case ctx.T_ALL() != nil && ctx.T_NOT() != nil && ctx.T_IN() != nil: + right, left := s.pop(), s.pop() + s.push(all(left.([]interface{}), in, right)) + case ctx.T_ANY() != nil && ctx.T_NOT() != nil && ctx.T_IN() != nil: + right, left := s.pop(), s.pop() + s.push(any(left.([]interface{}), in, right)) + case ctx.T_NONE() != nil && ctx.T_NOT() != nil && ctx.T_IN() != nil: + right, left := s.pop(), s.pop() + s.push(none(left.([]interface{}), in, right)) + + case ctx.T_LIKE() != nil: + m, err := like(s.binaryPop()) + s.appendErrors(err) + s.push(maybeNot(ctx, m)) + case ctx.T_REGEX_MATCH() != nil: + m, err := regexMatch(s.binaryPop()) + s.appendErrors(err) + s.push(maybeNot(ctx, m)) + case ctx.T_REGEX_NON_MATCH() != nil: + m, err := regexNonMatch(s.binaryPop()) + s.appendErrors(err) + s.push(maybeNot(ctx, m)) + + case ctx.T_AND() != nil: + s.push(and(s.binaryPop())) + case ctx.T_OR() != nil: + s.push(or(s.binaryPop())) + + case ctx.T_QUESTION() != nil && len(ctx.AllExpression()) == 3: + right, middle, left := s.pop(), s.pop(), s.pop() + s.push(ternary(left, middle, right)) + case ctx.T_QUESTION() != nil && len(ctx.AllExpression()) == 2: + right, left := s.pop(), s.pop() + s.push(ternary(left, nil, right)) + + default: + panic("unkown expression") + } +} + +func (s *aqlInterpreter) appendErrors(err error) { + if err != nil { + s.errs = append(s.errs, err) + } +} + +// ExitOperator_unary is called when production operator_unary is exited. +func (s *aqlInterpreter) ExitOperator_unary(ctx *parser.Operator_unaryContext) { + value := s.pop() + switch { + case ctx.T_PLUS() != nil: + s.push(value.(float64)) + case ctx.T_MINUS() != nil: + s.push(-value.(float64)) + case ctx.T_NOT() != nil: + s.push(!toBool(value)) + default: + panic(fmt.Sprintf("unexpected operation: %s", ctx.GetText())) + } +} + +// ExitReference is called when production reference is exited. +func (s *aqlInterpreter) ExitReference(ctx *parser.ReferenceContext) { + switch { + case ctx.DOT() != nil: + reference := s.pop() + + s.push(reference.(map[string]interface{})[ctx.T_STRING().GetText()]) + case ctx.T_STRING() != nil: + s.push(s.getVar(ctx.T_STRING().GetText())) + case ctx.Compound_value() != nil: + // pass + case ctx.Function_call() != nil: + // pass + case ctx.T_OPEN() != nil: + // pass + case ctx.T_ARRAY_OPEN() != nil: + key := s.pop() + reference := s.pop() + + if f, ok := key.(float64); ok { + index := int(f) + if index < 0 { + index = len(reference.([]interface{})) + index + } + + s.push(reference.([]interface{})[index]) + return + } + + s.push(reference.(map[string]interface{})[key.(string)]) + default: + panic(fmt.Sprintf("unexpected value: %s", ctx.GetText())) + } +} + +// ExitCompound_value is called when production compound_value is exited. +func (s *aqlInterpreter) ExitCompound_value(ctx *parser.Compound_valueContext) { + // pass +} + +// ExitFunction_call is called when production function_call is exited. +func (s *aqlInterpreter) ExitFunction_call(ctx *parser.Function_callContext) { + s.function(ctx) +} + +// ExitValue_literal is called when production value_literal is exited. +func (s *aqlInterpreter) ExitValue_literal(ctx *parser.Value_literalContext) { + switch { + case ctx.T_QUOTED_STRING() != nil: + st, err := unquote(ctx.GetText()) + s.appendErrors(err) + s.push(st) + case ctx.T_INT() != nil: + t := ctx.GetText() + + switch { + case strings.HasPrefix(strings.ToLower(t), "0b"): + i64, err := strconv.ParseInt(t[2:], 2, 64) + s.appendErrors(err) + s.push(float64(i64)) + case strings.HasPrefix(strings.ToLower(t), "0x"): + i64, err := strconv.ParseInt(t[2:], 16, 64) + s.appendErrors(err) + s.push(float64(i64)) + default: + i, err := strconv.Atoi(t) + s.appendErrors(err) + s.push(float64(i)) + } + case ctx.T_FLOAT() != nil: + i, err := strconv.ParseFloat(ctx.GetText(), 64) + s.appendErrors(err) + s.push(i) + case ctx.T_NULL() != nil: + s.push(nil) + case ctx.T_TRUE() != nil: + s.push(true) + case ctx.T_FALSE() != nil: + s.push(false) + default: + panic(fmt.Sprintf("unexpected value: %s", ctx.GetText())) + } +} + +// ExitArray is called when production array is exited. +func (s *aqlInterpreter) ExitArray(ctx *parser.ArrayContext) { + array := []interface{}{} + for range ctx.AllExpression() { + // prepend element + array = append([]interface{}{s.pop()}, array...) + } + s.push(array) +} + +// ExitObject is called when production object is exited. +func (s *aqlInterpreter) ExitObject(ctx *parser.ObjectContext) { + object := map[string]interface{}{} + for range ctx.AllObject_element() { + key, value := s.pop(), s.pop() + + object[key.(string)] = value + } + s.push(object) +} + +// ExitObject_element is called when production object_element is exited. +func (s *aqlInterpreter) ExitObject_element(ctx *parser.Object_elementContext) { + switch { + case ctx.T_STRING() != nil: + s.push(ctx.GetText()) + s.push(s.getVar(ctx.GetText())) + case ctx.Object_element_name() != nil, ctx.T_ARRAY_OPEN() != nil: + key, value := s.pop(), s.pop() + + s.push(key) + s.push(value) + default: + panic(fmt.Sprintf("unexpected value: %s", ctx.GetText())) + } +} + +// ExitObject_element_name is called when production object_element_name is exited. +func (s *aqlInterpreter) ExitObject_element_name(ctx *parser.Object_element_nameContext) { + switch { + case ctx.T_STRING() != nil: + s.push(ctx.T_STRING().GetText()) + case ctx.T_QUOTED_STRING() != nil: + st, err := unquote(ctx.T_QUOTED_STRING().GetText()) + if err != nil { + s.appendErrors(fmt.Errorf("%w: %s", err, ctx.GetText())) + } + s.push(st) + default: + panic(fmt.Sprintf("unexpected value: %s", ctx.GetText())) + } +} + +func (s *aqlInterpreter) getVar(identifier string) interface{} { + v, ok := s.values[identifier] + if !ok { + s.appendErrors(ErrUndefined) + } + + return v +} + +func maybeNot(ctx *parser.ExpressionContext, m bool) bool { + if ctx.T_NOT() != nil { + return !m + } + return m +} + +func getOp(tokenType int) func(left, right interface{}) bool { + switch tokenType { + case parser.CAQLLexerT_EQ: + return eq + case parser.CAQLLexerT_NE: + return ne + case parser.CAQLLexerT_LT: + return lt + case parser.CAQLLexerT_GT: + return gt + case parser.CAQLLexerT_LE: + return le + case parser.CAQLLexerT_GE: + return ge + case parser.CAQLLexerT_IN: + return in + default: + panic("unkown token type") + } +} + +func all(slice []interface{}, op func(interface{}, interface{}) bool, expr interface{}) bool { + for _, e := range slice { + if !op(e, expr) { + return false + } + } + return true +} + +func any(slice []interface{}, op func(interface{}, interface{}) bool, expr interface{}) bool { + for _, e := range slice { + if op(e, expr) { + return true + } + } + return false +} + +func none(slice []interface{}, op func(interface{}, interface{}) bool, expr interface{}) bool { + for _, e := range slice { + if op(e, expr) { + return false + } + } + return true +} diff --git a/caql/operations.go b/caql/operations.go new file mode 100644 index 0000000..e7e2ae9 --- /dev/null +++ b/caql/operations.go @@ -0,0 +1,497 @@ +package caql + +import ( + "math" + "regexp" + "sort" + "strconv" + "strings" +) + +// Logical operators https://www.arangodb.com/docs/3.7/aql/operators.html#logical-operators + +func or(left, right interface{}) interface{} { + if toBool(left) { + return left + } + return right +} + +func and(left, right interface{}) interface{} { + if !toBool(left) { + return left + } + return right +} + +func toBool(i interface{}) bool { + switch v := i.(type) { + case nil: + return false + case bool: + return v + case int: + return v != 0 + case float64: + return v != 0 + case string: + return v != "" + case []interface{}: + return true + case map[string]interface{}: + return true + default: + panic("bool conversion failed") + } +} + +// Arithmetic operators https://www.arangodb.com/docs/3.7/aql/operators.html#arithmetic-operators + +func plus(left, right interface{}) float64 { + return toNumber(left) + toNumber(right) +} + +func minus(left, right interface{}) float64 { + return toNumber(left) - toNumber(right) +} + +func times(left, right interface{}) float64 { + return round(toNumber(left) * toNumber(right)) +} + +func round(r float64) float64 { + return math.Round(r*100000) / 100000 +} + +func div(left, right interface{}) float64 { + b := toNumber(right) + if b == 0 { + return 0 + } + return round(toNumber(left) / b) +} + +func mod(left, right interface{}) float64 { + return math.Mod(toNumber(left), toNumber(right)) +} + +func toNumber(i interface{}) float64 { + switch v := i.(type) { + case nil: + return 0 + case bool: + if v { + return 1 + } + return 0 + case float64: + switch { + case math.IsNaN(v): + return 0 + case math.IsInf(v, 0): + return 0 + } + return v + case string: + f, err := strconv.ParseFloat(strings.TrimSpace(v), 64) + if err != nil { + return 0 + } + return f + case []interface{}: + if len(v) == 0 { + return 0 + } + if len(v) == 1 { + return toNumber(v[0]) + } + return 0 + case map[string]interface{}: + return 0 + default: + panic("number conversion error") + } +} + +// Logical operators https://www.arangodb.com/docs/3.7/aql/operators.html#logical-operators +// Order https://www.arangodb.com/docs/3.7/aql/fundamentals-type-value-order.html + +func eq(left, right interface{}) bool { + leftV, rightV := typeValue(left), typeValue(right) + if leftV != rightV { + return false + } + switch l := left.(type) { + case nil: + return true + case bool, float64, string: + return left == right + case []interface{}: + ra := right.([]interface{}) + max := len(l) + if len(ra) > max { + max = len(ra) + } + for i := 0; i < max; i++ { + var li interface{} = nil + var rai interface{} = nil + if len(l) > i { + li = l[i] + } + if len(ra) > i { + rai = ra[i] + } + + if !eq(li, rai) { + return false + } + } + return true + case map[string]interface{}: + ro := right.(map[string]interface{}) + + for _, key := range keys(l, ro) { + var li interface{} = nil + var rai interface{} = nil + if lv, ok := l[key]; ok { + li = lv + } + if rv, ok := ro[key]; ok { + rai = rv + } + + if !eq(li, rai) { + return false + } + } + return true + default: + panic("unknown type") + } +} + +func ne(left, right interface{}) bool { + return !eq(left, right) +} + +func lt(left, right interface{}) bool { + leftV, rightV := typeValue(left), typeValue(right) + if leftV != rightV { + return leftV < rightV + } + switch l := left.(type) { + case nil: + return false + case bool: + return toNumber(l) < toNumber(right) + case int: + return l < right.(int) + case float64: + return l < right.(float64) + case string: + return l < right.(string) + case []interface{}: + ra := right.([]interface{}) + max := len(l) + if len(ra) > max { + max = len(ra) + } + for i := 0; i < max; i++ { + var li interface{} = nil + var rai interface{} = nil + if len(l) > i { + li = l[i] + } + if len(ra) > i { + rai = ra[i] + } + + if !eq(li, rai) { + return lt(li, rai) + } + } + return false + case map[string]interface{}: + ro := right.(map[string]interface{}) + + for _, key := range keys(l, ro) { + var li interface{} = nil + var rai interface{} = nil + if lv, ok := l[key]; ok { + li = lv + } + if rv, ok := ro[key]; ok { + rai = rv + } + + if !eq(li, rai) { + return lt(li, rai) + } + } + return false + default: + panic("unknown type") + } +} + +func keys(l map[string]interface{}, ro map[string]interface{}) []string { + var keys []string + seen := map[string]bool{} + for _, a := range []map[string]interface{}{l, ro} { + for k := range a { + if _, ok := seen[k]; !ok { + seen[k] = true + keys = append(keys, k) + } + } + } + sort.Strings(keys) + return keys +} + +func gt(left, right interface{}) bool { + leftV, rightV := typeValue(left), typeValue(right) + if leftV != rightV { + return leftV > rightV + } + switch l := left.(type) { + case nil: + return false + case bool: + return toNumber(l) > toNumber(right) + case int: + return l > right.(int) + case float64: + return l > right.(float64) + case string: + return l > right.(string) + case []interface{}: + ra := right.([]interface{}) + max := len(l) + if len(ra) > max { + max = len(ra) + } + for i := 0; i < max; i++ { + var li interface{} = nil + var rai interface{} = nil + if len(l) > i { + li = l[i] + } + if len(ra) > i { + rai = ra[i] + } + + if !eq(li, rai) { + return gt(li, rai) + } + } + return false + case map[string]interface{}: + ro := right.(map[string]interface{}) + + for _, key := range keys(l, ro) { + var li interface{} = nil + var rai interface{} = nil + if lv, ok := l[key]; ok { + li = lv + } + if rv, ok := ro[key]; ok { + rai = rv + } + + if !eq(li, rai) { + return gt(li, rai) + } + } + return false + default: + panic("unknown type") + } +} + +func le(left, right interface{}) bool { + leftV, rightV := typeValue(left), typeValue(right) + if leftV != rightV { + return leftV <= rightV + } + switch l := left.(type) { + case nil: + return false + case bool: + return toNumber(l) <= toNumber(right) + case int: + return l <= right.(int) + case float64: + return l <= right.(float64) + case string: + return l <= right.(string) + case []interface{}: + ra := right.([]interface{}) + max := len(l) + if len(ra) > max { + max = len(ra) + } + for i := 0; i < max; i++ { + var li interface{} = nil + var rai interface{} = nil + if len(l) > i { + li = l[i] + } + if len(ra) > i { + rai = ra[i] + } + + if !eq(li, rai) { + return le(li, rai) + } + } + return true + case map[string]interface{}: + ro := right.(map[string]interface{}) + + for _, key := range keys(l, ro) { + var li interface{} = nil + var rai interface{} = nil + if lv, ok := l[key]; ok { + li = lv + } + if rv, ok := ro[key]; ok { + rai = rv + } + + if !eq(li, rai) { + return lt(li, rai) + } + } + return true + default: + panic("unknown type") + } +} + +func ge(left, right interface{}) bool { + leftV, rightV := typeValue(left), typeValue(right) + if leftV != rightV { + return leftV >= rightV + } + switch l := left.(type) { + case nil: + return false + case bool: + return toNumber(l) >= toNumber(right) + case int: + return l >= right.(int) + case float64: + return l >= right.(float64) + case string: + return l >= right.(string) + case []interface{}: + ra := right.([]interface{}) + max := len(l) + if len(ra) > max { + max = len(ra) + } + for i := 0; i < max; i++ { + var li interface{} = nil + var rai interface{} = nil + if len(l) > i { + li = l[i] + } + if len(ra) > i { + rai = ra[i] + } + + if !eq(li, rai) { + return ge(li, rai) + } + } + return true + case map[string]interface{}: + ro := right.(map[string]interface{}) + + for _, key := range keys(l, ro) { + var li interface{} = nil + var rai interface{} = nil + if lv, ok := l[key]; ok { + li = lv + } + if rv, ok := ro[key]; ok { + rai = rv + } + + if !eq(li, rai) { + return gt(li, rai) + } + } + return true + default: + panic("unknown type") + } +} + +func in(left, right interface{}) bool { + a, ok := right.([]interface{}) + if !ok { + return false + } + for _, v := range a { + if left == v { + return true + } + } + return false +} + +func like(left, right interface{}) (bool, error) { + return match(right.(string), left.(string)) +} + +func regexMatch(left, right interface{}) (bool, error) { + return regexp.Match(right.(string), []byte(left.(string))) +} + +func regexNonMatch(left, right interface{}) (bool, error) { + m, err := regexp.Match(right.(string), []byte(left.(string))) + return !m, err +} + +func typeValue(v interface{}) int { + switch v.(type) { + case nil: + return 0 + case bool: + return 1 + case float64, int: + return 2 + case string: + return 3 + case []interface{}: + return 4 + case map[string]interface{}: + return 5 + default: + panic("unknown type") + } +} + +// Ternary operator https://www.arangodb.com/docs/3.7/aql/operators.html#ternary-operator + +func ternary(left, middle, right interface{}) interface{} { + if toBool(left) { + if middle != nil { + return middle + } + return left + } + return right +} + +// Range operators https://www.arangodb.com/docs/3.7/aql/operators.html#range-operator + +func aqlrange(left, right interface{}) []float64 { + var v []float64 + for i := int(left.(float64)); i <= int(right.(float64)); i++ { + v = append(v, float64(i)) + } + return v +} diff --git a/caql/parser.go b/caql/parser.go new file mode 100644 index 0000000..05cc93c --- /dev/null +++ b/caql/parser.go @@ -0,0 +1,120 @@ +package caql + +import ( + "errors" + "fmt" + "strconv" + + "github.com/antlr/antlr4/runtime/Go/antlr" + + "github.com/SecurityBrewery/catalyst/generated/caql/parser" +) + +type Parser struct { + Searcher Searcher + Prefix string +} + +func (p *Parser) Parse(aql string) (t *Tree, err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("%s", r) + } + }() + // Setup the input + inputStream := antlr.NewInputStream(aql) + + errorListener := &errorListener{} + + // Create the Lexer + lexer := parser.NewCAQLLexer(inputStream) + lexer.RemoveErrorListeners() + lexer.AddErrorListener(errorListener) + stream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel) + + // Create the Parser + aqlParser := parser.NewCAQLParser(stream) + + aqlParser.RemoveErrorListeners() + aqlParser.AddErrorListener(errorListener) + aqlParser.SetErrorHandler(antlr.NewBailErrorStrategy()) + if errorListener.errs != nil { + err = errorListener.errs[0] + } + + return &Tree{aqlParser: aqlParser, parseContext: aqlParser.Parse(), searcher: p.Searcher, prefix: p.Prefix}, err +} + +type Tree struct { + parseContext parser.IParseContext + aqlParser *parser.CAQLParser + searcher Searcher + prefix string +} + +func (t *Tree) Eval(values map[string]interface{}) (i interface{}, err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("%s", r) + } + }() + interpreter := aqlInterpreter{values: values} + + antlr.ParseTreeWalkerDefault.Walk(&interpreter, t.parseContext) + + if interpreter.errs != nil { + return nil, interpreter.errs[0] + } + return interpreter.stack[0], nil +} + +func (t *Tree) String() (s string, err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("%s", r) + } + }() + builder := aqlBuilder{searcher: t.searcher, prefix: t.prefix} + + antlr.ParseTreeWalkerDefault.Walk(&builder, t.parseContext) + + return builder.stack[0], err +} + +func (t *Tree) BleveString() (s string, err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("%s", r) + } + }() + builder := bleveBuilder{} + + antlr.ParseTreeWalkerDefault.Walk(&builder, t.parseContext) + + if builder.err != nil { + return "", builder.err + } + + return builder.stack[0], err +} + +type errorListener struct { + *antlr.DefaultErrorListener + errs []error +} + +func (el *errorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, e antlr.RecognitionException) { + el.errs = append(el.errs, fmt.Errorf("line "+strconv.Itoa(line)+":"+strconv.Itoa(column)+" "+msg)) +} + +func (el *errorListener) ReportAmbiguity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex int, exact bool, ambigAlts *antlr.BitSet, configs antlr.ATNConfigSet) { + el.errs = append(el.errs, errors.New("ReportAmbiguity")) +} + +func (el *errorListener) ReportAttemptingFullContext(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex int, conflictingAlts *antlr.BitSet, configs antlr.ATNConfigSet) { + el.errs = append(el.errs, errors.New("ReportAttemptingFullContext")) +} + +func (el *errorListener) ReportContextSensitivity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex, prediction int, configs antlr.ATNConfigSet) { + el.errs = append(el.errs, errors.New("ReportContextSensitivity")) +} diff --git a/caql/rql_test.go b/caql/rql_test.go new file mode 100644 index 0000000..fe05fce --- /dev/null +++ b/caql/rql_test.go @@ -0,0 +1,352 @@ +package caql + +import ( + "encoding/json" + "reflect" + "testing" +) + +type MockSearcher struct{} + +func (m MockSearcher) Search(_ string) (ids []string, err error) { + return []string{"1", "2", "3"}, nil +} + +func TestParseSAQLEval(t *testing.T) { + tests := []struct { + name string + saql string + wantRebuild string + wantValue interface{} + wantParseErr bool + wantRebuildErr bool + wantEvalErr bool + values string + }{ + // Custom + {name: "Compare 1", saql: "1 <= 2", wantRebuild: "1 <= 2", wantValue: true}, + {name: "Compare 2", saql: "1 >= 2", wantRebuild: "1 >= 2", wantValue: false}, + {name: "Compare 3", saql: "1 == 2", wantRebuild: "1 == 2", wantValue: false}, + {name: "Compare 4", saql: "1 > 2", wantRebuild: "1 > 2", wantValue: false}, + {name: "Compare 5", saql: "1 < 2", wantRebuild: "1 < 2", wantValue: true}, + {name: "Compare 6", saql: "1 != 2", wantRebuild: "1 != 2", wantValue: true}, + + {name: "SymbolRef 1", saql: "name", wantRebuild: "name", wantValue: false, values: `{"name": false}`}, + {name: "SymbolRef 2", saql: "d.name", wantRebuild: "d.name", wantValue: false, values: `{"d": {"name": false}}`}, + {name: "SymbolRef 3", saql: "name == false", wantRebuild: "name == false", wantValue: true, values: `{"name": false}`}, + {name: "SymbolRef Error 1", saql: "name, title", wantParseErr: true}, + {name: "SymbolRef Error 2", saql: "unknown", wantRebuild: "unknown", wantValue: false, wantEvalErr: true, values: `{}`}, + + {name: "Misc 1", saql: `active == true && age < 39`, wantRebuild: `active == true AND age < 39`, wantValue: true, values: `{"active": true, "age": 2}`}, + {name: "Misc 2", saql: `(attr == 10) AND foo == 'bar' OR NOT baz`, wantRebuild: `(attr == 10) AND foo == "bar" OR NOT baz`, wantValue: false, values: `{"attr": 2, "foo": "bar", "baz": true}`}, + {name: "Misc 3", saql: `attr == 10 AND (foo == 'bar' OR foo == 'baz')`, wantRebuild: `attr == 10 AND (foo == "bar" OR foo == "baz")`, wantValue: false, values: `{"attr": 2, "foo": "bar", "baz": true}`}, + {name: "Misc 4", saql: `5 > 1 AND "a" != "b"`, wantRebuild: `5 > 1 AND "a" != "b"`, wantValue: true}, + + {name: "LIKE 1", saql: `"foo" LIKE "%f%"`, wantRebuild: `"foo" LIKE "%f%"`, wantValue: true}, + {name: "LIKE 2", saql: `"foo" NOT LIKE "%f%"`, wantRebuild: `"foo" NOT LIKE "%f%"`, wantValue: false}, + {name: "LIKE 3", saql: `NOT "foo" LIKE "%f%"`, wantRebuild: `NOT "foo" LIKE "%f%"`, wantValue: false}, + + {name: "Summand 1", saql: "1 + 2", wantRebuild: "1 + 2", wantValue: 3}, + {name: "Summand 2", saql: "1 - 2", wantRebuild: "1 - 2", wantValue: -1}, + + {name: "Factor 1", saql: "1 * 2", wantRebuild: "1 * 2", wantValue: 2}, + {name: "Factor 2", saql: "1 / 2", wantRebuild: "1 / 2", wantValue: 0.5}, + {name: "Factor 3", saql: "1.0 / 2.0", wantRebuild: "1.0 / 2.0", wantValue: 0.5}, + {name: "Factor 4", saql: "1 % 2", wantRebuild: "1 % 2", wantValue: 1}, + + {name: "Term 1", saql: "(1 + 2) * 2", wantRebuild: "(1 + 2) * 2", wantValue: 6}, + {name: "Term 2", saql: "2 * (1 + 2)", wantRebuild: "2 * (1 + 2)", wantValue: 6}, + + // https://www.arangodb.com/docs/3.7/aql/fundamentals-data-types.html + {name: "Null 1", saql: `null`, wantRebuild: "null"}, + {name: "Bool 1", saql: `true`, wantRebuild: "true", wantValue: true}, + {name: "Bool 2", saql: `false`, wantRebuild: "false", wantValue: false}, + {name: "Numeric 1", saql: "1", wantRebuild: "1", wantValue: 1}, + {name: "Numeric 2", saql: "+1", wantRebuild: "1", wantValue: 1}, + {name: "Numeric 3", saql: "42", wantRebuild: "42", wantValue: 42}, + {name: "Numeric 4", saql: "-1", wantRebuild: "-1", wantValue: -1}, + {name: "Numeric 5", saql: "-42", wantRebuild: "-42", wantValue: -42}, + {name: "Numeric 6", saql: "1.23", wantRebuild: "1.23", wantValue: 1.23}, + {name: "Numeric 7", saql: "-99.99", wantRebuild: "-99.99", wantValue: -99.99}, + {name: "Numeric 8", saql: "0.5", wantRebuild: "0.5", wantValue: 0.5}, + {name: "Numeric 9", saql: ".5", wantRebuild: ".5", wantValue: 0.5}, + {name: "Numeric 10", saql: "-4.87e103", wantRebuild: "-4.87e103", wantValue: -4.87e+103}, + {name: "Numeric 11", saql: "0b10", wantRebuild: "0b10", wantValue: 2}, + {name: "Numeric 12", saql: "0x10", wantRebuild: "0x10", wantValue: 16}, + {name: "Numeric Error 1", saql: "1.", wantParseErr: true}, + {name: "Numeric Error 2", saql: "01.23", wantParseErr: true}, + {name: "Numeric Error 3", saql: "00.23", wantParseErr: true}, + {name: "Numeric Error 4", saql: "00", wantParseErr: true}, + + // {name: "String 1", saql: `"yikes!"`, wantRebuild: `"yikes!"`, wantValue: "yikes!"}, + // {name: "String 2", saql: `"don't know"`, wantRebuild: `"don't know"`, wantValue: "don't know"}, + // {name: "String 3", saql: `"this is a \"quoted\" word"`, wantRebuild: `"this is a \"quoted\" word"`, wantValue: "this is a \"quoted\" word"}, + // {name: "String 4", saql: `"this is a longer string."`, wantRebuild: `"this is a longer string."`, wantValue: "this is a longer string."}, + // {name: "String 5", saql: `"the path separator on Windows is \\"`, wantRebuild: `"the path separator on Windows is \\"`, wantValue: "the path separator on Windows is \\"}, + // {name: "String 6", saql: `'yikes!'`, wantRebuild: `"yikes!"`, wantValue: "yikes!"}, + // {name: "String 7", saql: `'don\'t know'`, wantRebuild: `"don't know"`, wantValue: "don't know"}, + // {name: "String 8", saql: `'this is a "quoted" word'`, wantRebuild: `"this is a \"quoted\" word"`, wantValue: "this is a \"quoted\" word"}, + // {name: "String 9", saql: `'this is a longer string.'`, wantRebuild: `"this is a longer string."`, wantValue: "this is a longer string."}, + // {name: "String 10", saql: `'the path separator on Windows is \\'`, wantRebuild: `"the path separator on Windows is \\"`, wantValue: `the path separator on Windows is \`}, + + {name: "Array 1", saql: "[]", wantRebuild: "[]", wantValue: []interface{}{}}, + {name: "Array 2", saql: `[true]`, wantRebuild: `[true]`, wantValue: []interface{}{true}}, + {name: "Array 3", saql: `[1, 2, 3]`, wantRebuild: `[1, 2, 3]`, wantValue: []interface{}{float64(1), float64(2), float64(3)}}, + { + name: "Array 4", saql: `[-99, "yikes!", [false, ["no"], []], 1]`, wantRebuild: `[-99, "yikes!", [false, ["no"], []], 1]`, + wantValue: []interface{}{-99.0, "yikes!", []interface{}{false, []interface{}{"no"}, []interface{}{}}, float64(1)}, + }, + {name: "Array 5", saql: `[["fox", "marshal"]]`, wantRebuild: `[["fox", "marshal"]]`, wantValue: []interface{}{[]interface{}{"fox", "marshal"}}}, + {name: "Array 6", saql: `[1, 2, 3,]`, wantRebuild: `[1, 2, 3]`, wantValue: []interface{}{float64(1), float64(2), float64(3)}}, + + {name: "Array Error 1", saql: "(1,2,3)", wantParseErr: true}, + {name: "Array Access 1", saql: "u.friends[0]", wantRebuild: "u.friends[0]", wantValue: 7, values: `{"u": {"friends": [7,8,9]}}`}, + {name: "Array Access 2", saql: "u.friends[2]", wantRebuild: "u.friends[2]", wantValue: 9, values: `{"u": {"friends": [7,8,9]}}`}, + {name: "Array Access 3", saql: "u.friends[-1]", wantRebuild: "u.friends[-1]", wantValue: 9, values: `{"u": {"friends": [7,8,9]}}`}, + {name: "Array Access 4", saql: "u.friends[-2]", wantRebuild: "u.friends[-2]", wantValue: 8, values: `{"u": {"friends": [7,8,9]}}`}, + + {name: "Object 1", saql: "{}", wantRebuild: "{}", wantValue: map[string]interface{}{}}, + {name: "Object 2", saql: `{a: 1}`, wantRebuild: "{a: 1}", wantValue: map[string]interface{}{"a": float64(1)}}, + {name: "Object 3", saql: `{'a': 1}`, wantRebuild: `{'a': 1}`, wantValue: map[string]interface{}{"a": float64(1)}}, + {name: "Object 4", saql: `{"a": 1}`, wantRebuild: `{"a": 1}`, wantValue: map[string]interface{}{"a": float64(1)}}, + {name: "Object 5", saql: `{'return': 1}`, wantRebuild: `{'return': 1}`, wantValue: map[string]interface{}{"return": float64(1)}}, + {name: "Object 6", saql: `{"return": 1}`, wantRebuild: `{"return": 1}`, wantValue: map[string]interface{}{"return": float64(1)}}, + {name: "Object 9", saql: `{a: 1,}`, wantRebuild: "{a: 1}", wantValue: map[string]interface{}{"a": float64(1)}}, + {name: "Object 10", saql: `{"a": 1,}`, wantRebuild: `{"a": 1}`, wantValue: map[string]interface{}{"a": float64(1)}}, + // {"Object 8", "{`return`: 1}", `{"return": 1}`, true}, + // {"Object 7", "{´return´: 1}", `{"return": 1}`, true}, + {name: "Object Error 1: return is a keyword", saql: `{like: 1}`, wantParseErr: true}, + + {name: "Object Access 1", saql: "u.address.city.name", wantRebuild: "u.address.city.name", wantValue: "Munich", values: `{"u": {"address": {"city": {"name": "Munich"}}}}`}, + {name: "Object Access 2", saql: "u.friends[0].name.first", wantRebuild: "u.friends[0].name.first", wantValue: "Kevin", values: `{"u": {"friends": [{"name": {"first": "Kevin"}}]}}`}, + {name: "Object Access 3", saql: `u["address"]["city"]["name"]`, wantRebuild: `u["address"]["city"]["name"]`, wantValue: "Munich", values: `{"u": {"address": {"city": {"name": "Munich"}}}}`}, + {name: "Object Access 4", saql: `u["friends"][0]["name"]["first"]`, wantRebuild: `u["friends"][0]["name"]["first"]`, wantValue: "Kevin", values: `{"u": {"friends": [{"name": {"first": "Kevin"}}]}}`}, + {name: "Object Access 5", saql: "u._key", wantRebuild: "u._key", wantValue: false, values: `{"u": {"_key": false}}`}, + + // This query language does not support binds + // https://www.arangodb.com/docs/3.7/aql/fundamentals-bind-parameters.html + // {name: "Bind 1", saql: "u.id == @id && u.name == @name", wantRebuild: `u.id == @id AND u.name == @name`, wantValue: true}, + // {name: "Bind 2", saql: "u.id == CONCAT('prefix', @id, 'suffix') && u.name == @name", wantRebuild: `u.id == CONCAT('prefix', @id, 'suffix') AND u.name == @name`, wantValue: false}, + // {name: "Bind 3", saql: "doc.@attr.@subattr", wantRebuild: `doc.@attr.@subattr`, wantValue: true, values: `{"doc": {"@attr": {"@subattr": true}}}`}, + // {name: "Bind 4", saql: "doc[@attr][@subattr]", wantRebuild: `doc[@attr][@subattr]`, wantValue: true, values: `{"doc": {"@attr": {"@subattr": true}}}`}, + + // https://www.arangodb.com/docs/3.7/aql/fundamentals-type-value-order.html + {name: "Compare 7", saql: `null < false`, wantRebuild: `null < false`, wantValue: true}, + {name: "Compare 8", saql: `null < true`, wantRebuild: `null < true`, wantValue: true}, + {name: "Compare 9", saql: `null < 1`, wantRebuild: `null < 1`, wantValue: true}, + {name: "Compare 10", saql: `null < ''`, wantRebuild: `null < ""`, wantValue: true}, + {name: "Compare 11", saql: `null < ' '`, wantRebuild: `null < " "`, wantValue: true}, + {name: "Compare 12", saql: `null < '3'`, wantRebuild: `null < "3"`, wantValue: true}, + {name: "Compare 13", saql: `null < 'abc'`, wantRebuild: `null < "abc"`, wantValue: true}, + {name: "Compare 14", saql: `null < []`, wantRebuild: `null < []`, wantValue: true}, + {name: "Compare 15", saql: `null < {}`, wantRebuild: `null < {}`, wantValue: true}, + {name: "Compare 16", saql: `false < true`, wantRebuild: `false < true`, wantValue: true}, + {name: "Compare 17", saql: `false < 5`, wantRebuild: `false < 5`, wantValue: true}, + {name: "Compare 18", saql: `false < ''`, wantRebuild: `false < ""`, wantValue: true}, + {name: "Compare 19", saql: `false < ' '`, wantRebuild: `false < " "`, wantValue: true}, + {name: "Compare 20", saql: `false < '7'`, wantRebuild: `false < "7"`, wantValue: true}, + {name: "Compare 21", saql: `false < 'abc'`, wantRebuild: `false < "abc"`, wantValue: true}, + {name: "Compare 22", saql: `false < []`, wantRebuild: `false < []`, wantValue: true}, + {name: "Compare 23", saql: `false < {}`, wantRebuild: `false < {}`, wantValue: true}, + {name: "Compare 24", saql: `true < 9`, wantRebuild: `true < 9`, wantValue: true}, + {name: "Compare 25", saql: `true < ''`, wantRebuild: `true < ""`, wantValue: true}, + {name: "Compare 26", saql: `true < ' '`, wantRebuild: `true < " "`, wantValue: true}, + {name: "Compare 27", saql: `true < '11'`, wantRebuild: `true < "11"`, wantValue: true}, + {name: "Compare 28", saql: `true < 'abc'`, wantRebuild: `true < "abc"`, wantValue: true}, + {name: "Compare 29", saql: `true < []`, wantRebuild: `true < []`, wantValue: true}, + {name: "Compare 30", saql: `true < {}`, wantRebuild: `true < {}`, wantValue: true}, + {name: "Compare 31", saql: `13 < ''`, wantRebuild: `13 < ""`, wantValue: true}, + {name: "Compare 32", saql: `15 < ' '`, wantRebuild: `15 < " "`, wantValue: true}, + {name: "Compare 33", saql: `17 < '18'`, wantRebuild: `17 < "18"`, wantValue: true}, + {name: "Compare 34", saql: `21 < 'abc'`, wantRebuild: `21 < "abc"`, wantValue: true}, + {name: "Compare 35", saql: `23 < []`, wantRebuild: `23 < []`, wantValue: true}, + {name: "Compare 36", saql: `25 < {}`, wantRebuild: `25 < {}`, wantValue: true}, + {name: "Compare 37", saql: `'' < ' '`, wantRebuild: `"" < " "`, wantValue: true}, + {name: "Compare 38", saql: `'' < '27'`, wantRebuild: `"" < "27"`, wantValue: true}, + {name: "Compare 39", saql: `'' < 'abc'`, wantRebuild: `"" < "abc"`, wantValue: true}, + {name: "Compare 40", saql: `'' < []`, wantRebuild: `"" < []`, wantValue: true}, + {name: "Compare 41", saql: `'' < {}`, wantRebuild: `"" < {}`, wantValue: true}, + {name: "Compare 42", saql: `[] < {}`, wantRebuild: `[] < {}`, wantValue: true}, + {name: "Compare 43", saql: `[] < [29]`, wantRebuild: `[] < [29]`, wantValue: true}, + {name: "Compare 44", saql: `[1] < [2]`, wantRebuild: `[1] < [2]`, wantValue: true}, + {name: "Compare 45", saql: `[1, 2] < [2]`, wantRebuild: `[1, 2] < [2]`, wantValue: true}, + {name: "Compare 46", saql: `[99, 99] < [100]`, wantRebuild: `[99, 99] < [100]`, wantValue: true}, + {name: "Compare 47", saql: `[false] < [true]`, wantRebuild: `[false] < [true]`, wantValue: true}, + {name: "Compare 48", saql: `[false, 1] < [false, '']`, wantRebuild: `[false, 1] < [false, ""]`, wantValue: true}, + {name: "Compare 49", saql: `{} < {"a": 1}`, wantRebuild: `{} < {"a": 1}`, wantValue: true}, + {name: "Compare 50", saql: `{} == {"a": null}`, wantRebuild: `{} == {"a": null}`, wantValue: true}, + {name: "Compare 51", saql: `{"a": 1} < {"a": 2}`, wantRebuild: `{"a": 1} < {"a": 2}`, wantValue: true}, + {name: "Compare 52", saql: `{"b": 1} < {"a": 0}`, wantRebuild: `{"b": 1} < {"a": 0}`, wantValue: true}, + {name: "Compare 53", saql: `{"a": {"c": true}} < {"a": {"c": 0}}`, wantRebuild: `{"a": {"c": true}} < {"a": {"c": 0}}`, wantValue: true}, + {name: "Compare 54", saql: `{"a": {"c": true, "a": 0}} < {"a": {"c": false, "a": 1}}`, wantRebuild: `{"a": {"c": true, "a": 0}} < {"a": {"c": false, "a": 1}}`, wantValue: true}, + {name: "Compare 55", saql: `{"a": 1, "b": 2} == {"b": 2, "a": 1}`, wantRebuild: `{"a": 1, "b": 2} == {"b": 2, "a": 1}`, wantValue: true}, + + // https://www.arangodb.com/docs/3.7/aql/operators.html + {name: "Compare 56", saql: `0 == null`, wantRebuild: `0 == null`, wantValue: false}, + {name: "Compare 57", saql: `1 > 0`, wantRebuild: `1 > 0`, wantValue: true}, + {name: "Compare 58", saql: `true != null`, wantRebuild: `true != null`, wantValue: true}, + {name: "Compare 59", saql: `45 <= "yikes!"`, wantRebuild: `45 <= "yikes!"`, wantValue: true}, + {name: "Compare 60", saql: `65 != "65"`, wantRebuild: `65 != "65"`, wantValue: true}, + {name: "Compare 61", saql: `65 == 65`, wantRebuild: `65 == 65`, wantValue: true}, + {name: "Compare 62", saql: `1.23 > 1.32`, wantRebuild: `1.23 > 1.32`, wantValue: false}, + {name: "Compare 63", saql: `1.5 IN [2, 3, 1.5]`, wantRebuild: `1.5 IN [2, 3, 1.5]`, wantValue: true}, + {name: "Compare 64", saql: `"foo" IN null`, wantRebuild: `"foo" IN null`, wantValue: false}, + {name: "Compare 65", saql: `42 NOT IN [17, 40, 50]`, wantRebuild: `42 NOT IN [17, 40, 50]`, wantValue: true}, + {name: "Compare 66", saql: `"abc" == "abc"`, wantRebuild: `"abc" == "abc"`, wantValue: true}, + {name: "Compare 67", saql: `"abc" == "ABC"`, wantRebuild: `"abc" == "ABC"`, wantValue: false}, + {name: "Compare 68", saql: `"foo" LIKE "f%"`, wantRebuild: `"foo" LIKE "f%"`, wantValue: true}, + {name: "Compare 69", saql: `"foo" NOT LIKE "f%"`, wantRebuild: `"foo" NOT LIKE "f%"`, wantValue: false}, + {name: "Compare 70", saql: `"foo" =~ "^f[o].$"`, wantRebuild: `"foo" =~ "^f[o].$"`, wantValue: true}, + {name: "Compare 71", saql: `"foo" !~ "[a-z]+bar$"`, wantRebuild: `"foo" !~ "[a-z]+bar$"`, wantValue: true}, + + {name: "Compare 72", saql: `"abc" LIKE "a%"`, wantRebuild: `"abc" LIKE "a%"`, wantValue: true}, + {name: "Compare 73", saql: `"abc" LIKE "_bc"`, wantRebuild: `"abc" LIKE "_bc"`, wantValue: true}, + {name: "Compare 74", saql: `"a_b_foo" LIKE "a\\_b\\_foo"`, wantRebuild: `"a_b_foo" LIKE "a\\_b\\_foo"`, wantValue: true}, + + // https://www.arangodb.com/docs/3.7/aql/operators.html#array-comparison-operators + {name: "Compare Array 1", saql: `[1, 2, 3] ALL IN [2, 3, 4]`, wantRebuild: `[1, 2, 3] ALL IN [2, 3, 4]`, wantValue: false}, + {name: "Compare Array 2", saql: `[1, 2, 3] ALL IN [1, 2, 3]`, wantRebuild: `[1, 2, 3] ALL IN [1, 2, 3]`, wantValue: true}, + {name: "Compare Array 3", saql: `[1, 2, 3] NONE IN [3]`, wantRebuild: `[1, 2, 3] NONE IN [3]`, wantValue: false}, + {name: "Compare Array 4", saql: `[1, 2, 3] NONE IN [23, 42]`, wantRebuild: `[1, 2, 3] NONE IN [23, 42]`, wantValue: true}, + {name: "Compare Array 5", saql: `[1, 2, 3] ANY IN [4, 5, 6]`, wantRebuild: `[1, 2, 3] ANY IN [4, 5, 6]`, wantValue: false}, + {name: "Compare Array 6", saql: `[1, 2, 3] ANY IN [1, 42]`, wantRebuild: `[1, 2, 3] ANY IN [1, 42]`, wantValue: true}, + {name: "Compare Array 7", saql: `[1, 2, 3] ANY == 2`, wantRebuild: `[1, 2, 3] ANY == 2`, wantValue: true}, + {name: "Compare Array 8", saql: `[1, 2, 3] ANY == 4`, wantRebuild: `[1, 2, 3] ANY == 4`, wantValue: false}, + {name: "Compare Array 9", saql: `[1, 2, 3] ANY > 0`, wantRebuild: `[1, 2, 3] ANY > 0`, wantValue: true}, + {name: "Compare Array 10", saql: `[1, 2, 3] ANY <= 1`, wantRebuild: `[1, 2, 3] ANY <= 1`, wantValue: true}, + {name: "Compare Array 11", saql: `[1, 2, 3] NONE < 99`, wantRebuild: `[1, 2, 3] NONE < 99`, wantValue: false}, + {name: "Compare Array 12", saql: `[1, 2, 3] NONE > 10`, wantRebuild: `[1, 2, 3] NONE > 10`, wantValue: true}, + {name: "Compare Array 13", saql: `[1, 2, 3] ALL > 2`, wantRebuild: `[1, 2, 3] ALL > 2`, wantValue: false}, + {name: "Compare Array 14", saql: `[1, 2, 3] ALL > 0`, wantRebuild: `[1, 2, 3] ALL > 0`, wantValue: true}, + {name: "Compare Array 15", saql: `[1, 2, 3] ALL >= 3`, wantRebuild: `[1, 2, 3] ALL >= 3`, wantValue: false}, + {name: "Compare Array 16", saql: `["foo", "bar"] ALL != "moo"`, wantRebuild: `["foo", "bar"] ALL != "moo"`, wantValue: true}, + {name: "Compare Array 17", saql: `["foo", "bar"] NONE == "bar"`, wantRebuild: `["foo", "bar"] NONE == "bar"`, wantValue: false}, + {name: "Compare Array 18", saql: `["foo", "bar"] ANY == "foo"`, wantRebuild: `["foo", "bar"] ANY == "foo"`, wantValue: true}, + + // https://www.arangodb.com/docs/3.7/aql/operators.html#logical-operators + {name: "Logical 1", saql: "active == true OR age < 39", wantRebuild: "active == true OR age < 39", wantValue: true, values: `{"active": true, "age": 4}`}, + {name: "Logical 2", saql: "active == true || age < 39", wantRebuild: "active == true OR age < 39", wantValue: true, values: `{"active": true, "age": 4}`}, + {name: "Logical 3", saql: "active == true AND age < 39", wantRebuild: "active == true AND age < 39", wantValue: true, values: `{"active": true, "age": 4}`}, + {name: "Logical 4", saql: "active == true && age < 39", wantRebuild: "active == true AND age < 39", wantValue: true, values: `{"active": true, "age": 4}`}, + {name: "Logical 5", saql: "!active", wantRebuild: "NOT active", wantValue: false, values: `{"active": true}`}, + {name: "Logical 6", saql: "NOT active", wantRebuild: "NOT active", wantValue: false, values: `{"active": true}`}, + {name: "Logical 7", saql: "not active", wantRebuild: "NOT active", wantValue: false, values: `{"active": true}`}, + {name: "Logical 8", saql: "NOT NOT active", wantRebuild: "NOT NOT active", wantValue: true, values: `{"active": true}`}, + + {name: "Logical 9", saql: `u.age > 15 && u.address.city != ""`, wantRebuild: `u.age > 15 AND u.address.city != ""`, wantValue: false, values: `{"u": {"age": 2, "address": {"city": "Munich"}}}`}, + {name: "Logical 10", saql: `true || false`, wantRebuild: `true OR false`, wantValue: true}, + {name: "Logical 11", saql: `NOT u.isInvalid`, wantRebuild: `NOT u.isInvalid`, wantValue: false, values: `{"u": {"isInvalid": true}}`}, + {name: "Logical 12", saql: `1 || ! 0`, wantRebuild: `1 OR NOT 0`, wantValue: 1}, + + {name: "Logical 13", saql: `25 > 1 && 42 != 7`, wantRebuild: `25 > 1 AND 42 != 7`, wantValue: true}, + {name: "Logical 14", saql: `22 IN [23, 42] || 23 NOT IN [22, 7]`, wantRebuild: `22 IN [23, 42] OR 23 NOT IN [22, 7]`, wantValue: true}, + {name: "Logical 15", saql: `25 != 25`, wantRebuild: `25 != 25`, wantValue: false}, + + {name: "Logical 16", saql: `1 || 7`, wantRebuild: `1 OR 7`, wantValue: 1}, + // {name: "Logical 17", saql: `null || "foo"`, wantRebuild: `null OR "foo"`, wantValue: "foo"}, + {name: "Logical 17", saql: `null || "foo"`, wantRebuild: `null OR d._key IN ["1","2","3"]`, wantValue: "foo", values: `{"d": {"_key": "1"}}`}, // eval != rebuild + {name: "Logical 18", saql: `null && true`, wantRebuild: `null AND true`, wantValue: nil}, + {name: "Logical 19", saql: `true && 23`, wantRebuild: `true AND 23`, wantValue: 23}, + + {name: "Logical 20", saql: "true == (6 < 8)", wantRebuild: "true == (6 < 8)", wantValue: true}, + {name: "Logical 21", saql: "true == 6 < 8", wantRebuild: "true == 6 < 8", wantValue: true}, // does not work in go + + // https://www.arangodb.com/docs/3.7/aql/operators.html#arithmetic-operators + {name: "Arithmetic 1", saql: `1 + 1`, wantRebuild: `1 + 1`, wantValue: 2}, + {name: "Arithmetic 2", saql: `33 - 99`, wantRebuild: `33 - 99`, wantValue: -66}, + {name: "Arithmetic 3", saql: `12.4 * 4.5`, wantRebuild: `12.4 * 4.5`, wantValue: 55.8}, + {name: "Arithmetic 4", saql: `13.0 / 0.1`, wantRebuild: `13.0 / 0.1`, wantValue: 130.0}, + {name: "Arithmetic 5", saql: `23 % 7`, wantRebuild: `23 % 7`, wantValue: 2}, + {name: "Arithmetic 6", saql: `-15`, wantRebuild: `-15`, wantValue: -15}, + {name: "Arithmetic 7", saql: `+9.99`, wantRebuild: `9.99`, wantValue: 9.99}, + + {name: "Arithmetic 8", saql: `1 + "a"`, wantRebuild: `1 + "a"`, wantValue: 1}, + {name: "Arithmetic 9", saql: `1 + "99"`, wantRebuild: `1 + "99"`, wantValue: 100}, + {name: "Arithmetic 10", saql: `1 + null`, wantRebuild: `1 + null`, wantValue: 1}, + {name: "Arithmetic 11", saql: `null + 1`, wantRebuild: `null + 1`, wantValue: 1}, + {name: "Arithmetic 12", saql: `3 + []`, wantRebuild: `3 + []`, wantValue: 3}, + {name: "Arithmetic 13", saql: `24 + [2]`, wantRebuild: `24 + [2]`, wantValue: 26}, + {name: "Arithmetic 14", saql: `24 + [2, 4]`, wantRebuild: `24 + [2, 4]`, wantValue: 24}, + {name: "Arithmetic 15", saql: `25 - null`, wantRebuild: `25 - null`, wantValue: 25}, + {name: "Arithmetic 16", saql: `17 - true`, wantRebuild: `17 - true`, wantValue: 16}, + {name: "Arithmetic 17", saql: `23 * {}`, wantRebuild: `23 * {}`, wantValue: 0}, + {name: "Arithmetic 18", saql: `5 * [7]`, wantRebuild: `5 * [7]`, wantValue: 35}, + {name: "Arithmetic 19", saql: `24 / "12"`, wantRebuild: `24 / "12"`, wantValue: 2}, + {name: "Arithmetic Error 1: Divison by zero", saql: `1 / 0`, wantRebuild: `1 / 0`, wantValue: 0}, + + // https://www.arangodb.com/docs/3.7/aql/operators.html#ternary-operator + {name: "Ternary 1", saql: `u.age > 15 || u.active == true ? u.userId : null`, wantRebuild: `u.age > 15 OR u.active == true ? u.userId : null`, wantValue: 45, values: `{"u": {"active": true, "age": 2, "userId": 45}}`}, + {name: "Ternary 2", saql: `u.value ? : 'value is null, 0 or not present'`, wantRebuild: `u.value ? : "value is null, 0 or not present"`, wantValue: "value is null, 0 or not present", values: `{"u": {"value": 0}}`}, + + // https://www.arangodb.com/docs/3.7/aql/operators.html#range-operator + {name: "Range 1", saql: `2010..2013`, wantRebuild: `2010..2013`, wantValue: []float64{2010, 2011, 2012, 2013}}, + // {"Array operators 1", `u.friends[*].name`, `u.friends[*].name`, false}, + + // Security + {name: "Security 1", saql: `doc.value == 1 || true REMOVE doc IN collection //`, wantParseErr: true}, + {name: "Security 2", saql: `doc.value == 1 || true INSERT {foo: "bar"} IN collection //`, wantParseErr: true}, + + // https://www.arangodb.com/docs/3.7/aql/operators.html#operator-precedence + {name: "Precendence", saql: `2 > 15 && "a" != ""`, wantRebuild: `2 > 15 AND "a" != ""`, wantValue: false}, + } + for _, tt := range tests { + parser := &Parser{ + Searcher: &MockSearcher{}, + } + + t.Run(tt.name, func(t *testing.T) { + expr, err := parser.Parse(tt.saql) + if (err != nil) != tt.wantParseErr { + t.Errorf("Parse() error = %v, wantErr %v", err, tt.wantParseErr) + if expr != nil { + t.Error(expr.String()) + } + return + } + if err != nil { + return + } + + got, err := expr.String() + if (err != nil) != tt.wantRebuildErr { + t.Error(expr.String()) + t.Errorf("String() error = %v, wantErr %v", err, tt.wantParseErr) + return + } + if err != nil { + return + } + if got != tt.wantRebuild { + t.Errorf("String() got = %v, want %v", got, tt.wantRebuild) + } + + var myJson map[string]interface{} + if tt.values != "" { + err = json.Unmarshal([]byte(tt.values), &myJson) + if err != nil { + t.Fatal(err) + } + } + + value, err := expr.Eval(myJson) + if (err != nil) != tt.wantEvalErr { + t.Error(expr.String()) + t.Errorf("Parse() error = %v, wantErr %v", err, tt.wantParseErr) + return + } + if err != nil { + return + } + + wantValue := tt.wantValue + if i, ok := wantValue.(int); ok { + wantValue = float64(i) + } + + if !reflect.DeepEqual(value, wantValue) { + t.Error(expr.String()) + t.Errorf("Eval() got = %T %#v, want %T %#v", value, value, wantValue, wantValue) + } + }) + } +} diff --git a/caql/set.go b/caql/set.go new file mode 100644 index 0000000..b703d35 --- /dev/null +++ b/caql/set.go @@ -0,0 +1,154 @@ +// Adapted from https://github.com/badgerodon/collections under the MIT License +// Original License: +// +// Copyright (c) 2012 Caleb Doxsey +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package caql + +import "sort" + +type ( + Set struct { + hash map[interface{}]nothing + } + + nothing struct{} +) + +// Create a new set +func New(initial ...interface{}) *Set { + s := &Set{make(map[interface{}]nothing)} + + for _, v := range initial { + s.Insert(v) + } + + return s +} + +// Find the difference between two sets +func (s *Set) Difference(set *Set) *Set { + n := make(map[interface{}]nothing) + + for k := range s.hash { + if _, exists := set.hash[k]; !exists { + n[k] = nothing{} + } + } + + return &Set{n} +} + +// Call f for each item in the set +func (s *Set) Do(f func(interface{})) { + for k := range s.hash { + f(k) + } +} + +// Test to see whether or not the element is in the set +func (s *Set) Has(element interface{}) bool { + _, exists := s.hash[element] + return exists +} + +// Add an element to the set +func (s *Set) Insert(element interface{}) { + s.hash[element] = nothing{} +} + +// Find the intersection of two sets +func (s *Set) Intersection(set *Set) *Set { + n := make(map[interface{}]nothing) + + for k := range s.hash { + if _, exists := set.hash[k]; exists { + n[k] = nothing{} + } + } + + return &Set{n} +} + +// Return the number of items in the set +func (s *Set) Len() int { + return len(s.hash) +} + +// Test whether or not this set is a proper subset of "set" +func (s *Set) ProperSubsetOf(set *Set) bool { + return s.SubsetOf(set) && s.Len() < set.Len() +} + +// Remove an element from the set +func (s *Set) Remove(element interface{}) { + delete(s.hash, element) +} + +func (s *Set) Minus(set *Set) *Set { + n := make(map[interface{}]nothing) + for k := range s.hash { + n[k] = nothing{} + } + + for _, v := range set.Values() { + delete(n, v) + } + + return &Set{n} +} + +// Test whether or not this set is a subset of "set" +func (s *Set) SubsetOf(set *Set) bool { + if s.Len() > set.Len() { + return false + } + for k := range s.hash { + if _, exists := set.hash[k]; !exists { + return false + } + } + return true +} + +// Find the union of two sets +func (s *Set) Union(set *Set) *Set { + n := make(map[interface{}]nothing) + + for k := range s.hash { + n[k] = nothing{} + } + for k := range set.hash { + n[k] = nothing{} + } + + return &Set{n} +} + +func (s *Set) Values() []interface{} { + values := []interface{}{} + + for k := range s.hash { + values = append(values, k) + } + sort.Slice(values, func(i, j int) bool { return lt(values[i], values[j]) }) + + return values +} diff --git a/caql/set_test.go b/caql/set_test.go new file mode 100644 index 0000000..f4b56ef --- /dev/null +++ b/caql/set_test.go @@ -0,0 +1,96 @@ +// Adapted from https://github.com/badgerodon/collections under the MIT License +// Original License: +// +// Copyright (c) 2012 Caleb Doxsey +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package caql + +import ( + "testing" +) + +func Test(t *testing.T) { + s := New() + + s.Insert(5) + + if s.Len() != 1 { + t.Errorf("Length should be 1") + } + + if !s.Has(5) { + t.Errorf("Membership test failed") + } + + s.Remove(5) + + if s.Len() != 0 { + t.Errorf("Length should be 0") + } + + if s.Has(5) { + t.Errorf("The set should be empty") + } + + // Difference + s1 := New(1, 2, 3, 4, 5, 6) + s2 := New(4, 5, 6) + s3 := s1.Difference(s2) + + if s3.Len() != 3 { + t.Errorf("Length should be 3") + } + + if !(s3.Has(1) && s3.Has(2) && s3.Has(3)) { + t.Errorf("Set should only contain 1, 2, 3") + } + + // Intersection + s3 = s1.Intersection(s2) + if s3.Len() != 3 { + t.Errorf("Length should be 3 after intersection") + } + + if !(s3.Has(4) && s3.Has(5) && s3.Has(6)) { + t.Errorf("Set should contain 4, 5, 6") + } + + // Union + s4 := New(7, 8, 9) + s3 = s2.Union(s4) + + if s3.Len() != 6 { + t.Errorf("Length should be 6 after union") + } + + if !(s3.Has(7)) { + t.Errorf("Set should contain 4, 5, 6, 7, 8, 9") + } + + // Subset + if !s1.SubsetOf(s1) { + t.Errorf("set should be a subset of itself") + } + // Proper Subset + if s1.ProperSubsetOf(s1) { + t.Errorf("set should not be a subset of itself") + } + +} diff --git a/caql/unquote.go b/caql/unquote.go new file mode 100644 index 0000000..efbe0b4 --- /dev/null +++ b/caql/unquote.go @@ -0,0 +1,79 @@ +// Adapted from https://github.com/golang/go +// Original License: +// +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the https://go.dev/LICENSE file. + +package caql + +import ( + "strconv" + "strings" + "unicode/utf8" +) + +// unquote interprets s as a single-quoted, double-quoted, +// or backquoted string literal, returning the string value +// that s quotes. +func unquote(s string) (string, error) { + n := len(s) + if n < 2 { + return "", strconv.ErrSyntax + } + quote := s[0] + if quote != s[n-1] { + return "", strconv.ErrSyntax + } + s = s[1 : n-1] + + if quote == '`' { + if strings.ContainsRune(s, '`') { + return "", strconv.ErrSyntax + } + if strings.ContainsRune(s, '\r') { + // -1 because we know there is at least one \r to remove. + buf := make([]byte, 0, len(s)-1) + for i := 0; i < len(s); i++ { + if s[i] != '\r' { + buf = append(buf, s[i]) + } + } + return string(buf), nil + } + return s, nil + } + if quote != '"' && quote != '\'' { + return "", strconv.ErrSyntax + } + if strings.ContainsRune(s, '\n') { + return "", strconv.ErrSyntax + } + + // Is it trivial? Avoid allocation. + if !strings.ContainsRune(s, '\\') && !strings.ContainsRune(s, rune(quote)) { + switch quote { + case '"', '\'': + if utf8.ValidString(s) { + return s, nil + } + } + } + + var runeTmp [utf8.UTFMax]byte + buf := make([]byte, 0, 3*len(s)/2) // Try to avoid more allocations. + for len(s) > 0 { + c, multibyte, ss, err := strconv.UnquoteChar(s, quote) + if err != nil { + return "", err + } + s = ss + if c < utf8.RuneSelf || !multibyte { + buf = append(buf, byte(c)) + } else { + n := utf8.EncodeRune(runeTmp[:], c) + buf = append(buf, runeTmp[:n]...) + } + } + return string(buf), nil +} diff --git a/caql/unquote_test.go b/caql/unquote_test.go new file mode 100644 index 0000000..2044a0e --- /dev/null +++ b/caql/unquote_test.go @@ -0,0 +1,125 @@ +// Adapted from https://github.com/golang/go +// Original License: +// +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the https://go.dev/LICENSE file. + +package caql + +import ( + "strconv" + "testing" +) + +type quoteTest struct { + in string + out string + ascii string + graphic string +} + +var quotetests = []quoteTest{ + {in: "\a\b\f\r\n\t\v", out: `"\a\b\f\r\n\t\v"`, ascii: `"\a\b\f\r\n\t\v"`, graphic: `"\a\b\f\r\n\t\v"`}, + {"\\", `"\\"`, `"\\"`, `"\\"`}, + {"abc\xffdef", `"abc\xffdef"`, `"abc\xffdef"`, `"abc\xffdef"`}, + {"\u263a", `"☺"`, `"\u263a"`, `"☺"`}, + {"\U0010ffff", `"\U0010ffff"`, `"\U0010ffff"`, `"\U0010ffff"`}, + {"\x04", `"\x04"`, `"\x04"`, `"\x04"`}, + // Some non-printable but graphic runes. Final column is double-quoted. + {"!\u00a0!\u2000!\u3000!", `"!\u00a0!\u2000!\u3000!"`, `"!\u00a0!\u2000!\u3000!"`, "\"!\u00a0!\u2000!\u3000!\""}, +} + +type unQuoteTest struct { + in string + out string +} + +var unquotetests = []unQuoteTest{ + {`""`, ""}, + {`"a"`, "a"}, + {`"abc"`, "abc"}, + {`"☺"`, "☺"}, + {`"hello world"`, "hello world"}, + {`"\xFF"`, "\xFF"}, + {`"\377"`, "\377"}, + {`"\u1234"`, "\u1234"}, + {`"\U00010111"`, "\U00010111"}, + {`"\U0001011111"`, "\U0001011111"}, + {`"\a\b\f\n\r\t\v\\\""`, "\a\b\f\n\r\t\v\\\""}, + {`"'"`, "'"}, + + {`'a'`, "a"}, + {`'☹'`, "☹"}, + {`'\a'`, "\a"}, + {`'\x10'`, "\x10"}, + {`'\377'`, "\377"}, + {`'\u1234'`, "\u1234"}, + {`'\U00010111'`, "\U00010111"}, + {`'\t'`, "\t"}, + {`' '`, " "}, + {`'\''`, "'"}, + {`'"'`, "\""}, + + {"``", ``}, + {"`a`", `a`}, + {"`abc`", `abc`}, + {"`☺`", `☺`}, + {"`hello world`", `hello world`}, + {"`\\xFF`", `\xFF`}, + {"`\\377`", `\377`}, + {"`\\`", `\`}, + {"`\n`", "\n"}, + {"` `", ` `}, + {"` `", ` `}, + {"`a\rb`", "ab"}, +} + +var misquoted = []string{ + ``, + `"`, + `"a`, + `"'`, + `b"`, + `"\"`, + `"\9"`, + `"\19"`, + `"\129"`, + `'\'`, + `'\9'`, + `'\19'`, + `'\129'`, + // `'ab'`, + `"\x1!"`, + `"\U12345678"`, + `"\z"`, + "`", + "`xxx", + "`\"", + `"\'"`, + `'\"'`, + "\"\n\"", + "\"\\n\n\"", + "'\n'", +} + +func TestUnquote(t *testing.T) { + for _, tt := range unquotetests { + if out, err := unquote(tt.in); err != nil || out != tt.out { + t.Errorf("unquote(%#q) = %q, %v want %q, nil", tt.in, out, err, tt.out) + } + } + + // run the quote tests too, backward + for _, tt := range quotetests { + if in, err := unquote(tt.out); in != tt.in { + t.Errorf("unquote(%#q) = %q, %v, want %q, nil", tt.out, in, err, tt.in) + } + } + + for _, s := range misquoted { + if out, err := unquote(s); out != "" || err != strconv.ErrSyntax { + t.Errorf("unquote(%#q) = %q, %v want %q, %v", s, out, err, "", strconv.ErrSyntax) + } + } +} diff --git a/caql/wildcard.go b/caql/wildcard.go new file mode 100644 index 0000000..1eca811 --- /dev/null +++ b/caql/wildcard.go @@ -0,0 +1,155 @@ +// Adapted from https://github.com/golang/go +// Original License: +// +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the https://go.dev/LICENSE file. + +package caql + +import ( + "errors" + "strings" + "unicode/utf8" +) + +// ErrBadPattern indicates a pattern was malformed. +var ErrBadPattern = errors.New("syntax error in pattern") + +// match reports whether name matches the shell pattern. +// The pattern syntax is: +// +// pattern: +// { term } +// term: +// '%' matches any sequence of non-/ characters +// '_' matches any single non-/ character +// c matches character c (c != '%', '_', '\\') +// '\\' c matches character c +// +// match requires pattern to match all of name, not just a substring. +// The only possible returned error is ErrBadPattern, when pattern +// is malformed. +// +func match(pattern, name string) (matched bool, err error) { +Pattern: + for len(pattern) > 0 { + var star bool + var chunk string + star, chunk, pattern = scanChunk(pattern) + if star && chunk == "" { + // Trailing * matches rest of string unless it has a /. + return !strings.ContainsRune(name, '/'), nil + } + // Look for match at current position. + t, ok, err := matchChunk(chunk, name) + // if we're the last chunk, make sure we've exhausted the name + // otherwise we'll give a false result even if we could still match + // using the star + if ok && (len(t) == 0 || len(pattern) > 0) { + name = t + continue + } + if err != nil { + return false, err + } + if star { + // Look for match skipping i+1 bytes. + // Cannot skip /. + for i := 0; i < len(name) && name[i] != '/'; i++ { + t, ok, err := matchChunk(chunk, name[i+1:]) + if ok { + // if we're the last chunk, make sure we exhausted the name + if len(pattern) == 0 && len(t) > 0 { + continue + } + name = t + continue Pattern + } + if err != nil { + return false, err + } + } + } + // Before returning false with no error, + // check that the remainder of the pattern is syntactically valid. + for len(pattern) > 0 { + _, chunk, pattern = scanChunk(pattern) + if _, _, err := matchChunk(chunk, ""); err != nil { + return false, err + } + } + return false, nil + } + return len(name) == 0, nil +} + +// scanChunk gets the next segment of pattern, which is a non-star string +// possibly preceded by a star. +func scanChunk(pattern string) (star bool, chunk, rest string) { + for len(pattern) > 0 && pattern[0] == '%' { + pattern = pattern[1:] + star = true + } + var i int +Scan: + for i = 0; i < len(pattern); i++ { + switch pattern[i] { + case '\\': + // error check handled in matchChunk: bad pattern. + if i+1 < len(pattern) { + i++ + } + case '%': + break Scan + } + } + return star, pattern[0:i], pattern[i:] +} + +// matchChunk checks whether chunk matches the beginning of s. +// If so, it returns the remainder of s (after the match). +// Chunk is all single-character operators: literals, char classes, and ?. +func matchChunk(chunk, s string) (rest string, ok bool, err error) { + // failed records whether the match has failed. + // After the match fails, the loop continues on processing chunk, + // checking that the pattern is well-formed but no longer reading s. + failed := false + for len(chunk) > 0 { + if !failed && len(s) == 0 { + failed = true + } + switch chunk[0] { + + case '_': + if !failed { + if s[0] == '/' { + failed = true + } + _, n := utf8.DecodeRuneInString(s) + s = s[n:] + } + chunk = chunk[1:] + + case '\\': + chunk = chunk[1:] + if len(chunk) == 0 { + return "", false, ErrBadPattern + } + fallthrough + + default: + if !failed { + if chunk[0] != s[0] { + failed = true + } + s = s[1:] + } + chunk = chunk[1:] + } + } + if failed { + return "", false, nil + } + return s, true, nil +} diff --git a/caql/wildcard_test.go b/caql/wildcard_test.go new file mode 100644 index 0000000..e74536b --- /dev/null +++ b/caql/wildcard_test.go @@ -0,0 +1,50 @@ +// Adapted from https://github.com/golang/go +// Original License: +// +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the https://go.dev/LICENSE file. + +package caql + +import "testing" + +type MatchTest struct { + pattern, s string + match bool + err error +} + +var matchTests = []MatchTest{ + {"abc", "abc", true, nil}, + {"%", "abc", true, nil}, + {"%c", "abc", true, nil}, + {"a%", "a", true, nil}, + {"a%", "abc", true, nil}, + {"a%", "ab/c", false, nil}, + {"a%/b", "abc/b", true, nil}, + {"a%/b", "a/c/b", false, nil}, + {"a%b%c%d%e%/f", "axbxcxdxe/f", true, nil}, + {"a%b%c%d%e%/f", "axbxcxdxexxx/f", true, nil}, + {"a%b%c%d%e%/f", "axbxcxdxe/xxx/f", false, nil}, + {"a%b%c%d%e%/f", "axbxcxdxexxx/fff", false, nil}, + {"a%b_c%x", "abxbbxdbxebxczzx", true, nil}, + {"a%b_c%x", "abxbbxdbxebxczzy", false, nil}, + {"a\\%b", "a%b", true, nil}, + {"a\\%b", "ab", false, nil}, + {"a_b", "a☺b", true, nil}, + {"a___b", "a☺b", false, nil}, + {"a_b", "a/b", false, nil}, + {"a%b", "a/b", false, nil}, + {"\\", "a", false, ErrBadPattern}, + {"%x", "xxx", true, nil}, +} + +func TestMatch(t *testing.T) { + for _, tt := range matchTests { + ok, err := match(tt.pattern, tt.s) + if ok != tt.match || err != tt.err { + t.Errorf("match(%#q, %#q) = %v, %v want %v, %v", tt.pattern, tt.s, ok, err, tt.match, tt.err) + } + } +} diff --git a/cmd/catalyst-dev/main.go b/cmd/catalyst-dev/main.go new file mode 100644 index 0000000..a42f795 --- /dev/null +++ b/cmd/catalyst-dev/main.go @@ -0,0 +1,65 @@ +package main + +import ( + "context" + "log" + "net/http/httputil" + "net/url" + + "github.com/arangodb/go-driver" + "github.com/gin-contrib/sessions" + "github.com/gin-contrib/sessions/cookie" + "github.com/gin-gonic/gin" + + "github.com/SecurityBrewery/catalyst" + "github.com/SecurityBrewery/catalyst/cmd" + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/hooks" + "github.com/SecurityBrewery/catalyst/role" + "github.com/SecurityBrewery/catalyst/test" +) + +func main() { + log.SetFlags(log.LstdFlags | log.Lshortfile) + + config, err := cmd.ParseCatalystConfig() + if err != nil { + log.Fatal(err) + } + + // create app and clear db after start + theCatalyst, err := catalyst.New(&hooks.Hooks{ + DatabaseAfterConnectFuncs: []func(ctx context.Context, client driver.Client, name string){test.Clear}, + }, config) + if err != nil { + log.Fatal(err) + } + + demoUser := &models.UserResponse{ID: "demo", Roles: []string{role.Admin}} + ctx := busdb.UserContext(context.Background(), demoUser) + if err := test.SetupTestData(ctx, theCatalyst.DB); err != nil { + log.Fatal(err) + } + + // proxy static requests + theCatalyst.Server.NoRoute( + sessions.Sessions(catalyst.SessionName, cookie.NewStore(config.Secret)), + catalyst.Authenticate(theCatalyst.DB, config.Auth), + catalyst.AuthorizeBlockedUser, + proxy, + ) + + if err = theCatalyst.Server.RunWithSigHandler(); err != nil { + log.Fatal(err) + } +} + +func proxy(ctx *gin.Context) { + u, _ := url.Parse("http://localhost:8080") + proxy := httputil.NewSingleHostReverseProxy(u) + + ctx.Request.Host = ctx.Request.URL.Host + + proxy.ServeHTTP(ctx.Writer, ctx.Request) +} diff --git a/cmd/catalyst/main.go b/cmd/catalyst/main.go new file mode 100644 index 0000000..e2f3f02 --- /dev/null +++ b/cmd/catalyst/main.go @@ -0,0 +1,27 @@ +package main + +import ( + "log" + + "github.com/SecurityBrewery/catalyst" + "github.com/SecurityBrewery/catalyst/cmd" + "github.com/SecurityBrewery/catalyst/hooks" +) + +func main() { + log.SetFlags(log.LstdFlags | log.Lshortfile) + + config, err := cmd.ParseCatalystConfig() + if err != nil { + log.Fatal(err) + } + + theCatalyst, err := catalyst.New(&hooks.Hooks{}, config) + if err != nil { + log.Fatal(err) + } + + if err = theCatalyst.Server.RunWithSigHandler(); err != nil { + log.Fatal(err) + } +} diff --git a/cmd/cmd.go b/cmd/cmd.go new file mode 100644 index 0000000..f5dc6e5 --- /dev/null +++ b/cmd/cmd.go @@ -0,0 +1,151 @@ +package cmd + +import ( + "fmt" + + "github.com/alecthomas/kong" + kongyaml "github.com/alecthomas/kong-yaml" + "github.com/coreos/go-oidc/v3/oidc" + "golang.org/x/oauth2" + + "github.com/SecurityBrewery/catalyst" + "github.com/SecurityBrewery/catalyst/bus" + "github.com/SecurityBrewery/catalyst/database" + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/pointer" + "github.com/SecurityBrewery/catalyst/role" + "github.com/SecurityBrewery/catalyst/storage" +) + +type CLI struct { + Secret string `env:"SECRET" required:"" help:"A random secret value (can be created with 'openssl rand -hex 32')"` + ExternalAddress string `env:"EXTERNAL_ADDRESS" required:""` + CatalystAddress string `env:"CATALYST_ADDRESS" default:"http://catalyst"` + + OIDCIssuer string `env:"OIDC_ISSUER" required:""` + OIDCClientID string `env:"OIDC_CLIENT_ID" default:"catalyst"` + OIDCClientSecret string `env:"OIDC_CLIENT_SECRET" required:""` + OIDCScopes []string `env:"OIDC_SCOPES" help:"Additional scopes, ['oidc', 'profile', 'email'] are always added." placeholder:"customscopes"` + OIDCClaimUsername string `env:"OIDC_CLAIM_USERNAME" default:"preferred_username" help:"username field in the OIDC claim"` + OIDCClaimEmail string `env:"OIDC_CLAIM_EMAIL" default:"email" help:"email field in the OIDC claim"` + OIDCClaimName string `env:"OIDC_CLAIM_NAME" default:"name" help:"name field in the OIDC claim"` + AuthBlockNew bool `env:"AUTH_BLOCK_NEW" default:"true" help:"Block newly created users"` + AuthDefaultRoles []string `env:"AUTH_DEFAULT_ROLES" help:"Default roles for new users"` + + IndexPath string `env:"INDEX_PATH" default:"index.bleve" help:"Path for the bleve index"` + + ArangoDBHost string `env:"ARANGO_DB_HOST" default:"http://arangodb:8529"` + ArangoDBUser string `env:"ARANGO_DB_USER" default:"root"` + ArangoDBPassword string `env:"ARANGO_DB_PASSWORD" required:""` + + S3Host string `env:"S3_HOST" default:"http://minio:9000" name:"s3-host"` + S3User string `env:"S3_USER" default:"minio" name:"s3-user"` + S3Password string `env:"S3_PASSWORD" required:"" name:"s3-password"` + + EmitterIOHost string `env:"EMITTER_IO_HOST" default:"tcp://emitter:8080"` + EmitterIORKey string `env:"EMITTER_IO_KEY" required:""` + + Timeformat string `env:"TIMEFORMAT" default:"yyyy-MM-dd HH:mm:ss" help:""` + ArtifactStates []map[string]string `env:"ARTIFACT_STATES"` + InitialAPIKey string `env:"INITIAL_API_KEY"` +} + +func ParseCatalystConfig() (*catalyst.Config, error) { + var cli CLI + kong.Parse( + &cli, + kong.Configuration(kong.JSON, "/etc/catalyst.json", ".catalyst.json"), + kong.Configuration(kongyaml.Loader, "/etc/catalyst.yaml", ".catalyst.yaml"), + ) + + return MapConfig(cli) +} + +func MapConfig(cli CLI) (*catalyst.Config, error) { + roles := role.Explode(role.Analyst) + roles = append(roles, role.Explodes(cli.AuthDefaultRoles)...) + roles = role.Explodes(role.Strings(roles)) + + artifactStates, err := toTypes(cli.ArtifactStates) + if err != nil { + return nil, err + } + + if len(artifactStates) == 0 { + artifactStates = []*models.Type{ + {Icon: "mdi-help-circle-outline", ID: "unknown", Name: "Unknown", Color: pointer.String(models.TypeColorInfo)}, + {Icon: "mdi-skull", ID: "malicious", Name: "Malicious", Color: pointer.String(models.TypeColorError)}, + {Icon: "mdi-check", ID: "clean", Name: "Clean", Color: pointer.String(models.TypeColorSuccess)}, + } + } + + scopes := unique(append([]string{oidc.ScopeOpenID, "profile", "email"}, cli.OIDCScopes...)) + config := &catalyst.Config{ + IndexPath: cli.IndexPath, + DB: &database.Config{Host: cli.ArangoDBHost, User: cli.ArangoDBUser, Password: cli.ArangoDBPassword}, + Storage: &storage.Config{Host: cli.S3Host, User: cli.S3User, Password: cli.S3Password}, + Secret: []byte(cli.Secret), + ExternalAddress: cli.ExternalAddress, + Auth: &catalyst.AuthConfig{ + OIDCIssuer: cli.OIDCIssuer, + OAuth2: &oauth2.Config{ClientID: cli.OIDCClientID, ClientSecret: cli.OIDCClientSecret, RedirectURL: cli.ExternalAddress + "/callback", Scopes: scopes}, + OIDCClaimUsername: cli.OIDCClaimUsername, + OIDCClaimEmail: cli.OIDCClaimEmail, + OIDCClaimName: cli.OIDCClaimName, + AuthBlockNew: cli.AuthBlockNew, + AuthDefaultRoles: roles, + }, + Bus: &bus.Config{Host: cli.EmitterIOHost, Key: cli.EmitterIORKey, APIUrl: cli.CatalystAddress + "/api"}, + UISettings: &models.Settings{ + ArtifactStates: artifactStates, + Timeformat: cli.Timeformat, + Version: catalyst.GetVersion(), + Tier: models.SettingsTierCommunity, + }, + InitialAPIKey: cli.InitialAPIKey, + } + return config, nil +} + +func toTypes(params []map[string]string) ([]*models.Type, error) { + var types []*models.Type + for _, param := range params { + t := &models.Type{} + + icon, iconOK := param["icon"] + if iconOK { + t.Icon = icon + } + id, idOK := param["id"] + if idOK { + t.ID = id + } + name, nameOK := param["name"] + if nameOK { + t.Name = name + } + color, ok := param["color"] + if ok { + t.Color = pointer.String(color) + } + + if iconOK && idOK && nameOK { + types = append(types, t) + } else { + return nil, fmt.Errorf("incomplete type: icon, id and name need to be provided (%s)", params) + } + } + return types, nil +} + +func unique(l []string) []string { + keys := make(map[string]bool) + var list []string + for _, entry := range l { + if _, value := keys[entry]; !value { + keys[entry] = true + list = append(list, entry) + } + } + return list +} diff --git a/dag/dag.go b/dag/dag.go new file mode 100644 index 0000000..b002545 --- /dev/null +++ b/dag/dag.go @@ -0,0 +1,164 @@ +// Adapted from https://github.com/philopon/go-toposort under the MIT License +// Original License: +// +// Copyright (c) 2017 Hirotomo Moriwaki +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package dag + +import ( + "errors" + "sort" +) + +type Graph struct { + nodes []string + + outputs map[string]map[string]struct{} + + // node: number of parents + inputs map[string]int +} + +func NewGraph() *Graph { + return &Graph{ + nodes: []string{}, + inputs: make(map[string]int), + outputs: make(map[string]map[string]struct{}), + } +} + +func (g *Graph) AddNode(name string) error { + g.nodes = append(g.nodes, name) + + if _, ok := g.outputs[name]; ok { + return errors.New("duplicate detected") + } + g.outputs[name] = make(map[string]struct{}) + g.inputs[name] = 0 + return nil +} + +func (g *Graph) AddNodes(names ...string) error { + for _, name := range names { + if err := g.AddNode(name); err != nil { + return err + } + } + return nil +} + +func (g *Graph) AddEdge(from, to string) error { + m, ok := g.outputs[from] + if !ok { + return errors.New("node does not exist") + } + + m[to] = struct{}{} + g.inputs[to]++ + + return nil +} + +func (g *Graph) Toposort() ([]string, error) { + outputs := map[string]map[string]struct{}{} + for key, value := range g.outputs { + outputs[key] = map[string]struct{}{} + for k, v := range value { + outputs[key][k] = v + } + } + + L := make([]string, 0, len(g.nodes)) + S := make([]string, 0, len(g.nodes)) + + sort.Strings(g.nodes) + for _, n := range g.nodes { + if g.inputs[n] == 0 { + S = append(S, n) + } + } + + for len(S) > 0 { + var n string + n, S = S[0], S[1:] + L = append(L, n) + + ms := make([]string, len(outputs[n])) + for _, k := range keys(outputs[n]) { + m := k + // i := outputs[n][m] + // ms[i-1] = m + ms = append(ms, m) + } + + for _, m := range ms { + delete(outputs[n], m) + g.inputs[m]-- + + if g.inputs[m] == 0 { + S = append(S, m) + } + } + } + + N := 0 + for _, v := range g.inputs { + N += v + } + + if N > 0 { + return L, errors.New("cycle detected") + } + + return L, nil +} + +func keys(m map[string]struct{}) []string { + var keys []string + for k := range m { + keys = append(keys, k) + } + sort.Strings(keys) + return keys +} + +func (g *Graph) GetParents(id string) []string { + var parents []string + for node, targets := range g.outputs { + if _, ok := targets[id]; ok { + parents = append(parents, node) + } + } + sort.Strings(parents) + return parents +} + +func (g *Graph) GetRoot() (string, error) { + var roots []string + for n, parents := range g.inputs { + if parents == 0 { + roots = append(roots, n) + } + } + if len(roots) != 1 { + return "", errors.New("more than one root") + } + return roots[0], nil +} diff --git a/dag/dag_test.go b/dag/dag_test.go new file mode 100644 index 0000000..c13cd0f --- /dev/null +++ b/dag/dag_test.go @@ -0,0 +1,238 @@ +// Adapted from https://github.com/philopon/go-toposort under the MIT License +// Original License: +// +// Copyright (c) 2017 Hirotomo Moriwaki +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package dag + +import ( + "reflect" + "testing" + + "github.com/stretchr/testify/assert" +) + +func index(s []string, v string) int { + for i, s := range s { + if s == v { + return i + } + } + return -1 +} + +type Edge struct { + From string + To string +} + +func TestDuplicatedNode(t *testing.T) { + graph := NewGraph() + assert.NoError(t, graph.AddNode("a")) + assert.Error(t, graph.AddNode("a")) +} + +func TestWikipedia(t *testing.T) { + graph := NewGraph() + assert.NoError(t, graph.AddNodes("2", "3", "5", "7", "8", "9", "10", "11")) + + edges := []Edge{ + {"7", "8"}, + {"7", "11"}, + + {"5", "11"}, + + {"3", "8"}, + {"3", "10"}, + + {"11", "2"}, + {"11", "9"}, + {"11", "10"}, + + {"8", "9"}, + } + + for _, e := range edges { + assert.NoError(t, graph.AddEdge(e.From, e.To)) + } + + result, err := graph.Toposort() + if err != nil { + t.Errorf("closed path detected in no closed pathed graph") + } + + for _, e := range edges { + if i, j := index(result, e.From), index(result, e.To); i > j { + t.Errorf("dependency failed: not satisfy %v(%v) > %v(%v)", e.From, i, e.To, j) + } + } +} + +func TestCycle(t *testing.T) { + graph := NewGraph() + assert.NoError(t, graph.AddNodes("1", "2", "3")) + + assert.NoError(t, graph.AddEdge("1", "2")) + assert.NoError(t, graph.AddEdge("2", "3")) + assert.NoError(t, graph.AddEdge("3", "1")) + + _, err := graph.Toposort() + if err == nil { + t.Errorf("closed path not detected in closed pathed graph") + } +} + +func TestGraph_GetParents(t *testing.T) { + type fields struct { + nodes []string + edges map[string]string + } + type args struct { + id string + } + tests := []struct { + name string + fields fields + args args + want []string + }{ + {"parents 2", fields{nodes: []string{"1", "2", "3"}, edges: map[string]string{"1": "2", "2": "3"}}, args{id: "2"}, []string{"1"}}, + {"parents 3", fields{nodes: []string{"1", "2", "3"}, edges: map[string]string{"1": "3", "2": "3"}}, args{id: "3"}, []string{"1", "2"}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + g := NewGraph() + for _, node := range tt.fields.nodes { + assert.NoError(t, g.AddNode(node)) + } + for from, to := range tt.fields.edges { + assert.NoError(t, g.AddEdge(from, to)) + } + + if got := g.GetParents(tt.args.id); !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetParents() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestDAG_AddNode(t *testing.T) { + dag := NewGraph() + + v := "1" + assert.NoError(t, dag.AddNode(v)) + + assert.Error(t, dag.AddNode(v)) +} + +func TestDAG_AddEdge(t *testing.T) { + dag := NewGraph() + assert.NoError(t, dag.AddNode("0")) + assert.NoError(t, dag.AddNode("1")) + assert.NoError(t, dag.AddNode("2")) + assert.NoError(t, dag.AddNode("3")) + + // add a single edge and inspect the graph + assert.NoError(t, dag.AddEdge("1", "2")) + + if parents := dag.GetParents("2"); len(parents) != 1 { + t.Errorf("GetParents(v2) = %d, want 1", len(parents)) + } + + assert.NoError(t, dag.AddEdge("2", "3")) + + _ = dag.AddEdge("0", "1") +} + +func TestDAG_GetParents(t *testing.T) { + dag := NewGraph() + assert.NoError(t, dag.AddNode("1")) + assert.NoError(t, dag.AddNode("2")) + assert.NoError(t, dag.AddNode("3")) + _ = dag.AddEdge("1", "3") + _ = dag.AddEdge("2", "3") + + parents := dag.GetParents("3") + if length := len(parents); length != 2 { + t.Errorf("GetParents(v3) = %d, want 2", length) + } +} + +func TestDAG_GetDescendants(t *testing.T) { + dag := NewGraph() + assert.NoError(t, dag.AddNode("1")) + assert.NoError(t, dag.AddNode("2")) + assert.NoError(t, dag.AddNode("3")) + assert.NoError(t, dag.AddNode("4")) + + assert.NoError(t, dag.AddEdge("1", "2")) + assert.NoError(t, dag.AddEdge("2", "3")) + assert.NoError(t, dag.AddEdge("2", "4")) +} + +func TestDAG_Topsort(t *testing.T) { + dag := NewGraph() + assert.NoError(t, dag.AddNode("1")) + assert.NoError(t, dag.AddNode("2")) + assert.NoError(t, dag.AddNode("3")) + assert.NoError(t, dag.AddNode("4")) + + assert.NoError(t, dag.AddEdge("1", "2")) + assert.NoError(t, dag.AddEdge("2", "3")) + assert.NoError(t, dag.AddEdge("2", "4")) + + desc, _ := dag.Toposort() + assert.Equal(t, desc, []string{"1", "2", "3", "4"}) +} + +func TestDAG_TopsortStable(t *testing.T) { + dag := NewGraph() + assert.NoError(t, dag.AddNode("1")) + assert.NoError(t, dag.AddNode("2")) + assert.NoError(t, dag.AddNode("3")) + + assert.NoError(t, dag.AddEdge("1", "2")) + assert.NoError(t, dag.AddEdge("1", "3")) + + desc, _ := dag.Toposort() + assert.Equal(t, desc, []string{"1", "2", "3"}) +} + +func TestDAG_TopsortStable2(t *testing.T) { + dag := NewGraph() + + assert.NoError(t, dag.AddNodes("block-ioc", "block-iocs", "block-sender", "board", "fetch-iocs", "escalate", "extract-iocs", "mail-available", "search-email-gateway")) + assert.NoError(t, dag.AddEdge("block-iocs", "block-ioc")) + assert.NoError(t, dag.AddEdge("block-sender", "extract-iocs")) + assert.NoError(t, dag.AddEdge("board", "escalate")) + assert.NoError(t, dag.AddEdge("board", "mail-available")) + assert.NoError(t, dag.AddEdge("fetch-iocs", "block-iocs")) + assert.NoError(t, dag.AddEdge("extract-iocs", "fetch-iocs")) + assert.NoError(t, dag.AddEdge("mail-available", "block-sender")) + assert.NoError(t, dag.AddEdge("mail-available", "extract-iocs")) + assert.NoError(t, dag.AddEdge("mail-available", "search-email-gateway")) + assert.NoError(t, dag.AddEdge("search-email-gateway", "extract-iocs")) + + sorted, err := dag.Toposort() + assert.NoError(t, err) + + want := []string{"board", "escalate", "mail-available", "block-sender", "search-email-gateway", "extract-iocs", "fetch-iocs", "block-iocs", "block-ioc"} + assert.Equal(t, want, sorted) +} diff --git a/database/artifact.go b/database/artifact.go new file mode 100644 index 0000000..42a0679 --- /dev/null +++ b/database/artifact.go @@ -0,0 +1,101 @@ +package database + +import ( + "context" + "fmt" + "time" + + "github.com/arangodb/go-driver" + + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" +) + +func (db *Database) ArtifactGet(ctx context.Context, id int64, name string) (*models.Artifact, error) { + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketWriteFilter(ctx) + if err != nil { + return nil, err + } + + query := `LET d = DOCUMENT(@@collection, @ID) + ` + ticketFilterQuery + ` + FOR a in NOT_NULL(d.artifacts, []) + FILTER a.name == @name + RETURN a` + cursor, _, err := db.Query(ctx, query, mergeMaps(ticketFilterVars, map[string]interface{}{ + "@collection": TicketCollectionName, + "ID": fmt.Sprint(id), + "name": name, + }), busdb.ReadOperation) + if err != nil { + return nil, err + } + defer cursor.Close() + + var doc models.Artifact + _, err = cursor.ReadDocument(ctx, &doc) + if err != nil { + return nil, err + } + + return &doc, nil +} + +func (db *Database) ArtifactUpdate(ctx context.Context, id int64, name string, artifact *models.Artifact) (*models.TicketWithTickets, error) { + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketWriteFilter(ctx) + if err != nil { + return nil, err + } + + query := `LET d = DOCUMENT(@@collection, @ID) + ` + ticketFilterQuery + ` + FOR a IN NOT_NULL(d.artifacts, []) + FILTER a.name == @name + LET newartifacts = APPEND(REMOVE_VALUE(d.artifacts, a), @artifact) + UPDATE d WITH { "artifacts": newartifacts } IN @@collection + RETURN NEW` + return db.ticketGetQuery(ctx, id, query, mergeMaps(map[string]interface{}{ + "@collection": TicketCollectionName, + "ID": id, + "name": name, + "artifact": artifact, + }, ticketFilterVars), &busdb.Operation{ + OperationType: busdb.Update, + Ids: []driver.DocumentID{ + driver.DocumentID(fmt.Sprintf("%s/%d", TicketCollectionName, id)), + }, + Msg: fmt.Sprintf("Update artifact %s", name), + }) +} + +func (db *Database) EnrichArtifact(ctx context.Context, id int64, name string, enrichmentForm *models.EnrichmentForm) (*models.TicketWithTickets, error) { + enrichment := models.Enrichment{time.Now().UTC(), enrichmentForm.Data, enrichmentForm.Name} + + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketWriteFilter(ctx) + if err != nil { + return nil, err + } + + query := `LET d = DOCUMENT(@@collection, @ID) + ` + ticketFilterQuery + ` + FOR a IN d.artifacts + FILTER a.name == @name + LET enrichments = NOT_NULL(a.enrichments, {}) + LET newenrichments = MERGE(enrichments, ZIP( [@enrichmentname], [@enrichment]) ) + LET newartifacts = APPEND(REMOVE_VALUE(d.artifacts, a), MERGE(a, { "enrichments": newenrichments })) + UPDATE d WITH { "artifacts": newartifacts } IN @@collection + RETURN NEW` + return db.ticketGetQuery(ctx, id, query, mergeMaps(map[string]interface{}{ + "@collection": TicketCollectionName, + "ID": id, + "name": name, + "enrichmentname": enrichment.Name, + "enrichment": enrichment, + }, ticketFilterVars), &busdb.Operation{ + OperationType: busdb.Update, + Ids: []driver.DocumentID{ + driver.DocumentID(fmt.Sprintf("%s/%d", TicketCollectionName, id)), + }, + Msg: fmt.Sprintf("Run %s on artifact", enrichment.Name), + }) +} diff --git a/database/automation.go b/database/automation.go new file mode 100644 index 0000000..287371a --- /dev/null +++ b/database/automation.go @@ -0,0 +1,99 @@ +package database + +import ( + "context" + "errors" + + "github.com/arangodb/go-driver" + + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" +) + +func toAutomation(doc *models.AutomationForm) interface{} { + return &models.Automation{ + Image: doc.Image, + Script: doc.Script, + Schema: doc.Schema, + Type: doc.Type, + } +} + +func toAutomationResponse(id string, doc models.Automation) *models.AutomationResponse { + return &models.AutomationResponse{ + ID: id, + Image: doc.Image, + Script: doc.Script, + Schema: doc.Schema, + Type: doc.Type, + } +} + +func (db *Database) AutomationCreate(ctx context.Context, automation *models.AutomationForm) (*models.AutomationResponse, error) { + if automation == nil { + return nil, errors.New("requires automation") + } + if automation.ID == "" { + return nil, errors.New("requires automation ID") + } + + var doc models.Automation + newctx := driver.WithReturnNew(ctx, &doc) + + meta, err := db.automationCollection.CreateDocument(ctx, newctx, automation.ID, toAutomation(automation)) + if err != nil { + return nil, err + } + + return toAutomationResponse(meta.Key, doc), nil +} + +func (db *Database) AutomationGet(ctx context.Context, id string) (*models.AutomationResponse, error) { + var doc models.Automation + meta, err := db.automationCollection.ReadDocument(ctx, id, &doc) + if err != nil { + return nil, err + } + + return toAutomationResponse(meta.Key, doc), nil +} + +func (db *Database) AutomationUpdate(ctx context.Context, id string, automation *models.AutomationForm) (*models.AutomationResponse, error) { + var doc models.Automation + ctx = driver.WithReturnNew(ctx, &doc) + + meta, err := db.automationCollection.ReplaceDocument(ctx, id, toAutomation(automation)) + if err != nil { + return nil, err + } + + return toAutomationResponse(meta.Key, doc), nil +} + +func (db *Database) AutomationDelete(ctx context.Context, id string) error { + _, err := db.automationCollection.RemoveDocument(ctx, id) + return err +} + +func (db *Database) AutomationList(ctx context.Context) ([]*models.AutomationResponse, error) { + query := "FOR d IN @@collection SORT d._key ASC RETURN UNSET(d, 'script')" + cursor, _, err := db.Query(ctx, query, map[string]interface{}{"@collection": AutomationCollectionName}, busdb.ReadOperation) + if err != nil { + return nil, err + } + defer cursor.Close() + var docs []*models.AutomationResponse + for { + var doc models.Automation + meta, err := cursor.ReadDocument(ctx, &doc) + if driver.IsNoMoreDocuments(err) { + break + } else if err != nil { + return nil, err + } + + docs = append(docs, toAutomationResponse(meta.Key, doc)) + } + + return docs, err +} diff --git a/database/busdb/busdb.go b/database/busdb/busdb.go new file mode 100644 index 0000000..b9680c2 --- /dev/null +++ b/database/busdb/busdb.go @@ -0,0 +1,182 @@ +package busdb + +import ( + "context" + + "github.com/arangodb/go-driver" + + "github.com/SecurityBrewery/catalyst/bus" + "github.com/SecurityBrewery/catalyst/generated/models" +) + +type Hook interface { + PublishAction(action string, context, msg map[string]interface{}) error + PublishUpdate(col, id string) error +} + +// BusDatabase +// 1. Save entry to log +// 2. Send update ticket to bus +// 3. Add document to index +type BusDatabase struct { + internal driver.Database + logCollection driver.Collection + bus *bus.Bus + // index *index.Index +} + +func NewDatabase(ctx context.Context, internal driver.Database, b *bus.Bus) (*BusDatabase, error) { + logCollection, err := internal.Collection(ctx, LogCollectionName) + if err != nil { + return nil, err + } + + return &BusDatabase{ + internal: internal, + logCollection: logCollection, + bus: b, + }, nil +} + +type OperationType int + +const ( + Create OperationType = iota + Read = iota + Update = iota +) + +type Operation struct { + OperationType OperationType + Ids []driver.DocumentID + Msg string +} + +var CreateOperation = &Operation{OperationType: Create} +var ReadOperation = &Operation{OperationType: Read} + +func (db BusDatabase) Query(ctx context.Context, query string, vars map[string]interface{}, operation *Operation) (driver.Cursor, *models.LogEntry, error) { + cur, err := db.internal.Query(ctx, query, vars) + if err != nil { + return nil, nil, err + } + + var logs *models.LogEntry + + switch { + case operation.OperationType == Update: + if err := db.LogAndNotify(ctx, operation.Ids, operation.Msg); err != nil { + return nil, nil, err + } + } + + return cur, logs, err +} + +func (db BusDatabase) LogAndNotify(ctx context.Context, ids []driver.DocumentID, msg string) error { + var logEntries []*models.LogEntry + for _, i := range ids { + logEntries = append(logEntries, &models.LogEntry{Reference: i.String(), Message: msg}) + } + + if err := db.LogBatchCreate(ctx, logEntries); err != nil { + return err + } + + return db.bus.PublishUpdate(ids) +} + +func (db BusDatabase) Remove(ctx context.Context) error { + return db.internal.Remove(ctx) +} + +func (db BusDatabase) Collection(ctx context.Context, name string) (driver.Collection, error) { + return db.internal.Collection(ctx, name) +} + +type Collection struct { + internal driver.Collection + db *BusDatabase +} + +func NewCollection(internal driver.Collection, db *BusDatabase) *Collection { + return &Collection{internal: internal, db: db} +} + +func (c Collection) CreateDocument(ctx, newctx context.Context, key string, document interface{}) (driver.DocumentMeta, error) { + meta, err := c.internal.CreateDocument(newctx, &Keyed{Key: key, Doc: document}) + if err != nil { + return meta, err + } + + err = c.db.LogAndNotify(ctx, []driver.DocumentID{meta.ID}, "Document created") + if err != nil { + return meta, err + } + return meta, nil +} + +func (c Collection) CreateEdge(ctx, newctx context.Context, edge *driver.EdgeDocument) (driver.DocumentMeta, error) { + meta, err := c.internal.CreateDocument(newctx, edge) + if err != nil { + return meta, err + } + + err = c.db.LogAndNotify(ctx, []driver.DocumentID{meta.ID}, "Document created") + if err != nil { + return meta, err + } + return meta, nil +} + +func (c Collection) CreateEdges(ctx context.Context, edges []*driver.EdgeDocument) (driver.DocumentMetaSlice, error) { + metas, errs, err := c.internal.CreateDocuments(ctx, edges) + if err != nil { + return nil, err + } + if errs.FirstNonNil() != nil { + return nil, errs.FirstNonNil() + } + + var ids []driver.DocumentID + for _, meta := range metas { + ids = append(ids, meta.ID) + } + + err = c.db.LogAndNotify(ctx, ids, "Document created") + if err != nil { + return metas, err + } + + return metas, nil +} + +func (c Collection) DocumentExists(ctx context.Context, id string) (bool, error) { + return c.internal.DocumentExists(ctx, id) +} + +func (c Collection) ReadDocument(ctx context.Context, key string, result interface{}) (driver.DocumentMeta, error) { + return c.internal.ReadDocument(ctx, key, result) +} + +func (c Collection) UpdateDocument(ctx context.Context, key string, update interface{}) (driver.DocumentMeta, error) { + meta, err := c.internal.UpdateDocument(ctx, key, update) + if err != nil { + return meta, err + } + + return meta, c.db.bus.PublishUpdate([]driver.DocumentID{meta.ID}) +} + +func (c Collection) ReplaceDocument(ctx context.Context, key string, document interface{}) (driver.DocumentMeta, error) { + meta, err := c.internal.ReplaceDocument(ctx, key, document) + if err != nil { + return meta, err + } + + return meta, c.db.bus.PublishUpdate([]driver.DocumentID{meta.ID}) +} + +func (c Collection) RemoveDocument(ctx context.Context, formatInt string) (driver.DocumentMeta, error) { + return c.internal.RemoveDocument(ctx, formatInt) +} diff --git a/database/busdb/context.go b/database/busdb/context.go new file mode 100644 index 0000000..206487f --- /dev/null +++ b/database/busdb/context.go @@ -0,0 +1,34 @@ +package busdb + +import ( + "context" + + "github.com/gin-gonic/gin" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/role" +) + +const ( + userContextKey = "user" + groupContextKey = "groups" +) + +func SetContext(ctx *gin.Context, user *models.UserResponse) { + user.Roles = role.Strings(role.Explodes(user.Roles)) + ctx.Set(userContextKey, user) +} + +func SetGroupContext(ctx *gin.Context, groups []string) { + ctx.Set(groupContextKey, groups) +} + +func UserContext(ctx context.Context, user *models.UserResponse) context.Context { + user.Roles = role.Strings(role.Explodes(user.Roles)) + return context.WithValue(ctx, userContextKey, user) +} + +func UserFromContext(ctx context.Context) (*models.UserResponse, bool) { + u, ok := ctx.Value(userContextKey).(*models.UserResponse) + return u, ok +} diff --git a/database/busdb/keyed.go b/database/busdb/keyed.go new file mode 100644 index 0000000..8bfef39 --- /dev/null +++ b/database/busdb/keyed.go @@ -0,0 +1,25 @@ +package busdb + +import "encoding/json" + +type Keyed struct { + Key string + Doc interface{} +} + +func (p Keyed) MarshalJSON() ([]byte, error) { + b, err := json.Marshal(p.Doc) + if err != nil { + panic(err) + } + + var m map[string]interface{} + err = json.Unmarshal(b, &m) + if err != nil { + panic(err) + } + + m["_key"] = p.Key + + return json.Marshal(m) +} diff --git a/database/busdb/log.go b/database/busdb/log.go new file mode 100644 index 0000000..6fab570 --- /dev/null +++ b/database/busdb/log.go @@ -0,0 +1,92 @@ +package busdb + +import ( + "context" + "errors" + "time" + + "github.com/arangodb/go-driver" + + "github.com/SecurityBrewery/catalyst/generated/models" +) + +const LogCollectionName = "logs" + +func (db *BusDatabase) LogCreate(ctx context.Context, id, message string) (*models.LogEntry, error) { + user, ok := UserFromContext(ctx) + if !ok { + return nil, errors.New("no user in context") + } + + logentry := &models.LogEntry{ + Reference: id, + Created: time.Now(), + Creator: user.ID, + Message: message, + } + + doc := models.LogEntry{} + _, err := db.logCollection.CreateDocument(driver.WithReturnNew(ctx, &doc), logentry) + if err != nil { + return nil, err + } + + return &doc, db.bus.PublishUpdate([]driver.DocumentID{driver.DocumentID(logentry.Reference)}) +} + +func (db *BusDatabase) LogBatchCreate(ctx context.Context, logEntryForms []*models.LogEntry) error { + user, ok := UserFromContext(ctx) + if !ok { + return errors.New("no user in context") + } + + var ids []driver.DocumentID + var logentries []*models.LogEntry + for _, logEntryForm := range logEntryForms { + logentry := &models.LogEntry{ + Reference: logEntryForm.Reference, + Created: time.Now(), + Creator: user.ID, + Message: logEntryForm.Message, + } + + logentries = append(logentries, logentry) + ids = append(ids, driver.DocumentID(logentry.Reference)) + } + + _, errs, err := db.logCollection.CreateDocuments(ctx, logentries) + if err != nil { + return err + } + err = errs.FirstNonNil() + if err != nil { + return err + } + + return db.bus.PublishUpdate(ids) +} + +func (db *BusDatabase) LogList(ctx context.Context, reference string) ([]*models.LogEntry, error) { + query := "FOR d IN @@collection FILTER d.reference == @reference SORT d.created DESC RETURN d" + cursor, err := db.internal.Query(ctx, query, map[string]interface{}{ + "@collection": LogCollectionName, + "reference": reference, + }) + if err != nil { + return nil, err + } + defer cursor.Close() + var docs []*models.LogEntry + for { + var doc models.LogEntry + _, err := cursor.ReadDocument(ctx, &doc) + if driver.IsNoMoreDocuments(err) { + break + } else if err != nil { + return nil, err + } + docs = append(docs, &doc) + } + + return docs, err +} diff --git a/database/db.go b/database/db.go new file mode 100644 index 0000000..079f6c7 --- /dev/null +++ b/database/db.go @@ -0,0 +1,177 @@ +package database + +import ( + "context" + "fmt" + "log" + + "github.com/arangodb/go-driver" + "github.com/arangodb/go-driver/http" + + "github.com/SecurityBrewery/catalyst/bus" + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/database/migrations" + "github.com/SecurityBrewery/catalyst/hooks" + "github.com/SecurityBrewery/catalyst/index" +) + +const ( + Name = "catalyst" + TicketCollectionName = "tickets" + TemplateCollectionName = "templates" + PlaybookCollectionName = "playbooks" + AutomationCollectionName = "automations" + UserDataCollectionName = "userdata" + UserCollectionName = "users" + TicketTypeCollectionName = "tickettypes" + JobCollectionName = "jobs" + + TicketArtifactsGraphName = "Graph" + RelatedTicketsCollectionName = "related" +) + +type Database struct { + *busdb.BusDatabase + Index *index.Index + bus *bus.Bus + Hooks *hooks.Hooks + + templateCollection *busdb.Collection + ticketCollection *busdb.Collection + playbookCollection *busdb.Collection + automationCollection *busdb.Collection + userdataCollection *busdb.Collection + userCollection *busdb.Collection + tickettypeCollection *busdb.Collection + jobCollection *busdb.Collection + + relatedCollection *busdb.Collection + containsCollection *busdb.Collection +} + +type Config struct { + Host string + User string + Password string + Name string +} + +func New(ctx context.Context, index *index.Index, bus *bus.Bus, hooks *hooks.Hooks, config *Config) (*Database, error) { + name := config.Name + if config.Name == "" { + name = Name + } + + conn, err := http.NewConnection(http.ConnectionConfig{Endpoints: []string{config.Host}}) + if err != nil { + return nil, err + } + client, err := driver.NewClient(driver.ClientConfig{ + Connection: conn, + Authentication: driver.BasicAuthentication(config.User, config.Password), + }) + if err != nil { + return nil, err + } + + hooks.DatabaseAfterConnect(ctx, client, name) + + db, err := setupDB(ctx, client, name) + if err != nil { + return nil, fmt.Errorf("DB setup failed: %w", err) + } + + if err = migrations.PerformMigrations(ctx, db); err != nil { + return nil, fmt.Errorf("migrations failed: %w", err) + } + + ticketCollection, err := db.Collection(ctx, TicketCollectionName) + if err != nil { + return nil, err + } + templateCollection, err := db.Collection(ctx, TemplateCollectionName) + if err != nil { + return nil, err + } + playbookCollection, err := db.Collection(ctx, PlaybookCollectionName) + if err != nil { + return nil, err + } + relatedCollection, err := db.Collection(ctx, RelatedTicketsCollectionName) + if err != nil { + return nil, err + } + automationCollection, err := db.Collection(ctx, AutomationCollectionName) + if err != nil { + return nil, err + } + userdataCollection, err := db.Collection(ctx, UserDataCollectionName) + if err != nil { + return nil, err + } + userCollection, err := db.Collection(ctx, UserCollectionName) + if err != nil { + return nil, err + } + tickettypeCollection, err := db.Collection(ctx, TicketTypeCollectionName) + if err != nil { + return nil, err + } + jobCollection, err := db.Collection(ctx, JobCollectionName) + if err != nil { + return nil, err + } + + hookedDB, err := busdb.NewDatabase(ctx, db, bus) + if err != nil { + return nil, err + } + + return &Database{ + BusDatabase: hookedDB, + bus: bus, + Index: index, + Hooks: hooks, + templateCollection: busdb.NewCollection(templateCollection, hookedDB), + ticketCollection: busdb.NewCollection(ticketCollection, hookedDB), + playbookCollection: busdb.NewCollection(playbookCollection, hookedDB), + automationCollection: busdb.NewCollection(automationCollection, hookedDB), + relatedCollection: busdb.NewCollection(relatedCollection, hookedDB), + userdataCollection: busdb.NewCollection(userdataCollection, hookedDB), + userCollection: busdb.NewCollection(userCollection, hookedDB), + tickettypeCollection: busdb.NewCollection(tickettypeCollection, hookedDB), + jobCollection: busdb.NewCollection(jobCollection, hookedDB), + }, nil +} + +func setupDB(ctx context.Context, client driver.Client, dbName string) (driver.Database, error) { + databaseExists, err := client.DatabaseExists(ctx, dbName) + if err != nil { + return nil, err + } + + var db driver.Database + if !databaseExists { + db, err = client.CreateDatabase(ctx, dbName, nil) + } else { + db, err = client.Database(ctx, dbName) + } + if err != nil { + return nil, err + } + + collectionExists, err := db.CollectionExists(ctx, migrations.MigrationCollection) + if err != nil { + return nil, err + } + + if !collectionExists { + if _, err := db.CreateCollection(ctx, migrations.MigrationCollection, &driver.CreateCollectionOptions{ + KeyOptions: &driver.CollectionKeyOptions{AllowUserKeys: true}, + }); err != nil { + log.Println(err) + } + } + + return db, nil +} diff --git a/database/job.go b/database/job.go new file mode 100644 index 0000000..5143ea3 --- /dev/null +++ b/database/job.go @@ -0,0 +1,256 @@ +package database + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "strings" + + "github.com/arangodb/go-driver" + "github.com/docker/docker/client" + "github.com/xeipuuv/gojsonschema" + + "github.com/SecurityBrewery/catalyst/caql" + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" +) + +func toJob(doc *models.JobForm) *models.Job { + return &models.Job{ + Automation: doc.Automation, + Payload: doc.Payload, + Origin: doc.Origin, + Running: true, + Status: "created", + } +} + +func (db *Database) toJobResponse(ctx context.Context, key string, doc *models.Job, update bool) (*models.JobResponse, error) { + cli, err := client.NewClientWithOpts(client.FromEnv) + if err != nil { + return nil, err + } + defer cli.Close() + + status := doc.Status + + if doc.Running { + inspect, err := cli.ContainerInspect(ctx, key) + if err != nil || inspect.State == nil { + doc.Running = false + if update { + db.JobUpdate(ctx, key, doc) + } + } else if doc.Status != inspect.State.Status { + status = inspect.State.Status + doc.Status = inspect.State.Status + if update { + db.JobUpdate(ctx, key, doc) + } + } + } + + return &models.JobResponse{ + Automation: doc.Automation, + ID: key, + Log: doc.Log, + Payload: doc.Payload, + Origin: doc.Origin, + Output: doc.Output, + Status: status, + Container: doc.Container, + }, nil +} + +func (db *Database) JobCreate(ctx context.Context, id string, job *models.JobForm) (*models.JobResponse, error) { + if job == nil { + return nil, errors.New("requires job") + } + + var doc models.Job + newctx := driver.WithReturnNew(ctx, &doc) + + /* Start validation */ + j := toJob(job) + b, _ := json.Marshal(j) + + r, err := models.JobSchema.Validate(gojsonschema.NewBytesLoader(b)) + if err != nil { + return nil, err + } + + if !r.Valid() { + var errs []string + for _, e := range r.Errors() { + errs = append(errs, e.String()) + } + return nil, errors.New(strings.Join(errs, ", ")) + } + /* End validation */ + + meta, err := db.jobCollection.CreateDocument(ctx, newctx, id, j) + if err != nil { + return nil, err + } + + return db.toJobResponse(ctx, meta.Key, &doc, true) +} + +func (db *Database) JobGet(ctx context.Context, id string) (*models.JobResponse, error) { + var doc models.Job + meta, err := db.jobCollection.ReadDocument(ctx, id, &doc) + if err != nil { + return nil, err + } + + return db.toJobResponse(ctx, meta.Key, &doc, true) +} + +func (db *Database) JobUpdate(ctx context.Context, id string, job *models.Job) (*models.JobResponse, error) { + var doc models.Job + ctx = driver.WithReturnNew(ctx, &doc) + + /* Start validation */ + b, _ := json.Marshal(job) + + r, err := models.JobSchema.Validate(gojsonschema.NewBytesLoader(b)) + if err != nil { + return nil, err + } + + if !r.Valid() { + var errs []string + for _, e := range r.Errors() { + errs = append(errs, e.String()) + } + return nil, errors.New(strings.Join(errs, ", ")) + } + /* End validation */ + + meta, err := db.jobCollection.ReplaceDocument(ctx, id, job) + if err != nil { + return nil, err + } + + return db.toJobResponse(ctx, meta.Key, &doc, true) +} + +func (db *Database) JobLogAppend(ctx context.Context, id string, logLine string) error { + query := `LET d = DOCUMENT(@@collection, @ID) + UPDATE d WITH { "log": CONCAT(NOT_NULL(d.log, ""), @logline) } IN @@collection` + cur, _, err := db.Query(ctx, query, map[string]interface{}{ + "@collection": JobCollectionName, + "ID": id, + "logline": logLine, + }, &busdb.Operation{ + OperationType: busdb.Update, + Ids: []driver.DocumentID{ + driver.DocumentID(fmt.Sprintf("%s/%s", JobCollectionName, id)), + }, + Msg: fmt.Sprintf("Append logline"), + }) + if err != nil { + return err + } + defer cur.Close() + + return nil +} + +func (db *Database) JobComplete(ctx context.Context, id string, out interface{}) error { + query := `LET d = DOCUMENT(@@collection, @ID) + UPDATE d WITH { "output": @out, "status": "completed", "running": false } IN @@collection` + cur, _, err := db.Query(ctx, query, map[string]interface{}{ + "@collection": JobCollectionName, + "ID": id, + "out": out, + }, &busdb.Operation{ + OperationType: busdb.Update, + Ids: []driver.DocumentID{ + driver.DocumentID(fmt.Sprintf("%s/%s", JobCollectionName, id)), + }, + Msg: fmt.Sprintf("Set output"), + }) + if err != nil { + return err + } + defer cur.Close() + + return nil +} + +func (db *Database) JobDelete(ctx context.Context, id string) error { + _, err := db.jobCollection.RemoveDocument(ctx, id) + return err +} + +func (db *Database) JobList(ctx context.Context) ([]*models.JobResponse, error) { + query := "FOR d IN @@collection RETURN d" + cursor, _, err := db.Query(ctx, query, map[string]interface{}{"@collection": JobCollectionName}, busdb.ReadOperation) + if err != nil { + return nil, err + } + defer cursor.Close() + var docs []*models.JobResponse + for { + var doc models.Job + meta, err := cursor.ReadDocument(ctx, &doc) + if driver.IsNoMoreDocuments(err) { + break + } else if err != nil { + return nil, err + } + + job, err := db.toJobResponse(ctx, meta.Key, &doc, false) + if err != nil { + return nil, err + } + + docs = append(docs, job) + } + + return docs, err +} + +func publishJobMapping(id, automation string, contextStructs *models.Context, origin *models.Origin, payloadMapping map[string]string, db *Database) error { + msg, err := generatePayload(payloadMapping, contextStructs) + if err != nil { + return fmt.Errorf("message generation failed: %w", err) + } + + return publishJob(id, automation, contextStructs, origin, msg, db) +} + +func publishJob(id, automation string, contextStructs *models.Context, origin *models.Origin, payload map[string]interface{}, db *Database) error { + return db.bus.PublishJob(id, automation, payload, contextStructs, origin) +} + +func generatePayload(msgMapping map[string]string, contextStructs *models.Context) (map[string]interface{}, error) { + contextJson, err := json.Marshal(contextStructs) + if err != nil { + return nil, err + } + + automationContext := map[string]interface{}{} + err = json.Unmarshal(contextJson, &automationContext) + if err != nil { + return nil, err + } + + parser := caql.Parser{} + msg := map[string]interface{}{} + for arg, expr := range msgMapping { + tree, err := parser.Parse(expr) + if err != nil { + return nil, err + } + + v, err := tree.Eval(automationContext) + if err != nil { + return nil, err + } + msg[arg] = v + } + return msg, nil +} diff --git a/database/migrations/automations/comment.py b/database/migrations/automations/comment.py new file mode 100644 index 0000000..6a5c9bf --- /dev/null +++ b/database/migrations/automations/comment.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import subprocess +import sys + +subprocess.call( + [sys.executable, "-m", "pip", "install", "requests"], + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, +) + +import json +import requests + + +def run(msg): + if "ticket" in msg["context"]: + headers = {"PRIVATE-TOKEN": msg["secrets"]["catalyst_apikey"]} + url = "%s/tickets/%d/comments" % (msg["secrets"]["catalyst_apiurl"], msg["context"]["ticket"]["id"]) + data = {'message': msg["payload"]["default"], 'creator': 'automation'} + requests.post(url, json=data, headers=headers).json() + + return {"done": True} + + +print(json.dumps(run(json.loads(sys.argv[1])))) diff --git a/database/migrations/automations/hash.sha1.py b/database/migrations/automations/hash.sha1.py new file mode 100755 index 0000000..799ba06 --- /dev/null +++ b/database/migrations/automations/hash.sha1.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python + +import sys +import json +import hashlib + + +def run(msg): + sha1 = hashlib.sha1(msg['payload']['default'].encode('utf-8')) + return {"hash": sha1.hexdigest()} + + +print(json.dumps(run(json.loads(sys.argv[1])))) diff --git a/database/migrations/automations/thehive.py b/database/migrations/automations/thehive.py new file mode 100644 index 0000000..aa924d2 --- /dev/null +++ b/database/migrations/automations/thehive.py @@ -0,0 +1,630 @@ +#!/usr/bin/env python + +import subprocess +import sys +import json +from datetime import datetime +import io + +subprocess.check_call( + [sys.executable, "-m", "pip", "install", "thehive4py", "requests", "minio"], + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, +) + +defaultschema = { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Default", + "type": "object", + "required": [ + "severity", + "description", + "summary", + "tlp", + "pap" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Unknown", + "title": "Unknown", + "icon": "mdi-help" + }, + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + }, + { + "const": "Very High", + "title": "Very High", + "icon": "mdi-exclamation" + } + ] + }, + "flag": { + "title": "Flag", + "type": "boolean", + "x-cols": 6, + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "pap": { + "$id": "#root/pap", + "title": "PAP", + "type": "string", + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "tags": { + "$id": "#root/tags", + "title": "Tags", + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + }, + "resolutionStatus": { + "$id": "#root/resolutionStatus", + "title": "Resolution Status", + "type": "string", + "x-cols": 6, + "x-class": "pr-2", + }, + "endDate": { + "$id": "#root/endDate", + "title": "End Data", + "type": "string", + "format": "date-time", + "x-cols": 6, + "x-class": "pr-2", + }, + "summary": { + "$id": "#root/summary", + "title": "Summary", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } +} + +defaultalertschema = { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Default", + "type": "object", + "required": [ + "severity", + "description", + "summary", + "tlp", + "pap" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Unknown", + "title": "Unknown", + "icon": "mdi-help" + }, + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + }, + { + "const": "Very High", + "title": "Very High", + "icon": "mdi-exclamation" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "source": { + "$id": "#root/source", + "title": "Source", + "type": "string", + "x-cols": 4, + "x-class": "pr-2", + }, + "sourceRef": { + "$id": "#root/sourceRef", + "title": "Source Ref", + "type": "string", + "x-cols": 4, + "x-class": "pr-2", + }, + "type": { + "$id": "#root/type", + "title": "Type", + "type": "string", + "x-cols": 4, + "x-class": "pr-2", + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } +} + + +class schema: + def __init__(self): + self.schema = defaultschema + + def add_string(self, title): + self.schema["properties"][title] = { "type": "string", "x-cols": 6, "x-class": "pr-2" } + + def add_boolean(self, title): + self.schema["properties"][title] = { "type": "boolean", "x-cols": 6, "x-class": "pr-2" } + + def add_date(self, title): + self.schema["properties"][title] = { "type": "string", "format": "date-time", "x-cols": 6, "x-class": "pr-2" } + + def add_integer(self, title): + self.schema["properties"][title] = { "type": "integer", "x-cols": 6, "x-class": "pr-2" } + + def add_float(self, title): + self.schema["properties"][title] = { "type": "number", "x-cols": 6, "x-class": "pr-2" } + + +class alertschema: + def __init__(self): + self.schema = defaultalertschema + + +def maptime(hivetime): + if hivetime is None: + return None + return datetime.fromtimestamp(hivetime/1000).isoformat() + "Z" + + +def mapstatus(hivestatus): + if hivestatus == "Open" or hivestatus == "New": + return "open" + return "closed" + + +def maptlp(hivetlp): + if hivetlp == 0: + return "White" + if hivetlp == 1: + return "Green" + if hivetlp == 2: + return "Amber" + if hivetlp == 3: + return "Red" + return "White" + + +def mapseverity(hiveseverity): + if hiveseverity == 1: + return "Low" + if hiveseverity == 2: + return "Medium" + if hiveseverity == 3: + return "High" + if hiveseverity == 4: + return "Very High" + return "Unknown" + +# { +# "_id": "~16416", +# "id": "~16416", +# "createdBy": "jonas@thehive.local", +# "updatedBy": "jonas@thehive.local", +# "createdAt": 1638704013583, +# "updatedAt": 1638704061151, +# "_type": "case", +# "caseId": 1, +# "title": "My Test 1", +# "description": "My Testcase", +# "severity": 2, +# "startDate": 1638703980000, +# "endDate": null, +# "impactStatus": null, +# "resolutionStatus": null, +# "tags": [], +# "flag": false, +# "tlp": 2, +# "pap": 2, +# "status": "Open", +# "summary": null, +# "owner": "jonas@thehive.local", +# "customFields": {}, +# "stats": {}, +# "permissions": [ "manageShare", "manageAnalyse", "manageTask", "manageCaseTemplate", "manageCase", "manageUser", "manageProcedure", "managePage", "manageObservable", "manageTag", "manageConfig", "manageAlert", "accessTheHiveFS", "manageAction" ] +# } +def mapcase(hivecase, url, keep_ids): + + s = schema() + details = {} + for name, data in hivecase["customFields"].items(): + if "string" in data and data["string"] is not None: + s.add_string(name) + details[name] = data["string"] + if "boolean" in data and data["boolean"] is not None: + s.add_boolean(name) + details[name] = data["boolean"] + if "date" in data and data["date"] is not None: + s.add_date(name) + details[name] = maptime(data["date"]) + if "integer" in data and data["integer"] is not None: + s.add_integer(name) + details[name] = data["integer"] + if "float" in data and data["float"] is not None: + s.add_float(name) + details[name] = data["float"] + + case = {} + if keep_ids: + case["id"] = hivecase["caseId"] + + return { + "name": hivecase["title"], + "type": "incident", + "status": mapstatus(hivecase["status"]), + + "owner": hivecase["owner"], + # "write": hivecase["write"], + # "read": hivecase["read"], + + "schema": json.dumps(s.schema), + "details": { + "tlp": maptlp(hivecase["tlp"]), + "pap": maptlp(hivecase["pap"]), + "severity": mapseverity(hivecase["severity"]), + "description": hivecase["description"], + "summary": hivecase["summary"], + "tags": hivecase["tags"], + "endDate": maptime(hivecase["endDate"]), + "resolutionStatus": hivecase["resolutionStatus"], + "flag": hivecase["flag"], + } | details, + "references": [ + { "name": "TheHive #%d" % hivecase["caseId"], "href": "%s/index.html#!/case/~%s/details" % (url, hivecase["id"]) } + ], + # + # "playbooks": hivecase["playbooks"], + # + "files": [], + "comments": [], + # creator, created, message + # + "artifacts": [], + # name, type, status, enrichment + # name, data + + "created": maptime(hivecase["createdAt"]), + "modified": maptime(hivecase["updatedAt"]), + } | case + +# { +# "_id": "ce2c00f17132359cb3c50dfbb1901810", +# "_type": "alert", +# "artifacts": [], +# "createdAt": 1495012062014, +# "createdBy": "myuser", +# "date": 1495012062016, +# "description": "N/A", +# "follow": true, +# "id": "ce2c00f17132359cb3c50dfbb1901810", +# "lastSyncDate": 1495012062016, +# "severity": 2, +# "source": "instance1", +# "sourceRef": "alert-ref", +# "status": "New", +# "title": "New Alert", +# "tlp": 2, +# "type": "external", +# "user": "myuser" +# } +def mapalert(hivealert, url): + s = alertschema() + details = {} + + return { + "name": hivealert["title"], + "type": "alert", + "status": mapstatus(hivealert["status"]), + "owner": hivealert["user"], + "schema": json.dumps(s.schema), + "details": { + "tlp": maptlp(hivealert["tlp"]), + "severity": mapseverity(hivealert["severity"]), + "description": hivealert["description"], + "source": hivealert["source"], + "sourceRef": hivealert["sourceRef"], + "type": hivealert["type"], + } | details, + "references": [ + { "name": "TheHive Alerts", "href": "%s/index.html#!/alert/list" % url } + ], + "files": [], + "comments": [], + "artifacts": [], + "created": maptime(hivealert["createdAt"]), + "modified": maptime(hivealert["lastSyncDate"]), + } + +# { +# "_id": "~41152", +# "id": "~41152", +# "createdBy": "jonas@thehive.local", +# "createdAt": 1638723814523, +# "_type": "case_artifact", +# "dataType": "ip", +# "data": "2.2.2.2", +# "startDate": 1638723814523, +# "tlp": 2, +# "tags": [], +# "ioc": false, +# "sighted": false, +# "message": ".", +# "reports": {}, +# "stats": {}, +# "ignoreSimilarity": false +# } +def mapobservable(hiveobservable): + status = "unknown" + if hiveobservable["ioc"]: + status = "malicious" + return { + "name": hiveobservable["data"], + "type": hiveobservable["dataType"], + "status": status, + } + +# { +# "id": "~12296", +# "_id": "~12296", +# "createdBy": "jonas@thehive.local", +# "createdAt": 1638704029800, +# "_type": "case_task", +# "title": "Start", +# "group": "MyTaskGroup1", +# "owner": "jonas@thehive.local", +# "status": "InProgress", +# "flag": false, +# "startDate": 1638704115667, +# "order": 0 +# } +# { +# "_id": "~24656", +# "id": "~24656", +# "createdBy": "jonas@thehive.local", +# "createdAt": 1638729992590, +# "_type": "case_task_log", +# "message": "asd", +# "startDate": 1638729992590, +# "attachment": { +# "name": "Chemistry Vector.eps", +# "hashes": [ +# "adf2d4cd72f4141fe7f8eb4af035596415a29c048d3039be6449008f291258e9", +# "180f66a6d22b1f09ed198afd814f701e42440e7c", +# "b28ae347371df003b76cbb8c6199c97e" +# ], +# "size": 3421842, +# "contentType": "application/postscript", +# "id": "adf2d4cd72f4141fe7f8eb4af035596415a29c048d3039be6449008f291258e9" +# }, +# "status": "Ok", +# "owner": "jonas@thehive.local" +# } +def maptasklog(hivetask, hivetasklog): + message = "**" + hivetask["group"] + ": " + hivetask["title"] + "** (" + hivetask["status"] + ")\n\n" + message += hivetasklog["message"] + if 'attachment' in hivetasklog: + message += "\n\n*Attachment*: " + hivetasklog['attachment']["name"] + return { + "creator": hivetasklog["createdBy"], + "created": maptime(hivetasklog["createdAt"]), + "message": message, + } + + +def run(msg): + skip_files = msg["payload"]["skip_files"] + keep_ids = msg["payload"]["keep_ids"] + + from thehive4py.api import TheHiveApi + import requests + from minio import Minio + + headers = {"PRIVATE-TOKEN": msg["secrets"]["catalyst_apikey"]} + # minioclient = Minio("try.catalyst-soar.com:9000", access_key="minio", secret_key="password") + if not skip_files: + minioclient = Minio( + msg["secrets"]["minio_host"], + access_key=msg["secrets"]["minio_access_key"], + secret_key=msg["secrets"]["minio_secret_key"]) + + # url = "http://localhost:9000" + url = msg["payload"]["thehiveurl"] + # api = TheHiveApi(url, "dtUCnzY4h291GIFHJKW/Z2I2SgjTRQqo") + api = TheHiveApi(url, msg["payload"]["thehivekey"]) + + print("find alerts", file=sys.stderr) + alerts = [] + resp = api.find_alerts(query={}, sort=['-createdAt'], range='all') + resp.raise_for_status() + for alert in resp.json(): + alerts.append(mapalert(alert, url)) + + if alerts: + print("create %s alerts" % len(alerts), file=sys.stderr) + response = requests.post(msg["secrets"]["catalyst_apiurl"] + "/tickets/batch", json=alerts, headers=headers) + response.raise_for_status() + + print("find incidents", file=sys.stderr) + incidents = [] + resp = api.find_cases(query={}, sort=['-createdAt'], range='all') + resp.raise_for_status() + for case in resp.json(): + incident = mapcase(case, url, keep_ids) + for observable in api.get_case_observables(case["id"]).json(): + incident["artifacts"].append(mapobservable(observable)) + for task in api.get_case_tasks(case["id"]).json(): + for log in api.get_task_logs(task["id"]).json(): + incident["comments"].append(maptasklog(task, log)) + if 'attachment' in log and not skip_files: + incident["files"].append({ "key": log['attachment']["id"], "name": log['attachment']["name"] }) + + bucket_name = "catalyst-%d" % incident["id"] + if not minioclient.bucket_exists(bucket_name): + minioclient.make_bucket(bucket_name) + + response = api.download_attachment(log["attachment"]["id"]) + data = io.BytesIO(response.content) + + minioclient.put_object(bucket_name, log["attachment"]["id"], data, length=-1, part_size=10*1024*1024) + incidents.append(incident) + + if incidents: + if keep_ids: + print("delete incidents", file=sys.stderr) + for incident in incidents: + requests.delete(msg["secrets"]["catalyst_apiurl"] + "/tickets/%d" % incident["id"], headers=headers) + print("create %d incidents" % len(incidents), file=sys.stderr) + response = requests.post(msg["secrets"]["catalyst_apiurl"] + "/tickets/batch", json=incidents, headers=headers) + response.raise_for_status() + + return {"done": True} + + +print(json.dumps(run(json.loads(sys.argv[1])))) diff --git a/database/migrations/automations/vt.hash.py b/database/migrations/automations/vt.hash.py new file mode 100644 index 0000000..270c605 --- /dev/null +++ b/database/migrations/automations/vt.hash.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +import subprocess +import sys + +subprocess.call( + [sys.executable, "-m", "pip", "install", "requests"], + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, +) + +import json +import requests + + +def run(msg): + api_key = msg['secrets']['vt_api_key'].encode('utf-8') + resource = msg['payload']['default'].encode('utf-8') + params = {'apikey': api_key, 'resource': resource} + return requests.get("https://www.virustotal.com/vtapi/v2/file/report", params=params).json() + + +print(json.dumps(run(json.loads(sys.argv[1])))) diff --git a/database/migrations/content.go b/database/migrations/content.go new file mode 100644 index 0000000..372431b --- /dev/null +++ b/database/migrations/content.go @@ -0,0 +1,27 @@ +package migrations + +import _ "embed" + +//go:embed templates/default.json +var DefaultTemplateSchema string + +//go:embed automations/hash.sha1.py +var SHA1HashAutomation string + +//go:embed automations/vt.hash.py +var VTHashAutomation string + +//go:embed automations/thehive.py +var TheHiveAutomation string + +//go:embed automations/comment.py +var CommentAutomation string + +//go:embed playbooks/malware.yml +var MalwarePlaybook string + +//go:embed playbooks/phishing.yml +var PhishingPlaybook string + +//go:embed playbooks/simple.yaml +var SimplePlaybook string diff --git a/database/migrations/migrations.go b/database/migrations/migrations.go new file mode 100644 index 0000000..5329717 --- /dev/null +++ b/database/migrations/migrations.go @@ -0,0 +1,217 @@ +package migrations + +import ( + "context" + "fmt" + + "github.com/arangodb/go-driver" + + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/pointer" +) + +const MigrationCollection string = "migrations" + +type Migration interface { + MID() string + Migrate(ctx context.Context, driver driver.Database) error +} + +func generateMigrations() ([]Migration, error) { + // content here should never change + return []Migration{ + &createCollection{ID: "create-log-collection", Name: "logs", DataType: "log", Schema: `{"properties":{"created":{"format":"date-time","type":"string"},"creator":{"type":"string"},"message":{"type":"string"},"reference":{"type":"string"}},"required":["created","creator","message","reference"],"type":"object"}`}, + &createCollection{ID: "create-ticket-collection", Name: "tickets", DataType: "ticket", Schema: `{"properties":{"artifacts":{"items":{"properties":{"enrichments":{"additionalProperties":{"properties":{"created":{"format":"date-time","type":"string"},"data":{"example":{"hash":"b7a067a742c20d07a7456646de89bc2d408a1153"},"properties":{},"type":"object"},"name":{"example":"hash.sha1","type":"string"}},"required":["created","data","name"],"type":"object"},"type":"object"},"name":{"example":"2.2.2.2","type":"string"},"status":{"example":"Unknown","type":"string"},"type":{"type":"string"}},"required":["name"],"type":"object"},"type":"array"},"comments":{"items":{"properties":{"created":{"format":"date-time","type":"string"},"creator":{"type":"string"},"message":{"type":"string"}},"required":["created","creator","message"],"type":"object"},"type":"array"},"created":{"format":"date-time","type":"string"},"details":{"example":{"description":"my little incident"},"properties":{},"type":"object"},"files":{"items":{"properties":{"key":{"example":"myfile","type":"string"},"name":{"example":"notes.docx","type":"string"}},"required":["key","name"],"type":"object"},"type":"array"},"modified":{"format":"date-time","type":"string"},"name":{"example":"WannyCry","type":"string"},"owner":{"example":"bob","type":"string"},"playbooks":{"additionalProperties":{"properties":{"name":{"example":"Phishing","type":"string"},"tasks":{"additionalProperties":{"properties":{"automation":{"type":"string"},"closed":{"format":"date-time","type":"string"},"created":{"format":"date-time","type":"string"},"data":{"properties":{},"type":"object"},"done":{"type":"boolean"},"join":{"example":false,"type":"boolean"},"payload":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"example":"Inform user","type":"string"},"next":{"additionalProperties":{"type":"string"},"type":"object"},"owner":{"type":"string"},"schema":{"properties":{},"type":"object"},"type":{"enum":["task","input","automation"],"example":"task","type":"string"}},"required":["created","done","name","type"],"type":"object"},"type":"object"}},"required":["name","tasks"],"type":"object"},"type":"object"},"read":{"example":["bob"],"items":{"type":"string"},"type":"array"},"references":{"items":{"properties":{"href":{"example":"https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2017-0144","type":"string"},"name":{"example":"CVE-2017-0144","type":"string"}},"required":["href","name"],"type":"object"},"type":"array"},"schema":{"example":"{}","type":"string"},"status":{"example":"open","type":"string"},"type":{"example":"incident","type":"string"},"write":{"example":["alice"],"items":{"type":"string"},"type":"array"}},"required":["created","modified","name","schema","status","type"],"type":"object"}`}, + &createCollection{ID: "create-template-collection", Name: "templates", DataType: "template", Schema: `{"properties":{"name":{"type":"string"},"schema":{"type":"string"}},"required":["name","schema"],"type":"object"}`}, + &createCollection{ID: "create-playbook-collection", Name: "playbooks", DataType: "playbook", Schema: `{"properties":{"name":{"type":"string"},"yaml":{"type":"string"}},"required":["name","yaml"],"type":"object"}`}, + &createCollection{ID: "create-automation-collection", Name: "automations", DataType: "automation", Schema: `{"properties":{"image":{"type":"string"},"script":{"type":"string"}},"required":["image","script"],"type":"object"}`}, + &createCollection{ID: "create-userdata-collection", Name: "userdata", DataType: "userdata", Schema: `{"properties":{"email":{"type":"string"},"image":{"type":"string"},"name":{"type":"string"},"timeformat":{"title":"Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens)","type":"string"}},"type":"object"}`}, + &createCollection{ID: "create-tickettype-collection", Name: "tickettypes", DataType: "tickettype", Schema: `{"properties":{"default_groups":{"items":{"type":"string"},"type":"array"},"default_playbooks":{"items":{"type":"string"},"type":"array"},"default_template":{"type":"string"},"icon":{"type":"string"},"name":{"type":"string"}},"required":["default_playbooks","default_template","icon","name"],"type":"object"}`}, + &createCollection{ID: "create-user-collection", Name: "users", DataType: "user", Schema: `{"properties":{"apikey":{"type":"boolean"},"blocked":{"type":"boolean"},"roles":{"items":{"type":"string"},"type":"array"},"sha256":{"type":"string"}},"required":["apikey","blocked","roles"],"type":"object"}`}, + + &createGraph{ID: "create-ticket-graph", Name: "Graph", EdgeDefinitions: []driver.EdgeDefinition{{Collection: "related", From: []string{"tickets"}, To: []string{"tickets"}}}}, + + &createDocument{ID: "create-template-default", Collection: "templates", Document: &busdb.Keyed{Key: "default", Doc: models.TicketTemplate{Schema: DefaultTemplateSchema, Name: "Default"}}}, + &createDocument{ID: "create-automation-vt.hash", Collection: "automations", Document: &busdb.Keyed{Key: "vt.hash", Doc: models.Automation{Image: "docker.io/python:3", Script: VTHashAutomation}}}, + &createDocument{ID: "create-automation-comment", Collection: "automations", Document: &busdb.Keyed{Key: "comment", Doc: models.Automation{Image: "docker.io/python:3", Script: CommentAutomation}}}, + &createDocument{ID: "create-automation-thehive", Collection: "automations", Document: &busdb.Keyed{Key: "thehive", Doc: models.Automation{Image: "docker.io/python:3", Script: TheHiveAutomation}}}, + &createDocument{ID: "create-automation-hash.sha1", Collection: "automations", Document: &busdb.Keyed{Key: "hash.sha1", Doc: models.Automation{Image: "docker.io/python:3", Script: SHA1HashAutomation}}}, + &createDocument{ID: "create-playbook-malware", Collection: "playbooks", Document: &busdb.Keyed{Key: "malware", Doc: models.PlaybookTemplate{Name: "Malware", Yaml: MalwarePlaybook}}}, + &createDocument{ID: "create-playbook-phishing", Collection: "playbooks", Document: &busdb.Keyed{Key: "phishing", Doc: models.PlaybookTemplate{Name: "Phishing", Yaml: PhishingPlaybook}}}, + &createDocument{ID: "create-tickettype-alert", Collection: "tickettypes", Document: &busdb.Keyed{Key: "alert", Doc: models.TicketType{Name: "Alerts", Icon: "mdi-alert", DefaultTemplate: "default", DefaultPlaybooks: []string{}, DefaultGroups: nil}}}, + &createDocument{ID: "create-tickettype-incident", Collection: "tickettypes", Document: &busdb.Keyed{Key: "incident", Doc: models.TicketType{Name: "Incidents", Icon: "mdi-radioactive", DefaultTemplate: "default", DefaultPlaybooks: []string{}, DefaultGroups: nil}}}, + &createDocument{ID: "create-tickettype-investigation", Collection: "tickettypes", Document: &busdb.Keyed{Key: "investigation", Doc: models.TicketType{Name: "Forensic Investigations", Icon: "mdi-fingerprint", DefaultTemplate: "default", DefaultPlaybooks: []string{}, DefaultGroups: nil}}}, + &createDocument{ID: "create-tickettype-hunt", Collection: "tickettypes", Document: &busdb.Keyed{Key: "hunt", Doc: models.TicketType{Name: "Threat Hunting", Icon: "mdi-target", DefaultTemplate: "default", DefaultPlaybooks: []string{}, DefaultGroups: nil}}}, + + &updateSchema{ID: "update-automation-collection-1", Name: "automations", DataType: "automation", Schema: `{"properties":{"image":{"type":"string"},"script":{"type":"string"}},"required":["image","script"],"type":"object"}`}, + &updateDocument{ID: "update-automation-vt.hash-1", Collection: "automations", Key: "vt.hash", Document: models.Automation{Image: "docker.io/python:3", Script: VTHashAutomation, Schema: pointer.String(`{"title":"Input","type":"object","properties":{"default":{"type":"string","title":"Value"}},"required":["default"]}`), Type: []string{"global", "artifact", "playbook"}}}, + &updateDocument{ID: "update-automation-comment-1", Collection: "automations", Key: "comment", Document: models.Automation{Image: "docker.io/python:3", Script: CommentAutomation, Type: []string{"playbook"}}}, + &updateDocument{ID: "update-automation-thehive-1", Collection: "automations", Key: "thehive", Document: models.Automation{Image: "docker.io/python:3", Script: TheHiveAutomation, Schema: pointer.String(`{"title":"TheHive credentials","type":"object","properties":{"thehiveurl":{"type":"string","title":"TheHive URL (e.g. 'https://thehive.example.org')"},"thehivekey":{"type":"string","title":"TheHive API Key"},"skip_files":{"type":"boolean", "default": true, "title":"Skip Files (much faster)"},"keep_ids":{"type":"boolean", "default": true, "title":"Keep IDs and overwrite existing IDs"}},"required":["thehiveurl", "thehivekey", "skip_files", "keep_ids"]}`), Type: []string{"global"}}}, + &updateDocument{ID: "update-automation-hash.sha1-1", Collection: "automations", Key: "hash.sha1", Document: models.Automation{Image: "docker.io/python:3", Script: SHA1HashAutomation, Schema: pointer.String(`{"title":"Input","type":"object","properties":{"default":{"type":"string","title":"Value"}},"required":["default"]}`), Type: []string{"global", "artifact", "playbook"}}}, + + &createCollection{ID: "create-job-collection", Name: "jobs", DataType: "job", Schema: `{"properties":{"automation":{"type":"string"},"log":{"type":"string"},"payload":{},"origin":{"properties":{"artifact_origin":{"properties":{"artifact":{"type":"string"},"ticket_id":{"format":"int64","type":"integer"}},"required":["artifact","ticket_id"],"type":"object"},"task_origin":{"properties":{"playbook_id":{"type":"string"},"task_id":{"type":"string"},"ticket_id":{"format":"int64","type":"integer"}},"required":["playbook_id","task_id","ticket_id"],"type":"object"}},"type":"object"},"output":{"properties":{},"type":"object"},"running":{"type":"boolean"},"status":{"type":"string"}},"required":["automation","running","status"],"type":"object"}`}, + }, nil +} + +func loadSchema(dataType, jsonschema string) (*driver.CollectionSchemaOptions, error) { + ticketCollectionSchema := &driver.CollectionSchemaOptions{Level: driver.CollectionSchemaLevelStrict, Message: fmt.Sprintf("Validation of %s failed", dataType)} + + err := ticketCollectionSchema.LoadRule([]byte(jsonschema)) + return ticketCollectionSchema, err +} + +type migration struct { + Key string `json:"_key"` +} + +func PerformMigrations(ctx context.Context, db driver.Database) error { + collection, err := db.Collection(ctx, MigrationCollection) + if err != nil { + return err + } + + migrations, err := generateMigrations() + if err != nil { + return fmt.Errorf("could not generate migrations: %w", err) + } + + for _, m := range migrations { + migrationRan, err := collection.DocumentExists(ctx, m.MID()) + if err != nil { + return err + } + + if !migrationRan { + if err := m.Migrate(ctx, db); err != nil { + return fmt.Errorf("migration %s failed: %w", m.MID(), err) + } + + if _, err := collection.CreateDocument(ctx, &migration{Key: m.MID()}); err != nil { + return fmt.Errorf("could not save %s migration document: %w", m.MID(), err) + } + } + } + return nil +} + +type createCollection struct { + ID string + Name string + DataType string + Schema string +} + +func (m *createCollection) MID() string { + return m.ID +} + +func (m *createCollection) Migrate(ctx context.Context, db driver.Database) error { + schema, err := loadSchema(m.DataType, m.Schema) + if err != nil { + return err + } + + _, err = db.CreateCollection(ctx, m.Name, &driver.CreateCollectionOptions{ + Schema: schema, + }) + + return err +} + +type updateSchema struct { + ID string + Name string + DataType string + Schema string +} + +func (m *updateSchema) MID() string { + return m.ID +} + +func (m *updateSchema) Migrate(ctx context.Context, db driver.Database) error { + schema, err := loadSchema(m.DataType, m.Schema) + if err != nil { + return err + } + + col, err := db.Collection(ctx, m.Name) + if err != nil { + return err + } + + err = col.SetProperties(ctx, driver.SetCollectionPropertiesOptions{ + Schema: schema, + }) + + return err +} + +type createGraph struct { + ID string + Name string + EdgeDefinitions []driver.EdgeDefinition +} + +func (m *createGraph) MID() string { + return m.ID +} + +func (m *createGraph) Migrate(ctx context.Context, db driver.Database) error { + _, err := db.CreateGraph(ctx, m.Name, &driver.CreateGraphOptions{ + EdgeDefinitions: m.EdgeDefinitions, + }) + return err +} + +type createDocument struct { + ID string + Collection string + Document interface{} +} + +func (m *createDocument) MID() string { + return m.ID +} + +func (m *createDocument) Migrate(ctx context.Context, driver driver.Database) error { + collection, err := driver.Collection(ctx, m.Collection) + if err != nil { + return err + } + + _, err = collection.CreateDocument(ctx, m.Document) + return err +} + +type updateDocument struct { + ID string + Collection string + Key string + Document interface{} +} + +func (m *updateDocument) MID() string { + return m.ID +} + +func (m *updateDocument) Migrate(ctx context.Context, driver driver.Database) error { + collection, err := driver.Collection(ctx, m.Collection) + if err != nil { + return err + } + + exists, err := collection.DocumentExists(ctx, m.Key) + if err != nil { + return err + } + + if !exists { + _, err = collection.CreateDocument(ctx, m.Document) + return err + } + + _, err = collection.ReplaceDocument(ctx, m.Key, m.Document) + return err +} diff --git a/database/migrations/playbooks/malware.yml b/database/migrations/playbooks/malware.yml new file mode 100644 index 0000000..8bbb3c8 --- /dev/null +++ b/database/migrations/playbooks/malware.yml @@ -0,0 +1,63 @@ +name: Malware +tasks: + file-or-hash: + name: Do you have the file or the hash? + type: input + schema: + title: Malware + type: object + properties: + file: + type: string + title: "I have the" + enum: [ "File", "Hash" ] + next: + enter-hash: "file == 'Hash'" + upload: "file == 'File'" + + enter-hash: + name: Please enter the hash + type: input + schema: + title: Malware + type: object + properties: + hash: + type: string + title: Please enter the hash value + minlength: 32 + next: + virustotal: "hash != ''" + + upload: + name: Upload the malware + type: input + schema: + title: Malware + type: object + properties: + malware: + type: object + x-display: file + title: Please upload the malware + next: + hash: "malware" + + hash: + name: Hash the malware + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['upload'].data['malware']" + next: + virustotal: + + virustotal: + name: Send hash to VirusTotal + type: automation + automation: vt.hash + args: + hash: "playbook.tasks['enter-hash'].data['hash'] || playbook.tasks['hash'].data['hash']" + # next: + # known-malware: "score > 5" + # sandbox: "score < 6" # unknown-malware diff --git a/database/migrations/playbooks/phishing.yml b/database/migrations/playbooks/phishing.yml new file mode 100644 index 0000000..0934b95 --- /dev/null +++ b/database/migrations/playbooks/phishing.yml @@ -0,0 +1,85 @@ +name: Phishing +tasks: + board: + name: Board Involvement? + description: Is a board member involved? + type: input + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + next: + escalate: "boardInvolved == true" + mail-available: "boardInvolved == false" + + escalate: + name: Escalate to CISO + description: Please escalate the task to the CISO + type: task + + mail-available: + name: Mail available + type: input + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: 'yes' + type: string + required: + - mail + title: 'Yes' + - properties: + schemaKey: + const: 'no' + type: string + title: 'No' + title: Mail available + type: object + next: + block-sender: "schemaKey == 'yes'" + extract-iocs: "schemaKey == 'yes'" + search-email-gateway: "schemaKey == 'no'" + + search-email-gateway: + name: Search email gateway + description: Please search email-gateway for the phishing mail. + type: task + next: + extract-iocs: + + block-sender: + name: Block sender + type: task + next: + extract-iocs: + + extract-iocs: + name: Extract IOCs + description: Please insert the IOCs + type: input + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + next: + block-iocs: + + block-iocs: + name: Block IOCs + type: task diff --git a/database/migrations/playbooks/simple.yaml b/database/migrations/playbooks/simple.yaml new file mode 100644 index 0000000..5046453 --- /dev/null +++ b/database/migrations/playbooks/simple.yaml @@ -0,0 +1,37 @@ +name: Simple +tasks: + input: + name: Enter something to hash + type: input + schema: + title: Something + type: object + properties: + something: + type: string + title: Something + default: "" + next: + hash: "something != ''" + + hash: + name: Hash the something + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['input'].data['something']" + next: + comment: "hash != ''" + + comment: + name: Comment the hash + type: automation + automation: comment + payload: + default: "playbook.tasks['hash'].data['hash']" + next: + done: "done" + + done: + name: You can close this case now + type: task diff --git a/database/migrations/templates/advanced.json b/database/migrations/templates/advanced.json new file mode 100644 index 0000000..2dd7035 --- /dev/null +++ b/database/migrations/templates/advanced.json @@ -0,0 +1,208 @@ +{ + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Advanced", + "type": "object", + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + }, + + "type": { + "type": "object", + "title": "Select an incident type", + "oneOf": [ + { + "title": "Malware", + "properties": { + "schemaKey": { + "type": "string", + "const": "malware" + }, + "malware_type": { + "type": "string", + "title": "Malware Type", + "enum": ["Ransomware", "Worm", "Virus"] + } + } + }, + { + "title": "Phishing", + "properties": { + "schemaKey": { + "type": "string", + "const": "phishing" + }, + "phishing_type": { + "type": "string", + "title": "Phishing Type", + "enum": ["Normal", "Spear", "Whale"] + } + } + } + ], + "x-cols": 12 + }, + "apt": { + "type": "boolean", + "x-display": "switch", + "title": "APT involved?", + "x-cols": 6 + }, + "apt-group": { + "type": "string", + "title": "Select APT", + "enum": ["Lazarus Group", "Equation Group", "Fancy Bear (APT 28)", "OceanLotus (APT 32)", "Other"], + "x-if": "apt", + "x-cols": 6 + }, + "tactics": { + "type": "array", + "title": "MITRE Att&ck", + "description": "This description is used as a help message.", + "items": { + "type": "object", + "oneOf": [ + { + "title": "Reconnaissance", + "properties": { + "tactic": { + "type": "string", + "const": "reconnaissance", + "title": "Tactic", + "description": "The adversary is trying to gather information they can use to plan future operations." + }, + "techniques": { + "type": "array", + "title": "Techniques", + "items": { + "type": "string", + "oneOf": [ + { + "const": "T1595", + "title": "Active Scanning", + "description": "Adversaries may execute active reconnaissance scans to gather information that can be used during targeting. Active scans are those where the adversary probes victim infrastructure via network traffic, as opposed to other forms of reconnaissance that do not involve direct interaction." + }, + { + "const": "T1592", + "title": "Gather Victim Host Information" + } + ] + }, + "minItems": 1, + "uniqueItems": true + } + } + }, + { + "title": "Persistence", + "properties": { + "tactic": { + "type": "string", + "const": "persistence" + }, + "techniques": { + "type": "string", + "title": "Techniques", + "oneOf": [ + { + "const": "T1098", + "title": "Account Manipulation" + }, + { + "const": "T1197", + "title": "BITS Jobs" + } + ] + } + } + } + ] + }, + "uniqueItems": true + }, + "tags": { + "type": "array", + "title": "Tags", + "items": { + "type": "string", + "examples": [ + "misp", + "external report", + "internal report" + ] + } + } + }, + "required": ["severity", "description", "tactics", "type"] +} + diff --git a/database/migrations/templates/default.json b/database/migrations/templates/default.json new file mode 100644 index 0000000..20a186e --- /dev/null +++ b/database/migrations/templates/default.json @@ -0,0 +1,79 @@ +{ + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Default", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } +} diff --git a/database/migrations/templates/veris.json b/database/migrations/templates/veris.json new file mode 100644 index 0000000..c38f224 --- /dev/null +++ b/database/migrations/templates/veris.json @@ -0,0 +1,3644 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "properties": { + "security_incident": { + "title": "Incident confirmation", + "type": "string", + "description": "Was this a confirmed security incident?", + "enum": [ + "Confirmed", + "Suspected", + "Near miss", + "False positive" + ], + "x-cols": 6 + }, + "confidence": { + "title": "Confidence", + "type": "string", + "enum": [ + "High", + "Medium", + "Low", + "None" + ], + "x-cols": 6 + }, + "summary": { + "title": "Summary", + "type": "string", + "description": "Give a good descriptive summary of the incident in several sentences. Use natural language instead of VERIS notation, but we should be able to 'VERISize' the incident pretty well from just this description.", + "x-display": "textarea", + "x-cols": 12 + }, + "timeline": { + "title": "Timeline", + "additionalProperties": false, + "properties": { + "incident": { + "title": "Incident", + "description": "When did this incident initially occur?", + "additionalProperties": false, + "properties": { + "year": { + "title": "Year", + "type": "integer", + "maximum": 2022, + "minimum": 1950, + "x-cols": 3, + "x-class": "pr-1" + }, + "month": { + "title": "Month", + "type": "integer", + "maximum": 12, + "minimum": 1, + "x-cols": 3, + "x-class": "pr-1" + }, + "day": { + "title": "Day", + "type": "integer", + "maximum": 31, + "minimum": 1, + "x-cols": 3, + "x-class": "pr-1" + }, + "time": { + "title": "Time", + "description": "Use the format '05:45:00 PM'", + "type": "string", + "pattern": "^0[1-9]|1[0-2]:[0-5][0-9]:[0-5][0-9] [AP]M$", + "x-cols": 3 + } + }, + "required": [ + "year" + ], + "type": "object" + }, + "compromise": { + "title": "Compromise", + "description": "How long from the first action to the first compromise of an attribute?", + "additionalProperties": false, + "properties": { + "unit": { + "title": "Unit", + "x-cols": 6, + "type": "string", + "enum": [ + "Seconds", + "Minutes", + "Hours", + "Days", + "Weeks", + "Months", + "Years", + "Never", + "NA", + "Unknown" + ], + "x-class": "pr-2" + }, + "value": { + "title": "Value", + "x-cols": 6, + "type": "number" + } + }, + "required": [ + "unit" + ], + "type": "object" + }, + "exfiltration": { + "title": "Exfiltration", + "description": "How long from initial compromise to first known data exfiltration?", + "additionalProperties": false, + "properties": { + "unit": { + "title": "Unit", + "x-cols": 6, + "type": "string", + "enum": [ + "Seconds", + "Minutes", + "Hours", + "Days", + "Weeks", + "Months", + "Years", + "Never", + "NA", + "Unknown" + ], + "x-class": "pr-2" + }, + "value": { + "title": "Value", + "x-cols": 6, + "type": "number" + } + }, + "required": [ + "unit" + ], + "type": "object" + }, + "discovery": { + "title": "Discovery", + "description": "How long from compromise until the incident was discovered by the victim organization?", + "additionalProperties": false, + "properties": { + "unit": { + "title": "Unit", + "x-cols": 6, + "type": "string", + "enum": [ + "Seconds", + "Minutes", + "Hours", + "Days", + "Weeks", + "Months", + "Years", + "Never", + "NA", + "Unknown" + ], + "x-class": "pr-2" + }, + "value": { + "title": "Value", + "x-cols": 6, + "type": "number" + } + }, + "required": [ + "unit" + ], + "type": "object" + }, + "containment": { + "title": "Containment", + "description": "How long did it take the organization to contain the incident once it was discovered?", + "additionalProperties": false, + "properties": { + "unit": { + "title": "Unit", + "x-cols": 6, + "type": "string", + "enum": [ + "Seconds", + "Minutes", + "Hours", + "Days", + "Weeks", + "Months", + "Years", + "Never", + "NA", + "Unknown" + ], + "x-class": "pr-2" + }, + "value": { + "title": "Value", + "x-cols": 6, + "type": "number" + } + }, + "required": [ + "unit" + ], + "type": "object" + } + }, + "required": [ + "incident" + ], + "type": "object" + }, + "victim": { + "title": "Victim", + "description": "[More Info](http://veriscommunity.net/victim-demo.html)", + "additionalProperties": false, + "properties": { + "employee_count": { + "title": "Employee Count", + "description": "Number of employees. Only use the count of the individual instance of a business (e.g. franchise location vs entire company) if the action vector was explicitly something unique to this individual instance. (i.e. This franchisee used a non-standard POS system that was then compromised.)", + "type": "string", + "enum": [ + "Small", + "1 to 10", + "11 to 100", + "101 to 1000", + "Large", + "1001 to 10000", + "10001 to 25000", + "25001 to 50000", + "50001 to 100000", + "Over 100000", + "Unknown" + ], + "x-cols": 4 + }, + "industry": { + "title": "Industry", + "description": "Victim NAICS Code. You can look it up [here](http://www.farsmarterbids.com/reference/naics-list.php) or [here](http://www.naics.com/search).", + "maxLength": 6, + "minLength": 2, + "pattern": "(00|11|2[1-3]|3[1-3]|4[24589]|5[1-6]|6[1-2]|7[12]|81|92)-?\\d{0,4}", + "type": "string", + "x-cols": 4 + }, + "government": { + "title": "Government", + "description": "The level of government if industry starts with 92. Otherwise 'NA'", + "items": { + "type": "string", + "default": "NA", + "enum": [ + "Federal", + "Regional", + "Local", + "Unknown", + "Other", + "NA" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 4 + }, + "locations_affected": { + "title": "Location affected", + "description": "The number of victim locations, (stores, offices, etc), affected", + "type": "integer", + "x-cols": 3 + }, + "country": { + "title": "Country", + "description": "Victim country of operation", + "items": { + "type": "string", + "default": "Unknown", + "enum": [ + "Unknown", + "AD", + "AE", + "AF", + "AG", + "AI", + "AL", + "AM", + "AO", + "AQ", + "AR", + "AS", + "AT", + "AU", + "AW", + "AX", + "AZ", + "BA", + "BB", + "BD", + "BE", + "BF", + "BG", + "BH", + "BI", + "BJ", + "BL", + "BM", + "BN", + "BO", + "BQ", + "BR", + "BS", + "BT", + "BV", + "BW", + "BY", + "BZ", + "CA", + "CC", + "CD", + "CF", + "CG", + "CH", + "CI", + "CK", + "CL", + "CM", + "CN", + "CO", + "CR", + "CU", + "CV", + "CW", + "CX", + "CY", + "CZ", + "DE", + "DJ", + "DK", + "DM", + "DO", + "DZ", + "EC", + "EE", + "EG", + "EH", + "ER", + "ES", + "ET", + "FI", + "FJ", + "FK", + "FM", + "FO", + "FR", + "GA", + "GB", + "GD", + "GE", + "GF", + "GG", + "GH", + "GI", + "GL", + "GM", + "GN", + "GP", + "GQ", + "GR", + "GS", + "GT", + "GU", + "GW", + "GY", + "HK", + "HM", + "HN", + "HR", + "HT", + "HU", + "ID", + "IE", + "IL", + "IM", + "IN", + "IO", + "IQ", + "IR", + "IS", + "IT", + "JE", + "JM", + "JO", + "JP", + "KE", + "KG", + "KH", + "KI", + "KM", + "KN", + "KP", + "KR", + "KW", + "KY", + "KZ", + "LA", + "LB", + "LC", + "LI", + "LK", + "LR", + "LS", + "LT", + "LU", + "LV", + "LY", + "MA", + "MC", + "MD", + "ME", + "MF", + "MG", + "MH", + "MK", + "ML", + "MM", + "MN", + "MO", + "MP", + "MQ", + "MR", + "MS", + "MT", + "MU", + "MV", + "MW", + "MX", + "MY", + "MZ", + "NA", + "NC", + "NE", + "NF", + "NG", + "NI", + "NL", + "NO", + "NP", + "NR", + "NU", + "NZ", + "OM", + "PA", + "PE", + "PF", + "PG", + "PH", + "PK", + "PL", + "PM", + "PN", + "PR", + "PS", + "PT", + "PW", + "PY", + "QA", + "RE", + "RO", + "RS", + "RU", + "RW", + "SA", + "SB", + "SC", + "SD", + "SE", + "SG", + "SH", + "SI", + "SJ", + "SK", + "SL", + "SM", + "SN", + "SO", + "SR", + "SS", + "ST", + "SV", + "SX", + "SY", + "SZ", + "TC", + "TD", + "TF", + "TG", + "TH", + "TJ", + "TK", + "TL", + "TM", + "TN", + "TO", + "TR", + "TT", + "TV", + "TW", + "TZ", + "UA", + "UG", + "UM", + "US", + "UY", + "UZ", + "VA", + "VC", + "VE", + "VG", + "VI", + "VN", + "VU", + "WF", + "WS", + "YE", + "YT", + "ZA", + "ZM", + "ZW", + "XK", + "Other" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 3 + }, + "region": { + "title": "Region", + "description": "The [UN M.49](https://en.wikipedia.org/wiki/UN_M.49) super-region and sub-region joined together. e.g. North America: 019021. South America (Brazil): 019005, Asia: 142000, East Asia (includes China): 142030, West Asia (Middle East): 142145, South Asia (India): 142034, Eastern Europe: 150151, Western Europe: 150155. Use 000000 if you do not know and 000001 for 'other' (includes international waters and outer space). If you only know the super-region, use zero's for the region. (e.g. 019000 for Americas.)", + "items": { + "type": "string", + "maxLength": 6, + "minLength": 6, + "pattern": "\\d{6}" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 3 + }, + "state": { + "title": "State", + "description": "ALL CAPS. For US states, you can use the [ISO_3166-2 2-character state code](https://en.wikipedia.org/wiki/ISO_3166-2:US), otherwise use the full [ISO_3166-2 Country subdivision code](https://en.wikipedia.org/wiki/ISO_3166-2)", + "type": "string", + "x-cols": 3 + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + } + }, + "required": [ + "country", + "employee_count", + "industry", + "government" + ], + "type": "object" + }, + "action": { + "title": "Action", + "description": "What threat actions were involved? [More Info](http://veriscommunity.net/actions.html)", + "oneOf": [ + { + "title": "Hacking", + "description": "Think things a person does at a keyboard (rather than by a program). [More Info](http://veriscommunity.net/actions.html#section-hacking)", + "additionalProperties": false, + "properties": { + "schemaKey": { + "type": "string", + "const": "subSchema1" + }, + "variety": { + "title": "Variety", + "items": { + "type": "string", + "enum": [ + "Abuse of functionality", + "Brute force", + "Buffer overflow", + "Cache poisoning", + "Cryptanalysis", + "CSRF", + "DoS", + "Exploit misconfig", + "Exploit vuln", + "Footprinting", + "Forced browsing", + "Format string attack", + "Fuzz testing", + "HTTP request smuggling", + "HTTP request splitting", + "HTTP response smuggling", + "HTTP Response Splitting", + "Insecure deserialization", + "Integer overflows", + "LDAP injection", + "Mail command injection", + "MitM", + "Null byte injection", + "Offline cracking", + "OS commanding", + "Pass-the-hash", + "Path traversal", + "Reverse engineering", + "RFI", + "Routing detour", + "Session fixation", + "Session prediction", + "Session replay", + "Soap array abuse", + "Special element injection", + "SQLi", + "SSI injection", + "URL redirector abuse", + "Use of backdoor or C2", + "Use of stolen creds", + "User breakout", + "Virtual machine escape", + "XML attribute blowup", + "XML entity expansion", + "XML external entities", + "XML injection", + "XPath injection", + "XQuery injection", + "XSS", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 6 + }, + "vector": { + "title": "Vector", + "items": { + "type": "string", + "enum": [ + "3rd party desktop", + "Backdoor or C2", + "Command shell", + "Desktop sharing", + "Desktop sharing software", + "Hypervisor", + "Inter-tenant", + "Other", + "Partner", + "Physical access", + "VPN", + "Web application", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 6 + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + }, + "result": { + "title": "Result", + "description": "The result of the action. If there's a difference between action result and actor intent, use the result not intent.", + "items": { + "type": "string", + "enum": [ + "Infiltrate", + "Exfiltrate", + "Elevate", + "Lateral movement", + "Deploy payload", + "Other", + "Unknown", + "NA" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "cve": { + "title": "CVE", + "description": "CVE(s) exploited through hacking", + "type": "string" + } + }, + "required": [ + "vector", + "variety" + ], + "type": "object" + }, + { + "title": "Malware", + "description": "Think things a program does (rather than a person on a keyboard) [More Info](http://veriscommunity.net/actions.html#section-malware)", + "additionalProperties": false, + "properties": { + "schemaKey": { + "type": "string", + "const": "subSchema2" + }, + "variety": { + "title": "Variety", + "items": { + "type": "string", + "enum": [ + "Adminware", + "Adware", + "Backdoor", + "Brute force", + "C2", + "Capture app data", + "Capture stored data", + "Click fraud", + "Click fraud and cryptocurrency mining", + "Client-side attack", + "Cryptocurrency mining", + "Destroy data", + "In-memory", + "Modify data", + "Disable controls", + "DoS", + "Downloader", + "Exploit misconfig", + "Exploit vuln", + "Export data", + "Packet sniffer", + "Password dumper", + "RAM scraper", + "Ransomware", + "RAT", + "Rootkit", + "Scan network", + "Spam", + "Spyware/Keylogger", + "SQL injection", + "Trojan", + "Worm", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 6 + }, + "vector": { + "title": "Vector", + "items": { + "type": "string", + "enum": [ + "Direct install", + "Download by malware", + "Email", + "Email attachment", + "Email autoexecute", + "Email link", + "Email unknown", + "Email other", + "Instant messaging", + "Network propagation", + "Remote injection", + "Removable media", + "Software update", + "Web application", + "Web application - download", + "Web application - drive-by", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 6 + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + }, + "result": { + "title": "Result", + "description": "The result of the action. If there's a difference between action result and actor intent, use the result not intent.", + "items": { + "type": "string", + "enum": [ + "Infiltrate", + "Exfiltrate", + "Elevate", + "Lateral movement", + "Deploy payload", + "Other", + "Unknown", + "NA" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "name": { + "title": "Name", + "description": "Common name(s) or strain(s) of malware", + "type": "string", + "x-cols": 6 + }, + "cve": { + "title": "CVE", + "description": "CVE(s) exploited by this malware", + "type": "string", + "x-cols": 6 + } + }, + "required": [ + "vector", + "variety" + ], + "type": "object" + }, + { + "title": "Social", + "description": "Actions done to a person. [More Info](http://veriscommunity.net/actions.html#section-social)", + "additionalProperties": false, + "properties": { + "schemaKey": { + "type": "string", + "const": "subSchema3" + }, + "variety": { + "title": "Variety", + "description": "Varities of social tactics", + "items": { + "type": "string", + "enum": [ + "Baiting", + "Bribery", + "Elicitation", + "Extortion", + "Forgery", + "Influence", + "Phishing", + "Pretexting", + "Propaganda", + "Scam", + "Spam", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 4 + }, + "vector": { + "title": "Vector", + "description": "Vectors of communication", + "items": { + "type": "string", + "enum": [ + "Documents", + "Email", + "IM", + "In-person", + "Phone", + "Removable media", + "SMS", + "Social media", + "Software", + "Website", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 4 + }, + "target": { + "title": "Target", + "description": "Target of social tactics", + "items": { + "type": "string", + "enum": [ + "Auditor", + "Call center", + "Cashier", + "Customer", + "Developer", + "End-user", + "End-user or employee", + "Executive", + "Finance", + "Former employee", + "Guard", + "Helpdesk", + "Human resources", + "Maintenance", + "Manager", + "Other employee", + "Partner", + "System admin", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 4 + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + }, + "result": { + "title": "Result", + "description": "The result of the action. If there's a difference between action result and actor intent, use the result not intent.", + "items": { + "type": "string", + "enum": [ + "Infiltrate", + "Exfiltrate", + "Elevate", + "Lateral movement", + "Deploy payload", + "Other", + "Unknown", + "NA" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + } + }, + "required": [ + "vector", + "variety", + "target" + ], + "type": "object" + }, + { + "title": "Error", + "description": "Unintentional actions. [More Info](http://veriscommunity.net/actions.html#section-error)", + "additionalProperties": false, + "properties": { + "schemaKey": { + "type": "string", + "const": "subSchema4" + }, + "variety": { + "title": "Variety", + "items": { + "type": "string", + "enum": [ + "Capacity shortage", + "Classification error", + "Data entry error", + "Disposal error", + "Gaffe", + "Loss", + "Maintenance error", + "Malfunction", + "Misconfiguration", + "Misdelivery", + "Misinformation", + "Omission", + "Physical accidents", + "Programming error", + "Publishing error", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 6 + }, + "vector": { + "title": "Vector", + "description": "Reasons errors occurred", + "items": { + "type": "string", + "enum": [ + "Carelessness", + "Inadequate personnel", + "Inadequate processes", + "Inadequate technology", + "Other", + "Random error", + "Web application", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 6 + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + } + }, + "required": [ + "variety", + "vector" + ], + "type": "object" + }, + { + "title": "Misuse", + "description": "Unapproved use of legitimate access or permissions. [More Info](http://veriscommunity.net/actions.html#section-misuse)", + "additionalProperties": false, + "properties": { + "schemaKey": { + "type": "string", + "const": "subSchema5" + }, + "variety": { + "title": "Variety", + "items": { + "type": "string", + "enum": [ + "Data mishandling", + "Email misuse", + "Illicit content", + "Knowledge abuse", + "Net misuse", + "Possession abuse", + "Privilege abuse", + "Snap picture", + "Unapproved hardware", + "Unapproved software", + "Unapproved workaround", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 6 + }, + "vector": { + "title": "Vector", + "description": "Vectors or access methods", + "items": { + "type": "string", + "enum": [ + "LAN access", + "Non-corporate", + "Physical access", + "Remote access", + "Web application", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 6 + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + }, + "result": { + "title": "Result", + "description": "The result of the action. If there's a difference between action result and actor intent, use the result not intent.", + "items": { + "type": "string", + "enum": [ + "Infiltrate", + "Exfiltrate", + "Elevate", + "Lateral movement", + "Deploy payload", + "Other", + "Unknown", + "NA" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + } + }, + "required": [ + "vector", + "variety" + ], + "type": "object" + }, + { + "title": "Physical", + "description": "Actions involving proximity and physical contact. [More Info](http://veriscommunity.net/actions.html#section-physical)", + "additionalProperties": false, + "properties": { + "schemaKey": { + "type": "string", + "const": "subSchema6" + }, + "variety": { + "title": "Variety", + "items": { + "type": "string", + "enum": [ + "Assault", + "Bypassed controls", + "Connection", + "Destruction", + "Disabled controls", + "Skimmer", + "Snooping", + "Surveillance", + "Tampering", + "Theft", + "Wiretapping", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 6 + }, + "vector": { + "title": "Vector", + "description": "Vector of physical access", + "items": { + "type": "string", + "enum": [ + "Partner facility", + "Partner vehicle", + "Personal residence", + "Personal vehicle", + "Public facility", + "Public vehicle", + "Victim grounds", + "Victim public area", + "Victim secure area", + "Victim work area", + "Unknown", + "Other" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 6 + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + }, + "result": { + "title": "Result", + "description": "The result of the action. If there's a difference between action result and actor intent, use the result not intent.", + "items": { + "type": "string", + "enum": [ + "Infiltrate", + "Exfiltrate", + "Elevate", + "Lateral movement", + "Deploy payload", + "Other", + "Unknown", + "NA" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + } + }, + "required": [ + "vector", + "variety" + ], + "type": "object" + }, + { + "title": "Environmental", + "description": "Forces of nature. Cannot include intentional actions. [More Info](http://veriscommunity.net/actions.html#section-environmental)", + "additionalProperties": false, + "properties": { + "schemaKey": { + "type": "string", + "const": "subSchema7" + }, + "variety": { + "title": "Variety", + "description": "Varieties of environmental events", + "items": { + "type": "string", + "enum": [ + "Deterioration", + "Earthquake", + "EMI", + "ESD", + "Fire", + "Flood", + "Hazmat", + "Humidity", + "Hurricane", + "Ice", + "Landslide", + "Leak", + "Lightning", + "Meteorite", + "Particulates", + "Pathogen", + "Power failure", + "Temperature", + "Tornado", + "Tsunami", + "Vermin", + "Volcano", + "Wind", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + } + }, + "required": [ + "variety" + ], + "type": "object" + }, + { + "title": "Unknown", + "description": "The action taken was unknown", + "properties": { + "schemaKey": { + "type": "string", + "const": "subSchema8" + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + }, + "result": { + "title": "Result", + "description": "The result of the action. If there's a difference between action result and actor intent, use the result not intent.", + "items": { + "type": "string", + "enum": [ + "Infiltrate", + "Exfiltrate", + "Elevate", + "Lateral movement", + "Deploy payload", + "Other", + "Unknown", + "NA" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + } + }, + "type": "object" + } + ], + "type": "object" + }, + "actor": { + "title": "Actor", + "description": "What entity did the threat action? [More Info](http://veriscommunity.net/actors.html)", + "oneOf": [ + { + "title": "External", + "description": "Unaffiliated with the victim. [More Info](http://veriscommunity.net/actors.html#section-external)", + "additionalProperties": false, + "properties": { + "schemaKey": { + "type": "string", + "const": "subSchema1" + }, + "variety": { + "title": "Variety", + "items": { + "type": "string", + "enum": [ + "Acquaintance", + "Activist", + "Auditor", + "Competitor", + "Customer", + "Force majeure", + "Former employee", + "Nation-state", + "Organized crime", + "State-affiliated", + "Terrorist", + "Unaffiliated", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 6 + }, + "motive": { + "title": "Motive", + "items": { + "type": "string", + "enum": [ + "Convenience", + "Espionage", + "Fear", + "Financial", + "Fun", + "Grudge", + "Ideology", + "NA", + "Secondary", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 6 + }, + "notes": { + "title": "Notes", + "description": "Misc external actor notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + }, + "country": { + "title": "Country", + "items": { + "type": "string", + "enum": [ + "Unknown", + "AD", + "AE", + "AF", + "AG", + "AI", + "AL", + "AM", + "AO", + "AQ", + "AR", + "AS", + "AT", + "AU", + "AW", + "AX", + "AZ", + "BA", + "BB", + "BD", + "BE", + "BF", + "BG", + "BH", + "BI", + "BJ", + "BL", + "BM", + "BN", + "BO", + "BQ", + "BR", + "BS", + "BT", + "BV", + "BW", + "BY", + "BZ", + "CA", + "CC", + "CD", + "CF", + "CG", + "CH", + "CI", + "CK", + "CL", + "CM", + "CN", + "CO", + "CR", + "CU", + "CV", + "CW", + "CX", + "CY", + "CZ", + "DE", + "DJ", + "DK", + "DM", + "DO", + "DZ", + "EC", + "EE", + "EG", + "EH", + "ER", + "ES", + "ET", + "FI", + "FJ", + "FK", + "FM", + "FO", + "FR", + "GA", + "GB", + "GD", + "GE", + "GF", + "GG", + "GH", + "GI", + "GL", + "GM", + "GN", + "GP", + "GQ", + "GR", + "GS", + "GT", + "GU", + "GW", + "GY", + "HK", + "HM", + "HN", + "HR", + "HT", + "HU", + "ID", + "IE", + "IL", + "IM", + "IN", + "IO", + "IQ", + "IR", + "IS", + "IT", + "JE", + "JM", + "JO", + "JP", + "KE", + "KG", + "KH", + "KI", + "KM", + "KN", + "KP", + "KR", + "KW", + "KY", + "KZ", + "LA", + "LB", + "LC", + "LI", + "LK", + "LR", + "LS", + "LT", + "LU", + "LV", + "LY", + "MA", + "MC", + "MD", + "ME", + "MF", + "MG", + "MH", + "MK", + "ML", + "MM", + "MN", + "MO", + "MP", + "MQ", + "MR", + "MS", + "MT", + "MU", + "MV", + "MW", + "MX", + "MY", + "MZ", + "NA", + "NC", + "NE", + "NF", + "NG", + "NI", + "NL", + "NO", + "NP", + "NR", + "NU", + "NZ", + "OM", + "PA", + "PE", + "PF", + "PG", + "PH", + "PK", + "PL", + "PM", + "PN", + "PR", + "PS", + "PT", + "PW", + "PY", + "QA", + "RE", + "RO", + "RS", + "RU", + "RW", + "SA", + "SB", + "SC", + "SD", + "SE", + "SG", + "SH", + "SI", + "SJ", + "SK", + "SL", + "SM", + "SN", + "SO", + "SR", + "SS", + "ST", + "SV", + "SX", + "SY", + "SZ", + "TC", + "TD", + "TF", + "TG", + "TH", + "TJ", + "TK", + "TL", + "TM", + "TN", + "TO", + "TR", + "TT", + "TV", + "TW", + "TZ", + "UA", + "UG", + "UM", + "US", + "UY", + "UZ", + "VA", + "VC", + "VE", + "VG", + "VI", + "VN", + "VU", + "WF", + "WS", + "YE", + "YT", + "ZA", + "ZM", + "ZW", + "XK", + "Other" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "region": { + "title": "Region", + "description": "The [UN M.49](https://en.wikipedia.org/wiki/UN_M.49) super-region and sub-region joined together. e.g. North America: 019021. South America (Brazil): 019005, Asia: 142000, East Asia (includes China): 142030, West Asia (Middle East): 142145, South Asia (India): 142034, Eastern Europe: 150151, Western Europe: 150155. Use 000000 if you do not know and 000001 for 'other' (includes international waters and outer space). If you only know the super-region, use zero's for the region. (e.g. 019000 for Americas.)", + "items": { + "type": "string", + "maxLength": 6, + "minLength": 6, + "pattern": "\\d{6}" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "name": { + "title": "Name", + "description": "Actor name (if known). e.g. 'lizard squad'", + "items": { + "type": "string" + }, + "type": "array", + "uniqueItems": true + } + }, + "required": [ + "variety", + "motive" + ], + "type": "object" + }, + { + "title": "Interal", + "description": "The victim or a part thereof (such as an employee). [More Info](http://veriscommunity.net/actors.html#section-internal)", + "additionalProperties": false, + "properties": { + "schemaKey": { + "type": "string", + "const": "subSchema2" + }, + "variety": { + "title": "Variety", + "items": { + "type": "string", + "enum": [ + "Auditor", + "Call center", + "Cashier", + "Developer", + "End-user", + "Executive", + "Finance", + "Guard", + "Helpdesk", + "Human resources", + "Maintenance", + "Manager", + "System admin", + "Doctor or nurse", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 4 + }, + "motive": { + "title": "Motive", + "items": { + "type": "string", + "enum": [ + "Convenience", + "Espionage", + "Fear", + "Financial", + "Fun", + "Grudge", + "Ideology", + "Secondary", + "NA", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 4 + }, + "job_change": { + "title": "Job Change", + "description": "Recent job change PRIOR to incident? (i.e., not asking if 'let go' afterwards)", + "items": { + "type": "string", + "enum": [ + "Demoted", + "Hired", + "Job eval", + "Lateral move", + "Let go", + "Passed over", + "Personal issues", + "Promoted", + "Reprimanded", + "Resigned", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 4 + }, + "notes": { + "title": "Notes", + "description": "Misc internal actor notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + } + }, + "required": [ + "motive", + "variety" + ], + "type": "object" + }, + { + "title": "Partner", + "description": "An entity with an organizational relationship to the victim, but not the victim. [More Info](http://veriscommunity.net/actors.html#section-partner)", + "additionalProperties": false, + "properties": { + "schemaKey": { + "type": "string", + "const": "subSchema3" + }, + "motive": { + "title": "Motive", + "items": { + "type": "string", + "enum": [ + "Convenience", + "Espionage", + "Fear", + "Financial", + "Fun", + "Grudge", + "Ideology", + "Secondary", + "NA", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "notes": { + "title": "Notes", + "description": "Misc partner actor notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + }, + "industry": { + "title": "Industry", + "maxLength": 6, + "minLength": 2, + "pattern": "\\d{2}-?\\d{0,4}", + "type": "string", + "x-cols": 4 + }, + "country": { + "title": "Country", + "items": { + "type": "string", + "enum": [ + "Unknown", + "AD", + "AE", + "AF", + "AG", + "AI", + "AL", + "AM", + "AO", + "AQ", + "AR", + "AS", + "AT", + "AU", + "AW", + "AX", + "AZ", + "BA", + "BB", + "BD", + "BE", + "BF", + "BG", + "BH", + "BI", + "BJ", + "BL", + "BM", + "BN", + "BO", + "BQ", + "BR", + "BS", + "BT", + "BV", + "BW", + "BY", + "BZ", + "CA", + "CC", + "CD", + "CF", + "CG", + "CH", + "CI", + "CK", + "CL", + "CM", + "CN", + "CO", + "CR", + "CU", + "CV", + "CW", + "CX", + "CY", + "CZ", + "DE", + "DJ", + "DK", + "DM", + "DO", + "DZ", + "EC", + "EE", + "EG", + "EH", + "ER", + "ES", + "ET", + "FI", + "FJ", + "FK", + "FM", + "FO", + "FR", + "GA", + "GB", + "GD", + "GE", + "GF", + "GG", + "GH", + "GI", + "GL", + "GM", + "GN", + "GP", + "GQ", + "GR", + "GS", + "GT", + "GU", + "GW", + "GY", + "HK", + "HM", + "HN", + "HR", + "HT", + "HU", + "ID", + "IE", + "IL", + "IM", + "IN", + "IO", + "IQ", + "IR", + "IS", + "IT", + "JE", + "JM", + "JO", + "JP", + "KE", + "KG", + "KH", + "KI", + "KM", + "KN", + "KP", + "KR", + "KW", + "KY", + "KZ", + "LA", + "LB", + "LC", + "LI", + "LK", + "LR", + "LS", + "LT", + "LU", + "LV", + "LY", + "MA", + "MC", + "MD", + "ME", + "MF", + "MG", + "MH", + "MK", + "ML", + "MM", + "MN", + "MO", + "MP", + "MQ", + "MR", + "MS", + "MT", + "MU", + "MV", + "MW", + "MX", + "MY", + "MZ", + "NA", + "NC", + "NE", + "NF", + "NG", + "NI", + "NL", + "NO", + "NP", + "NR", + "NU", + "NZ", + "OM", + "PA", + "PE", + "PF", + "PG", + "PH", + "PK", + "PL", + "PM", + "PN", + "PR", + "PS", + "PT", + "PW", + "PY", + "QA", + "RE", + "RO", + "RS", + "RU", + "RW", + "SA", + "SB", + "SC", + "SD", + "SE", + "SG", + "SH", + "SI", + "SJ", + "SK", + "SL", + "SM", + "SN", + "SO", + "SR", + "SS", + "ST", + "SV", + "SX", + "SY", + "SZ", + "TC", + "TD", + "TF", + "TG", + "TH", + "TJ", + "TK", + "TL", + "TM", + "TN", + "TO", + "TR", + "TT", + "TV", + "TW", + "TZ", + "UA", + "UG", + "UM", + "US", + "UY", + "UZ", + "VA", + "VC", + "VE", + "VG", + "VI", + "VN", + "VU", + "WF", + "WS", + "YE", + "YT", + "ZA", + "ZM", + "ZW", + "XK", + "Other" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 4 + }, + "region": { + "title": "Region", + "description": "The [UN M.49](https://en.wikipedia.org/wiki/UN_M.49) super-region and sub-region joined together. e.g. North America: 019021. South America (Brazil): 019005, Asia: 142000, East Asia (includes China): 142030, West Asia (Middle East): 142145, South Asia (India): 142034, Eastern Europe: 150151, Western Europe: 150155. Use 000000 if you do not know and 000001 for 'other' (includes international waters and outer space). If you only know the super-region, use zero's for the region. (e.g. 019000 for Americas.)", + "items": { + "type": "string", + "maxLength": 6, + "minLength": 6, + "pattern": "\\d{6}" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 4 + }, + "name": { + "title": "Name", + "items": { + "type": "string" + }, + "type": "array", + "uniqueItems": true + } + }, + "required": [ + "country", + "motive" + ], + "type": "object" + }, + { + "title": "Unknown", + "description": "If the actor is unknown, you *must* add a note of some type, otherwise the incident will not validate.", + "properties": { + "schemaKey": { + "type": "string", + "const": "subSchema4" + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + } + }, + "type": "object" + } + ], + "type": "object" + }, + "asset": { + "title": "Assets", + "description": "What assets were affected by the incident actions. Data types and record count will be covered in the attributes section. [More Info](http://veriscommunity.net/assets.html)", + "additionalProperties": false, + "minProperties": 1, + "properties": { + "total_amount": { + "title": "Total Amount", + "type": "number" + }, + "assets": { + "title": "Assets", + "items": { + "additionalProperties": false, + "properties": { + "variety": { + "title": "Variety", + "description": "What varieties of assets were compromised?", + "type": "string", + "enum": [ + "M - Disk drive", + "M - Disk media", + "M - Documents", + "M - Flash drive", + "M - Payment card", + "M - Smart card", + "M - Tapes", + "M - Other", + "M - Unknown", + "M - Fax", + "N - Access reader", + "N - Broadband", + "N - Camera", + "N - Firewall", + "N - HSM", + "N - IDS", + "N - LAN", + "N - NAS", + "N - PBX", + "N - PLC", + "N - Private WAN", + "N - Public WAN", + "N - Router or switch", + "N - RTU", + "N - SAN", + "N - Telephone", + "N - VoIP adapter", + "N - WLAN", + "N - Other", + "N - Unknown", + "P - Auditor", + "P - Call center", + "P - Cashier", + "P - Customer", + "P - Developer", + "P - End-user", + "P - End-user or employee", + "P - Executive", + "P - Finance", + "P - Former employee", + "P - Guard", + "P - Helpdesk", + "P - Human resources", + "P - Maintenance", + "P - Manager", + "P - Other employee", + "P - Partner", + "P - System admin", + "P - Other", + "P - Unknown", + "S - Authentication", + "S - Backup", + "S - Configuration or patch management", + "S - Code repository", + "S - Database", + "S - DCS", + "S - DHCP", + "S - Directory", + "S - DNS", + "S - File", + "S - ICS", + "S - Log", + "S - Mail", + "S - Mainframe", + "S - Payment switch", + "S - POS controller", + "S - Print", + "S - Proxy", + "S - Remote access", + "S - VM host", + "S - Web application", + "S - Other", + "S - Unknown", + "T - ATM", + "T - Gas terminal", + "T - Kiosk", + "T - PED pad", + "T - Other", + "T - Unknown", + "U - Auth token", + "U - Desktop", + "U - Desktop or laptop", + "U - Laptop", + "U - Media", + "U - Mobile phone", + "U - Peripheral", + "U - POS terminal", + "U - Tablet", + "U - Telephone", + "U - VoIP phone", + "U - Other", + "U - Unknown", + "E - Telemetry", + "E - Telematics", + "E - Other", + "E - Unknown", + "Unknown", + "Other" + ] + }, + "amount": { + "title": "Amount", + "description": "How many total systems were compromised?", + "type": "integer" + } + }, + "required": [ + "variety" + ], + "type": "object" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "ownership": { + "title": "Ownership", + "description": "Who owns the affected asset? This can allow us to identify employee-owned (BYOD) assets.", + "items": { + "type": "string", + "enum": [ + "Customer", + "Employee", + "NA", + "Partner", + "Unknown", + "Victim", + "Other" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 6 + }, + "cloud": { + "title": "On-Premise or Cloud", + "description": "Only answer if you know for sure if the asset was hosted in a cloud service.", + "items": { + "type": "string", + "enum": [ + "On-Premise Asset(s)", + "External Cloud Asset(s)", + "Other", + "Unknown", + "NA" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 6 + }, + "hosting": { + "title": "Hosting Location", + "description": "Where is the affected asset hosted/located?", + "items": { + "type": "string", + "enum": [ + "External - unknown environment", + "External - dedicated environment", + "External - shared environment", + "Internal", + "NA", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 4 + }, + "management": { + "title": "Management", + "description": "Independent of physical location, who administers and maintains the affected asset?", + "items": { + "type": "string", + "enum": [ + "External", + "Internal", + "Co-managed", + "NA", + "Unknown", + "Other" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 4 + }, + "role": { + "title": "IT or OT", + "description": "Is the asset Information Technology (IT) such as email or the domain controller or Operational Technology (OT) such as rail-switching computers for a railroad or manufacturing robots for a manufacturing company.", + "items": { + "type": "string", + "enum": [ + "IT", + "OT", + "Unknown", + "Other", + "NA" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 4 + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + }, + "country": { + "title": "Country", + "description": "The country hosting the asset.", + "items": { + "type": "string", + "enum": [ + "Unknown", + "AD", + "AE", + "AF", + "AG", + "AI", + "AL", + "AM", + "AO", + "AQ", + "AR", + "AS", + "AT", + "AU", + "AW", + "AX", + "AZ", + "BA", + "BB", + "BD", + "BE", + "BF", + "BG", + "BH", + "BI", + "BJ", + "BL", + "BM", + "BN", + "BO", + "BQ", + "BR", + "BS", + "BT", + "BV", + "BW", + "BY", + "BZ", + "CA", + "CC", + "CD", + "CF", + "CG", + "CH", + "CI", + "CK", + "CL", + "CM", + "CN", + "CO", + "CR", + "CU", + "CV", + "CW", + "CX", + "CY", + "CZ", + "DE", + "DJ", + "DK", + "DM", + "DO", + "DZ", + "EC", + "EE", + "EG", + "EH", + "ER", + "ES", + "ET", + "FI", + "FJ", + "FK", + "FM", + "FO", + "FR", + "GA", + "GB", + "GD", + "GE", + "GF", + "GG", + "GH", + "GI", + "GL", + "GM", + "GN", + "GP", + "GQ", + "GR", + "GS", + "GT", + "GU", + "GW", + "GY", + "HK", + "HM", + "HN", + "HR", + "HT", + "HU", + "ID", + "IE", + "IL", + "IM", + "IN", + "IO", + "IQ", + "IR", + "IS", + "IT", + "JE", + "JM", + "JO", + "JP", + "KE", + "KG", + "KH", + "KI", + "KM", + "KN", + "KP", + "KR", + "KW", + "KY", + "KZ", + "LA", + "LB", + "LC", + "LI", + "LK", + "LR", + "LS", + "LT", + "LU", + "LV", + "LY", + "MA", + "MC", + "MD", + "ME", + "MF", + "MG", + "MH", + "MK", + "ML", + "MM", + "MN", + "MO", + "MP", + "MQ", + "MR", + "MS", + "MT", + "MU", + "MV", + "MW", + "MX", + "MY", + "MZ", + "NA", + "NC", + "NE", + "NF", + "NG", + "NI", + "NL", + "NO", + "NP", + "NR", + "NU", + "NZ", + "OM", + "PA", + "PE", + "PF", + "PG", + "PH", + "PK", + "PL", + "PM", + "PN", + "PR", + "PS", + "PT", + "PW", + "PY", + "QA", + "RE", + "RO", + "RS", + "RU", + "RW", + "SA", + "SB", + "SC", + "SD", + "SE", + "SG", + "SH", + "SI", + "SJ", + "SK", + "SL", + "SM", + "SN", + "SO", + "SR", + "SS", + "ST", + "SV", + "SX", + "SY", + "SZ", + "TC", + "TD", + "TF", + "TG", + "TH", + "TJ", + "TK", + "TL", + "TM", + "TN", + "TO", + "TR", + "TT", + "TV", + "TW", + "TZ", + "UA", + "UG", + "UM", + "US", + "UY", + "UZ", + "VA", + "VC", + "VE", + "VG", + "VI", + "VN", + "VU", + "WF", + "WS", + "YE", + "YT", + "ZA", + "ZM", + "ZW", + "XK", + "Other" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + } + }, + "type": "object", + "required": [ + "assets", + "cloud" + ] + }, + "attribute": { + "title": "Attribute", + "description": "What attributes were compromised? [More Info](http://veriscommunity.net/attributes.html)", + "additionalProperties": false, + "minProperties": 1, + "properties": { + "confidentiality": { + "title": "Confidentiality", + "description": "Was data (potentially) disclosed to an unauthorized party? [More Info](http://veriscommunity.net/attributes.html#section-confidentiality)", + "additionalProperties": false, + "properties": { + "data_disclosure": { + "title": "Data Disclosure", + "description": "Was data disclosed? This is the core determiner if this incident is a breach. If this is 'Yes', it will be considered a breach. If it is anything else, it will only be an incident.", + "type": "string", + "enum": [ + "No", + "Potentially", + "Yes", + "Unknown" + ], + "x-cols": 6 + }, + "data_total": { + "title": "Data Total", + "description": "Total records breached", + "type": "integer", + "x-cols": 6 + }, + "data": { + "title": "Compromised Data", + "description": "Varieties (and amount) of data compromised. Click the red \u2018Add\u2019 button to record multiple data varieties.", + "items": { + "additionalProperties": false, + "properties": { + "amount": { + "title": "Amount", + "type": "integer" + }, + "variety": { + "title": "Variety", + "type": "string", + "enum": [ + "Bank", + "Classified", + "Copyrighted", + "Credentials", + "Digital certificate", + "Internal", + "Medical", + "Payment", + "Personal", + "Secrets", + "Source code", + "System", + "Virtual currency", + "Other", + "Unknown" + ] + } + }, + "required": [ + "variety" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "data_victim": { + "title": "Data Victim", + "items": { + "type": "string", + "enum": [ + "Customer", + "Employee", + "Partner", + "Patient", + "Student", + "Victim organization", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 6 + }, + "state": { + "title": "State", + "items": { + "type": "string", + "enum": [ + "Processed", + "Stored", + "Stored encrypted", + "Stored unencrypted", + "Transmitted", + "Transmitted encrypted", + "Transmitted unencrypted", + "Other", + "Unknown", + "Printed" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 6 + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + } + }, + "required": [ + "data_disclosure" + ], + "type": "object" + }, + "integrity": { + "title": "Integrity", + "description": "Was a person manipulated or the state of a system changed? [More Info](http://veriscommunity.net/attributes.html#section-integrity)", + "additionalProperties": false, + "properties": { + "variety": { + "title": "Variety", + "items": { + "type": "string", + "enum": [ + "Alter behavior", + "Created account", + "Defacement", + "Fraudulent transaction", + "Hardware tampering", + "Log tampering", + "Misrepresentation", + "Modify configuration", + "Modify data", + "Modify privileges", + "Repurpose", + "Software installation", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + } + }, + "required": [ + "variety" + ], + "type": "object" + }, + "availability": { + "title": "Availability", + "description": "Was something rendered partially or wholly unavailable? [More Info](http://veriscommunity.net/attributes.html#section-availability)", + "properties": { + "variety": { + "title": "Variety", + "items": { + "type": "string", + "enum": [ + "Acceleration", + "Degradation", + "Destruction", + "Interruption", + "Loss", + "Obscuration", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true, + "x-cols": 6, + "x-class": "pr-2" + }, + "duration": { + "description": "Specific value of the specific selected unit, (i.e., # of 'days').", + "additionalProperties": false, + "properties": { + "unit": { + "title": "Unit", + "x-cols": 6, + "type": "string", + "enum": [ + "Seconds", + "Minutes", + "Hours", + "Days", + "Weeks", + "Months", + "Years", + "Never", + "NA", + "Unknown" + ], + "x-class": "pr-2" + }, + "value": { + "title": "Value", + "x-cols": 6, + "type": "number" + } + }, + "required": [ + "unit" + ], + "type": "object", + "x-cols": 6 + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + } + }, + "required": [ + "variety" + ], + "type": "object" + }, + "unknown": { + "title": "Unknown", + "properties": { + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + }, + "result": { + "title": "Result", + "description": "The result of the action. If there's a difference between action result and actor intent, use the result not intent.", + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + } + }, + "type": "object" + } + }, + "type": "object" + }, + "targeted": { + "title": "Targeted vs Opportunistic", + "description": "Was this a targeted or opportunistic attack? [More Info](http://veriscommunity.net/discovery.html#section-target-opportunistic)
N/A: Not an attack (e.g., unintentional actions)
Opportunistic: Victim was NOT pre-selected as a target; they were identified/attacked because they exhibited a weakness the attacker knew how to exploit.
Targeted: The victim is pre-selected as a target; the attacker(s) then determined what weaknesses exist within the target that could be exploited.", + "type": "string", + "enum": [ + "Opportunistic", + "Targeted", + "NA", + "Unknown" + ] + }, + "discovery_method": { + "title": "Discovery Method", + "description": "What discovery method was involved? [More Info](http://veriscommunity.net/discovery.html#section-discovery-method)", + "minProperties": 1, + "additionalProperties": false, + "oneOf": [ + { + "title": "External", + "description": "Discovered by an external entity.", + "additionalProperties": false, + "properties": { + "schemaKey": { + "type": "string", + "const": "subSchema1" + }, + "variety": { + "title": "Variety", + "items": { + "type": "string", + "enum": [ + "Actor disclosure", + "Audit", + "Customer", + "Emergency response team", + "Found documents", + "Fraud detection", + "Incident response", + "Law enforcement", + "Other", + "Security researcher", + "Suspicious traffic", + "Unknown", + "Unrelated 3rd party" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + } + }, + "required": [ + "variety" + ], + "type": "object" + }, + { + "title": "Internal", + "description": "Discovered by an external partner.", + "additionalProperties": false, + "properties": { + "schemaKey": { + "type": "string", + "const": "subSchema2" + }, + "variety": { + "title": "Variety", + "items": { + "type": "string", + "enum": [ + "Antivirus", + "Break in discovered", + "Data loss prevention", + "Financial audit", + "Fraud detection", + "Hids", + "Incident response", + "Infrastructure monitoring", + "It review", + "Log review", + "Nids", + "Other", + "Reported by employee", + "Security alarm", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + } + }, + "required": [ + "variety" + ], + "type": "object" + }, + { + "title": "Partner", + "description": "Discovered by a partner of the victim.", + "additionalProperties": false, + "properties": { + "schemaKey": { + "type": "string", + "const": "subSchema3" + }, + "variety": { + "title": "Variety", + "items": { + "type": "string", + "enum": [ + "Antivirus", + "Audit", + "Incident response", + "Monitoring service", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + } + }, + "required": [ + "variety" + ], + "type": "object" + }, + { + "title": "Other", + "type": "boolean", + "properties": { + "schemaKey": { + "type": "string", + "const": "subSchema4" + } + }, + "x-cols": 6 + }, + { + "title": "Unknown", + "type": "boolean", + "properties": { + "schemaKey": { + "type": "string", + "const": "subSchema5" + } + }, + "x-cols": 6 + } + ], + "type": "object" + }, + "discovery_notes": { + "title": "Discovery Notes", + "description": "How was the incident discovered? [More Info](http://veriscommunity.net/discovery.html#section-discovery-method)", + "minLength": 1, + "type": "string" + }, + "value_chain": { + "title": "Value Chain", + "description": "Capabilities and investments an attacker must aquire prior to the actions on target. May be internal to the actors organization (vertically integrated org), or external (purchased in a criminal market).", + "minProperties": 1, + "additionalProperties": false, + "properties": { + "development": { + "title": "Development", + "description": "Software that must be developed to accomplish the actions on target.", + "additionalProperties": false, + "properties": { + "variety": { + "title": "Variety", + "description": "Varieties of development investments", + "items": { + "type": "string", + "enum": [ + "Bot", + "Exploit", + "Exploit Kits", + "Payload", + "Persona", + "Ransomware", + "Trojan", + "Website", + "NA", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + } + }, + "required": [ + "variety" + ], + "type": "object" + }, + "non-distribution services": { + "title": "Non-Distribution Services", + "description": "Services provided and used by malicious actors other than those used for distribution of actor content", + "additionalProperties": false, + "properties": { + "variety": { + "title": "Variety", + "description": "Varieties of non-distribution service investments", + "items": { + "type": "string", + "enum": [ + "C2", + "Counter AV", + "DNS", + "Escrow", + "Hashcracking", + "Marketplace", + "Proxy", + "VPN", + "NA", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + } + }, + "required": [ + "variety" + ], + "type": "object" + }, + "targeting": { + "title": "Targeting", + "description": "Things that identify exploitable opportunities. These overlap heavily with data varieties that are compromised.", + "additionalProperties": false, + "properties": { + "variety": { + "title": "Variety", + "description": "Varieties of targeting investments", + "items": { + "type": "string", + "enum": [ + "Default credentials", + "Email addresses", + "Lost or stolen credentials", + "Misconfigurations", + "Partner", + "Personal Information", + "Organizational Information", + "Vulnerabilities", + "Weaknesses", + "NA", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + } + }, + "required": [ + "variety" + ], + "type": "object" + }, + "distribution": { + "title": "Distribution", + "description": "Services used to distribute actor content.", + "additionalProperties": false, + "properties": { + "variety": { + "title": "Variety", + "description": "Varieties of distribution investments", + "items": { + "type": "string", + "enum": [ + "Botnet", + "Compromised server", + "Direct", + "Email", + "Loader", + "Partner", + "Phone", + "Website", + "NA", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + } + }, + "required": [ + "variety" + ], + "type": "object" + }, + "cash-out": { + "title": "Cash Out", + "description": "Methods for converting something (likely the attribute compromised) into currency.", + "additionalProperties": false, + "properties": { + "variety": { + "title": "Variety", + "description": "Varieties of cash-out investments", + "items": { + "type": "string", + "enum": [ + "Cryptocurrency", + "Direct", + "Fraud", + "Hijacked rewards", + "Provide service", + "Sell stolen goods", + "NA", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + } + }, + "required": [ + "variety" + ], + "type": "object" + }, + "money laundering": { + "title": "Money Laundering", + "description": "Methods for concealing the origins of illegally obtained money.", + "additionalProperties": false, + "properties": { + "variety": { + "title": "Variety", + "description": "Varieties of money laundering", + "items": { + "type": "string", + "enum": [ + "Bank", + "Company", + "Cryptocurrency tumbling", + "Employment", + "Gambling", + "Physical", + "Provide service", + "Re-shipping", + "Smurfing", + "NA", + "Other", + "Unknown" + ] + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + } + }, + "required": [ + "variety" + ], + "type": "object" + }, + "NA": { + "type": "boolean" + } + }, + "type": "object" + }, + "impact": { + "title": "Impact", + "description": "[Impact Info](http://veriscommunity.net/impact.html)", + "additionalProperties": false, + "properties": { + "overall_rating": { + "title": "Overall Rating", + "type": "string", + "enum": [ + "Catastrophic", + "Damaging", + "Painful", + "Distracting", + "Insignificant", + "Unknown" + ] + }, + "iso_currency_code": { + "title": "ISO 4217 currency code", + "description": "ISO_4217 currency code. [More Info](https://en.wikipedia.org/wiki/ISO_4217)", + "type": "string", + "enum": [ + "AED", + "AFN", + "ALL", + "AMD", + "ANG", + "AOA", + "ARS", + "AUD", + "AWG", + "AZN", + "BAM", + "BBD", + "BDT", + "BGN", + "BHD", + "BIF", + "BMD", + "BND", + "BOB", + "BRL", + "BSD", + "BTN", + "BWP", + "BYR", + "BZD", + "CAD", + "CDF", + "CHF", + "CLP", + "CNY", + "COP", + "CRC", + "CUC", + "CUP", + "CVE", + "CZK", + "DJF", + "DKK", + "DOP", + "DZD", + "EGP", + "ERN", + "ETB", + "EUR", + "FJD", + "FKP", + "GBP", + "GEL", + "GGP", + "GHS", + "GIP", + "GMD", + "GNF", + "GTQ", + "GYD", + "HKD", + "HNL", + "HRK", + "HTG", + "HUF", + "IDR", + "ILS", + "IMP", + "INR", + "IQD", + "IRR", + "ISK", + "JEP", + "JMD", + "JOD", + "JPY", + "KES", + "KGS", + "KHR", + "KMF", + "KPW", + "KRW", + "KWD", + "KYD", + "KZT", + "LAK", + "LBP", + "LKR", + "LRD", + "LSL", + "LTL", + "LVL", + "LYD", + "MAD", + "MDL", + "MGA", + "MKD", + "MMK", + "MNT", + "MOP", + "MRO", + "MUR", + "MVR", + "MWK", + "MXN", + "MYR", + "MZN", + "NAD", + "NGN", + "NIO", + "NOK", + "NPR", + "NZD", + "OMR", + "PAB", + "PEN", + "PGK", + "PHP", + "PKR", + "PLN", + "PYG", + "QAR", + "RON", + "RSD", + "RUB", + "RWF", + "SAR", + "SBD", + "SCR", + "SDG", + "SEK", + "SGD", + "SHP", + "SLL", + "SOS", + "SPL", + "SRD", + "STD", + "SVC", + "SYP", + "SZL", + "THB", + "TJS", + "TMT", + "TND", + "TOP", + "TRY", + "TTD", + "TVD", + "TWD", + "TZS", + "UAH", + "UGX", + "USD", + "UYU", + "UZS", + "VEF", + "VND", + "VUV", + "WST", + "XAF", + "XCD", + "XDR", + "XOF", + "XPF", + "YER", + "ZAR", + "ZMK", + "ZWD", + "XBT", + "BCH", + "Ether", + "Litecoin", + "XMR", + "ZEC" + ] + }, + "overall_amount": { + "title": "Overall amount", + "description": "The total amount lost in the given ISO currency code.", + "type": "number", + "x-cols": 4 + }, + "overall_min_amount": { + "title": "Overall minimum account", + "description": "When 'overall_amount' would be a range, use this field for the minimum of that range. Note: Values here will not appear in searches for 'overall_amount'.", + "type": "number", + "x-cols": 4 + }, + "overall_max_amount": { + "title": "Overall maximum account", + "description": "When 'overall_amount' would be a range, use this field for the maximum of that range. Note: Values here will not appear in searches for 'overall_amount'.", + "type": "number", + "x-cols": 4 + }, + "loss": { + "title": "Reported Losses", + "description": "Were any losses or costs reported for this incident? (Definitions for loss varieties and ratings are [here](http://veriscommunity.net/impact.html#section-loss-estimation))", + "items": { + "additionalProperties": false, + "properties": { + "variety": { + "title": "Variety", + "type": "string", + "enum": [ + "Asset and fraud", + "Brand damage", + "Business disruption", + "Competitive advantage", + "Legal and regulatory", + "Operating costs", + "Response and recovery", + "Other" + ] + }, + "rating": { + "title": "Rating", + "type": "string", + "enum": [ + "Major", + "Moderate", + "Minor", + "None", + "Unknown" + ] + }, + "amount": { + "title": "Amount", + "type": "number" + }, + "min_amount": { + "title": "Min Amount", + "type": "number" + }, + "max_amount": { + "title": "Max Amount", + "type": "number" + } + }, + "required": [ + "variety" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "x-display": "textarea" + } + }, + "required": [ + "overall_rating" + ], + "type": "object" + }, + "notes": { + "title": "Notes", + "minLength": 1, + "type": "string", + "description": "Record notes about the incident.", + "x-display": "textarea" + }, + "corrective_action": { + "title": "Corrective Action", + "description": "What corrective action(s) are planned (or recommended) to prevent and/or detect similar incidents in the future?
This can include general recommendations, specific changes to policy, procedures, personnel, and technology, short-term and long-term strategies, etc. Don't simply copy what the investigator said. Tie to the root causes listed above, and focus on practical, effective corrective actions.", + "type": "string", + "x-cols": 6 + }, + "cost_corrective_action": { + "title": "Cost Corrective Action", + "type": "string", + "enum": [ + "Difficult and expensive", + "Something in-between", + "Simple and cheap", + "Unknown" + ], + "x-cols": 6 + }, + "control_failure": { + "title": "Control Failure", + "description": "What were the root control failures or weaknesses that allowed this incident to occur?
Obviously, there may be a multitude of factors that could be listed here. Include as many as you want, but focus on the issues most pertinent to why the incident occurred.", + "type": "string" + } + }, + "required": [ + "actor", + "action", + "discovery_method", + "schema_version", + "asset", + "timeline", + "incident_id", + "security_incident", + "summary" + ], + "type": "object" +} diff --git a/database/playbook.go b/database/playbook.go new file mode 100644 index 0000000..9c1b810 --- /dev/null +++ b/database/playbook.go @@ -0,0 +1,152 @@ +package database + +import ( + "context" + "errors" + "time" + + "github.com/arangodb/go-driver" + "github.com/iancoleman/strcase" + "github.com/icza/dyno" + "gopkg.in/yaml.v3" + + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" +) + +type PlaybookYAML struct { + Name string `yaml:"name"` + Tasks map[string]TaskYAML `yaml:"tasks"` +} + +type TaskYAML struct { + Name string `yaml:"name"` + Type string `yaml:"type"` + Schema interface{} `yaml:"schema"` + Automation string `yaml:"automation"` + Payload map[string]string `yaml:"payload"` + Next map[string]string `yaml:"next"` + Join bool `yaml:"join"` +} + +func toPlaybooks(docs []*models.PlaybookTemplateForm) (map[string]*models.Playbook, error) { + playbooks := map[string]*models.Playbook{} + for _, doc := range docs { + playbook, err := toPlaybook(doc) + if err != nil { + return nil, err + } + if doc.ID != nil { + playbooks[*doc.ID] = playbook + } else { + playbooks[strcase.ToKebab(playbook.Name)] = playbook + } + } + return playbooks, nil +} + +func toPlaybook(doc *models.PlaybookTemplateForm) (*models.Playbook, error) { + ticketPlaybook := &models.Playbook{} + err := yaml.Unmarshal([]byte(doc.Yaml), ticketPlaybook) + if err != nil { + return nil, err + } + for idx, task := range ticketPlaybook.Tasks { + if task.Schema != nil { + task.Schema = dyno.ConvertMapI2MapS(task.Schema.(map[string]interface{})) + } + task.Created = time.Now().UTC() + ticketPlaybook.Tasks[idx] = task + } + return ticketPlaybook, nil +} + +func toPlaybookTemplateResponse(key string, doc *models.PlaybookTemplate) *models.PlaybookTemplateResponse { + return &models.PlaybookTemplateResponse{ID: key, Name: doc.Name, Yaml: doc.Yaml} +} + +func (db *Database) PlaybookCreate(ctx context.Context, playbook *models.PlaybookTemplateForm) (*models.PlaybookTemplateResponse, error) { + if playbook == nil { + return nil, errors.New("requires playbook") + } + + var playbookYAML PlaybookYAML + err := yaml.Unmarshal([]byte(playbook.Yaml), &playbookYAML) + if err != nil { + return nil, err + } + + if playbookYAML.Name == "" { + return nil, errors.New("requires template name") + } + p := models.PlaybookTemplate{Name: playbookYAML.Name, Yaml: playbook.Yaml} + + var doc models.PlaybookTemplate + newctx := driver.WithReturnNew(ctx, &doc) + + meta, err := db.playbookCollection.CreateDocument(ctx, newctx, strcase.ToKebab(playbookYAML.Name), p) + if err != nil { + return nil, err + } + + return toPlaybookTemplateResponse(meta.Key, &doc), nil +} + +func (db *Database) PlaybookGet(ctx context.Context, id string) (*models.PlaybookTemplateResponse, error) { + doc := models.PlaybookTemplate{} + meta, err := db.playbookCollection.ReadDocument(ctx, id, &doc) + if err != nil { + return nil, err + } + + return toPlaybookTemplateResponse(meta.Key, &doc), nil +} + +func (db *Database) PlaybookDelete(ctx context.Context, id string) error { + _, err := db.playbookCollection.RemoveDocument(ctx, id) + return err +} + +func (db *Database) PlaybookUpdate(ctx context.Context, id string, playbook *models.PlaybookTemplateForm) (*models.PlaybookTemplateResponse, error) { + var pb PlaybookYAML + err := yaml.Unmarshal([]byte(playbook.Yaml), &pb) + if err != nil { + return nil, err + } + + if pb.Name == "" { + return nil, errors.New("requires template name") + } + + var doc models.PlaybookTemplate + ctx = driver.WithReturnNew(ctx, &doc) + + meta, err := db.playbookCollection.ReplaceDocument(ctx, id, models.PlaybookTemplate{Name: pb.Name, Yaml: playbook.Yaml}) + if err != nil { + return nil, err + } + + return toPlaybookTemplateResponse(meta.Key, &doc), nil +} + +func (db *Database) PlaybookList(ctx context.Context) ([]*models.PlaybookTemplateResponse, error) { + query := "FOR d IN @@collection RETURN d" + cursor, _, err := db.Query(ctx, query, map[string]interface{}{"@collection": PlaybookCollectionName}, busdb.ReadOperation) + if err != nil { + return nil, err + } + defer cursor.Close() + var docs []*models.PlaybookTemplateResponse + for { + var doc models.PlaybookTemplate + meta, err := cursor.ReadDocument(ctx, &doc) + if driver.IsNoMoreDocuments(err) { + break + } else if err != nil { + return nil, err + } + docs = append(docs, toPlaybookTemplateResponse(meta.Key, &doc)) + } + + return docs, err +} diff --git a/database/playbookutils.go b/database/playbookutils.go new file mode 100644 index 0000000..2df7eef --- /dev/null +++ b/database/playbookutils.go @@ -0,0 +1,182 @@ +package database + +import ( + "errors" + "fmt" + "log" + "sort" + + "github.com/SecurityBrewery/catalyst/caql" + "github.com/SecurityBrewery/catalyst/dag" + "github.com/SecurityBrewery/catalyst/generated/models" +) + +func playbookGraph(playbook *models.Playbook) (*dag.Graph, error) { + d := dag.NewGraph() + + var taskIDs []string + for taskID := range playbook.Tasks { + taskIDs = append(taskIDs, taskID) + } + sort.Strings(taskIDs) + + for _, taskID := range taskIDs { + if err := d.AddNode(taskID); err != nil { + return nil, errors.New("could not add node") + } + } + for _, taskID := range taskIDs { + task := playbook.Tasks[taskID] + for next := range task.Next { + if err := d.AddEdge(taskID, next); err != nil { + return nil, errors.New("could not add edge") + } + } + } + return d, nil +} + +func toTaskResponse(playbook *models.Playbook, taskID string, order int, graph *dag.Graph) (*models.TaskResponse, error) { + task, ok := playbook.Tasks[taskID] + if !ok { + return nil, fmt.Errorf("task %s not found", taskID) + } + + tr := &models.TaskResponse{ + Automation: task.Automation, + Closed: task.Closed, + Created: task.Created, + Data: task.Data, + Done: task.Done, + Join: task.Join, + Payload: task.Payload, + Name: task.Name, + Next: task.Next, + Owner: task.Owner, + Schema: task.Schema, + Type: task.Type, + // Active: active, + // Order: v.Order, + } + + tr.Order = int64(order) + + taskActive, _ := active(playbook, taskID, graph, task) + tr.Active = taskActive + + return tr, nil +} + +func activePlaybook(playbook *models.Playbook, taskID string) (bool, error) { + task, ok := playbook.Tasks[taskID] + if !ok { + return false, fmt.Errorf("playbook does not contain tasks %s", taskID) + } + + d, err := playbookGraph(playbook) + if err != nil { + return false, err + } + + return active(playbook, taskID, d, task) +} + +func active(playbook *models.Playbook, taskID string, d *dag.Graph, task *models.Task) (bool, error) { + if task.Done { + return false, nil + } + + parents := d.GetParents(taskID) + + if len(parents) == 0 { + return true, nil // valid(&task) + } + + if task.Join != nil && *task.Join { + for _, parent := range parents { + parentTask := playbook.Tasks[parent] + if !parentTask.Done { + return false, nil + } + requirement := parentTask.Next[taskID] + + b, err := evalRequirement(requirement, parentTask.Data) + if err != nil { + return false, err + } + + if !b { + return false, nil + } + } + return true, nil + } + + for _, parent := range parents { + parentTask := playbook.Tasks[parent] + if !parentTask.Done { + // return false, nil + continue + } + requirement := parentTask.Next[taskID] + + b, err := evalRequirement(requirement, parentTask.Data) + if err != nil { + continue + } + + if b { + return true, nil + } + } + return false, nil +} + +func evalRequirement(aql string, data interface{}) (bool, error) { + if aql == "" { + return true, nil + } + + parser := caql.Parser{} + tree, err := parser.Parse(aql) + if err != nil { + return false, err + } + + var dataMap map[string]interface{} + if data != nil { + if dataMapX, ok := data.(map[string]interface{}); ok { + dataMap = dataMapX + } else { + log.Println("wrong data type for task data") + } + } + + v, err := tree.Eval(dataMap) + if err != nil { + return false, err + } + + if b, ok := v.(bool); ok { + return b, nil + } + return false, err +} + +/* +// "github.com/qri-io/jsonschema" +func valid(task *models.Task) (bool, error) { + schema, err := json.Marshal(task.Schema) + if err != nil { + return false, err + } + + rs := &jsonschema.Schema{} + if err := json.Unmarshal(schema, rs); err != nil { + return false, err + } + + state := rs.Validate(context.Background(), task.Data) + return len(*state.Errs) > 0, nil +} +*/ diff --git a/database/playbookutils_test.go b/database/playbookutils_test.go new file mode 100644 index 0000000..25ed2bf --- /dev/null +++ b/database/playbookutils_test.go @@ -0,0 +1,135 @@ +package database + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/SecurityBrewery/catalyst/generated/models" +) + +var playbook2 = &models.Playbook{ + Name: "Phishing", + Tasks: map[string]*models.Task{ + "board": {Next: map[string]string{ + "escalate": "boardInvolved == true", + "aquire-mail": "boardInvolved == false", + }}, + "escalate": {}, + "aquire-mail": {Next: map[string]string{ + "extract-iocs": "schemaKey == 'yes'", + "block-sender": "schemaKey == 'yes'", + "search-email-gateway": "schemaKey == 'no'", + }}, + "extract-iocs": {Next: map[string]string{"fetch-iocs": ""}}, + "fetch-iocs": {Next: map[string]string{"block-iocs": ""}}, + "search-email-gateway": {Next: map[string]string{"block-iocs": ""}}, + "block-sender": {Next: map[string]string{"block-iocs": ""}}, + "block-iocs": {Next: map[string]string{"block-ioc": ""}}, + "block-ioc": {}, + }, +} + +var playbook3 = &models.Playbook{ + Name: "Phishing", + Tasks: map[string]*models.Task{ + "board": {Next: map[string]string{ + "escalate": "boardInvolved == true", + "aquire-mail": "boardInvolved == false", + }, Data: map[string]interface{}{"boardInvolved": true}, Done: true}, + "escalate": {}, + "aquire-mail": {Next: map[string]string{ + "extract-iocs": "schemaKey == 'yes'", + "block-sender": "schemaKey == 'yes'", + "search-email-gateway": "schemaKey == 'no'", + }}, + "extract-iocs": {Next: map[string]string{"fetch-iocs": ""}}, + "fetch-iocs": {Next: map[string]string{"block-iocs": ""}}, + "search-email-gateway": {Next: map[string]string{"block-iocs": ""}}, + "block-sender": {Next: map[string]string{"block-iocs": ""}}, + "block-iocs": {Next: map[string]string{"block-ioc": ""}}, + "block-ioc": {}, + }, +} + +var playbook4 = &models.Playbook{ + Name: "Malware", + Tasks: map[string]*models.Task{ + "file-or-hash": {Next: map[string]string{ + "enter-hash": "file == 'Hash'", + "upload": "file == 'File'", + }}, + "enter-hash": {Next: map[string]string{ + "virustotal": "hash != ''", + }}, + "upload": {Next: map[string]string{ + "hash": "malware", + }}, + "hash": {Next: map[string]string{"virustotal": ""}}, + "virustotal": {}, + }, +} + +func Test_canBeCompleted(t *testing.T) { + type args struct { + playbook *models.Playbook + taskID string + } + tests := []struct { + name string + args args + want bool + wantErr bool + }{ + {"playbook2 board", args{playbook: playbook2, taskID: "board"}, true, false}, + {"playbook2 escalate", args{playbook: playbook2, taskID: "escalate"}, false, false}, + {"playbook2 aquire-mail", args{playbook: playbook2, taskID: "aquire-mail"}, false, false}, + {"playbook2 block-ioc", args{playbook: playbook2, taskID: "block-ioc"}, false, false}, + {"playbook3 board", args{playbook: playbook3, taskID: "board"}, false, false}, + {"playbook3 escalate", args{playbook: playbook3, taskID: "escalate"}, true, false}, + {"playbook3 aquire-mail", args{playbook: playbook3, taskID: "aquire-mail"}, false, false}, + {"playbook3 block-ioc", args{playbook: playbook3, taskID: "block-ioc"}, false, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := activePlaybook(tt.args.playbook, tt.args.taskID) + if (err != nil) != tt.wantErr { + t.Errorf("activePlaybook() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("activePlaybook() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_playbookOrder(t *testing.T) { + type args struct { + playbook *models.Playbook + } + tests := []struct { + name string + args args + want []string + wantErr bool + }{ + {"playbook4", args{playbook: playbook4}, []string{"file-or-hash", "enter-hash", "upload", "hash", "virustotal"}, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := toPlaybookResponse(tt.args.playbook) + if (err != nil) != tt.wantErr { + t.Errorf("activePlaybook() error = %v, wantErr %v", err, tt.wantErr) + return + } + + names := make([]string, len(got.Tasks)) + for name, task := range got.Tasks { + names[task.Order] = name + } + + assert.Equal(t, tt.want, names) + }) + } +} diff --git a/database/relationships.go b/database/relationships.go new file mode 100644 index 0000000..95ff059 --- /dev/null +++ b/database/relationships.go @@ -0,0 +1,48 @@ +package database + +import ( + "context" + "errors" + "strconv" + + "github.com/arangodb/go-driver" + + "github.com/SecurityBrewery/catalyst/database/busdb" +) + +func (db *Database) RelatedCreate(ctx context.Context, id, id2 int64) error { + if id == id2 { + return errors.New("tickets cannot relate to themself") + } + + _, err := db.relatedCollection.CreateEdge(ctx, ctx, &driver.EdgeDocument{ + From: driver.DocumentID(TicketCollectionName + "/" + strconv.Itoa(int(id))), + To: driver.DocumentID(TicketCollectionName + "/" + strconv.Itoa(int(id2))), + }) + return err +} + +func (db *Database) RelatedBatchCreate(ctx context.Context, edges []*driver.EdgeDocument) error { + _, err := db.relatedCollection.CreateEdges(ctx, edges) + return err +} + +func (db *Database) RelatedRemove(ctx context.Context, id, id2 int64) error { + q := ` + FOR d in @@collection + FILTER (d._from == @id && d._to == @id2) || (d._to == @id && d._from == @id2) + REMOVE d in @@collection` + _, _, err := db.Query(ctx, q, map[string]interface{}{ + "@collection": RelatedTicketsCollectionName, + "id": driver.DocumentID(TicketCollectionName + "/" + strconv.Itoa(int(id))), + "id2": driver.DocumentID(TicketCollectionName + "/" + strconv.Itoa(int(id2))), + }, &busdb.Operation{ + OperationType: busdb.Update, + Ids: []driver.DocumentID{ + driver.DocumentID(TicketCollectionName + "/" + strconv.Itoa(int(id))), + driver.DocumentID(TicketCollectionName + "/" + strconv.Itoa(int(id2))), + }, + Msg: "Removed ticket/artifact relation", + }) + return err +} diff --git a/database/settings.go b/database/settings.go new file mode 100644 index 0000000..67136b7 --- /dev/null +++ b/database/settings.go @@ -0,0 +1,86 @@ +package database + +import ( + "context" + "errors" + + "github.com/arangodb/go-driver" + "github.com/gin-gonic/gin" + + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" +) + +func toUserDataResponse(key string, doc *models.UserData) *models.UserDataResponse { + return &models.UserDataResponse{ + Email: doc.Email, + ID: key, + Image: doc.Image, + Name: doc.Name, + Timeformat: doc.Timeformat, + } +} + +func (db *Database) UserDataCreate(ctx context.Context, id string, userdata *models.UserData) error { + if userdata == nil { + return errors.New("requires setting") + } + if id == "" { + return errors.New("requires username") + } + + _, err := db.userdataCollection.CreateDocument(ctx, ctx, id, userdata) + return err +} + +func (db *Database) UserDataGetOrCreate(ctx *gin.Context, id string, newUserData *models.UserData) (*models.UserDataResponse, error) { + setting, err := db.UserDataGet(ctx, id) + if err != nil { + return toUserDataResponse(id, newUserData), db.UserDataCreate(ctx, id, newUserData) + } + return setting, nil +} + +func (db *Database) UserDataGet(ctx context.Context, id string) (*models.UserDataResponse, error) { + var doc models.UserData + meta, err := db.userdataCollection.ReadDocument(ctx, id, &doc) + if err != nil { + return nil, err + } + + return toUserDataResponse(meta.Key, &doc), err +} + +func (db *Database) UserDataList(ctx context.Context) ([]*models.UserDataResponse, error) { + query := "FOR d IN @@collection SORT d.username ASC RETURN d" + cursor, _, err := db.Query(ctx, query, map[string]interface{}{"@collection": UserDataCollectionName}, busdb.ReadOperation) + if err != nil { + return nil, err + } + defer cursor.Close() + var docs []*models.UserDataResponse + for { + var doc models.UserData + meta, err := cursor.ReadDocument(ctx, &doc) + if driver.IsNoMoreDocuments(err) { + break + } else if err != nil { + return nil, err + } + docs = append(docs, toUserDataResponse(meta.Key, &doc)) + } + + return docs, err +} + +func (db *Database) UserDataUpdate(ctx context.Context, id string, userdata *models.UserData) (*models.UserDataResponse, error) { + var doc models.UserData + ctx = driver.WithReturnNew(ctx, &doc) + + meta, err := db.userdataCollection.ReplaceDocument(ctx, id, userdata) + if err != nil { + return nil, err + } + + return toUserDataResponse(meta.Key, &doc), nil +} diff --git a/database/settings_test.go b/database/settings_test.go new file mode 100644 index 0000000..52adc05 --- /dev/null +++ b/database/settings_test.go @@ -0,0 +1,159 @@ +package database_test + +import ( + "testing" + + "github.com/gin-gonic/gin" + "github.com/stretchr/testify/assert" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/pointer" + "github.com/SecurityBrewery/catalyst/test" +) + +func init() { + gin.SetMode(gin.TestMode) +} + +var bob = &models.UserData{ + Email: pointer.String("bob@example.org"), + Name: pointer.String("Bob"), +} + +var bobResponse = &models.UserDataResponse{ + ID: "bob", + Email: pointer.String("bob@example.org"), + Name: pointer.String("Bob"), +} + +func TestDatabase_UserDataCreate(t *testing.T) { + type args struct { + id string + setting *models.UserData + } + tests := []struct { + name string + args args + wantErr bool + }{ + {name: "Normal setting", args: args{id: "bob", setting: bob}, wantErr: false}, + {name: "Nil setting", args: args{id: "bob"}, wantErr: true}, + {name: "UserData without settingname", args: args{id: ""}, wantErr: true}, + {name: "Only settingname", args: args{id: "bob"}, wantErr: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, _, _, _, _, db, cleanup, err := test.DB(t) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + if err := db.UserDataCreate(test.Context(), tt.args.id, tt.args.setting); (err != nil) != tt.wantErr { + t.Errorf("settingCreate() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestDatabase_UserDataGet(t *testing.T) { + type args struct { + id string + } + tests := []struct { + name string + args args + want *models.UserDataResponse + wantErr bool + }{ + {name: "Normal get", args: args{id: "bob"}, want: bobResponse}, + {name: "Not existing", args: args{id: "foo"}, wantErr: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, _, _, _, _, db, cleanup, err := test.DB(t) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + if err := db.UserDataCreate(test.Context(), "bob", bob); err != nil { + t.Errorf("settingCreate() error = %v", err) + } + + got, err := db.UserDataGet(test.Context(), tt.args.id) + if (err != nil) != tt.wantErr { + t.Errorf("UserDataGet() error = %v, wantErr %v", err, tt.wantErr) + return + } + if err != nil { + return + } + + assert.Equal(t, tt.want, got) + }) + } +} + +func TestDatabase_UserDataList(t *testing.T) { + tests := []struct { + name string + want []*models.UserDataResponse + wantErr bool + }{ + {name: "Normal list", want: []*models.UserDataResponse{bobResponse}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, _, _, _, _, db, cleanup, err := test.DB(t) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + if err := db.UserDataCreate(test.Context(), "bob", bob); err != nil { + t.Errorf("settingCreate() error = %v", err) + } + + got, err := db.UserDataList(test.Context()) + if (err != nil) != tt.wantErr { + t.Errorf("UserDataList() error = %v, wantErr %v", err, tt.wantErr) + return + } + + assert.Equal(t, tt.want, got) + }) + } +} + +func TestDatabase_UserDataUpdate(t *testing.T) { + type args struct { + id string + setting *models.UserData + } + tests := []struct { + name string + args args + wantErr bool + }{ + {name: "Normal", args: args{id: "bob", setting: bob}}, + {name: "Not existing", args: args{id: "foo"}, wantErr: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, _, _, _, _, db, cleanup, err := test.DB(t) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + if err := db.UserDataCreate(test.Context(), "bob", bob); err != nil { + t.Errorf("settingCreate() error = %v", err) + } + + if _, err := db.UserDataUpdate(test.Context(), tt.args.id, tt.args.setting); (err != nil) != tt.wantErr { + t.Errorf("UserDataUpdate() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/database/statistics.go b/database/statistics.go new file mode 100644 index 0000000..3073f94 --- /dev/null +++ b/database/statistics.go @@ -0,0 +1,43 @@ +package database + +import ( + "context" + + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" +) + +func (db *Database) Statistics(ctx context.Context) (*models.Statistics, error) { + query := `RETURN { + tickets_per_type: MERGE(FOR d in tickets + COLLECT type = d.type WITH COUNT INTO typecount + RETURN ZIP([type], [typecount])), + + unassigned: FIRST(FOR d in tickets + FILTER d.status == "open" AND !d.owner + COLLECT WITH COUNT INTO length + RETURN length), + + open_tickets_per_user: MERGE(FOR d in tickets + FILTER d.status == "open" + COLLECT user = d.owner WITH COUNT INTO usercount + RETURN ZIP([user], [usercount])), + + tickets_per_week: MERGE(FOR d in tickets + COLLECT week = CONCAT(DATE_YEAR(d.created), "-", DATE_ISOWEEK(d.created) < 10 ? "0" : "", DATE_ISOWEEK(d.created)) WITH COUNT INTO weekcount + RETURN ZIP([week], [weekcount])), + }` + + cur, _, err := db.Query(ctx, query, nil, busdb.ReadOperation) + if err != nil { + return nil, err + } + defer cur.Close() + + statistics := models.Statistics{} + if _, err := cur.ReadDocument(ctx, &statistics); err != nil { + return nil, err + } + + return &statistics, nil +} diff --git a/database/task.go b/database/task.go new file mode 100644 index 0000000..b8b2d81 --- /dev/null +++ b/database/task.go @@ -0,0 +1,68 @@ +package database + +import ( + "context" + + "github.com/arangodb/go-driver" + + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" +) + +type playbookResponse struct { + PlaybookId string `json:"playbook_id"` + PlaybookName string `json:"playbook_name"` + Playbook models.Playbook `json:"playbook"` + TicketId int64 `json:"ticket_id"` + TicketName string `json:"ticket_name"` +} + +func (db *Database) TaskList(ctx context.Context) ([]*models.TaskWithContext, error) { + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketWriteFilter(ctx) + if err != nil { + return nil, err + } + + query := `FOR d IN @@collection + ` + ticketFilterQuery + ` + FILTER d.status == 'open' + FOR playbook IN NOT_NULL(VALUES(d.playbooks), []) + RETURN { ticket_id: TO_NUMBER(d._key), ticket_name: d.name, playbook_id: POSITION(d.playbooks, playbook, true), playbook_name: playbook.name, playbook: playbook }` + cursor, _, err := db.Query(ctx, query, mergeMaps(ticketFilterVars, map[string]interface{}{ + "@collection": TicketCollectionName, + }), busdb.ReadOperation) + if err != nil { + return nil, err + } + defer cursor.Close() + docs := []*models.TaskWithContext{} + for { + var doc playbookResponse + _, err := cursor.ReadDocument(ctx, &doc) + if driver.IsNoMoreDocuments(err) { + break + } else if err != nil { + return nil, err + } + + + playbook, err := toPlaybookResponse(&doc.Playbook) + if err != nil { + return nil, err + } + + for _, task := range playbook.Tasks { + if task.Active { + docs = append(docs, &models.TaskWithContext{ + PlaybookId: doc.PlaybookId, + PlaybookName: doc.PlaybookName, + Task: *task, + TicketId: doc.TicketId, + TicketName: doc.TicketName, + }) + } + } + } + + return docs, err +} diff --git a/database/template.go b/database/template.go new file mode 100644 index 0000000..5e33996 --- /dev/null +++ b/database/template.go @@ -0,0 +1,88 @@ +package database + +import ( + "context" + "errors" + + "github.com/arangodb/go-driver" + "github.com/iancoleman/strcase" + + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" +) + +func toTicketTemplate(doc *models.TicketTemplateForm) *models.TicketTemplate { + return &models.TicketTemplate{Name: doc.Name, Schema: doc.Schema} +} + +func toTicketTemplateResponse(key string, doc *models.TicketTemplate) *models.TicketTemplateResponse { + return &models.TicketTemplateResponse{ID: key, Name: doc.Name, Schema: doc.Schema} +} + +func (db *Database) TemplateCreate(ctx context.Context, template *models.TicketTemplateForm) (*models.TicketTemplateResponse, error) { + if template == nil { + return nil, errors.New("requires template") + } + if template.Name == "" { + return nil, errors.New("requires template name") + } + + var doc models.TicketTemplate + newctx := driver.WithReturnNew(ctx, &doc) + + meta, err := db.templateCollection.CreateDocument(ctx, newctx, strcase.ToKebab(template.Name), toTicketTemplate(template)) + if err != nil { + return nil, err + } + + return toTicketTemplateResponse(meta.Key, &doc), nil +} + +func (db *Database) TemplateGet(ctx context.Context, id string) (*models.TicketTemplateResponse, error) { + var doc models.TicketTemplate + meta, err := db.templateCollection.ReadDocument(ctx, id, &doc) + if err != nil { + return nil, err + } + + return toTicketTemplateResponse(meta.Key, &doc), nil +} + +func (db *Database) TemplateUpdate(ctx context.Context, id string, template *models.TicketTemplateForm) (*models.TicketTemplateResponse, error) { + var doc models.TicketTemplate + ctx = driver.WithReturnNew(ctx, &doc) + + meta, err := db.templateCollection.ReplaceDocument(ctx, id, toTicketTemplate(template)) + if err != nil { + return nil, err + } + + return toTicketTemplateResponse(meta.Key, &doc), nil +} + +func (db *Database) TemplateDelete(ctx context.Context, id string) error { + _, err := db.templateCollection.RemoveDocument(ctx, id) + return err +} + +func (db *Database) TemplateList(ctx context.Context) ([]*models.TicketTemplateResponse, error) { + query := "FOR d IN @@collection RETURN d" + cursor, _, err := db.Query(ctx, query, map[string]interface{}{"@collection": TemplateCollectionName}, busdb.ReadOperation) + if err != nil { + return nil, err + } + defer cursor.Close() + var docs []*models.TicketTemplateResponse + for { + var doc models.TicketTemplate + meta, err := cursor.ReadDocument(ctx, &doc) + if driver.IsNoMoreDocuments(err) { + break + } else if err != nil { + return nil, err + } + docs = append(docs, toTicketTemplateResponse(meta.Key, &doc)) + } + + return docs, err +} diff --git a/database/template_test.go b/database/template_test.go new file mode 100644 index 0000000..76fa1c6 --- /dev/null +++ b/database/template_test.go @@ -0,0 +1,182 @@ +package database_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/SecurityBrewery/catalyst/database/migrations" + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/test" +) + +var template1 = &models.TicketTemplateForm{ + Schema: migrations.DefaultTemplateSchema, + Name: "Template 1", +} +var default1 = &models.TicketTemplateForm{ + Schema: migrations.DefaultTemplateSchema, + Name: "Default", +} + +func TestDatabase_TemplateCreate(t *testing.T) { + type args struct { + template *models.TicketTemplateForm + } + tests := []struct { + name string + args args + wantErr bool + }{ + {name: "Normal", args: args{template: template1}}, + {name: "Duplicate", args: args{template: default1}, wantErr: true}, + {name: "Nil template", args: args{}, wantErr: true}, + {name: "Template without fields", args: args{template: &models.TicketTemplateForm{}}, wantErr: true}, + {name: "Only name", args: args{template: &models.TicketTemplateForm{Name: "name"}}, wantErr: false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, _, _, _, _, db, cleanup, err := test.DB(t) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + if _, err := db.TemplateCreate(test.Context(), tt.args.template); (err != nil) != tt.wantErr { + t.Errorf("TemplateCreate() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestDatabase_TemplateDelete(t *testing.T) { + type args struct { + id string + } + tests := []struct { + name string + args args + wantErr bool + }{ + {name: "Normal", args: args{"default"}}, + {name: "Not existing", args: args{"foobar"}, wantErr: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, _, _, _, _, db, cleanup, err := test.DB(t) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + if _, err := db.TemplateCreate(test.Context(), template1); err != nil { + t.Errorf("TemplateCreate() error = %v", err) + } + + if err := db.TemplateDelete(test.Context(), tt.args.id); (err != nil) != tt.wantErr { + t.Errorf("TemplateDelete() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestDatabase_TemplateGet(t *testing.T) { + type args struct { + id string + } + tests := []struct { + name string + args args + want *models.TicketTemplateResponse + wantErr bool + }{ + {name: "Normal", args: args{id: "default"}, want: &models.TicketTemplateResponse{ID: "default", Name: "Default", Schema: migrations.DefaultTemplateSchema}}, + {name: "Not existing", args: args{id: "foobar"}, wantErr: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, _, _, _, _, db, cleanup, err := test.DB(t) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + if _, err := db.TemplateCreate(test.Context(), template1); err != nil { + t.Errorf("TemplateCreate() error = %v", err) + } + + got, err := db.TemplateGet(test.Context(), tt.args.id) + if (err != nil) != tt.wantErr { + t.Errorf("TemplateGet() error = %v, wantErr %v", err, tt.wantErr) + return + } + if err != nil { + return + } + + assert.Equal(t, got, tt.want) + }) + } +} + +func TestDatabase_TemplateList(t *testing.T) { + tests := []struct { + name string + want []*models.TicketTemplateResponse + wantErr bool + }{ + {name: "Normal", want: []*models.TicketTemplateResponse{{ID: "default", Name: "Default", Schema: migrations.DefaultTemplateSchema}, {ID: "template-1", Name: template1.Name, Schema: template1.Schema}}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, _, _, _, _, db, cleanup, err := test.DB(t) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + if _, err := db.TemplateCreate(test.Context(), template1); err != nil { + t.Errorf("TemplateCreate() error = %v", err) + } + + got, err := db.TemplateList(test.Context()) + if (err != nil) != tt.wantErr { + t.Errorf("TemplateList() error = %v, wantErr %v", err, tt.wantErr) + return + } + assert.Equal(t, got, tt.want) + }) + } +} + +func TestDatabase_TemplateUpdate(t *testing.T) { + type args struct { + id string + template *models.TicketTemplateForm + } + tests := []struct { + name string + args args + wantErr bool + }{ + {name: "Normal", args: args{"default", template1}}, + {name: "Not existing", args: args{"foobar", template1}, wantErr: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, _, _, _, _, db, cleanup, err := test.DB(t) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + if _, err := db.TemplateCreate(test.Context(), template1); err != nil { + t.Errorf("TemplateCreate() error = %v", err) + } + + if _, err := db.TemplateUpdate(test.Context(), tt.args.id, tt.args.template); (err != nil) != tt.wantErr { + t.Errorf("TemplateUpdate() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/database/ticket.go b/database/ticket.go new file mode 100644 index 0000000..bb03c75 --- /dev/null +++ b/database/ticket.go @@ -0,0 +1,604 @@ +package database + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "sort" + "strconv" + "strings" + "sync" + "time" + + "github.com/arangodb/go-driver" + "github.com/xeipuuv/gojsonschema" + + "github.com/SecurityBrewery/catalyst/caql" + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/index" +) + +func toTicket(ticketForm *models.TicketForm) (interface{}, error) { + playbooks, err := toPlaybooks(ticketForm.Playbooks) + if err != nil { + return nil, err + } + + ticket := &models.Ticket{ + Artifacts: ticketForm.Artifacts, + Comments: ticketForm.Comments, + Details: ticketForm.Details, + Files: ticketForm.Files, + Name: ticketForm.Name, + Owner: ticketForm.Owner, + Playbooks: playbooks, + Read: ticketForm.Read, + References: ticketForm.References, + Status: ticketForm.Status, + Type: ticketForm.Type, + Write: ticketForm.Write, + // ID: ticketForm.ID, + // Created: ticketForm.Created, + // Modified: ticketForm.Modified, + // Schema: ticketForm.Schema, + } + + if ticketForm.Created != nil { + ticket.Created = *ticketForm.Created + } else { + ticket.Created = time.Now().UTC() + } + if ticketForm.Modified != nil { + ticket.Modified = *ticketForm.Modified + } else { + ticket.Modified = time.Now().UTC() + } + if ticketForm.Schema != nil { + ticket.Schema = *ticketForm.Schema + } else { + ticket.Schema = "{}" + } + if ticketForm.Status == "" { + ticket.Status = "open" + } + if ticketForm.ID != nil { + return &busdb.Keyed{Key: strconv.FormatInt(*ticketForm.ID, 10), Doc: ticket}, nil + } + return ticket, nil +} + +func toTicketResponses(tickets []*models.TicketSimpleResponse) ([]*models.TicketResponse, error) { + var extendedTickets []*models.TicketResponse + for _, simple := range tickets { + tr, err := toTicketResponse(simple) + if err != nil { + return nil, err + } + extendedTickets = append(extendedTickets, tr) + } + return extendedTickets, nil +} + +func toTicketResponse(ticket *models.TicketSimpleResponse) (*models.TicketResponse, error) { + playbooks, err := toPlaybookResponses(ticket.Playbooks) + if err != nil { + return nil, err + } + + return &models.TicketResponse{ + ID: ticket.ID, + Artifacts: ticket.Artifacts, + Comments: ticket.Comments, + Created: ticket.Created, + Details: ticket.Details, + Files: ticket.Files, + Modified: ticket.Modified, + Name: ticket.Name, + Owner: ticket.Owner, + Playbooks: playbooks, + Read: ticket.Read, + References: ticket.References, + Schema: ticket.Schema, + Status: ticket.Status, + Type: ticket.Type, + Write: ticket.Write, + }, nil +} + +func toTicketSimpleResponse(key string, ticket *models.Ticket) (*models.TicketSimpleResponse, error) { + id, err := strconv.ParseInt(key, 10, 64) + if err != nil { + return nil, err + } + + return &models.TicketSimpleResponse{ + Artifacts: ticket.Artifacts, + Comments: ticket.Comments, + Created: ticket.Created, + Details: ticket.Details, + Files: ticket.Files, + ID: id, + Modified: ticket.Modified, + Name: ticket.Name, + Owner: ticket.Owner, + Playbooks: ticket.Playbooks, + Read: ticket.Read, + References: ticket.References, + Schema: ticket.Schema, + Status: ticket.Status, + Type: ticket.Type, + Write: ticket.Write, + }, nil +} + +func toTicketWithTickets(ticketResponse *models.TicketResponse, tickets []*models.TicketSimpleResponse) *models.TicketWithTickets { + return &models.TicketWithTickets{ + Artifacts: ticketResponse.Artifacts, + Comments: ticketResponse.Comments, + Created: ticketResponse.Created, + Details: ticketResponse.Details, + Files: ticketResponse.Files, + ID: ticketResponse.ID, + Modified: ticketResponse.Modified, + Name: ticketResponse.Name, + Owner: ticketResponse.Owner, + Playbooks: ticketResponse.Playbooks, + Read: ticketResponse.Read, + References: ticketResponse.References, + Schema: ticketResponse.Schema, + Status: ticketResponse.Status, + Type: ticketResponse.Type, + Write: ticketResponse.Write, + + Tickets: tickets, + } +} + +func toPlaybookResponses(playbooks map[string]*models.Playbook) (map[string]*models.PlaybookResponse, error) { + pr := map[string]*models.PlaybookResponse{} + var err error + for k, v := range playbooks { + pr[k], err = toPlaybookResponse(v) + if err != nil { + return nil, err + } + } + return pr, nil +} + +func toPlaybookResponse(playbook *models.Playbook) (*models.PlaybookResponse, error) { + graph, err := playbookGraph(playbook) + if err != nil { + return nil, err + } + + re := &models.PlaybookResponse{ + Name: playbook.Name, + Tasks: map[string]*models.TaskResponse{}, + } + + results, err := graph.Toposort() + if err != nil { + return nil, err + } + + i := 0 + for _, taskID := range results { + rootTask, err := toTaskResponse(playbook, taskID, i, graph) + if err != nil { + return nil, err + } + re.Tasks[taskID] = rootTask + i++ + } + return re, nil +} + +func (db *Database) TicketBatchCreate(ctx context.Context, ticketForms []*models.TicketForm) ([]*models.TicketResponse, error) { + update, err := db.Hooks.IngestionFilter(ctx, db.Index) + if err != nil { + return nil, err + } + + var dbTickets []interface{} + for _, ticketForm := range ticketForms { + ticket, err := toTicket(ticketForm) + if err != nil { + return nil, err + } + + if err := validate(ticket, models.TicketSchema); err != nil { + return nil, err + } + + dbTickets = append(dbTickets, ticket) + } + + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketWriteFilter(ctx) + if err != nil { + return nil, err + } + + query := `FOR d IN @tickets + ` + ticketFilterQuery + ` + LET updates = ` + update + ` + LET newdoc = LENGTH(updates) != 0 ? APPLY("MERGE_RECURSIVE", APPEND([d], updates)) : d + LET keyeddoc = HAS(newdoc, "id") ? MERGE(newdoc, {"_key": TO_STRING(newdoc.id)}) : newdoc + LET noiddoc = UNSET(keyeddoc, "id") + INSERT noiddoc INTO @@collection + RETURN NEW` + apiTickets, _, err := db.ticketListQuery(ctx, query, mergeMaps(map[string]interface{}{ + "tickets": dbTickets, + }, ticketFilterVars), busdb.CreateOperation) + if err != nil { + return nil, err + } + + if err = batchIndex(db.Index, apiTickets); err != nil { + return nil, err + } + + var ids []driver.DocumentID + for _, apiTicket := range apiTickets { + ids = append(ids, driver.NewDocumentID(TicketCollectionName, fmt.Sprint(apiTicket.ID))) + } + if err := db.BusDatabase.LogAndNotify(ctx, ids, "Ticket created"); err != nil { + return nil, err + } + + ticketResponses, err := toTicketResponses(apiTickets) + if err != nil { + return nil, err + } + + for _, ticketResponse := range ticketResponses { + for playbookID := range ticketResponse.Playbooks { + if err := runRootTask(ticketResponse, playbookID, db); err != nil { + return nil, err + } + } + } + + return ticketResponses, nil +} + +func (db *Database) IndexRebuild(ctx context.Context) error { + if err := db.Index.Truncate(); err != nil { + return err + } + + tickets, _, err := db.ticketListQuery(ctx, "FOR d IN @@collection RETURN d", nil, busdb.ReadOperation) + if err != nil { + return err + } + + return batchIndex(db.Index, tickets) +} + +func batchIndex(index *index.Index, tickets []*models.TicketSimpleResponse) error { + var wg sync.WaitGroup + var batch []*models.TicketSimpleResponse + for _, ticket := range tickets { + batch = append(batch, ticket) + + if len(batch) > 100 { + wg.Add(1) + go func(docs []*models.TicketSimpleResponse) { + index.Index(docs) + wg.Done() + }(batch) + batch = []*models.TicketSimpleResponse{} + } + } + wg.Wait() + return nil +} + +func (db *Database) TicketGet(ctx context.Context, ticketID int64) (*models.TicketWithTickets, error) { + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketReadFilter(ctx) + if err != nil { + return nil, err + } + + return db.ticketGetQuery(ctx, ticketID, `LET d = DOCUMENT(@@collection, @ID) `+ticketFilterQuery+` RETURN d`, ticketFilterVars, busdb.ReadOperation) +} + +func (db *Database) ticketGetQuery(ctx context.Context, ticketID int64, query string, bindVars map[string]interface{}, operation *busdb.Operation) (*models.TicketWithTickets, error) { + if bindVars == nil { + bindVars = map[string]interface{}{} + } + bindVars["@collection"] = TicketCollectionName + if ticketID != 0 { + bindVars["ID"] = fmt.Sprint(ticketID) + } + + cur, _, err := db.Query(ctx, query, bindVars, operation) + if err != nil { + return nil, err + } + defer cur.Close() + + ticket := models.Ticket{} + meta, err := cur.ReadDocument(ctx, &ticket) + if err != nil { + return nil, err + } + + ticketSimpleResponse, err := toTicketSimpleResponse(meta.Key, &ticket) + if err != nil { + return nil, err + } + + // index + go db.Index.Index([]*models.TicketSimpleResponse{ticketSimpleResponse}) + + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketReadFilter(ctx) + if err != nil { + return nil, err + } + + // tickets + ticketsQuery := `FOR vertex, edge IN OUTBOUND + DOCUMENT(@@tickets, @ID) + GRAPH @graph + FILTER IS_SAME_COLLECTION(@@collection, vertex) + FILTER vertex != null + LET d = DOCUMENT(@@collection, edge["_to"]) + ` + ticketFilterQuery + ` + RETURN d` + + outTickets, _, err := db.ticketListQuery(ctx, ticketsQuery, mergeMaps(map[string]interface{}{ + "ID": fmt.Sprint(ticketID), + "graph": TicketArtifactsGraphName, + "@tickets": TicketCollectionName, + }, ticketFilterVars), busdb.ReadOperation) + if err != nil { + return nil, err + } + + ticketsQuery = `FOR vertex, edge IN INBOUND + DOCUMENT(@@tickets, @ID) + GRAPH @graph + FILTER IS_SAME_COLLECTION(@@collection, vertex) + FILTER vertex != null + LET d = DOCUMENT(@@collection, edge["_from"]) + ` + ticketFilterQuery + ` + RETURN d` + + inTickets, _, err := db.ticketListQuery(ctx, ticketsQuery, mergeMaps(map[string]interface{}{ + "ID": fmt.Sprint(ticketID), + "graph": TicketArtifactsGraphName, + "@tickets": TicketCollectionName, + }, ticketFilterVars), busdb.ReadOperation) + if err != nil { + return nil, err + } + + var artifactNames []string + for _, artifact := range ticketSimpleResponse.Artifacts { + artifactNames = append(artifactNames, artifact.Name) + } + ticketsQuery = `FOR d IN @@collection + FILTER d._key != @ID + ` + ticketFilterQuery + ` + FOR a IN NOT_NULL(d.artifacts, []) + FILTER POSITION(@artifacts, a.name) + RETURN d` + sameArtifactTickets, _, err := db.ticketListQuery(ctx, ticketsQuery, mergeMaps(map[string]interface{}{ + "ID": fmt.Sprint(ticketID), + "artifacts": artifactNames, + }, ticketFilterVars), busdb.ReadOperation) + if err != nil { + return nil, err + } + + tickets := append(outTickets, inTickets...) + tickets = append(tickets, sameArtifactTickets...) + sort.Slice(tickets, func(i, j int) bool { + return tickets[i].ID < tickets[j].ID + }) + + ticketResponse, err := toTicketResponse(ticketSimpleResponse) + if err != nil { + return nil, err + } + + return toTicketWithTickets(ticketResponse, tickets), nil +} + +func (db *Database) TicketUpdate(ctx context.Context, ticketID int64, ticket *models.Ticket) (*models.TicketWithTickets, error) { + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketWriteFilter(ctx) + if err != nil { + return nil, err + } + + query := `LET d = DOCUMENT(@@collection, @ID) + ` + ticketFilterQuery + ` + REPLACE d WITH @ticket IN @@collection + RETURN NEW` + ticket.Modified = time.Now().UTC() // TODO make setable? + return db.ticketGetQuery(ctx, ticketID, query, mergeMaps(map[string]interface{}{"ticket": ticket}, ticketFilterVars), &busdb.Operation{ + OperationType: busdb.Update, Ids: []driver.DocumentID{ + driver.NewDocumentID(TicketCollectionName, strconv.FormatInt(ticketID, 10)), + }, + Msg: "Ticket updated", + }) +} + +func (db *Database) TicketDelete(ctx context.Context, ticketID int64) error { + _, err := db.TicketGet(ctx, ticketID) + if err != nil { + return err + } + + _, err = db.ticketCollection.RemoveDocument(ctx, strconv.FormatInt(ticketID, 10)) + if err != nil { + return err + } + + return nil +} + +func (db *Database) TicketList(ctx context.Context, ticketType string, query string, sorts []string, desc []bool, offset, count int64) (*models.TicketList, error) { + binVars := map[string]interface{}{} + + parser := &caql.Parser{Searcher: db.Index, Prefix: "d."} + + var typeString = "" + if ticketType != "" { + typeString = "FILTER d.type == @type " + binVars["type"] = ticketType + } + + var filterString = "" + if query != "" { + queryTree, err := parser.Parse(query) + if err != nil { + return nil, errors.New("invalid filter query: syntax error") + } + filterString, err = queryTree.String() + if err != nil { + return nil, fmt.Errorf("invalid filter query: %w", err) + } + filterString = "FILTER " + filterString + } + + documentCount, err := db.TicketCount(ctx, typeString, filterString, binVars) + if err != nil { + return nil, err + } + + sortQ := sortQuery(sorts, desc, binVars) + binVars["offset"] = offset + binVars["count"] = count + + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketReadFilter(ctx) + if err != nil { + return nil, err + } + + q := `FOR d IN @@collection + ` + ticketFilterQuery + ` + ` + sortQ + ` + ` + typeString + ` + ` + filterString + ` + LIMIT @offset, @count + SORT d._key ASC + RETURN d` + // RETURN KEEP(d, "_key", "id", "name", "type", "created")` + ticketList, _, err := db.ticketListQuery(ctx, q, mergeMaps(binVars, ticketFilterVars), busdb.ReadOperation) + return &models.TicketList{ + Count: documentCount, + Tickets: ticketList, + }, err + // return map[string]interface{}{"tickets": ticketList, "count": documentCount}, err +} + +func (db *Database) ticketListQuery(ctx context.Context, query string, bindVars map[string]interface{}, operation *busdb.Operation) ([]*models.TicketSimpleResponse, *models.LogEntry, error) { + if bindVars == nil { + bindVars = map[string]interface{}{} + } + bindVars["@collection"] = TicketCollectionName + + cursor, logEntry, err := db.Query(ctx, query, bindVars, operation) + if err != nil { + return nil, nil, err + } + defer cursor.Close() + + var docs []*models.TicketSimpleResponse + for { + doc := models.Ticket{} + meta, err := cursor.ReadDocument(ctx, &doc) + if driver.IsNoMoreDocuments(err) { + break + } else if err != nil { + return nil, nil, err + } + + resp, err := toTicketSimpleResponse(meta.Key, &doc) + if err != nil { + return nil, nil, err + } + + docs = append(docs, resp) + } + + return docs, logEntry, nil +} + +func (db *Database) TicketCount(ctx context.Context, typequery, filterquery string, bindVars map[string]interface{}) (int, error) { + if bindVars == nil { + bindVars = map[string]interface{}{} + } + bindVars["@collection"] = TicketCollectionName + + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketReadFilter(ctx) + if err != nil { + return 0, err + } + + countQuery := `RETURN LENGTH(FOR d IN @@collection ` + ticketFilterQuery + " " + typequery + " " + filterquery + ` RETURN 1)` + cursor, _, err := db.Query(ctx, countQuery, mergeMaps(bindVars, ticketFilterVars), busdb.ReadOperation) + if err != nil { + return 0, err + } + documentCount := 0 + _, err = cursor.ReadDocument(ctx, &documentCount) + if err != nil { + return 0, err + } + cursor.Close() + return documentCount, nil +} + +func sortQuery(paramsSort []string, paramsDesc []bool, bindVars map[string]interface{}) string { + sort := "" + if len(paramsSort) > 0 { + var sorts []string + for i, column := range paramsSort { + colsort := fmt.Sprintf("d.@column%d", i) + if len(paramsDesc) > i && paramsDesc[i] { + colsort += " DESC" + } + sorts = append(sorts, colsort) + bindVars[fmt.Sprintf("column%d", i)] = column + } + sort = "SORT " + strings.Join(sorts, ", ") + } + return sort +} + +func mergeMaps(a map[string]interface{}, b map[string]interface{}) map[string]interface{} { + merged := map[string]interface{}{} + for k, v := range a { + merged[k] = v + } + for k, v := range b { + merged[k] = v + } + return merged +} + +func validate(e interface{}, schema *gojsonschema.Schema) error { + b, err := json.Marshal(e) + if err != nil { + return err + } + + res, err := schema.Validate(gojsonschema.NewStringLoader(string(b))) + if err != nil { + return err + } + + if len(res.Errors()) > 0 { + var l []string + for _, e := range res.Errors() { + l = append(l, e.String()) + } + return fmt.Errorf("validation failed: %v", strings.Join(l, ", ")) + } + return nil +} diff --git a/database/ticket_field.go b/database/ticket_field.go new file mode 100644 index 0000000..7f7df2b --- /dev/null +++ b/database/ticket_field.go @@ -0,0 +1,291 @@ +package database + +import ( + "context" + "errors" + "fmt" + "time" + + "github.com/arangodb/go-driver" + "github.com/iancoleman/strcase" + "github.com/mingrammer/commonregex" + + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/pointer" +) + +func (db *Database) AddArtifact(ctx context.Context, id int64, artifact *models.Artifact) (*models.TicketWithTickets, error) { + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketWriteFilter(ctx) + if err != nil { + return nil, err + } + + if artifact.Status == nil { + artifact.Status = pointer.String("unknown") + } + + if artifact.Type == nil { + artifact.Type = pointer.String(inferType(artifact.Name)) + } + + query := `LET d = DOCUMENT(@@collection, @ID) + ` + ticketFilterQuery + ` + UPDATE d WITH { "modified": DATE_ISO8601(DATE_NOW()), "artifacts": PUSH(NOT_NULL(d.artifacts, []), @artifact) } IN @@collection + RETURN NEW` + return db.ticketGetQuery(ctx, id, query, mergeMaps(map[string]interface{}{"artifact": artifact}, ticketFilterVars), &busdb.Operation{ + OperationType: busdb.Update, + Ids: []driver.DocumentID{ + driver.DocumentID(fmt.Sprintf("%s/%d", TicketCollectionName, id)), + }, + Msg: "Add artifact", + }) +} + +func inferType(name string) string { + switch { + case commonregex.IPRegex.MatchString(name): + return "ip" + case commonregex.LinkRegex.MatchString(name): + return "url" + case commonregex.EmailRegex.MatchString(name): + return "email" + case commonregex.MD5HexRegex.MatchString(name): + return "md5" + case commonregex.SHA1HexRegex.MatchString(name): + return "sha1" + case commonregex.SHA256HexRegex.MatchString(name): + return "sha256" + } + return "unknown" +} + +func (db *Database) RemoveArtifact(ctx context.Context, id int64, name string) (*models.TicketWithTickets, error) { + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketWriteFilter(ctx) + if err != nil { + return nil, err + } + + query := `LET d = DOCUMENT(@@collection, @ID) + ` + ticketFilterQuery + ` + FOR a IN NOT_NULL(d.artifacts, []) + FILTER a.name == @name + LET newartifacts = REMOVE_VALUE(d.artifacts, a) + UPDATE d WITH { "modified": DATE_ISO8601(DATE_NOW()), "artifacts": newartifacts } IN @@collection + RETURN NEW` + return db.ticketGetQuery(ctx, id, query, mergeMaps(map[string]interface{}{"name": name}, ticketFilterVars), &busdb.Operation{ + OperationType: busdb.Update, + Ids: []driver.DocumentID{ + driver.DocumentID(fmt.Sprintf("%s/%d", TicketCollectionName, id)), + }, + Msg: "Remove artifact", + }) +} + +func (db *Database) SetTemplate(ctx context.Context, id int64, schema string) (*models.TicketWithTickets, error) { + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketWriteFilter(ctx) + if err != nil { + return nil, err + } + + query := `LET d = DOCUMENT(@@collection, @ID) + ` + ticketFilterQuery + ` + UPDATE d WITH { "schema": @schema } IN @@collection + RETURN NEW` + return db.ticketGetQuery(ctx, id, query, mergeMaps(map[string]interface{}{"schema": schema}, ticketFilterVars), &busdb.Operation{ + OperationType: busdb.Update, + Ids: []driver.DocumentID{ + driver.DocumentID(fmt.Sprintf("%s/%d", TicketCollectionName, id)), + }, + Msg: "Set Template", + }) +} + +func (db *Database) AddComment(ctx context.Context, id int64, comment *models.CommentForm) (*models.TicketWithTickets, error) { + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketWriteFilter(ctx) + if err != nil { + return nil, err + } + + if comment.Creator == nil || *comment.Creator == "" { + user, exists := busdb.UserFromContext(ctx) + if !exists { + return nil, errors.New("no user in context") + } + + comment.Creator = pointer.String(user.ID) + } + + if comment.Created == nil { + comment.Created = pointer.Time(time.Now().UTC()) + } + + query := `LET d = DOCUMENT(@@collection, @ID) + ` + ticketFilterQuery + ` + UPDATE d WITH { "modified": DATE_ISO8601(DATE_NOW()), "comments": PUSH(NOT_NULL(d.comments, []), @comment) } IN @@collection + RETURN NEW` + return db.ticketGetQuery(ctx, id, query, mergeMaps(map[string]interface{}{"comment": comment}, ticketFilterVars), &busdb.Operation{ + OperationType: busdb.Update, + Ids: []driver.DocumentID{ + driver.DocumentID(fmt.Sprintf("%s/%d", TicketCollectionName, id)), + }, + Msg: "Add comment", + }) +} + +func (db *Database) RemoveComment(ctx context.Context, id int64, commentID int64) (*models.TicketWithTickets, error) { + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketWriteFilter(ctx) + if err != nil { + return nil, err + } + + query := `LET d = DOCUMENT(@@collection, @ID) + ` + ticketFilterQuery + ` + UPDATE d WITH { "modified": DATE_ISO8601(DATE_NOW()), "comments": REMOVE_NTH(d.comments, @commentID) } IN @@collection + RETURN NEW` + return db.ticketGetQuery(ctx, id, query, mergeMaps(map[string]interface{}{"commentID": commentID}, ticketFilterVars), &busdb.Operation{ + OperationType: busdb.Update, + Ids: []driver.DocumentID{ + driver.DocumentID(fmt.Sprintf("%s/%d", TicketCollectionName, id)), + }, + Msg: "Remove comment", + }) +} + +func (db *Database) SetReferences(ctx context.Context, id int64, references []*models.Reference) (*models.TicketWithTickets, error) { + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketWriteFilter(ctx) + if err != nil { + return nil, err + } + + query := `LET d = DOCUMENT(@@collection, @ID) + ` + ticketFilterQuery + ` + UPDATE d WITH { "modified": DATE_ISO8601(DATE_NOW()), "references": @references } IN @@collection + RETURN NEW` + return db.ticketGetQuery(ctx, id, query, mergeMaps(map[string]interface{}{"references": references}, ticketFilterVars), &busdb.Operation{ + OperationType: busdb.Update, + Ids: []driver.DocumentID{ + driver.DocumentID(fmt.Sprintf("%s/%d", TicketCollectionName, id)), + }, + Msg: "Changed references", + }) +} + +func (db *Database) LinkFiles(ctx context.Context, id int64, files []*models.File) (*models.TicketWithTickets, error) { + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketWriteFilter(ctx) + if err != nil { + return nil, err + } + + query := `LET d = DOCUMENT(@@collection, @ID) + ` + ticketFilterQuery + ` + UPDATE d WITH { "modified": DATE_ISO8601(DATE_NOW()), "files": @files } IN @@collection + RETURN NEW` + return db.ticketGetQuery(ctx, id, query, mergeMaps(map[string]interface{}{"files": files}, ticketFilterVars), &busdb.Operation{ + OperationType: busdb.Update, + Ids: []driver.DocumentID{ + driver.DocumentID(fmt.Sprintf("%s/%d", TicketCollectionName, id)), + }, + Msg: "Linked files", + }) +} + +func (db *Database) AddTicketPlaybook(ctx context.Context, id int64, playbookTemplate *models.PlaybookTemplateForm) (*models.TicketWithTickets, error) { + pb, err := toPlaybook(playbookTemplate) + if err != nil { + return nil, err + } + + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketWriteFilter(ctx) + if err != nil { + return nil, err + } + + playbookID := strcase.ToKebab(pb.Name) + if playbookTemplate.ID != nil { + playbookID = *playbookTemplate.ID + } + + parentTicket, err := db.TicketGet(ctx, id) + if err != nil { + return nil, err + } + + query := `FOR d IN @@collection + ` + ticketFilterQuery + ` + FILTER d._key == @ID + LET newplaybook = ZIP( [@playbookID], [@playbook] ) + LET newplaybooks = MERGE(NOT_NULL(d.playbooks, {}), newplaybook) + LET newticket = MERGE(d, { "modified": DATE_ISO8601(DATE_NOW()), "playbooks": newplaybooks }) + REPLACE d WITH newticket IN @@collection + RETURN NEW` + ticket, err := db.ticketGetQuery(ctx, id, query, mergeMaps(map[string]interface{}{ + "playbook": pb, + "playbookID": findName(parentTicket.Playbooks, playbookID), + }, ticketFilterVars), &busdb.Operation{ + OperationType: busdb.Update, + Ids: []driver.DocumentID{ + driver.NewDocumentID(TicketCollectionName, fmt.Sprintf("%d", id)), + }, + Msg: "Added playbook", + }) + if err != nil { + return nil, err + } + + if err := runRootTask(extractTicketResponse(ticket), playbookID, db); err != nil { + return nil, err + } + + return ticket, nil +} + +func findName(playbooks map[string]*models.PlaybookResponse, name string) string { + if _, ok := playbooks[name]; !ok { + return name + } + + for i := 0; ; i++ { + try := fmt.Sprintf("%s%d", name, i) + if _, ok := playbooks[try]; !ok { + return try + } + } +} + +func runRootTask(ticket *models.TicketResponse, playbookID string, db *Database) error { + playbook := ticket.Playbooks[playbookID] + + var root *models.TaskResponse + for _, task := range playbook.Tasks { + if task.Order == 0 { + root = task + } + } + + runNextTasks(ticket.ID, playbookID, root.Next, root.Data, ticket, db) + return nil +} + +func (db *Database) RemoveTicketPlaybook(ctx context.Context, id int64, playbookID string) (*models.TicketWithTickets, error) { + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketWriteFilter(ctx) + if err != nil { + return nil, err + } + + query := `FOR d IN @@collection + ` + ticketFilterQuery + ` + FILTER d._key == @ID + LET newplaybooks = UNSET(d.playbooks, @playbookID) + REPLACE d WITH MERGE(d, { "modified": DATE_ISO8601(DATE_NOW()), "playbooks": newplaybooks }) IN @@collection + RETURN NEW` + return db.ticketGetQuery(ctx, id, query, mergeMaps(map[string]interface{}{ + "playbookID": playbookID, + }, ticketFilterVars), &busdb.Operation{ + OperationType: busdb.Update, + Ids: []driver.DocumentID{ + driver.NewDocumentID(TicketCollectionName, fmt.Sprintf("%d", id)), + }, + Msg: fmt.Sprintf("Removed playbook %s", playbookID), + }) +} diff --git a/database/ticket_task.go b/database/ticket_task.go new file mode 100644 index 0000000..2c119af --- /dev/null +++ b/database/ticket_task.go @@ -0,0 +1,186 @@ +package database + +import ( + "context" + "errors" + "fmt" + "log" + "time" + + "github.com/arangodb/go-driver" + "github.com/google/uuid" + + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" +) + +func (db *Database) TaskGet(ctx context.Context, id int64, playbookID string, taskID string) (*models.TicketWithTickets, *models.PlaybookResponse, *models.TaskWithContext, error) { + inc, err := db.TicketGet(ctx, id) + if err != nil { + return nil, nil, nil, err + } + + playbook, ok := inc.Playbooks[playbookID] + if !ok { + return nil, nil, nil, errors.New("playbook does not exist") + } + + task, ok := playbook.Tasks[taskID] + if !ok { + return nil, nil, nil, errors.New("task does not exist") + } + + return inc, playbook, &models.TaskWithContext{ + PlaybookId: playbookID, + PlaybookName: playbook.Name, + TaskId: taskID, + Task: *task, + TicketId: id, + TicketName: inc.Name, + }, nil +} + +func (db *Database) TaskComplete(ctx context.Context, id int64, playbookID string, taskID string, data interface{}) (*models.TicketWithTickets, error) { + inc, err := db.TicketGet(ctx, id) + if err != nil { + return nil, err + } + + completable := inc.Playbooks[playbookID].Tasks[taskID].Active + if !completable { + return nil, errors.New("cannot be completed") + } + + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketWriteFilter(ctx) + if err != nil { + return nil, err + } + + query := `LET d = DOCUMENT(@@collection, @ID) + ` + ticketFilterQuery + ` + LET playbook = d.playbooks[@playbookID] + LET task = playbook.tasks[@taskID] + LET newtask = MERGE(task, {"data": NOT_NULL(@data, {}), "done": true, closed: @closed }) + LET newtasks = MERGE(playbook.tasks, { @taskID: newtask } ) + LET newplaybook = MERGE(playbook, {"tasks": newtasks}) + LET newplaybooks = MERGE(d.playbooks, { @playbookID: newplaybook } ) + + UPDATE d WITH { "modified": DATE_ISO8601(DATE_NOW()), "playbooks": newplaybooks } IN @@collection + RETURN NEW` + ticket, err := db.ticketGetQuery(ctx, id, query, mergeMaps(map[string]interface{}{ + "playbookID": playbookID, + "taskID": taskID, + "data": data, + "closed": time.Now().UTC(), + }, ticketFilterVars), &busdb.Operation{ + OperationType: busdb.Update, + Ids: []driver.DocumentID{ + driver.NewDocumentID(TicketCollectionName, fmt.Sprintf("%d", id)), + }, + Msg: fmt.Sprintf("Completed task %s in playbook %s", taskID, playbookID), + }) + if err != nil { + return nil, err + } + + playbook := ticket.Playbooks[playbookID] + task := playbook.Tasks[taskID] + + runNextTasks(id, playbookID, task.Next, task.Data, extractTicketResponse(ticket), db) + + return ticket, nil +} + +func extractTicketResponse(ticket *models.TicketWithTickets) *models.TicketResponse { + return &models.TicketResponse{ + Artifacts: ticket.Artifacts, + Comments: ticket.Comments, + Created: ticket.Created, + Details: ticket.Details, + Files: ticket.Files, + ID: ticket.ID, + Modified: ticket.Modified, + Name: ticket.Name, + Owner: ticket.Owner, + Playbooks: ticket.Playbooks, + Read: ticket.Read, + References: ticket.References, + Schema: ticket.Schema, + Status: ticket.Status, + Type: ticket.Type, + Write: ticket.Write, + } +} + +func (db *Database) TaskUpdate(ctx context.Context, id int64, playbookID string, taskID string, task *models.Task) (*models.TicketWithTickets, error) { + ticketFilterQuery, ticketFilterVars, err := db.Hooks.TicketWriteFilter(ctx) + if err != nil { + return nil, err + } + + query := `LET d = DOCUMENT(@@collection, @ID) + ` + ticketFilterQuery + ` + LET playbook = d.playbooks[@playbookID] + LET newtasks = MERGE(playbook.tasks, { @taskID: @task } ) + LET newplaybook = MERGE(playbook, {"tasks": newtasks}) + LET newplaybooks = MERGE(d.playbooks, { @playbookID: newplaybook } ) + + UPDATE d WITH { "modified": DATE_ISO8601(DATE_NOW()), "playbooks": newplaybooks } IN @@collection + RETURN NEW` + ticket, err := db.ticketGetQuery(ctx, id, query, mergeMaps(map[string]interface{}{ + "playbookID": playbookID, + "taskID": taskID, + "task": task, + }, ticketFilterVars), &busdb.Operation{ + OperationType: busdb.Update, + Ids: []driver.DocumentID{ + driver.NewDocumentID(TicketCollectionName, fmt.Sprintf("%d", id)), + }, + Msg: fmt.Sprintf("Saved task %s in playbook %s", taskID, playbookID), + }) + if err != nil { + return nil, err + } + + return ticket, nil +} + +func (db *Database) TaskRun(ctx context.Context, id int64, playbookID string, taskID string) error { + ticket, _, task, err := db.TaskGet(ctx, id, playbookID, taskID) + if err != nil { + return err + } + + if task.Task.Type == models.TaskTypeAutomation { + if err := runTask(id, playbookID, taskID, &task.Task, extractTicketResponse(ticket), db); err != nil { + return err + } + } + + return nil +} + +func runNextTasks(id int64, playbookID string, next map[string]string, data interface{}, ticket *models.TicketResponse, db *Database) { + for nextTaskID, requirement := range next { + nextTask := ticket.Playbooks[playbookID].Tasks[nextTaskID] + if nextTask.Type == models.TaskTypeAutomation { + b, err := evalRequirement(requirement, data) + if err != nil { + continue + } + if b { + if err := runTask(id, playbookID, nextTaskID, nextTask, ticket, db); err != nil { + log.Println(err) + } + } + } + } +} + +func runTask(ticketID int64, playbookID string, taskID string, task *models.TaskResponse, ticket *models.TicketResponse, db *Database) error { + playbook := ticket.Playbooks[playbookID] + msgContext := &models.Context{Playbook: playbook, Task: task, Ticket: ticket} + origin := &models.Origin{TaskOrigin: &models.TaskOrigin{TaskId: taskID, PlaybookId: playbookID, TicketId: ticketID}} + jobID := uuid.NewString() + return publishJobMapping(jobID, *task.Automation, msgContext, origin, task.Payload, db) +} diff --git a/database/tickettype.go b/database/tickettype.go new file mode 100644 index 0000000..f4581bc --- /dev/null +++ b/database/tickettype.go @@ -0,0 +1,101 @@ +package database + +import ( + "context" + "errors" + + "github.com/arangodb/go-driver" + "github.com/iancoleman/strcase" + + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" +) + +func toTicketType(doc *models.TicketTypeForm) *models.TicketType { + return &models.TicketType{ + Name: doc.Name, + Icon: doc.Icon, + DefaultPlaybooks: doc.DefaultPlaybooks, + DefaultTemplate: doc.DefaultTemplate, + DefaultGroups: doc.DefaultGroups, + } +} + +func toTicketTypeResponse(key string, doc *models.TicketType) *models.TicketTypeResponse { + return &models.TicketTypeResponse{ + ID: key, + Name: doc.Name, + Icon: doc.Icon, + DefaultPlaybooks: doc.DefaultPlaybooks, + DefaultTemplate: doc.DefaultTemplate, + DefaultGroups: doc.DefaultGroups, + } +} + +func (db *Database) TicketTypeCreate(ctx context.Context, tickettype *models.TicketTypeForm) (*models.TicketTypeResponse, error) { + if tickettype == nil { + return nil, errors.New("requires ticket type") + } + if tickettype.Name == "" { + return nil, errors.New("requires ticket type name") + } + + var doc models.TicketType + newctx := driver.WithReturnNew(ctx, &doc) + + meta, err := db.tickettypeCollection.CreateDocument(ctx, newctx, strcase.ToKebab(tickettype.Name), toTicketType(tickettype)) + if err != nil { + return nil, err + } + + return toTicketTypeResponse(meta.Key, &doc), nil +} + +func (db *Database) TicketTypeGet(ctx context.Context, id string) (*models.TicketTypeResponse, error) { + var doc models.TicketType + meta, err := db.tickettypeCollection.ReadDocument(ctx, id, &doc) + if err != nil { + return nil, err + } + + return toTicketTypeResponse(meta.Key, &doc), nil +} + +func (db *Database) TicketTypeUpdate(ctx context.Context, id string, tickettype *models.TicketTypeForm) (*models.TicketTypeResponse, error) { + var doc models.TicketType + ctx = driver.WithReturnNew(ctx, &doc) + + meta, err := db.tickettypeCollection.ReplaceDocument(ctx, id, toTicketType(tickettype)) + if err != nil { + return nil, err + } + + return toTicketTypeResponse(meta.Key, &doc), nil +} + +func (db *Database) TicketTypeDelete(ctx context.Context, id string) error { + _, err := db.tickettypeCollection.RemoveDocument(ctx, id) + return err +} + +func (db *Database) TicketTypeList(ctx context.Context) ([]*models.TicketTypeResponse, error) { + query := "FOR d IN @@collection RETURN d" + cursor, _, err := db.Query(ctx, query, map[string]interface{}{"@collection": TicketTypeCollectionName}, busdb.ReadOperation) + if err != nil { + return nil, err + } + defer cursor.Close() + var docs []*models.TicketTypeResponse + for { + var doc models.TicketType + meta, err := cursor.ReadDocument(ctx, &doc) + if driver.IsNoMoreDocuments(err) { + break + } else if err != nil { + return nil, err + } + docs = append(docs, toTicketTypeResponse(meta.Key, &doc)) + } + + return docs, err +} diff --git a/database/user.go b/database/user.go new file mode 100644 index 0000000..2a03baf --- /dev/null +++ b/database/user.go @@ -0,0 +1,201 @@ +package database + +import ( + "context" + "crypto/sha256" + "errors" + "fmt" + "math/rand" + "time" + + "github.com/arangodb/go-driver" + "github.com/gin-gonic/gin" + "github.com/iancoleman/strcase" + + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/pointer" + "github.com/SecurityBrewery/catalyst/role" +) + +var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_") + +func init() { + rand.Seed(time.Now().UnixNano()) +} + +func generateKey() string { + b := make([]rune, 32) + for i := range b { + b[i] = letters[rand.Intn(len(letters))] + } + return string(b) +} + +func toUser(user *models.UserForm, sha256 *string) *models.User { + roles := []string{} + roles = append(roles, role.Strings(role.Explodes(user.Roles))...) + u := &models.User{ + Blocked: user.Blocked, + Roles: roles, + Sha256: sha256, + Apikey: user.Apikey, + } + + // log.Println(u) + // b, _ := json.Marshal(u) + // loader := gojsonschema.NewBytesLoader(b) + // res, err := models.UserSchema.Validate(loader) + // if err != nil { + // log.Println(err) + // } + // log.Println(res.Errors()) + + return u +} + +func toUserResponse(key string, user *models.User) *models.UserResponse { + return &models.UserResponse{ + ID: key, + Roles: user.Roles, + Blocked: user.Blocked, + Apikey: user.Apikey, + } +} + +func toNewUserResponse(key string, user *models.User, secret *string) *models.NewUserResponse { + return &models.NewUserResponse{ + ID: key, + Roles: user.Roles, + Secret: secret, + Blocked: user.Blocked, + } +} + +func (db *Database) UserGetOrCreate(ctx *gin.Context, newUser *models.UserForm) (*models.UserResponse, error) { + user, err := db.UserGet(ctx, newUser.ID) + if err != nil { + newUser, err := db.UserCreate(ctx, newUser) + if err != nil { + return nil, err + } + return &models.UserResponse{ID: newUser.ID, Roles: newUser.Roles, Blocked: newUser.Blocked}, nil + } + return user, nil +} + +func (db *Database) UserCreate(ctx context.Context, newUser *models.UserForm) (*models.NewUserResponse, error) { + var key string + var hash *string + if newUser.Apikey { + key = generateKey() + hash = pointer.String(fmt.Sprintf("%x", sha256.Sum256([]byte(key)))) + } + + var doc models.User + newctx := driver.WithReturnNew(ctx, &doc) + meta, err := db.userCollection.CreateDocument(ctx, newctx, strcase.ToKebab(newUser.ID), toUser(newUser, hash)) + if err != nil { + return nil, err + } + + return toNewUserResponse(meta.Key, &doc, pointer.String(key)), nil +} + +func (db *Database) UserCreateSetupAPIKey(ctx context.Context, key string) (*models.UserResponse, error) { + newUser := &models.UserForm{ + ID: "setup", + Roles: []string{role.Admin}, + Apikey: true, + Blocked: false, + } + hash := pointer.String(fmt.Sprintf("%x", sha256.Sum256([]byte(key)))) + + var doc models.User + newctx := driver.WithReturnNew(ctx, &doc) + meta, err := db.userCollection.CreateDocument(ctx, newctx, strcase.ToKebab(newUser.ID), toUser(newUser, hash)) + if err != nil { + return nil, err + } + + return toUserResponse(meta.Key, &doc), nil +} + +func (db *Database) UserGet(ctx context.Context, id string) (*models.UserResponse, error) { + var doc models.User + meta, err := db.userCollection.ReadDocument(ctx, id, &doc) + if err != nil { + return nil, err + } + + return toUserResponse(meta.Key, &doc), nil +} + +func (db *Database) UserDelete(ctx context.Context, id string) error { + _, err := db.userCollection.RemoveDocument(ctx, id) + return err +} + +func (db *Database) UserList(ctx context.Context) ([]*models.UserResponse, error) { + query := "FOR d IN @@collection RETURN d" + cursor, _, err := db.Query(ctx, query, map[string]interface{}{"@collection": UserCollectionName}, busdb.ReadOperation) + if err != nil { + return nil, err + } + defer cursor.Close() + var docs []*models.UserResponse + for { + var doc models.User + meta, err := cursor.ReadDocument(ctx, &doc) + if driver.IsNoMoreDocuments(err) { + break + } else if err != nil { + return nil, err + } + doc.Sha256 = nil + docs = append(docs, toUserResponse(meta.Key, &doc)) + } + + return docs, err +} + +func (db *Database) UserByHash(ctx context.Context, sha256 string) (*models.UserResponse, error) { + query := `FOR d in @@collection + FILTER d.sha256 == @sha256 + RETURN d` + + cursor, _, err := db.Query(ctx, query, map[string]interface{}{"@collection": UserCollectionName, "sha256": sha256}, busdb.ReadOperation) + if err != nil { + return nil, err + } + defer cursor.Close() + + var doc models.User + meta, err := cursor.ReadDocument(ctx, &doc) + if err != nil { + return nil, err + } + + return toUserResponse(meta.Key, &doc), err +} + +func (db *Database) UserUpdate(ctx context.Context, id string, user *models.UserForm) (*models.UserResponse, error) { + var doc models.User + _, err := db.userCollection.ReadDocument(ctx, id, &doc) + if err != nil { + return nil, err + } + + if doc.Sha256 != nil { + return nil, errors.New("cannot update an API key") + } + + ctx = driver.WithReturnNew(ctx, &doc) + + meta, err := db.userCollection.ReplaceDocument(ctx, id, toUser(user, nil)) + if err != nil { + return nil, err + } + + return toUserResponse(meta.Key, &doc), nil +} diff --git a/definition/CAQLLexer.g4 b/definition/CAQLLexer.g4 new file mode 100644 index 0000000..45def35 --- /dev/null +++ b/definition/CAQLLexer.g4 @@ -0,0 +1,160 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 by Martin Mirchev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Project : sqlite-parser; an ANTLR4 grammar for SQLite https://github.com/bkiers/sqlite-parser + * Developed by : Bart Kiers, bart@big-o.nl + */ + +// $antlr-format alignTrailingComments on, columnLimit 150, maxEmptyLinesToKeep 1, reflowComments off, useTab off +// $antlr-format allowShortRulesOnASingleLine on, alignSemicolons ownLine + +lexer grammar CAQLLexer; + +channels { ERRORCHANNEL } + + +DOT: '.'; + +// https://github.com/arangodb/arangodb/blob/devel/arangod/Aql/grammar.y +T_REGEX_MATCH: '=~'; // "~= operator" +T_REGEX_NON_MATCH: '!~'; // "~! operator" + +T_EQ: '=='; // "== operator"; +T_NE: '!='; // "!= operator"; +T_LT: '<'; // "< operator"; +T_GT: '>'; // "> operator"; +T_LE: '<='; // "<= operator"; +T_GE: '>='; // ">= operator"; + +T_PLUS: '+'; // "+ operator" +T_MINUS: '-'; // "- operator" +T_TIMES: '*'; // "* operator" +T_DIV: '/'; // "/ operator" +T_MOD: '%'; // "% operator" + +T_QUESTION: '?'; // "?" +T_COLON: ':'; // ":" +T_SCOPE: '::'; // "::" +T_RANGE: '..'; // ".." + +T_COMMA: ','; // "," +T_OPEN: '('; // "(" +T_CLOSE: ')'; // ")" +T_OBJECT_OPEN: '{'; // "{" +T_OBJECT_CLOSE: '}'; // "}" +T_ARRAY_OPEN: '['; // "[" +T_ARRAY_CLOSE: ']'; // "]" + + +// https://www.arangodb.com/docs/stable/aql/fundamentals-syntax.html#keywords +T_AGGREGATE: A G G R E G A T E; +T_ALL: A L L; +T_AND: (A N D | '&&'); +T_ANY: A N Y; +T_ASC: A S C; +T_COLLECT: C O L L E C T; +T_DESC: D E S C; +T_DISTINCT: D I S T I N C T; +T_FALSE: F A L S E; +T_FILTER: F I L T E R; +T_FOR: F O R; +T_GRAPH: G R A P H; +T_IN: I N; +T_INBOUND: I N B O U N D; +T_INSERT: I N S E R T; +T_INTO: I N T O; +T_K_SHORTEST_PATHS: K '_' S H O R T E S T '_' P A T H S; +T_LET: L E T; +T_LIKE: L I K E; +T_LIMIT: L I M I T; +T_NONE: N O N E; +T_NOT: (N O T | '!'); +T_NULL: N U L L; +T_OR: (O R | '||'); +T_OUTBOUND: O U T B O U N D; +T_REMOVE: R E M O V E; +T_REPLACE: R E P L A C E; +T_RETURN: R E T U R N; +T_SHORTEST_PATH: S H O R T E S T '_' P A T H; +T_SORT: S O R T; +T_TRUE: T R U E; +T_UPDATE: U P D A T E; +T_UPSERT: U P S E R T; +T_WITH: W I T H; + +T_KEEP: K E E P; +T_COUNT: C O U N T; +T_OPTIONS: O P T I O N S; +T_PRUNE: P R U N E; +T_SEARCH: S E A R C H; +T_TO: T O; + +T_CURRENT: C U R R E N T; +T_NEW: N E W; +T_OLD: O L D; + +T_STRING: [a-zA-Z_] [a-zA-Z_0-9]*; + +T_INT: [1-9] DIGIT* | '0' | '0x' HEX_DIGIT+ | '0b' [0-1]+; +T_FLOAT: ( [1-9] DIGIT* | '0' )? '.' DIGIT+ (E [-+]? DIGIT+)?; + +T_PARAMETER: '@' T_STRING; + +T_QUOTED_STRING: ('\'' ('\\'. | '\'\'' | ~('\'' | '\\'))* '\'' | '"' ( '\\'. | '""' | ~('"'| '\\') )* '"'); + +SINGLE_LINE_COMMENT: '//' ~[\r\n]* (('\r'? '\n') | EOF) -> channel(HIDDEN); + +MULTILINE_COMMENT: '/*' .*? '*/' -> channel(HIDDEN); + +SPACES: [ \u000B\t\r\n] -> channel(HIDDEN); + +UNEXPECTED_CHAR: .; + +fragment HEX_DIGIT: [0-9a-fA-F]; +fragment DIGIT: [0-9]; + +fragment A: [aA]; +fragment B: [bB]; +fragment C: [cC]; +fragment D: [dD]; +fragment E: [eE]; +fragment F: [fF]; +fragment G: [gG]; +fragment H: [hH]; +fragment I: [iI]; +fragment J: [jJ]; +fragment K: [kK]; +fragment L: [lL]; +fragment M: [mM]; +fragment N: [nN]; +fragment O: [oO]; +fragment P: [pP]; +fragment Q: [qQ]; +fragment R: [rR]; +fragment S: [sS]; +fragment T: [tT]; +fragment U: [uU]; +fragment V: [vV]; +fragment W: [wW]; +fragment X: [xX]; +fragment Y: [yY]; +fragment Z: [zZ]; + +ERROR_RECONGNIGION: . -> channel(ERRORCHANNEL); diff --git a/definition/CAQLParser.g4 b/definition/CAQLParser.g4 new file mode 100644 index 0000000..ffa84a7 --- /dev/null +++ b/definition/CAQLParser.g4 @@ -0,0 +1,109 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2014 by Bart Kiers + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Project : sqlite-parser; an ANTLR4 grammar for SQLite https://github.com/bkiers/sqlite-parser + * Developed by: + * Bart Kiers, bart@big-o.nl + * Martin Mirchev, marti_2203@abv.bg + * Mike Lische, mike@lischke-online.de + */ + +// $antlr-format alignTrailingComments on, columnLimit 130, minEmptyLines 1, maxEmptyLinesToKeep 1, reflowComments off +// $antlr-format useTab off, allowShortRulesOnASingleLine off, allowShortBlocksOnASingleLine on, alignSemicolons ownLine + +parser grammar CAQLParser; + +options { + tokenVocab = CAQLLexer; +} + +parse: expression EOF +; + +expression: + value_literal + | reference + | operator_unary + | expression (T_PLUS|T_MINUS) expression + | expression (T_TIMES|T_DIV|T_MOD) expression + | expression T_RANGE expression + | expression (T_LT|T_GT|T_LE|T_GE) expression + | expression T_NOT? T_IN expression + | expression (T_EQ|T_NE) expression + | expression (T_ALL|T_ANY|T_NONE) eq_op=(T_EQ|T_NE|T_LT|T_GT|T_LE|T_GE|T_IN) expression + | expression (T_ALL|T_ANY|T_NONE) T_NOT T_IN expression + | expression T_NOT? (T_LIKE|T_REGEX_MATCH|T_REGEX_NON_MATCH) expression + | expression T_AND expression + | expression T_OR expression + | expression T_QUESTION expression T_COLON expression + | expression T_QUESTION T_COLON expression +; + +operator_unary: ( + T_PLUS expression + | T_MINUS expression + | T_NOT expression +); + +reference: + T_STRING + | compound_value + | function_call + | T_OPEN expression T_CLOSE + | reference DOT T_STRING + | reference T_ARRAY_OPEN expression T_ARRAY_CLOSE +; + +compound_value: ( + array + | object +); + +function_call: ( + T_STRING T_OPEN expression? (T_COMMA expression)*? T_COMMA? T_CLOSE +); + +value_literal: ( + T_QUOTED_STRING + | T_INT + | T_FLOAT + | T_NULL + | T_TRUE + | T_FALSE +); + +array:( + T_ARRAY_OPEN expression? (T_COMMA expression)*? T_COMMA? T_ARRAY_CLOSE +); + +object: + T_OBJECT_OPEN object_element? (T_COMMA object_element)* T_COMMA? T_OBJECT_CLOSE +; + +object_element:( + T_STRING + | object_element_name T_COLON expression + | T_ARRAY_OPEN expression T_ARRAY_CLOSE T_COLON expression +); + +object_element_name:( + T_STRING + | T_QUOTED_STRING +); diff --git a/definition/artifacts.yaml b/definition/artifacts.yaml new file mode 100644 index 0000000..346f22b --- /dev/null +++ b/definition/artifacts.yaml @@ -0,0 +1,29 @@ +swagger: "2.0" +info: { version: "", title: "" } + +paths: { } + +definitions: + Artifact: + type: object + required: [ name ] + properties: + name: { type: string, example: "2.2.2.2" } + type: { type: string } + status: { type: string, example: "Unknown" } + enrichments: { type: object, additionalProperties: { $ref: "#/definitions/Enrichment" } } + + EnrichmentForm: + type: object + required: [ name, data ] + properties: + name: { type: string, example: "hash.sha1" } + data: { type: object, example: { "hash": "b7a067a742c20d07a7456646de89bc2d408a1153" } } + + Enrichment: + type: object + required: [ name, data, created ] + properties: + name: { type: string, example: "hash.sha1" } + data: { type: object, example: { "hash": "b7a067a742c20d07a7456646de89bc2d408a1153" } } + created: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" } diff --git a/definition/automation.yaml b/definition/automation.yaml new file mode 100644 index 0000000..92f1acb --- /dev/null +++ b/definition/automation.yaml @@ -0,0 +1,165 @@ +swagger: "2.0" +info: { version: "", title: "" } + +paths: + /automations: + get: + tags: [ "automations" ] + summary: "List automations" + operationId: "listAutomations" + responses: + "200": + description: "successful operation" + schema: { type: array, items: { $ref: "#/definitions/AutomationResponse" } } + examples: + test: + - id: comment + image: "docker.io/python:3" + script: "" + type: [ playbook ] + - id: hash.sha1 + image: "docker.io/python:3" + script: "" + type: [ global, artifact, playbook ] + schema: "{\"title\":\"Input\",\"type\":\"object\",\"properties\":{\"default\":{\"type\":\"string\",\"title\":\"Value\"}},\"required\":[\"default\"]}" + - id: thehive + image: "docker.io/python:3" + script: "" + type: [ global ] + schema: "{\"title\":\"TheHive credentials\",\"type\":\"object\",\"properties\":{\"thehiveurl\":{\"type\":\"string\",\"title\":\"TheHive URL (e.g. 'https://thehive.example.org')\"},\"thehivekey\":{\"type\":\"string\",\"title\":\"TheHive API Key\"},\"skip_files\":{\"type\":\"boolean\", \"default\": true, \"title\":\"Skip Files (much faster)\"},\"keep_ids\":{\"type\":\"boolean\", \"default\": true, \"title\":\"Keep IDs and overwrite existing IDs\"}},\"required\":[\"thehiveurl\", \"thehivekey\", \"skip_files\", \"keep_ids\"]}" + - id: vt.hash + image: "docker.io/python:3" + script: "" + type: [ global, artifact, playbook ] + schema: "{\"title\":\"Input\",\"type\":\"object\",\"properties\":{\"default\":{\"type\":\"string\",\"title\":\"Value\"}},\"required\":[\"default\"]}" + security: [ { roles: [ "automation:read" ] } ] + post: + tags: [ "automations" ] + summary: "Create a new automation" + operationId: "createAutomation" + parameters: + - { name: "automation", in: "body", description: "New automation", required: true, schema: { $ref: "#/definitions/AutomationForm" }, x-example: { id: "hash-sha-256", image: "docker.io/python:3", script: "import sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha256 = hashlib.sha256(msg['payload']['default'].encode('utf-8'))\n return {'hash': sha256.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", type: [ global ] } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/AutomationResponse" } + examples: + test: + id: "hash-sha-256" + image: "docker.io/python:3" + type: [ global ] + script: | + import sys + import json + import hashlib + + + def run(msg): + sha256 = hashlib.sha256(msg['payload']['default'].encode('utf-8')) + return {'hash': sha256.hexdigest()} + + + print(json.dumps(run(json.loads(sys.argv[1])))) + + security: [ { roles: [ "automation:write" ] } ] + + /automations/{id}: + get: + tags: [ "automations" ] + summary: "Get a single automation" + operationId: "getAutomation" + parameters: + - { name: "id", in: "path", description: "Automation ID", required: true, type: string, x-example: "hash.sha1" } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/AutomationResponse" } + examples: + test: + id: hash.sha1 + image: "docker.io/python:3" + type: [ global, artifact, playbook ] + schema: "{\"title\":\"Input\",\"type\":\"object\",\"properties\":{\"default\":{\"type\":\"string\",\"title\":\"Value\"}},\"required\":[\"default\"]}" + script: | + #!/usr/bin/env python + + import sys + import json + import hashlib + + + def run(msg): + sha1 = hashlib.sha1(msg['payload']['default'].encode('utf-8')) + return {"hash": sha1.hexdigest()} + + + print(json.dumps(run(json.loads(sys.argv[1])))) + security: [ { roles: [ "automation:read" ] } ] + put: + tags: [ "automations" ] + summary: "Update an existing automation" + operationId: "updateAutomation" + parameters: + - { name: "id", in: "path", description: "Automation ID", required: true, type: string, x-example: "hash.sha1" } + - { name: "automation", in: "body", description: "Automation object that needs to be added", required: true, schema: { $ref: "#/definitions/AutomationForm" }, x-example: { id: hash.sha1, image: "docker.io/python:3", script: "import sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha1 = hashlib.sha1(msg['payload'].encode('utf-8'))\n return {'hash': sha1.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", type: [ global, artifact, playbook ] } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/AutomationResponse" } + examples: + test: + id: hash.sha1 + image: "docker.io/python:3" + type: [ global, artifact, playbook ] + script: | + import sys + import json + import hashlib + + + def run(msg): + sha1 = hashlib.sha1(msg['payload'].encode('utf-8')) + return {'hash': sha1.hexdigest()} + + + print(json.dumps(run(json.loads(sys.argv[1])))) + security: [ { roles: [ "automation:write" ] } ] + delete: + tags: [ "automations" ] + summary: "Delete a automation" + operationId: "deleteAutomation" + parameters: + - { name: "id", in: "path", description: "Automation ID", required: true, type: string, x-example: "hash.sha1" } + responses: + "204": { description: "successful operation" } + security: [ { roles: [ "automation:write" ] } ] + +definitions: + AutomationForm: + type: object + required: [ id, image, script, type ] + properties: + id: { type: string } + image: { type: string } + script: { type: string } + type: { type: array, items: { type: string, enum: [ artifact, playbook, global ] } } + schema: { type: string, example: "{}" } + + Automation: + type: object + required: [ image, script, type ] + properties: + image: { type: string } + script: { type: string } + type: { type: array, items: { type: string, enum: [ artifact, playbook, global ] } } + schema: { type: string, example: "{}" } + + AutomationResponse: + type: object + required: [ id, image, script, type ] + properties: + id: { type: string } + image: { type: string } + script: { type: string } + type: { type: array, items: { type: string, enum: [ artifact, playbook, global ] } } + schema: { type: string, example: "{}" } diff --git a/definition/enterprise/graph.yaml b/definition/enterprise/graph.yaml new file mode 100644 index 0000000..0060149 --- /dev/null +++ b/definition/enterprise/graph.yaml @@ -0,0 +1,52 @@ +swagger: "2.0" +info: { version: "", title: "" } + +paths: + /graph/{col}/{id}: + get: + tags: [ "graph" ] + summary: "Graph" + operationId: "graph" + parameters: + - { name: "col", in: "path", description: "Graph Start", required: true, type: string, x-example: "tickets" } + - { name: "id", in: "path", description: "Graph Start", required: true, type: string, x-example: "88" } + - { name: "depth", in: "query", description: "Graph Start", required: true, type: integer, x-example: 1 } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/Graph" } + examples: + test: + nodes: + - { id: "artifacts/94d5cab6f5fe3422a447ab15436e7a672bc0c09a", name: "94d5cab6f5fe3422a447ab15436e7a672bc0c09a" } + - { id: "artifacts/http%3A%2F%2Fwww.customerviral.io%2Fscalable%2Fvertical%2Fkiller", name: "http://www.customerviral.io/scalable/vertical/killer" } + - { id: "artifacts/leadreintermediate.io", name: "leadreintermediate.io" } + - { id: "tickets/88", name: "live zebra" } + links: + - { id: "296239", sid: "tickets/88", tid: "artifacts/http%3A%2F%2Fwww.customerviral.io%2Fscalable%2Fvertical%2Fkiller" } + - { id: "296240", sid: "tickets/88", tid: "artifacts/leadreintermediate.io" } + - { id: "296242", sid: "tickets/88", tid: "artifacts/94d5cab6f5fe3422a447ab15436e7a672bc0c09a" } + security: [ { roles: [ "ticket:read" ] } ] + +definitions: + Graph: + type: object + properties: + nodes: { type: array, items: { $ref: "#/definitions/Node" } } + links: { type: array, items: { $ref: "#/definitions/Link" } } + + Node: + type: object + required: [ id, name ] + properties: + id: { type: string } + name: { type: string } + + Link: + type: object + required: [ id, tid, sid ] + properties: + id: { type: string } + # name: { type: string } + tid: { type: string } + sid: { type: string } diff --git a/definition/enterprise/groups.yaml b/definition/enterprise/groups.yaml new file mode 100644 index 0000000..6a2f91a --- /dev/null +++ b/definition/enterprise/groups.yaml @@ -0,0 +1,84 @@ +swagger: "2.0" +info: { version: "", title: "" } + +paths: + /groups: + get: + tags: [ "groups" ] + summary: "List groups" + operationId: "listGroups" + responses: + "200": + description: "successful operation" + schema: { type: array, items: { $ref: "#/definitions/Group" } } + security: [ { roles: [ "group:read" ] } ] + post: + tags: [ "groups" ] + summary: "Create a new group" + operationId: "createGroup" + parameters: + - { name: "group", in: "body", description: "New group", required: true, schema: { $ref: "#/definitions/GroupForm" } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/GroupResponse" } + security: [ { roles: [ "group:write" ] } ] + + /groups/{id}: + get: + tags: [ "groups" ] + summary: "Get a single group" + operationId: "getGroup" + parameters: + - { name: "id", in: "path", description: "Group ID", required: true, type: string } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/GroupResponse" } + security: [ { roles: [ "group:read" ] } ] + put: + tags: [ "groups" ] + summary: "Update an existing group" + operationId: "updateGroup" + parameters: + - { name: "id", in: "path", description: "Group ID", required: true, type: string } + - { name: "group", in: "body", description: "Group object that needs to be added", required: true, schema: { $ref: "#/definitions/Group" } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/Group" } + security: [ { roles: [ "group:write" ] } ] + delete: + tags: [ "groups" ] + summary: "Delete a group" + operationId: "deleteGroup" + parameters: + - { name: "id", in: "path", description: "Group ID", required: true, type: string } + responses: + "204": { description: "successful operation" } + security: [ { roles: [ "group:write" ] } ] + +definitions: + GroupForm: + type: object + required: [ name, users ] + properties: + id: { type: string } + name: { type: string } + users: { type: array, items: { type: string } } + + Group: + type: object + required: [ name, users ] + properties: + name: { type: string } + users: { type: array, items: { type: string } } + + + GroupResponse: + type: object + required: [ id, name, users ] + properties: + id: { type: string } + name: { type: string } + users: { type: array, items: { type: string } } diff --git a/definition/enterprise/rules.yaml b/definition/enterprise/rules.yaml new file mode 100644 index 0000000..6fdffa0 --- /dev/null +++ b/definition/enterprise/rules.yaml @@ -0,0 +1,110 @@ +swagger: "2.0" +info: { version: "", title: "" } + +paths: + /rules: + get: + tags: [ "rules" ] + summary: "List rules" + operationId: "listRules" + responses: + "200": + description: "successful operation" + schema: { type: array, items: { $ref: "#/definitions/RuleResponse" } } + examples: + test: + - id: ignore-alerts + name: Ignore Alerts + condition: "type == 'alert'" + update: { "status": "closed" } + security: [ { roles: [ "rule:read" ] } ] + post: + tags: [ "rules" ] + summary: "Create a rule" + operationId: "createRule" + parameters: + - { name: "rule", in: "body", description: "New rule", required: true, schema: { $ref: "#/definitions/RuleForm" }, x-example: { name: "Ignore all Alerts", condition: "type == 'alert'", update: { "status": "closed" } } } + responses: + "200": + description: "successful operation" + schema: { type: array, items: { $ref: "#/definitions/RuleResponse" } } + examples: + test: + id: ignore-all-alerts + name: Ignore all Alerts + condition: "type == 'alert'" + update: { "status": "closed" } + security: [ { roles: [ "rule:write" ] } ] + + /rules/{id}: + get: + tags: [ "rules" ] + summary: "Get a single rule" + operationId: "getRule" + parameters: + - { name: "id", in: "path", description: "Rule name", required: true, type: string, x-example: "ignore-alerts" } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/RuleResponse" } + examples: + test: + id: ignore-alerts + name: Ignore Alerts + condition: "type == 'alert'" + update: { "status": "closed" } + security: [ { roles: [ "rule:read" ] } ] + put: + tags: [ "rules" ] + summary: "Update an existing ticket rule" + operationId: "updateRule" + parameters: + - { name: "id", in: "path", description: "Rule ID", required: true, type: string, x-example: "ignore-alerts" } + - { name: "rule", in: "body", description: "Updated rule", required: true, schema: { $ref: "#/definitions/RuleForm" }, x-example: { name: "Ignore Alerts", condition: "type == 'alert'", update: { "status": "invalid" } } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/RuleResponse" } + examples: + test: + id: ignore-alerts + name: Ignore Alerts + condition: "type == 'alert'" + update: { "status": "invalid" } + security: [ { roles: [ "rule:write" ] } ] + delete: + tags: [ "rules" ] + summary: "Delete a rule" + operationId: "deleteRule" + parameters: + - { name: "id", in: "path", description: "Rule name", required: true, type: string, x-example: "ignore-alerts" } + responses: + "204": { description: "successful operation" } + security: [ { roles: [ "rule:write" ] } ] + +definitions: + RuleForm: + type: object + required: [ name, condition, update ] + properties: + id: { type: string } + name: { type: string } + condition: { type: string } + update: { type: object } + + Rule: + type: object + required: [ name, condition, update ] + properties: + name: { type: string } + condition: { type: string } + update: { type: object } + + RuleResponse: + type: object + required: [ id, name, condition, update ] + properties: + id: { type: string } + name: { type: string } + condition: { type: string } + update: { type: object } diff --git a/definition/jobs.yaml b/definition/jobs.yaml new file mode 100644 index 0000000..d9f9e43 --- /dev/null +++ b/definition/jobs.yaml @@ -0,0 +1,130 @@ +swagger: "2.0" +info: { version: "", title: "" } + +paths: + /jobs: + get: + tags: [ "jobs" ] + summary: "List jobs" + operationId: "listJobs" + responses: + "200": + description: "successful operation" + schema: { type: array, items: { $ref: "#/definitions/JobResponse" } } + examples: + test: + - id: "99cd67131b48" + automation: "hash.sha1" + payload: "test" + status: "created" + security: [ { roles: [ "job:read" ] } ] + post: + tags: [ "jobs" ] + summary: "Start a new job" + operationId: "runJob" + parameters: + - { name: "job", in: "body", description: "New job", required: true, schema: { $ref: "#/definitions/JobForm" }, x-example: { automation: "hash.sha1", message: { payload: "test" } } } + responses: + "204": { description: "successful operation" } + security: [ { roles: [ "job:write" ] } ] + + /jobs/{id}: + get: + tags: [ "jobs" ] + summary: "Get a single job" + operationId: "getJob" + parameters: + - { name: "id", in: "path", description: "Job ID", required: true, type: string, x-example: "99cd67131b48" } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/JobResponse" } + examples: + test: { id: "99cd67131b48", automation: "hash.sha1", payload: "test", status: "created" } + security: [ { roles: [ "job:read" ] } ] + put: + tags: [ "jobs" ] + summary: "Update an existing job" + operationId: "updateJob" + parameters: + - { name: "id", in: "path", description: "Job ID", required: true, type: string, x-example: "99cd67131b48" } + - { name: "job", in: "body", description: "Job object that needs to be added", required: true, schema: { $ref: "#/definitions/Job" }, x-example: { id: "99cd67131b48", automation: "hash.sha1", payload: "test", status: "failed" } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/JobResponse" } + examples: + test: { id: "99cd67131b48", automation: "hash.sha1", payload: "test", status: "failed" } + + security: [ { roles: [ "job:write" ] } ] + +definitions: + Message: + type: object + properties: + payload: { type: object } + secrets: { type: object, additionalProperties: { type: string } } + context: { $ref: "#/definitions/Context" } + + Context: + type: object + properties: + artifact: { $ref: "#/definitions/Artifact" } + playbook: { $ref: "#/definitions/PlaybookResponse" } + task: { $ref: "#/definitions/TaskResponse" } + ticket: { $ref: "#/definitions/TicketResponse" } + + Origin: + type: object + properties: + task_origin: { $ref: "#/definitions/TaskOrigin" } + artifact_origin: { $ref: "#/definitions/ArtifactOrigin" } + + TaskOrigin: + type: object + required: [ ticket_id, playbook_id, task_id ] + properties: + ticket_id: { type: integer, format: int64 } + playbook_id: { type: string } + task_id: { type: string } + + ArtifactOrigin: + type: object + required: [ ticket_id, artifact ] + properties: + ticket_id: { type: integer, format: int64 } + artifact: { type: string } + + JobForm: + type: object + required: [ automation ] + properties: + automation: { type: string } + payload: { } + origin: { $ref: "#/definitions/Origin" } + + Job: + type: object + required: [ automation, running, status ] + properties: + automation: { type: string } + container: { type: string } + payload: { } + running: { type: boolean } + status: { type: string } + log: { type: string } + output: { type: object } + origin: { $ref: "#/definitions/Origin" } + + JobResponse: + type: object + required: [ id, automation, status ] + properties: + id: { type: string } + automation: { type: string } + container: { type: string } + status: { type: string } + payload: { } + log: { type: string } + output: { type: object } + origin: { $ref: "#/definitions/Origin" } diff --git a/definition/logs.yaml b/definition/logs.yaml new file mode 100644 index 0000000..1d811a4 --- /dev/null +++ b/definition/logs.yaml @@ -0,0 +1,30 @@ +swagger: "2.0" +info: { version: "", title: "" } + +paths: + + /logs/{reference}: + get: + tags: [ "logs" ] + summary: "Get log entries" + operationId: "getLogs" + parameters: + - { name: "reference", in: "path", description: "Reference", required: true, type: string, x-example: "tickets%2F294511" } + responses: + "200": + description: "successful operation" + schema: { type: array, items: { $ref: "#/definitions/LogEntry" } } + examples: + test: + - { "created": "2021-10-02T18:05:00.333535+02:00","creator": "bob","reference": "tickets/294511","message": "Fail run account resist lend solve incident centre priority temperature. Cause change distribution examine location technique shape partner milk customer. Rail tea plate soil report cook railway interpretation breath action. Exercise dream accept park conclusion addition shoot assistance may answer. Gold writer link stop combine hear power name commitment operation. Determine lifespan support grow degree henry exclude detail set religion. Direct library policy convention chain retain discover ride walk student. Gather proposal select march aspect play noise avoid encourage employ. Assessment preserve transport combine wish influence income guess run stand. Charge limit crime ignore statement foundation study issue stop claim." } + security: [ { roles: [ "log:read" ] } ] + +definitions: + LogEntry: + type: object + required: [ reference, creator, created, message ] + properties: + reference: { type: string } + creator: { type: string } + created: { type: string, format: "date-time" } + message: { type: string } diff --git a/definition/playbooks.yaml b/definition/playbooks.yaml new file mode 100644 index 0000000..0af18ef --- /dev/null +++ b/definition/playbooks.yaml @@ -0,0 +1,202 @@ +swagger: "2.0" +info: { version: "", title: "" } + +paths: + /playbooks: + get: + tags: [ "playbooks" ] + summary: "List playbooks" + operationId: "listPlaybooks" + responses: + "200": + description: "successful operation" + schema: { type: array, items: { $ref: "#/definitions/PlaybookTemplateResponse" } } + examples: + test: + - id: malware + name: Malware + yaml: "name: Malware\ntasks:\n file-or-hash:\n name: Do you have the file or the hash?\n type: input\n schema:\n title: Malware\n type: object\n properties:\n file:\n type: string\n title: \"I have the\"\n enum: [ \"File\", \"Hash\" ]\n next:\n enter-hash: \"file == 'Hash'\"\n upload: \"file == 'File'\"\n\n enter-hash:\n name: Please enter the hash\n type: input\n schema:\n title: Malware\n type: object\n properties:\n hash:\n type: string\n title: Please enter the hash value\n minlength: 32\n next:\n virustotal: \"hash != ''\"\n\n upload:\n name: Upload the malware\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: object\n x-display: file\n title: Please upload the malware\n next:\n hash: \"malware\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['upload'].data['malware']\"\n next:\n virustotal:\n\n virustotal:\n name: Send hash to VirusTotal\n type: automation\n automation: vt.hash\n args:\n hash: \"playbook.tasks['enter-hash'].data['hash'] || playbook.tasks['hash'].data['hash']\"\n # next:\n # known-malware: \"score > 5\"\n # sandbox: \"score < 6\" # unknown-malware\n" + - id: phishing + name: Phishing + yaml: "name: Phishing\ntasks:\n board:\n name: Board Involvement?\n description: Is a board member involved?\n type: input\n schema:\n properties:\n boardInvolved:\n default: false\n title: A board member is involved.\n type: boolean\n required:\n - boardInvolved\n title: Board Involvement?\n type: object\n next:\n escalate: \"boardInvolved == true\"\n mail-available: \"boardInvolved == false\"\n\n escalate:\n name: Escalate to CISO\n description: Please escalate the task to the CISO\n type: task\n\n mail-available:\n name: Mail available\n type: input\n schema:\n oneOf:\n - properties:\n mail:\n title: Mail\n type: string\n x-display: textarea\n schemaKey:\n const: 'yes'\n type: string\n required:\n - mail\n title: 'Yes'\n - properties:\n schemaKey:\n const: 'no'\n type: string\n title: 'No'\n title: Mail available\n type: object\n next:\n block-sender: \"schemaKey == 'yes'\"\n extract-iocs: \"schemaKey == 'yes'\"\n search-email-gateway: \"schemaKey == 'no'\"\n\n search-email-gateway:\n name: Search email gateway\n description: Please search email-gateway for the phishing mail.\n type: task\n next:\n extract-iocs:\n\n block-sender:\n name: Block sender\n type: task\n next:\n extract-iocs:\n\n extract-iocs:\n name: Extract IOCs\n description: Please insert the IOCs\n type: input\n schema:\n properties:\n iocs:\n items:\n type: string\n title: IOCs\n type: array\n title: Extract IOCs\n type: object\n next:\n block-iocs:\n\n block-iocs:\n name: Block IOCs\n type: task\n" + - id: simple + name: Simple + yaml: "name: Simple\ntasks:\n input:\n name: Enter something to hash\n type: input\n schema:\n title: Something\n type: object\n properties:\n something:\n type: string\n title: Something\n default: \"\"\n next:\n hash: \"something != ''\"\n\n hash:\n name: Hash the something\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['something']\"\n next:\n comment: \"hash != ''\"\n\n comment:\n name: Comment the hash\n type: automation\n automation: comment\n payload:\n default: \"playbook.tasks['hash'].data['hash']\"\n next:\n done: \"done\"\n\n done:\n name: You can close this case now\n type: task\n" + security: [ { roles: [ "playbook:read" ] } ] + post: + tags: [ "playbooks" ] + summary: "Create a playbook" + operationId: "createPlaybook" + parameters: + - { name: "playbook", in: "body", description: "New playbook", required: true, schema: { $ref: "#/definitions/PlaybookTemplateForm" }, x-example: { yaml: "name: Simple2\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n" } } + responses: + "200": + description: "successful operation" + schema: { type: array, items: { $ref: "#/definitions/PlaybookTemplateResponse" } } + examples: + test: + id: simple-2 + name: Simple2 + yaml: | + name: Simple2 + tasks: + input: + name: Upload malware if possible + type: input + schema: + title: Malware + type: object + properties: + malware: + type: string + title: Select malware + default: "" + next: + hash: "malware != ''" + + hash: + name: Hash the malware + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['input'].data['malware']" + next: + escalate: + + escalate: + name: Escalate to malware team + type: task + security: [ { roles: [ "playbook:write" ] } ] + + /playbooks/{id}: + get: + tags: [ "playbooks" ] + summary: "Get a single playbook" + operationId: "getPlaybook" + parameters: + - { name: "id", in: "path", description: "Playbook name", required: true, type: string, x-example: "simple" } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/PlaybookTemplateResponse" } + examples: + test: + id: simple + name: Simple + yaml: | + name: Simple + tasks: + input: + name: Enter something to hash + type: input + schema: + title: Something + type: object + properties: + something: + type: string + title: Something + default: "" + next: + hash: "something != ''" + + hash: + name: Hash the something + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['input'].data['something']" + next: + comment: "hash != ''" + + comment: + name: Comment the hash + type: automation + automation: comment + payload: + default: "playbook.tasks['hash'].data['hash']" + next: + done: "done" + + done: + name: You can close this case now + type: task + + security: [ { roles: [ "playbook:read" ] } ] + put: + tags: [ "playbooks" ] + summary: "Update an existing ticket playbook" + operationId: "updatePlaybook" + parameters: + - { name: "id", in: "path", description: "Playbook ID", required: true, type: string, x-example: "simple" } + - { name: "playbook", in: "body", description: "Updated playbook", required: true, schema: { $ref: "#/definitions/PlaybookTemplateForm" }, x-example: { yaml: "name: Simple\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n" } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/PlaybookTemplateResponse" } + examples: + test: + id: simple + name: Simple + yaml: | + name: Simple + tasks: + input: + name: Upload malware if possible + type: input + schema: + title: Malware + type: object + properties: + malware: + type: string + title: Select malware + default: "" + next: + hash: "malware != ''" + + hash: + name: Hash the malware + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['input'].data['malware']" + next: + escalate: + + escalate: + name: Escalate to malware team + type: task + security: [ { roles: [ "playbook:write" ] } ] + delete: + tags: [ "playbooks" ] + summary: "Delete a playbook" + operationId: "deletePlaybook" + parameters: + - { name: "id", in: "path", description: "Playbook name", required: true, type: string, x-example: "simple" } + responses: + "204": { description: "successful operation" } + security: [ { roles: [ "playbook:write" ] } ] + +definitions: + PlaybookTemplateForm: + type: object + required: [ yaml ] + properties: + id: { type: string } + yaml: { type: string } + + PlaybookTemplate: + type: object + required: [ name, yaml ] + properties: + name: { type: string } + yaml: { type: string } + + PlaybookTemplateResponse: + type: object + required: [ id, name, yaml ] + properties: + id: { type: string } + name: { type: string } + yaml: { type: string } diff --git a/definition/settings.yaml b/definition/settings.yaml new file mode 100644 index 0000000..7a2c173 --- /dev/null +++ b/definition/settings.yaml @@ -0,0 +1,59 @@ +swagger: "2.0" +info: { version: "", title: "" } + +paths: + /settings: + get: + tags: [ "settings" ] + summary: "Get settings" + operationId: "getSettings" + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/Settings" } + examples: + test: + version: "0.0.0-test" + tier: community + timeformat: "YYYY-MM-DDThh:mm:ss" + ticketTypes: + - { icon: "mdi-alert", id: "alert", name: "Alerts", default_template: "default", default_playbooks: [ ] } + - { icon: "mdi-radioactive", id: "incident", name: "Incidents", default_template: "default", default_playbooks: [ ] } + - { icon: "mdi-fingerprint", id: "investigation", name: "Forensic Investigations", default_template: "default", default_playbooks: [ ] } + - { icon: "mdi-target", id: "hunt", name: "Threat Hunting", default_template: "default", default_playbooks: [ ] } + artifactStates: + - { icon: "mdi-help-circle-outline", id: "unknown", name: "Unknown", color: "info" } + - { icon: "mdi-skull", id: "malicious", name: "Malicious", color: "error" } + - { icon: "mdi-check", id: "clean", name: "Clean", color: "success" } + roles: [ + "admin:backup:read", "admin:backup:restore", "admin:group:write", "admin:job:read", "admin:job:write", + "admin:log:read", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", + "admin:userdata:write", "analyst:automation:read", + "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", + "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", + "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", + "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", + "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", + "engineer:tickettype:write" ] + security: [ { roles: [ "settings:read" ] } ] + +definitions: + Settings: + type: object + required: [ version, tier, timeformat, ticketTypes, artifactStates ] + properties: + version: { title: "Version", type: string } + tier: { title: "Tier", type: string, enum: [ "community", "enterprise" ] } + timeformat: { title: "Time Format", type: string } + ticketTypes: { title: "Ticket Types", type: array, items: { $ref: "#/definitions/TicketTypeResponse" } } + artifactStates: { title: "Artifact States", type: array, items: { $ref: "#/definitions/Type" } } + roles: { title: "Roles", type: array, items: { type: string } } + + Type: + type: object + required: [ id, name, icon ] + properties: + id: { title: ID, type: string, x-cols: 3, x-class: pr-2 } + name: { title: Name, type: string, x-cols: 3, x-class: pr-2 } + icon: { title: "Icon (https://materialdesignicons.com)", type: string, x-cols: 3, x-class: pr-2 } + color: { title: Color, type: string, x-cols: 3, enum: [ error, info, success, warning ] } diff --git a/definition/statistics.yaml b/definition/statistics.yaml new file mode 100644 index 0000000..acfd678 --- /dev/null +++ b/definition/statistics.yaml @@ -0,0 +1,31 @@ +swagger: "2.0" +info: { version: "", title: "" } + +paths: + /statistics: + get: + tags: [ "statistics" ] + summary: "Get statistics" + operationId: "getStatistics" + responses: + "200": + description: "successful operation" + schema: { $ref: '#/definitions/Statistics' } + examples: + test: + unassigned: 0 + open_tickets_per_user: { } + tickets_per_week: { "2021-39": 3 } + tickets_per_type: { "alert": 2, "incident": 1 } + security: [ { roles: [ "ticket:read" ] } ] + +definitions: + + Statistics: + type: object + required: [ unassigned, open_tickets_per_user, tickets_per_week, tickets_per_type ] + properties: + unassigned: { type: integer } + open_tickets_per_user: { type: object, additionalProperties: { type: integer } } + tickets_per_week: { type: object, additionalProperties: { type: integer } } + tickets_per_type: { type: object, additionalProperties: { type: integer } } diff --git a/definition/swagger.yaml b/definition/swagger.yaml new file mode 100644 index 0000000..24d9a98 --- /dev/null +++ b/definition/swagger.yaml @@ -0,0 +1,18 @@ +swagger: "2.0" +info: + version: "0.0.3" + title: "Catalyst" + description: API for the catalyst incident response platform. + +host: "." +basePath: "/api" +schemes: + # - "https" + - "http" + +consumes: [ "application/json" ] +produces: [ "application/json" ] + +paths: {} + +definitions: {} diff --git a/definition/tasks.yaml b/definition/tasks.yaml new file mode 100644 index 0000000..7b5e15e --- /dev/null +++ b/definition/tasks.yaml @@ -0,0 +1,107 @@ +swagger: "2.0" +info: { version: "", title: "" } + +paths: + /tasks: + get: + tags: [ "tasks" ] + summary: "List tasks" + operationId: "listTasks" + responses: + "200": + description: "successful operation" + schema: { type: array, items: { $ref: "#/definitions/TaskResponse" } } + examples: + test: [ ] + security: [ { roles: [ "ticket:read" ] } ] + +definitions: + TaskForm: + type: object + required: [ name, type ] + properties: + name: { type: string, example: "Inform user" } + type: { type: string, enum: [ task, input, automation ], example: "task" } + done: { type: boolean } + + owner: { type: string } + data: { type: object } + + # automation + automation: { type: string } + payload: { type: object, additionalProperties: { type: string } } + + # input + schema: { type: object } + + # workflow + join: { type: boolean, example: false } + next: { type: object, additionalProperties: { type: string } } + + created: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" } + closed: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" } + + Task: + type: object + required: [ name, type, done, created ] + properties: + name: { type: string, example: "Inform user" } + type: { type: string, enum: [ task, input, automation ], example: "task" } + done: { type: boolean } + + owner: { type: string } + data: { type: object } + + # automation + automation: { type: string } + payload: { type: object, additionalProperties: { type: string } } + + # input + schema: { type: object } + + # workflow + join: { type: boolean, example: false } + next: { type: object, additionalProperties: { type: string } } + + created: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" } + closed: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" } + + TaskResponse: + type: object + required: [ name, type, done, created, order, active ] + properties: + name: { type: string, example: "Inform user" } + type: { type: string, enum: [ task, input, automation ], example: "task" } + done: { type: boolean } + + owner: { type: string } + data: { type: object } + + # automation + automation: { type: string } + payload: { type: object, additionalProperties: { type: string } } + + # input + schema: { type: object } + + # workflow + join: { type: boolean, example: false } + next: { type: object, additionalProperties: { type: string } } + + created: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" } + closed: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" } + + # helper + order: { type: number, format: "int64", example: 2 } + active: { type: boolean, example: false } + + TaskWithContext: + type: object + required: [ ticket_id, ticket_name, playbook_id, playbook_name, task_id, task ] + properties: + ticket_id: { type: number, format: "int64" } + ticket_name: { type: string } + playbook_id: { type: string } + playbook_name: { type: string } + task_id: { type: string } + task: { $ref: '#/definitions/TaskResponse' } diff --git a/definition/templates.yaml b/definition/templates.yaml new file mode 100644 index 0000000..b000dd4 --- /dev/null +++ b/definition/templates.yaml @@ -0,0 +1,104 @@ +swagger: "2.0" +info: { version: "", title: "" } + +paths: + /templates: + get: + tags: [ "templates" ] + summary: "List templates" + operationId: "listTemplates" + responses: + "200": + description: "successful operation" + schema: { type: array, items: { $ref: "#/definitions/TicketTemplateResponse" } } + examples: + test: + - id: default + name: Default + schema: "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Default\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + security: [ { roles: [ "template:read" ] } ] + post: + tags: [ "templates" ] + summary: "Create a new template" + operationId: "createTemplate" + parameters: + - { name: "template", in: "body", description: "New template", required: true, schema: { $ref: "#/definitions/TicketTemplateForm" }, x-example: { name: "My Template", schema: "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketTemplateResponse" } + examples: + test: + id: "my-template" + name: "My Template" + schema: "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + security: [ { roles: [ "template:write" ] } ] + + /templates/{id}: + get: + tags: [ "templates" ] + summary: "Get a single template" + operationId: "getTemplate" + parameters: + - { name: "id", in: "path", description: "Template ID", required: true, type: string, x-example: "default" } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketTemplateResponse" } + examples: + test: + id: default + name: Default + schema: "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Default\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + security: [ { roles: [ "template:read" ] } ] + put: + tags: [ "templates" ] + summary: "Update an existing template" + operationId: "updateTemplate" + parameters: + - { name: "id", in: "path", description: "Template ID", required: true, type: string, x-example: "default" } + - { name: "template", in: "body", description: "Template object that needs to be added", required: true, schema: { $ref: "#/definitions/TicketTemplateForm" }, x-example: { name: "My Template", schema: "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketTemplateResponse" } + examples: + test: + id: default + name: "My Template" + schema: "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + + security: [ { roles: [ "template:write" ] } ] + delete: + tags: [ "templates" ] + summary: "Delete a template" + operationId: "deleteTemplate" + parameters: + - { name: "id", in: "path", description: "Template ID", required: true, type: string, x-example: "default" } + responses: + "204": { description: "successful operation" } + security: [ { roles: [ "template:write" ] } ] + +definitions: + TicketTemplateForm: + type: object + required: [ name, schema ] + properties: + id: { type: string } + name: { type: string } + schema: { type: string } + + TicketTemplate: + type: object + required: [ name, schema ] + properties: + name: { type: string } + schema: { type: string } + + TicketTemplateResponse: + type: object + required: [ id, name, schema ] + properties: + id: { type: string } + name: { type: string } + schema: { type: string } diff --git a/definition/tickets.yaml b/definition/tickets.yaml new file mode 100644 index 0000000..59b7bff --- /dev/null +++ b/definition/tickets.yaml @@ -0,0 +1,1094 @@ +swagger: "2.0" +info: { version: "", title: "" } + +paths: + /tickets: + get: + tags: [ "tickets" ] + summary: "List tickets" + operationId: "listTickets" + parameters: + - { name: "type", in: "query", description: "Ticket Type", type: string } + - { name: "offset", in: "query", description: "Offset of the list", type: integer, default: 0 } + - { name: "count", in: "query", description: "Number of tickets", type: integer, maximum: 100, default: 25 } + - { name: "sort", in: "query", description: "Sort columns", type: array, items: { type: string } } #, example: [ "name", "id" ] + - { name: "desc", in: "query", description: "Sort descending", type: array, items: { type: boolean } } #, example: [ false, true ] + - { name: "query", in: "query", description: "Search query", type: string } + responses: + "200": + description: "successful operation" + schema: { $ref: '#/definitions/TicketList' } + examples: + test: + count: 3 + tickets: + - id: 8123 + created: "2021-10-02T18:04:59.078206+02:00" + modified: "2021-10-02T18:04:59.078206+02:00" + name: "live zebra" + owner: "demo" + playbooks: + phishing: + name: "Phishing" + tasks: + "block-iocs": { created: "2021-10-02T18:04:59.078186+02:00", done: false, name: "Block IOCs", type: "task" } + "block-sender": { created: "2021-10-02T18:04:59.078186+02:00", done: false, name: "Block sender","next": { "extract-iocs": "" }, type: "task" } + "board": { created: "2021-10-02T18:04:59.078186+02:00", done: false, name: "Board Involvement?","next": { "escalate": "boardInvolved == true","mail-available": "boardInvolved == false" },"schema": { "properties": { "boardInvolved": { "default": false, "title": "A board member is involved.", type: "boolean" } }, "required": [ "boardInvolved" ], "title": "Board Involvement?", type: "object" }, type: "input" } + "escalate": { created: "2021-10-02T18:04:59.078186+02:00", done: false, name: "Escalate to CISO", type: "task" } + "extract-iocs": { created: "2021-10-02T18:04:59.078186+02:00", done: false, name: "Extract IOCs", "next": { "block-iocs": "" },"schema": { "properties": { "iocs": { "items": { type: "string" },"title": "IOCs", type: "array" } }, "title": "Extract IOCs", type: "object" }, type: "input" } + "mail-available": { created: "2021-10-02T18:04:59.078186+02:00", done: false, name: "Mail available","next": { "block-sender": "schemaKey == 'yes'", "extract-iocs": "schemaKey == 'yes'", "search-email-gateway": "schemaKey == 'no'" },"schema": { "oneOf": [ { "properties": { "mail": { "title": "Mail", type: "string", "x-display": "textarea" }, "schemaKey": { "const": "yes", type: "string" } },"required": [ "mail" ], "title": "Yes" },{ "properties": { "schemaKey": { "const": "no", type: "string" } },"title": "No" } ],"title": "Mail available", type: "object" }, type: "input" } + "search-email-gateway": { created: "2021-10-02T18:04:59.078186+02:00", done: false, name: "Search email gateway","next": { "extract-iocs": "" }, type: "task" } + references: + - { href: "https://www.leadmaximize.net/e-services/back-end", name: "performance" } + - { href: "http://www.corporateinteractive.name/rich", name: "autumn" } + - { href: "https://www.corporateintuitive.org/intuitive/platforms/integrate", name: "suggest" } + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + status: "closed" + type: "incident" + artifacts: + - { name: "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", status: "unknown" } + - { name: "http://www.customerviral.io/scalable/vertical/killer", status: "clean" } + - { name: "leadreintermediate.io", status: "malicious" } + - { id: 8125, created: "2021-10-02T18:04:59.078186+02:00", modified: "2021-10-02T18:04:59.078186+02:00",name: "phishing from selenafadel@von.com detected", owner: "demo", references: [ { href: "https://www.seniorleading-edge.name/users/efficient", name: "recovery" },{ href: "http://www.dynamicseamless.com/clicks-and-mortar", name: "force" },{ href: "http://www.leadscalable.biz/envisioneer", name: "fund" } ],"schema": "{}", status: "closed", type: "alert" } + - { id: 8126, created: "2021-10-02T18:04:59.078186+02:00", modified: "2021-10-02T18:04:59.078186+02:00", name: "Surfaceintroduce virus detected", owner: "demo", references: [ { href: "http://www.centralworld-class.io/synthesize", name: "university" },{ href: "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", name: "goal" },{ href: "http://www.chiefsyndicate.io/action-items", name: "unemployment" } ],"schema": "{}", status: "closed", type: "alert" } + security: [ { roles: [ "ticket:read" ] } ] + post: + tags: [ "tickets" ] + summary: "Create a new ticket" + operationId: "createTicket" + parameters: + - { name: "ticket", in: "body", description: "New ticket", required: true, schema: { $ref: "#/definitions/TicketForm" }, x-example: { id: 123, owner: bob, name: "Wannacry infection", status: "open", type: "incident" } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketResponse" } + examples: + test: + id: 123 + name: "Wannacry infection" + type: "incident" + status: "open" + created: "1985-04-12T23:20:50.52Z" + modified: "1985-04-12T23:20:50.52Z" + owner: "bob" + schema: "{}" + security: [ { roles: [ "ticket:write" ] } ] + + /tickets/batch: + post: + tags: [ "tickets" ] + summary: "Create a new tickets in batch" + operationId: "createTicketBatch" + parameters: + - { name: "ticket", in: "body", description: "New ticket", required: true, schema: { type: array, items: { $ref: "#/definitions/TicketForm" } }, x-example: [ { id: 123, owner: bob, name: "Wannacry infection", status: "open", type: "incident" } ] } + responses: + "204": { description: "successful operation" } + security: [ { roles: [ "ticket:write" ] } ] + + /tickets/{id}: + get: + tags: [ "tickets" ] + summary: "Get a single ticket" + operationId: "getTicket" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8125 } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketResponse" } + examples: + test: + id: 8125 + created: "2021-10-02T18:04:59.078186+02:00" + modified: "2021-10-02T18:04:59.078186+02:00" + name: "phishing from selenafadel@von.com detected" + owner: "demo" + references: + - href: "https://www.seniorleading-edge.name/users/efficient" + name: "recovery" + - href: "http://www.dynamicseamless.com/clicks-and-mortar" + name: "force" + - href: "http://www.leadscalable.biz/envisioneer" + name: "fund" + schema: "{}" + status: "closed" + type: "alert" + tickets: + - { id: 8126, created: "2021-10-02T18:04:59.078186+02:00", modified: "2021-10-02T18:04:59.078186+02:00", name: "Surfaceintroduce virus detected", owner: "demo", references: [ { href: "http://www.centralworld-class.io/synthesize", name: "university" },{ href: "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", name: "goal" },{ href: "http://www.chiefsyndicate.io/action-items", name: "unemployment" } ],"schema": "{}", status: "closed", type: "alert" } + security: [ { roles: [ "ticket:read" ] } ] + put: + tags: [ "tickets" ] + summary: "Update an existing ticket" + operationId: "updateTicket" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8125 } + - { name: "ticket", in: "body", description: "Updated ticket", required: true, schema: { $ref: "#/definitions/Ticket" }, x-example: { "created": "2021-10-02T18:04:59.078186+02:00",modified: "2021-10-02T18:04:59.078186+02:00", name: "phishing from selenafadel@von.org detected", owner: "demo", references: [ { href: "https://www.seniorleading-edge.name/users/efficient", name: "recovery" },{ href: "http://www.dynamicseamless.com/clicks-and-mortar", name: "force" },{ href: "http://www.leadscalable.biz/envisioneer", name: "fund" } ], schema: "{}", status: "closed", type: "alert" } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketResponse" } + examples: + test: + id: 8125 + created: "2021-10-02T18:04:59.078186+02:00" + modified: "2021-10-02T18:04:59.078186+02:00" + name: "phishing from selenafadel@von.org detected" + owner: "demo" + references: + - href: "https://www.seniorleading-edge.name/users/efficient" + name: "recovery" + - href: "http://www.dynamicseamless.com/clicks-and-mortar" + name: "force" + - href: "http://www.leadscalable.biz/envisioneer" + name: "fund" + schema: "{}" + status: "closed" + type: "alert" + tickets: + - { id: 8126, created: "2021-10-02T18:04:59.078186+02:00", modified: "2021-10-02T18:04:59.078186+02:00", name: "Surfaceintroduce virus detected", owner: "demo", references: [ { href: "http://www.centralworld-class.io/synthesize", name: "university" },{ href: "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", name: "goal" },{ href: "http://www.chiefsyndicate.io/action-items", name: "unemployment" } ],"schema": "{}", status: "closed", type: "alert" } + security: [ { roles: [ "ticket:write" ] } ] + delete: + tags: [ "tickets" ] + summary: "Delete an ticket" + operationId: "deleteTicket" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8125 } + responses: + "204": { description: "successful operation" } + security: [ { roles: [ "ticket:delete" ] } ] + + /tickets/{id}/tickets: + patch: + tags: [ "tickets" ] + summary: "Link an ticket to an ticket" + operationId: "linkTicket" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8126 } + - { name: "linkedID", in: "body", description: "Added ticket ID", required: true, schema: { type: integer, format: "int64" }, x-example: 8123 } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketResponse" } + examples: + test: + id: 8126 + created: "2021-10-02T18:04:59.078186+02:00" + modified: "2021-10-02T18:04:59.078186+02:00" + name: "Surfaceintroduce virus detected" + owner: "demo" + references: + - { "href": "http://www.centralworld-class.io/synthesize", "name": "university" } + - { "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", "name": "goal" } + - { "href": "http://www.chiefsyndicate.io/action-items", "name": "unemployment" } + schema: "{}" + status: "closed" + type: "alert" + tickets: + - id: 8123 + created: "2021-10-02T18:04:59.078206+02:00" + modified: "2021-10-02T18:04:59.078206+02:00" + name: "live zebra" + owner: "demo" + playbooks: + phishing: + name: "Phishing" + tasks: + "block-iocs": { created: "2021-10-02T18:04:59.078186+02:00", done: false, name: "Block IOCs", type: "task" } + "block-sender": { created: "2021-10-02T18:04:59.078186+02:00", done: false, name: "Block sender","next": { "extract-iocs": "" }, type: "task" } + "board": { created: "2021-10-02T18:04:59.078186+02:00", done: false, name: "Board Involvement?","next": { "escalate": "boardInvolved == true","mail-available": "boardInvolved == false" },"schema": { "properties": { "boardInvolved": { "default": false, "title": "A board member is involved.", type: "boolean" } }, "required": [ "boardInvolved" ], "title": "Board Involvement?", type: "object" }, type: "input" } + "escalate": { created: "2021-10-02T18:04:59.078186+02:00", done: false, name: "Escalate to CISO", type: "task" } + "extract-iocs": { created: "2021-10-02T18:04:59.078186+02:00", done: false, name: "Extract IOCs", "next": { "block-iocs": "" },"schema": { "properties": { "iocs": { "items": { type: "string" },"title": "IOCs", type: "array" } }, "title": "Extract IOCs", type: "object" }, type: "input" } + "mail-available": { created: "2021-10-02T18:04:59.078186+02:00", done: false, name: "Mail available","next": { "block-sender": "schemaKey == 'yes'", "extract-iocs": "schemaKey == 'yes'", "search-email-gateway": "schemaKey == 'no'" },"schema": { "oneOf": [ { "properties": { "mail": { "title": "Mail", type: "string", "x-display": "textarea" }, "schemaKey": { "const": "yes", type: "string" } },"required": [ "mail" ], "title": "Yes" },{ "properties": { "schemaKey": { "const": "no", type: "string" } },"title": "No" } ],"title": "Mail available", type: "object" }, type: "input" } + "search-email-gateway": { created: "2021-10-02T18:04:59.078186+02:00", done: false, name: "Search email gateway","next": { "extract-iocs": "" }, type: "task" } + references: + - { href: "https://www.leadmaximize.net/e-services/back-end", name: "performance" } + - { href: "http://www.corporateinteractive.name/rich", name: "autumn" } + - { href: "https://www.corporateintuitive.org/intuitive/platforms/integrate", name: "suggest" } + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + status: "closed" + type: "incident" + artifacts: + - { name: "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", status: "unknown" } + - { name: "http://www.customerviral.io/scalable/vertical/killer", status: "clean" } + - { name: "leadreintermediate.io", status: "malicious" } + - id: 8125 + created: "2021-10-02T18:04:59.078186+02:00" + modified: "2021-10-02T18:04:59.078186+02:00" + name: "phishing from selenafadel@von.com detected" + owner: "demo" + references: + - { href: "https://www.seniorleading-edge.name/users/efficient", name: "recovery" } + - { href: "http://www.dynamicseamless.com/clicks-and-mortar", name: "force" } + - { href: "http://www.leadscalable.biz/envisioneer", name: "fund" } + "schema": "{}" + status: "closed" + type: "alert" + security: [ { roles: [ "ticket:write" ] } ] + delete: + tags: [ "tickets" ] + summary: "Unlink an ticket to an ticket" + operationId: "unlinkTicket" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8126 } + - { name: "linkedID", in: "body", description: "Added ticket ID", required: true, schema: { type: integer, format: "int64" }, x-example: 8125 } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketResponse" } + examples: + test: + id: 8126 + created: "2021-10-02T18:04:59.078186+02:00" + modified: "2021-10-02T18:04:59.078186+02:00" + name: "Surfaceintroduce virus detected" + owner: "demo" + references: + - { href: "http://www.centralworld-class.io/synthesize", name: "university" } + - { href: "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", name: "goal" } + - { href: "http://www.chiefsyndicate.io/action-items", name: "unemployment" } + "schema": "{}" + status: "closed" + type: "alert" + security: [ { roles: [ "ticket:write" ] } ] + + /tickets/{id}/comments: + post: + tags: [ "tickets" ] + summary: "Add ticket comment" + operationId: "addComment" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8125 } + - { name: "comment", in: "body", description: "Ticket comment", required: true, schema: { $ref: "#/definitions/CommentForm" } , x-example: { message: "My first comment" } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketResponse" } + examples: + test: + id: 8125 + created: "2021-10-02T18:04:59.078186+02:00" + modified: "2021-10-02T18:04:59.078186+02:00" + name: "phishing from selenafadel@von.com detected" + owner: "demo" + comments: + - created: "2021-10-02T18:04:59.078186+02:00" + creator: "bob" + message: "My first comment" + references: + - { href: "https://www.seniorleading-edge.name/users/efficient", name: "recovery" } + - { href: "http://www.dynamicseamless.com/clicks-and-mortar", name: "force" } + - { href: "http://www.leadscalable.biz/envisioneer", name: "fund" } + "schema": "{}" + status: "closed" + type: "alert" + tickets: + - { id: 8126, created: "2021-10-02T18:04:59.078186+02:00", modified: "2021-10-02T18:04:59.078186+02:00", name: "Surfaceintroduce virus detected", owner: "demo", references: [ { href: "http://www.centralworld-class.io/synthesize", name: "university" },{ href: "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", name: "goal" },{ href: "http://www.chiefsyndicate.io/action-items", name: "unemployment" } ],"schema": "{}", status: "closed", type: "alert" } + security: [ { roles: [ "ticket:write" ] } ] + + /tickets/{id}/comments/{commentID}: + delete: + tags: [ "tickets" ] + summary: "Remove an comment from an ticket" + description: "Comment will be removed from the ticket." + operationId: "removeComment" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8123 } + - { name: "commentID", in: "path", description: "Comment ID to remove", required: true, type: integer, x-example: 0 } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketResponse" } + examples: + test: + id: 8123 + created: "2021-10-02T18:04:59.078206+02:00" + modified: "2021-10-02T18:04:59.078206+02:00" + name: "live zebra" + owner: "demo" + playbooks: + phishing: + name: "Phishing" + tasks: + "block-iocs": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 6, name: "Block IOCs", type: "task" } + "block-sender": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 3, name: "Block sender","next": { "extract-iocs": "" }, type: "task" } + "board": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": true, "order": 0, name: "Board Involvement?","next": { "escalate": "boardInvolved == true","mail-available": "boardInvolved == false" },"schema": { "properties": { "boardInvolved": { "default": false, "title": "A board member is involved.", type: "boolean" } }, "required": [ "boardInvolved" ], "title": "Board Involvement?", type: "object" }, type: "input" } + "escalate": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 1, name: "Escalate to CISO", type: "task" } + "extract-iocs": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 5, name: "Extract IOCs", "next": { "block-iocs": "" },"schema": { "properties": { "iocs": { "items": { type: "string" },"title": "IOCs", type: "array" } }, "title": "Extract IOCs", type: "object" }, type: "input" } + "mail-available": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 2, name: "Mail available","next": { "block-sender": "schemaKey == 'yes'", "extract-iocs": "schemaKey == 'yes'", "search-email-gateway": "schemaKey == 'no'" },"schema": { "oneOf": [ { "properties": { "mail": { "title": "Mail", type: "string", "x-display": "textarea" }, "schemaKey": { "const": "yes", type: "string" } },"required": [ "mail" ], "title": "Yes" },{ "properties": { "schemaKey": { "const": "no", type: "string" } },"title": "No" } ],"title": "Mail available", type: "object" }, type: "input" } + "search-email-gateway": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 4, name: "Search email gateway","next": { "extract-iocs": "" }, type: "task" } + references: + - { href: "https://www.leadmaximize.net/e-services/back-end", name: "performance" } + - { href: "http://www.corporateinteractive.name/rich", name: "autumn" } + - { href: "https://www.corporateintuitive.org/intuitive/platforms/integrate", name: "suggest" } + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + status: "closed" + type: "incident" + artifacts: + - { name: "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", status: "unknown" } + - { name: "http://www.customerviral.io/scalable/vertical/killer", status: "clean" } + - { name: "leadreintermediate.io", status: "malicious" } + security: [ { roles: [ "ticket:write" ] } ] + + /tickets/{id}/references: + put: + tags: [ "tickets" ] + summary: "Set ticket references" + operationId: "setReferences" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8125 } + - { name: "references", in: "body", description: "All ticket references", required: true, schema: { type: array, items: { $ref: "#/definitions/Reference" } }, x-example: [ { href: "http://www.leadscalable.biz/envisioneer", name: "fund" } ] } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketResponse" } + examples: + test: + id: 8125 + created: "2021-10-02T18:04:59.078186+02:00" + modified: "2021-10-02T18:04:59.078186+02:00" + name: "phishing from selenafadel@von.com detected" + owner: "demo" + references: [ { href: "http://www.leadscalable.biz/envisioneer", name: "fund" } ] + "schema": "{}" + status: "closed" + type: "alert" + tickets: + - { id: 8126, created: "2021-10-02T18:04:59.078186+02:00", modified: "2021-10-02T18:04:59.078186+02:00", name: "Surfaceintroduce virus detected", owner: "demo", references: [ { href: "http://www.centralworld-class.io/synthesize", name: "university" },{ href: "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", name: "goal" },{ href: "http://www.chiefsyndicate.io/action-items", name: "unemployment" } ],"schema": "{}", status: "closed", type: "alert" } + security: [ { roles: [ "ticket:write" ] } ] + + /tickets/{id}/schema: + put: + tags: [ "tickets" ] + summary: "Set ticket schema" + operationId: "setSchema" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8125 } + - { name: "schema", in: "body", description: "New ticket schema", schema: { type: string }, x-example: "{}" } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketResponse" } + examples: + test: + id: 8125 + created: "2021-10-02T18:04:59.078186+02:00" + modified: "2021-10-02T18:04:59.078186+02:00" + name: "phishing from selenafadel@von.com detected" + owner: "demo" + references: + - { href: "https://www.seniorleading-edge.name/users/efficient", name: "recovery" } + - { href: "http://www.dynamicseamless.com/clicks-and-mortar", name: "force" } + - { href: "http://www.leadscalable.biz/envisioneer", name: "fund" } + "schema": "{}" + status: "closed" + type: "alert" + tickets: + - { id: 8126, created: "2021-10-02T18:04:59.078186+02:00", modified: "2021-10-02T18:04:59.078186+02:00", name: "Surfaceintroduce virus detected", owner: "demo", references: [ { href: "http://www.centralworld-class.io/synthesize", name: "university" },{ href: "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", name: "goal" },{ href: "http://www.chiefsyndicate.io/action-items", name: "unemployment" } ],"schema": "{}", status: "closed", type: "alert" } + security: [ { roles: [ "ticket:write" ] } ] + + /tickets/{id}/files: + put: + tags: [ "tickets" ] + summary: "Link files to an ticket" + description: "Link files to an ticket. The files themself will be stored in object storage." + operationId: "linkFiles" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8125 } + - { name: "files", in: "body", description: "Added files", required: true, schema: { type: array, items: { $ref: "#/definitions/File" } }, x-example: [ { key: myfile, name: "document.doc" } ] } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketResponse" } + examples: + test: + id: 8125 + created: "2021-10-02T18:04:59.078186+02:00" + modified: "2021-10-02T18:04:59.078186+02:00" + name: "phishing from selenafadel@von.com detected" + owner: "demo" + references: + - { href: "https://www.seniorleading-edge.name/users/efficient", name: "recovery" } + - { href: "http://www.dynamicseamless.com/clicks-and-mortar", name: "force" } + - { href: "http://www.leadscalable.biz/envisioneer", name: "fund" } + "schema": "{}" + status: "closed" + type: "alert" + files: [ { key: myfile, name: "document.doc" } ] + tickets: + - { id: 8126, created: "2021-10-02T18:04:59.078186+02:00", modified: "2021-10-02T18:04:59.078186+02:00", name: "Surfaceintroduce virus detected", owner: "demo", references: [ { href: "http://www.centralworld-class.io/synthesize", name: "university" },{ href: "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", name: "goal" },{ href: "http://www.chiefsyndicate.io/action-items", name: "unemployment" } ],"schema": "{}", status: "closed", type: "alert" } + + security: [ { roles: [ "ticket:write" ] } ] + + /tickets/{id}/playbooks: + post: + tags: [ "tickets" ] + summary: "Add a new ticket playbook" + operationId: "addTicketPlaybook" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8125 } + - { name: "playbook", in: "body", description: "Ticket playbook object that needs to be added", required: true, schema: { $ref: "#/definitions/PlaybookTemplateForm" }, x-example: { yaml: "name: Simple\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n" } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketResponse" } + examples: + test: + id: 8125 + name: phishing from selenafadel@von.com detected + owner: demo + type: "alert" + status: "closed" + created: "1985-04-12T23:20:50.52Z" + modified: "1985-04-12T23:20:50.52Z" + schema: "{}" + tickets: + - { id: 8126, created: "2021-10-02T18:04:59.078186+02:00", modified: "2021-10-02T18:04:59.078186+02:00", name: "Surfaceintroduce virus detected", owner: "demo", references: [ { href: "http://www.centralworld-class.io/synthesize", name: "university" },{ href: "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", name: "goal" },{ href: "http://www.chiefsyndicate.io/action-items", name: "unemployment" } ],"schema": "{}", status: "closed", type: "alert" } + references: + - { href: "https://www.seniorleading-edge.name/users/efficient", name: recovery } + - { href: "http://www.dynamicseamless.com/clicks-and-mortar", name: force } + - { href: "http://www.leadscalable.biz/envisioneer", name: fund } + playbooks: + simple: + name: Simple + tasks: + input: + active: true + done: false + created: "2021-10-02T18:04:59.078186+02:00" + order: 0 + name: Upload malware if possible + type: input + schema: + title: Malware + type: object + properties: + malware: + type: string + title: Select malware + default: "" + next: + hash: "malware != ''" + + hash: + active: false + done: false + created: "2021-10-02T18:04:59.078186+02:00" + order: 1 + name: Hash the malware + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['input'].data['malware']" + next: + escalate: "" + + escalate: + active: false + done: false + created: "2021-10-02T18:04:59.078186+02:00" + order: 2 + name: Escalate to malware team + type: task + + /tickets/{id}/playbooks/{playbookID}: + delete: + tags: [ "tickets" ] + summary: "Remove an ticket playbook" + operationId: "removeTicketPlaybook" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8123 } + - { name: "playbookID", in: "path", description: "Playbook ID", required: true, type: string, x-example: "phishing" } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketResponse" } + examples: + test: + id: 8123 + name: "live zebra" + type: "incident" + status: "closed" + created: "1985-04-12T23:20:50.52Z" + modified: "1985-04-12T23:20:50.52Z" + owner: "demo" + references: + - { href: "https://www.leadmaximize.net/e-services/back-end", name: performance } + - { href: "http://www.corporateinteractive.name/rich", name: autumn } + - { href: "https://www.corporateintuitive.org/intuitive/platforms/integrate", name: suggest } + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + artifacts: + - { name: "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", status: "unknown" } + - { name: "http://www.customerviral.io/scalable/vertical/killer", status: "clean" } + - { name: "leadreintermediate.io", status: "malicious" } + security: [ { roles: [ "ticket:write" ] } ] + + /tickets/{id}/playbooks/{playbookID}/task/{taskID}: + put: + tags: [ "tickets" ] + summary: "Set a ticket playbook task" + operationId: "setTask" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8123 } + - { name: "playbookID", in: "path", description: "Playbook ID", required: true, type: string, x-example: "phishing" } + - { name: "taskID", in: "path", description: "Task ID", required: true, type: string, x-example: "board" } + - { name: "task", in: "body", description: "Task", required: true, schema: { $ref: "#/definitions/Task" }, x-example: { done: false, "active": true, "order": 0, name: "Board Involvement?","next": { "escalate": "boardInvolved == true","mail-available": "boardInvolved == false" },"schema": { "properties": { "boardInvolved": { "default": false, "title": "A board member is involved.", type: "boolean" } }, "required": [ "boardInvolved" ], "title": "Board Involvement?", type: "object" }, type: "input", data: { boardInvolved: true } } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketResponse" } + examples: + test: + id: 8123 + created: "2021-10-02T18:04:59.078206+02:00" + modified: "2021-10-02T18:04:59.078206+02:00" + name: "live zebra" + owner: "demo" + playbooks: + phishing: + name: "Phishing" + tasks: + "block-iocs": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 6, name: "Block IOCs", type: "task" } + "block-sender": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 3, name: "Block sender","next": { "extract-iocs": "" }, type: "task" } + "board": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": true, "order": 0, name: "Board Involvement?","next": { "escalate": "boardInvolved == true","mail-available": "boardInvolved == false" },"schema": { "properties": { "boardInvolved": { "default": false, "title": "A board member is involved.", type: "boolean" } }, "required": [ "boardInvolved" ], "title": "Board Involvement?", type: "object" }, type: "input", data: { boardInvolved: true } } + "escalate": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 1, name: "Escalate to CISO", type: "task" } + "extract-iocs": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 5, name: "Extract IOCs", "next": { "block-iocs": "" },"schema": { "properties": { "iocs": { "items": { type: "string" },"title": "IOCs", type: "array" } }, "title": "Extract IOCs", type: "object" }, type: "input" } + "mail-available": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 2, name: "Mail available","next": { "block-sender": "schemaKey == 'yes'", "extract-iocs": "schemaKey == 'yes'", "search-email-gateway": "schemaKey == 'no'" },"schema": { "oneOf": [ { "properties": { "mail": { "title": "Mail", type: "string", "x-display": "textarea" }, "schemaKey": { "const": "yes", type: "string" } },"required": [ "mail" ], "title": "Yes" },{ "properties": { "schemaKey": { "const": "no", type: "string" } },"title": "No" } ],"title": "Mail available", type: "object" }, type: "input" } + "search-email-gateway": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 4, name: "Search email gateway","next": { "extract-iocs": "" }, type: "task" } + references: + - { href: "https://www.leadmaximize.net/e-services/back-end", name: "performance" } + - { href: "http://www.corporateinteractive.name/rich", name: "autumn" } + - { href: "https://www.corporateintuitive.org/intuitive/platforms/integrate", name: "suggest" } + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + status: "closed" + type: "incident" + artifacts: + - { name: "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", status: "unknown" } + - { name: "http://www.customerviral.io/scalable/vertical/killer", status: "clean" } + - { name: "leadreintermediate.io", status: "malicious" } + security: [ { roles: [ "ticket:write" ] } ] + + /tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete: + put: + tags: [ "tickets" ] + summary: "Complete ticket playbook task" + operationId: "completeTask" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8123 } + - { name: "playbookID", in: "path", description: "Playbook ID", required: true, type: string, x-example: "phishing" } + - { name: "taskID", in: "path", description: "Task ID", required: true, type: string, x-example: "board" } + - { name: "data", in: "body", description: "Ticket playbook object that needs to be added", required: true, schema: { type: object }, x-example: { boardInvolved: true } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketResponse" } + examples: + test: + id: 8123 + created: "2021-10-02T18:04:59.078206+02:00" + modified: "2021-10-02T18:04:59.078206+02:00" + name: "live zebra" + owner: "demo" + playbooks: + phishing: + name: "Phishing" + tasks: + "block-iocs": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 6, name: "Block IOCs", type: "task" } + "block-sender": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 3, name: "Block sender","next": { "extract-iocs": "" }, type: "task" } + "board": { created: "2021-10-02T18:04:59.078186+02:00", closed: "2021-10-02T18:04:59.078186+02:00", done: true, "active": false, "order": 0, name: "Board Involvement?","next": { "escalate": "boardInvolved == true","mail-available": "boardInvolved == false" },"schema": { "properties": { "boardInvolved": { "default": false, "title": "A board member is involved.", type: "boolean" } }, "required": [ "boardInvolved" ], "title": "Board Involvement?", type: "object" }, type: "input", data: { boardInvolved: true } } + "escalate": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": true, "order": 1, name: "Escalate to CISO", type: "task" } + "extract-iocs": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 5, name: "Extract IOCs", "next": { "block-iocs": "" },"schema": { "properties": { "iocs": { "items": { type: "string" },"title": "IOCs", type: "array" } }, "title": "Extract IOCs", type: "object" }, type: "input" } + "mail-available": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 2, name: "Mail available","next": { "block-sender": "schemaKey == 'yes'", "extract-iocs": "schemaKey == 'yes'", "search-email-gateway": "schemaKey == 'no'" },"schema": { "oneOf": [ { "properties": { "mail": { "title": "Mail", type: "string", "x-display": "textarea" }, "schemaKey": { "const": "yes", type: "string" } },"required": [ "mail" ], "title": "Yes" },{ "properties": { "schemaKey": { "const": "no", type: "string" } },"title": "No" } ],"title": "Mail available", type: "object" }, type: "input" } + "search-email-gateway": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 4, name: "Search email gateway","next": { "extract-iocs": "" }, type: "task" } + references: + - { href: "https://www.leadmaximize.net/e-services/back-end", name: "performance" } + - { href: "http://www.corporateinteractive.name/rich", name: "autumn" } + - { href: "https://www.corporateintuitive.org/intuitive/platforms/integrate", name: "suggest" } + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + status: "closed" + type: "incident" + artifacts: + - { name: "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", status: "unknown" } + - { name: "http://www.customerviral.io/scalable/vertical/killer", status: "clean" } + - { name: "leadreintermediate.io", status: "malicious" } + security: [ { roles: [ "ticket:write" ] } ] + + /tickets/{id}/playbooks/{playbookID}/task/{taskID}/run: + post: + tags: [ "tickets" ] + summary: "Run ticket playbook task" + operationId: "runTask" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8123 } + - { name: "playbookID", in: "path", description: "Playbook ID", required: true, type: string, x-example: "phishing" } + - { name: "taskID", in: "path", description: "Task ID", required: true, type: string, x-example: "board" } + responses: + "204": { description: "successful operation" } + security: [ { roles: [ "ticket:write" ] } ] + + /tickets/{id}/artifacts: + post: + tags: [ "tickets" ] + summary: "Add a single artifact" + operationId: "addArtifact" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8123 } + - { name: "artifact", in: "body", description: "Artifact object that needs to be added", required: true, schema: { $ref: "#/definitions/Artifact" }, x-example: { name: "2.2.2.2" } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketResponse" } + examples: + test: + id: 8123 + created: "2021-10-02T18:04:59.078206+02:00" + modified: "2021-10-02T18:04:59.078206+02:00" + name: "live zebra" + owner: "demo" + playbooks: + phishing: + name: "Phishing" + tasks: + "block-iocs": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 6, name: "Block IOCs", type: "task" } + "block-sender": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 3, name: "Block sender","next": { "extract-iocs": "" }, type: "task" } + "board": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": true, "order": 0, name: "Board Involvement?","next": { "escalate": "boardInvolved == true","mail-available": "boardInvolved == false" },"schema": { "properties": { "boardInvolved": { "default": false, "title": "A board member is involved.", type: "boolean" } }, "required": [ "boardInvolved" ], "title": "Board Involvement?", type: "object" }, type: "input" } + "escalate": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 1, name: "Escalate to CISO", type: "task" } + "extract-iocs": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 5, name: "Extract IOCs", "next": { "block-iocs": "" },"schema": { "properties": { "iocs": { "items": { type: "string" },"title": "IOCs", type: "array" } }, "title": "Extract IOCs", type: "object" }, type: "input" } + "mail-available": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 2, name: "Mail available","next": { "block-sender": "schemaKey == 'yes'", "extract-iocs": "schemaKey == 'yes'", "search-email-gateway": "schemaKey == 'no'" },"schema": { "oneOf": [ { "properties": { "mail": { "title": "Mail", type: "string", "x-display": "textarea" }, "schemaKey": { "const": "yes", type: "string" } },"required": [ "mail" ], "title": "Yes" },{ "properties": { "schemaKey": { "const": "no", type: "string" } },"title": "No" } ],"title": "Mail available", type: "object" }, type: "input" } + "search-email-gateway": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 4, name: "Search email gateway","next": { "extract-iocs": "" }, type: "task" } + references: + - { href: "https://www.leadmaximize.net/e-services/back-end", name: "performance" } + - { href: "http://www.corporateinteractive.name/rich", name: "autumn" } + - { href: "https://www.corporateintuitive.org/intuitive/platforms/integrate", name: "suggest" } + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + status: "closed" + type: "incident" + artifacts: + - { name: "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", status: "unknown" } + - { name: "http://www.customerviral.io/scalable/vertical/killer", status: "clean" } + - { name: "leadreintermediate.io", status: "malicious" } + - { name: "2.2.2.2", status: "unknown", type: "ip" } + security: [ { roles: [ "ticket:write" ] } ] + + /tickets/{id}/artifacts/{name}: + get: + tags: [ "tickets" ] + summary: "Get a single artifact" + operationId: "getArtifact" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8123 } + - { name: "name", in: "path", required: true, type: string, x-example: "leadreintermediate.io" } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/Artifact" } + examples: + test: { name: "leadreintermediate.io", status: "malicious" } + security: [ { roles: [ "ticket:write" ] } ] + put: + tags: [ "tickets" ] + summary: "Set a single artifact" + operationId: "setArtifact" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8123 } + - { name: "name", in: "path", required: true, type: string, x-example: "leadreintermediate.io" } + - { name: "artifact", in: "body", required: true, schema: { $ref: "#/definitions/Artifact" }, x-example: { name: "leadreintermediate.io", status: "clean" } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketResponse" } + examples: + test: + id: 8123 + created: "2021-10-02T18:04:59.078206+02:00" + modified: "2021-10-02T18:04:59.078206+02:00" + name: "live zebra" + owner: "demo" + playbooks: + phishing: + name: "Phishing" + tasks: + "block-iocs": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 6, name: "Block IOCs", type: "task" } + "block-sender": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 3, name: "Block sender","next": { "extract-iocs": "" }, type: "task" } + "board": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": true, "order": 0, name: "Board Involvement?","next": { "escalate": "boardInvolved == true","mail-available": "boardInvolved == false" },"schema": { "properties": { "boardInvolved": { "default": false, "title": "A board member is involved.", type: "boolean" } }, "required": [ "boardInvolved" ], "title": "Board Involvement?", type: "object" }, type: "input" } + "escalate": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 1, name: "Escalate to CISO", type: "task" } + "extract-iocs": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 5, name: "Extract IOCs", "next": { "block-iocs": "" },"schema": { "properties": { "iocs": { "items": { type: "string" },"title": "IOCs", type: "array" } }, "title": "Extract IOCs", type: "object" }, type: "input" } + "mail-available": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 2, name: "Mail available","next": { "block-sender": "schemaKey == 'yes'", "extract-iocs": "schemaKey == 'yes'", "search-email-gateway": "schemaKey == 'no'" },"schema": { "oneOf": [ { "properties": { "mail": { "title": "Mail", type: "string", "x-display": "textarea" }, "schemaKey": { "const": "yes", type: "string" } },"required": [ "mail" ], "title": "Yes" },{ "properties": { "schemaKey": { "const": "no", type: "string" } },"title": "No" } ],"title": "Mail available", type: "object" }, type: "input" } + "search-email-gateway": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 4, name: "Search email gateway","next": { "extract-iocs": "" }, type: "task" } + references: + - { href: "https://www.leadmaximize.net/e-services/back-end", name: "performance" } + - { href: "http://www.corporateinteractive.name/rich", name: "autumn" } + - { href: "https://www.corporateintuitive.org/intuitive/platforms/integrate", name: "suggest" } + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + status: "closed" + type: "incident" + artifacts: + - { name: "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", status: "unknown" } + - { name: "http://www.customerviral.io/scalable/vertical/killer", status: "clean" } + - { name: "leadreintermediate.io", status: "clean" } + security: [ { roles: [ "ticket:write" ] } ] + delete: + tags: [ "tickets" ] + summary: "Remove an artifact" + operationId: "removeArtifact" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8123 } + - { name: "name", in: "path", required: true, type: string, x-example: "leadreintermediate.io" } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketResponse" } + examples: + test: + id: 8123 + created: "2021-10-02T18:04:59.078206+02:00" + modified: "2021-10-02T18:04:59.078206+02:00" + name: "live zebra" + owner: "demo" + playbooks: + phishing: + name: "Phishing" + tasks: + "block-iocs": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 6, name: "Block IOCs", type: "task" } + "block-sender": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 3, name: "Block sender","next": { "extract-iocs": "" }, type: "task" } + "board": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": true, "order": 0, name: "Board Involvement?","next": { "escalate": "boardInvolved == true","mail-available": "boardInvolved == false" },"schema": { "properties": { "boardInvolved": { "default": false, "title": "A board member is involved.", type: "boolean" } }, "required": [ "boardInvolved" ], "title": "Board Involvement?", type: "object" }, type: "input" } + "escalate": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 1, name: "Escalate to CISO", type: "task" } + "extract-iocs": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 5, name: "Extract IOCs", "next": { "block-iocs": "" },"schema": { "properties": { "iocs": { "items": { type: "string" },"title": "IOCs", type: "array" } }, "title": "Extract IOCs", type: "object" }, type: "input" } + "mail-available": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 2, name: "Mail available","next": { "block-sender": "schemaKey == 'yes'", "extract-iocs": "schemaKey == 'yes'", "search-email-gateway": "schemaKey == 'no'" },"schema": { "oneOf": [ { "properties": { "mail": { "title": "Mail", type: "string", "x-display": "textarea" }, "schemaKey": { "const": "yes", type: "string" } },"required": [ "mail" ], "title": "Yes" },{ "properties": { "schemaKey": { "const": "no", type: "string" } },"title": "No" } ],"title": "Mail available", type: "object" }, type: "input" } + "search-email-gateway": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 4, name: "Search email gateway","next": { "extract-iocs": "" }, type: "task" } + references: + - { href: "https://www.leadmaximize.net/e-services/back-end", name: "performance" } + - { href: "http://www.corporateinteractive.name/rich", name: "autumn" } + - { href: "https://www.corporateintuitive.org/intuitive/platforms/integrate", name: "suggest" } + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + status: "closed" + type: "incident" + artifacts: + - { name: "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", status: "unknown" } + - { name: "http://www.customerviral.io/scalable/vertical/killer", status: "clean" } + security: [ { roles: [ "ticket:write" ] } ] + + /tickets/{id}/artifacts/{name}/run/{automation}: + post: + tags: [ "tickets" ] + summary: "Run automation on a single artifact" + operationId: "runArtifact" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8123 } + - { name: "name", in: "path", required: true, type: string, x-example: "leadreintermediate.io" } + - { name: "automation", in: "path", required: true, type: string, x-example: "hash.sha1" } + responses: + "204": { description: "successful operation" } + security: [ { roles: [ "ticket:write" ] } ] + + /tickets/{id}/artifacts/{name}/enrich: + post: + tags: [ "tickets" ] + summary: "Enrich a single artifact" + operationId: "enrichArtifact" + parameters: + - { name: "id", in: "path", description: "Ticket ID", required: true, type: integer, format: "int64", x-example: 8123 } + - { name: "name", in: "path", required: true, type: string, x-example: "leadreintermediate.io" } + - { name: "data", in: "body", required: true, schema: { $ref: "#/definitions/EnrichmentForm" }, x-example: { name: "hash.sha1", data: { "hash": "b7a067a742c20d07a7456646de89bc2d408a1153" } } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/Artifact" } + examples: + test: + id: 8123 + created: "2021-10-02T18:04:59.078206+02:00" + modified: "2021-10-02T18:04:59.078206+02:00" + name: "live zebra" + owner: "demo" + playbooks: + phishing: + name: "Phishing" + tasks: + "block-iocs": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 6, name: "Block IOCs", type: "task" } + "block-sender": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 3, name: "Block sender","next": { "extract-iocs": "" }, type: "task" } + "board": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": true, "order": 0, name: "Board Involvement?","next": { "escalate": "boardInvolved == true","mail-available": "boardInvolved == false" },"schema": { "properties": { "boardInvolved": { "default": false, "title": "A board member is involved.", type: "boolean" } }, "required": [ "boardInvolved" ], "title": "Board Involvement?", type: "object" }, type: "input" } + "escalate": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 1, name: "Escalate to CISO", type: "task" } + "extract-iocs": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 5, name: "Extract IOCs", "next": { "block-iocs": "" },"schema": { "properties": { "iocs": { "items": { type: "string" },"title": "IOCs", type: "array" } }, "title": "Extract IOCs", type: "object" }, type: "input" } + "mail-available": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 2, name: "Mail available","next": { "block-sender": "schemaKey == 'yes'", "extract-iocs": "schemaKey == 'yes'", "search-email-gateway": "schemaKey == 'no'" },"schema": { "oneOf": [ { "properties": { "mail": { "title": "Mail", type: "string", "x-display": "textarea" }, "schemaKey": { "const": "yes", type: "string" } },"required": [ "mail" ], "title": "Yes" },{ "properties": { "schemaKey": { "const": "no", type: "string" } },"title": "No" } ],"title": "Mail available", type: "object" }, type: "input" } + "search-email-gateway": { created: "2021-10-02T18:04:59.078186+02:00", done: false, "active": false, "order": 4, name: "Search email gateway","next": { "extract-iocs": "" }, type: "task" } + references: + - { href: "https://www.leadmaximize.net/e-services/back-end", name: "performance" } + - { href: "http://www.corporateinteractive.name/rich", name: "autumn" } + - { href: "https://www.corporateintuitive.org/intuitive/platforms/integrate", name: "suggest" } + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + status: "closed" + type: "incident" + artifacts: + - { name: "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", status: "unknown" } + - { name: "http://www.customerviral.io/scalable/vertical/killer", status: "clean" } + - { name: "leadreintermediate.io", status: "malicious", enrichments: { hash.sha1: { name: "hash.sha1", created: "2021-10-03T18:44:06.488923+02:00", data: { "hash": "b7a067a742c20d07a7456646de89bc2d408a1153" } } } } + security: [ { roles: [ "ticket:write" ] } ] + +definitions: + + TicketForm: + type: object + required: [ name, type, status ] + properties: + id: { type: integer, format: int64, example: 123 } + name: { type: string, example: WannyCry } + type: { type: string, example: incident } + status: { type: string, example: "open" } + + owner: { type: string, example: "bob" } + write: { type: array, items: { type: string }, example: [ "alice" ] } + read: { type: array, items: { type: string }, example: [ "bob" ] } + + schema: { type: string, example: "{}" } + details: { type: object, example: { "description": "my little incident" } } + + references: { type: array, items: { $ref: '#/definitions/Reference' } } + playbooks: { type: array, items: { $ref: '#/definitions/PlaybookTemplateForm' } } + files: { type: array, items: { $ref: '#/definitions/File' } } + comments: { type: array, items: { $ref: '#/definitions/Comment' } } + artifacts: { type: array, items: { $ref: "#/definitions/Artifact" } } + + created: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" } + modified: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" } + + Ticket: + type: object + required: [ name, type, status, created, modified, schema ] + properties: + name: { type: string, example: WannyCry } + type: { type: string, example: incident } + status: { type: string, example: "open" } + + owner: { type: string, example: "bob" } + write: { type: array, items: { type: string }, example: [ "alice" ] } + read: { type: array, items: { type: string }, example: [ "bob" ] } + + schema: { type: string, example: "{}" } + details: { type: object, example: { "description": "my little incident" } } + + references: { type: array, items: { $ref: '#/definitions/Reference' } } + playbooks: { type: object, additionalProperties: { $ref: '#/definitions/Playbook' } } + files: { type: array, items: { $ref: '#/definitions/File' } } + comments: { type: array, items: { $ref: '#/definitions/Comment' } } + artifacts: { type: array, items: { $ref: "#/definitions/Artifact" } } + + created: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" } + modified: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" } + + TicketResponse: + type: object + required: [ id, name, type, status, created, modified, schema ] + properties: + id: { type: integer, format: int64, example: 123 } + name: { type: string, example: WannyCry } + type: { type: string, example: incident } + status: { type: string, example: "open" } + + owner: { type: string, example: "bob" } + write: { type: array, items: { type: string }, example: [ "alice" ] } + read: { type: array, items: { type: string }, example: [ "bob" ] } + + schema: { type: string, example: "{}" } + details: { type: object, example: { "description": "my little incident" } } + + references: { type: array, items: { $ref: '#/definitions/Reference' } } + playbooks: { type: object, additionalProperties: { $ref: '#/definitions/PlaybookResponse' } } + files: { type: array, items: { $ref: '#/definitions/File' } } + comments: { type: array, items: { $ref: '#/definitions/Comment' } } + artifacts: { type: array, items: { $ref: "#/definitions/Artifact" } } + + created: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" } + modified: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" } + + TicketSimpleResponse: + type: object + required: [ id, name, type, status, created, modified, schema ] + properties: + id: { type: integer, format: int64, example: 123 } + name: { type: string, example: WannyCry } + type: { type: string, example: incident } + status: { type: string, example: "open" } + + owner: { type: string, example: "bob" } + write: { type: array, items: { type: string }, example: [ "alice" ] } + read: { type: array, items: { type: string }, example: [ "bob" ] } + + schema: { type: string, example: "{}" } + details: { type: object, example: { "description": "my little incident" } } + + references: { type: array, items: { $ref: '#/definitions/Reference' } } + playbooks: { type: object, additionalProperties: { $ref: '#/definitions/Playbook' } } + files: { type: array, items: { $ref: '#/definitions/File' } } + comments: { type: array, items: { $ref: '#/definitions/Comment' } } + artifacts: { type: array, items: { $ref: "#/definitions/Artifact" } } + + created: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" } + modified: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" } + + TicketWithTickets: + type: object + required: [ id, name, type, status, created, modified, schema ] + properties: + id: { type: integer, format: int64, example: 123 } + name: { type: string, example: WannyCry } + type: { type: string, example: incident } + status: { type: string, example: "open" } + + owner: { type: string, example: "bob" } + write: { type: array, items: { type: string }, example: [ "alice" ] } + read: { type: array, items: { type: string }, example: [ "bob" ] } + + schema: { type: string, example: "{}" } + details: { type: object, example: { "description": "my little incident" } } + + references: { type: array, items: { $ref: '#/definitions/Reference' } } + playbooks: { type: object, additionalProperties: { $ref: '#/definitions/PlaybookResponse' } } + files: { type: array, items: { $ref: '#/definitions/File' } } + comments: { type: array, items: { $ref: '#/definitions/Comment' } } + artifacts: { type: array, items: { $ref: "#/definitions/Artifact" } } + + created: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" } + modified: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" } + + tickets: { type: array, items: { $ref: "#/definitions/TicketSimpleResponse" } } + + TicketList: + type: object + required: [ tickets, count ] + properties: + tickets: { type: array, items: { $ref: "#/definitions/TicketSimpleResponse" } } + count: { type: number, example: 3 } + + CommentForm: + type: object + required: [ message ] + properties: + creator: { type: string } + created: { type: string, format: "date-time" } + message: { type: string } + + Comment: + type: object + required: [ creator, created, message ] + properties: + creator: { type: string } + created: { type: string, format: "date-time" } + message: { type: string } + + Reference: + type: object + required: [ name, href ] + properties: + name: { type: string, example: "CVE-2017-0144" } + href: { type: string, example: "https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2017-0144" } + + File: + type: object + required: [ key, name ] + properties: + key: { type: string, example: "myfile" } + name: { type: string, example: "notes.docx" } + + Playbook: + type: object + required: [ name, tasks ] + properties: + name: { type: string, example: "Phishing" } + tasks: { type: object, additionalProperties: { $ref: '#/definitions/Task' } } + + PlaybookResponse: + type: object + required: [ name, tasks ] + properties: + name: { type: string, example: "Phishing" } + tasks: { type: object, additionalProperties: { $ref: '#/definitions/TaskResponse' } } diff --git a/definition/tickettype.yaml b/definition/tickettype.yaml new file mode 100644 index 0000000..3c8b491 --- /dev/null +++ b/definition/tickettype.yaml @@ -0,0 +1,121 @@ +swagger: "2.0" +info: { version: "", title: "" } + + +paths: + /tickettypes: + get: + tags: [ "tickettypes" ] + summary: "List tickettypes" + operationId: "listTicketTypes" + responses: + "200": + description: "successful operation" + schema: { type: array, items: { $ref: "#/definitions/TicketTypeResponse" } } + examples: + test: + - { icon: "mdi-alert", id: "alert", name: "Alerts", default_template: "default", default_playbooks: [ ] } + - { icon: "mdi-radioactive", id: "incident", name: "Incidents", default_template: "default", default_playbooks: [ ] } + - { icon: "mdi-fingerprint", id: "investigation", name: "Forensic Investigations", default_template: "default", default_playbooks: [ ] } + - { icon: "mdi-target", id: "hunt", name: "Threat Hunting", default_template: "default", default_playbooks: [ ] } + security: [ { roles: [ "tickettype:read" ] } ] + post: + tags: [ "tickettypes" ] + summary: "Create a new tickettype" + operationId: "createTicketType" + parameters: + - { name: "tickettype", in: "body", description: "New tickettype", required: true, schema: { $ref: "#/definitions/TicketTypeForm" }, x-example: { name: "TI Tickets", icon: "mdi-newspaper-variant-outline", default_template: "default", default_playbooks: [ ] } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketTypeResponse" } + examples: + test: + id: "ti-tickets" + name: "TI Tickets" + icon: "mdi-newspaper-variant-outline" + default_template: "default" + default_playbooks: [ ] + security: [ { roles: [ "tickettype:write" ] } ] + + /tickettypes/{id}: + get: + tags: [ "tickettypes" ] + summary: "Get a single tickettype" + operationId: "getTicketType" + parameters: + - { name: "id", in: "path", description: "TicketType ID", required: true, type: string, x-example: "alert" } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketTypeResponse" } + examples: + test: + icon: "mdi-alert" + id: "alert" + name: "Alerts" + default_template: "default" + default_playbooks: [ ] + security: [ { roles: [ "tickettype:read" ] } ] + put: + tags: [ "tickettypes" ] + summary: "Update an existing tickettype" + operationId: "updateTicketType" + parameters: + - { name: "id", in: "path", description: "TicketType ID", required: true, type: string, x-example: "alert" } + - { name: "tickettype", in: "body", description: "TicketType object that needs to be added", required: true, schema: { $ref: "#/definitions/TicketTypeForm" }, x-example: { icon: "mdi-bell", id: "alert", name: "Alerts", default_template: "default", default_playbooks: [ ] } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/TicketTypeResponse" } + examples: + test: + icon: "mdi-bell" + id: "alert" + name: "Alerts" + default_template: "default" + default_playbooks: [ ] + + security: [ { roles: [ "tickettype:write" ] } ] + delete: + tags: [ "tickettypes" ] + summary: "Delete a tickettype" + operationId: "deleteTicketType" + parameters: + - { name: "id", in: "path", description: "TicketType ID", required: true, type: string, x-example: "alert" } + responses: + "204": { description: "successful operation" } + security: [ { roles: [ "tickettype:write" ] } ] + +definitions: + TicketTypeForm: + type: object + required: [ name, icon, default_template, default_playbooks ] + properties: + id: { type: string } + icon: { type: string } + name: { type: string } + default_template: { type: string } + default_playbooks: { type: array, items: { type: string } } + default_groups: { type: array, items: { type: string } } + + TicketType: + type: object + required: [ name, icon, default_template, default_playbooks ] + properties: + icon: { type: string } + name: { type: string } + default_template: { type: string } + default_playbooks: { type: array, items: { type: string } } + default_groups: { type: array, items: { type: string } } + + TicketTypeResponse: + type: object + required: [ id, name, icon, default_template, default_playbooks ] + properties: + id: { type: string } + icon: { type: string } + name: { type: string } + default_template: { type: string } + default_playbooks: { type: array, items: { type: string } } + default_groups: { type: array, items: { type: string } } diff --git a/definition/userdata.yaml b/definition/userdata.yaml new file mode 100644 index 0000000..449fbca --- /dev/null +++ b/definition/userdata.yaml @@ -0,0 +1,94 @@ +swagger: "2.0" +info: { version: "", title: "" } + +paths: + /currentuserdata: + get: + tags: [ "userdata" ] + summary: "Get current user data" + operationId: "currentUserData" + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/UserDataResponse" } + examples: + test: { id: bob, name: "Bob Bad", email: "bob@example.org" } + security: [ { roles: [ "currentuserdata:read" ] } ] + put: + tags: [ "userdata" ] + summary: "Update current user data" + operationId: "updateCurrentUserData" + parameters: + - { name: "userdata", in: "body", description: "User data object that needs to be added", required: true, schema: { $ref: "#/definitions/UserData" }, x-example: { name: "Bob Bad", email: "bob@example.org" } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/UserDataResponse" } + examples: + test: { id: bob, name: "Bob Bad", email: "bob@example.org" } + security: [ { roles: [ "currentuserdata:write" ] } ] + + /userdata: + get: + tags: [ "userdata" ] + summary: "List userdata" + operationId: "listUserData" + responses: + "200": + description: "successful operation" + schema: { type: array, items: { $ref: "#/definitions/UserDataResponse" } } + examples: + test: + - { id: bob, name: "Bob Bad", email: "bob@example.org" } + security: [ { roles: [ "userdata:read" ] } ] + + /userdata/{id}: + get: + tags: [ "userdata" ] + summary: "Get a single user data" + operationId: "getUserData" + parameters: + - { name: "id", in: "path", description: "User Data ID", required: true, type: string, x-example: "bob" } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/UserDataResponse" } + examples: + test: + id: bob + name: "Bob Bad" + email: "bob@example.org" + security: [ { roles: [ "userdata:read" ] } ] + put: + tags: [ "userdata" ] + summary: "Update an existing user data" + operationId: "updateUserData" + parameters: + - { name: "id", in: "path", description: "User Data ID", required: true, type: string, x-example: "bob" } + - { name: "userdata", in: "body", description: "User data object that needs to be added", required: true, schema: { $ref: "#/definitions/UserData" }, x-example: { name: "Bob Bad", email: "bob@example.org", blocked: false } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/UserDataResponse" } + examples: + test: { id: bob, name: "Bob Bad", email: "bob@example.org" } + security: [ { roles: [ "userdata:write" ] } ] + +definitions: + UserData: + type: object + properties: + name: { type: string, x-example: "Robert Smith" } + email: { type: string, x-example: "bob@example.org" } + image: { type: string, x-display: "custom-avatar" } + timeformat: { title: "Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens)", type: string } + + UserDataResponse: + type: object + required: [ id ] + properties: + id: { type: string } + name: { type: string, x-example: "Robert Smith" } + email: { type: string, x-example: "bob@example.org" } + image: { type: string, x-display: "custom-avatar" } + timeformat: { title: "Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens)", type: string } diff --git a/definition/users.yaml b/definition/users.yaml new file mode 100644 index 0000000..5020cfd --- /dev/null +++ b/definition/users.yaml @@ -0,0 +1,122 @@ +swagger: "2.0" +info: { version: "", title: "" } + +paths: + /currentuser: + get: + tags: [ "users" ] + summary: "Get current user" + operationId: "currentUser" + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/UserResponse" } + examples: + test: { id: bob, roles: [ "admin:backup:read", "admin:backup:restore", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ], blocked: false, apikey: false } + security: [ { roles: [ "currentuser:read" ] } ] + + /users: + get: + tags: [ "users" ] + summary: "List users" + operationId: "listUsers" + responses: + "200": + description: "successful operation" + schema: { type: array, items: { $ref: "#/definitions/UserResponse" } } + examples: + test: + - { id: bob, blocked: false, roles: [ "admin:backup:read", "admin:backup:restore", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ], apikey: false } + - { id: script, roles: [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ], blocked: false, apikey: true } + security: [ { roles: [ "user:read" ] } ] + post: + tags: [ "users" ] + summary: "Create user" + operationId: "createUser" + parameters: + - { name: "user", in: "body", description: "user object that needs to be added", required: true, schema: { $ref: "#/definitions/UserForm" }, x-example: { id: "syncscript", roles: [ "analyst" ] } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/NewUserResponse" } + examples: + test: { id: "syncscript", roles: [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read" ], secret: "v39bOuobnlEljfWzjAgoKzhmnh1xSMxH", blocked: false } + security: [ { roles: [ "user:write" ] } ] + /users/{id}: + get: + tags: [ "users" ] + summary: "Get a single user" + operationId: "getUser" + parameters: + - { name: "id", in: "path", description: "user ID", required: true, type: string, x-example: "script" } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/UserResponse" } + examples: + test: { id: "script", roles: [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ], blocked: false, apikey: true } + security: [ { roles: [ "user:read" ] } ] + put: + tags: [ "users" ] + summary: "Update user" + operationId: "updateUser" + parameters: + - { name: "id", in: "path", description: "Template ID", required: true, type: string, x-example: "bob" } + - { name: "user", in: "body", description: "user object that needs to be added", required: true, schema: { $ref: "#/definitions/UserForm" }, x-example: { roles: [ "analyst", "admin" ] } } + responses: + "200": + description: "successful operation" + schema: { $ref: "#/definitions/UserResponse" } + examples: + test: + id: bob + roles: [ "admin:backup:read", "admin:backup:restore", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + apikey: false + blocked: false + security: [ { roles: [ "user:write" ] } ] + delete: + tags: [ "users" ] + summary: "Delete user" + operationId: "deleteUser" + parameters: + - { name: "id", in: "path", description: "user ID", required: true, type: string, x-example: "script" } + responses: + "204": { description: "successful operation" } + security: [ { roles: [ "user:write" ] } ] + +definitions: + UserForm: + type: object + required: [ id, blocked, roles, apikey ] + properties: + id: { type: string } + blocked: { type: boolean } + apikey: { type: boolean } + roles: { type: array, items: { type: string } } + + User: + type: object + required: [ blocked, apikey, roles ] + properties: + blocked: { type: boolean } + apikey: { type: boolean } + roles: { type: array, items: { type: string } } + sha256: { type: string } # for api keys + + UserResponse: + type: object + required: [ id, blocked, roles, apikey ] + properties: + id: { type: string } + blocked: { type: boolean } + apikey: { type: boolean } + roles: { type: array, items: { type: string } } + + NewUserResponse: + type: object + required: [ id, blocked, roles ] + properties: + id: { type: string } + blocked: { type: boolean } + roles: { type: array, items: { type: string } } + secret: { type: string } diff --git a/dev/docker-compose.yml b/dev/docker-compose.yml new file mode 100644 index 0000000..4308c8a --- /dev/null +++ b/dev/docker-compose.yml @@ -0,0 +1,49 @@ +version: '2.2' +services: + nginx: + image: nginx:1.21 + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf:ro + ports: [ "80:80", "8529:8529", "9000:9000", "9001:9001", "9002:9002" ] + + arangodb: + image: arangodb/arangodb:3.8.1 + environment: + ARANGO_ROOT_PASSWORD: foobar + + emitter: + image: emitter/server + environment: + - EMITTER_LICENSE=PfA8ID8izeSlDUlNZgNXo77DQV9QzlNtxTk64WreCXKfDZsREAVXUXwh20UKOZdkALbLTmOytO_iC6mc_twKAQ:3 + # A9RysEsPJni8RaHeg_K0FKXQNfBrUyw- + + minio: + image: minio/minio + environment: + MINIO_ROOT_USER: minio + MINIO_ROOT_PASSWORD: minio123 + command: server /data -console-address ":9003" + + postgres: + image: postgres + environment: + POSTGRES_DB: keycloak + POSTGRES_USER: keycloak + POSTGRES_PASSWORD: password + + keycloak: + image: quay.io/keycloak/keycloak:14.0.0 + environment: + DB_VENDOR: POSTGRES + DB_ADDR: postgres + DB_DATABASE: keycloak + DB_USER: keycloak + DB_SCHEMA: public + DB_PASSWORD: password + KEYCLOAK_USER: admin + KEYCLOAK_PASSWORD: admin + KEYCLOAK_IMPORT: /tmp/realm.json + PROXY_ADDRESS_FORWARDING: "true" + volumes: + - ./keycloak/realm.json:/tmp/realm.json + depends_on: [ postgres ] diff --git a/dev/keycloak/realm.json b/dev/keycloak/realm.json new file mode 100644 index 0000000..a8f59a8 --- /dev/null +++ b/dev/keycloak/realm.json @@ -0,0 +1,1997 @@ +{ + "id": "catalyst", + "realm": "catalyst", + "notBefore": 0, + "defaultSignatureAlgorithm": "RS256", + "revokeRefreshToken": false, + "refreshTokenMaxReuse": 0, + "accessTokenLifespan": 300, + "accessTokenLifespanForImplicitFlow": 900, + "ssoSessionIdleTimeout": 1800, + "ssoSessionMaxLifespan": 36000, + "ssoSessionIdleTimeoutRememberMe": 0, + "ssoSessionMaxLifespanRememberMe": 0, + "offlineSessionIdleTimeout": 2592000, + "offlineSessionMaxLifespanEnabled": false, + "offlineSessionMaxLifespan": 5184000, + "clientSessionIdleTimeout": 0, + "clientSessionMaxLifespan": 0, + "clientOfflineSessionIdleTimeout": 0, + "clientOfflineSessionMaxLifespan": 0, + "accessCodeLifespan": 60, + "accessCodeLifespanUserAction": 300, + "accessCodeLifespanLogin": 1800, + "actionTokenGeneratedByAdminLifespan": 43200, + "actionTokenGeneratedByUserLifespan": 300, + "oauth2DeviceCodeLifespan": 600, + "oauth2DevicePollingInterval": 5, + "enabled": true, + "sslRequired": "external", + "registrationAllowed": false, + "registrationEmailAsUsername": false, + "rememberMe": false, + "verifyEmail": false, + "loginWithEmailAllowed": true, + "duplicateEmailsAllowed": false, + "resetPasswordAllowed": false, + "editUsernameAllowed": false, + "bruteForceProtected": false, + "permanentLockout": false, + "maxFailureWaitSeconds": 900, + "minimumQuickLoginWaitSeconds": 60, + "waitIncrementSeconds": 60, + "quickLoginCheckMilliSeconds": 1000, + "maxDeltaTimeSeconds": 43200, + "failureFactor": 30, + "defaultRole": { + "id": "43c7a86b-0423-4699-bc4f-94979c8995c6", + "name": "default-roles-catalyst", + "description": "${role_default-roles}", + "composite": true, + "clientRole": false, + "containerId": "catalyst" + }, + "requiredCredentials": [ + "password" + ], + "otpPolicyType": "totp", + "otpPolicyAlgorithm": "HmacSHA1", + "otpPolicyInitialCounter": 0, + "otpPolicyDigits": 6, + "otpPolicyLookAheadWindow": 1, + "otpPolicyPeriod": 30, + "otpSupportedApplications": [ + "FreeOTP", + "Google Authenticator" + ], + "webAuthnPolicyRpEntityName": "keycloak", + "webAuthnPolicySignatureAlgorithms": [ + "ES256" + ], + "webAuthnPolicyRpId": "", + "webAuthnPolicyAttestationConveyancePreference": "not specified", + "webAuthnPolicyAuthenticatorAttachment": "not specified", + "webAuthnPolicyRequireResidentKey": "not specified", + "webAuthnPolicyUserVerificationRequirement": "not specified", + "webAuthnPolicyCreateTimeout": 0, + "webAuthnPolicyAvoidSameAuthenticatorRegister": false, + "webAuthnPolicyAcceptableAaguids": [], + "webAuthnPolicyPasswordlessRpEntityName": "keycloak", + "webAuthnPolicyPasswordlessSignatureAlgorithms": [ + "ES256" + ], + "webAuthnPolicyPasswordlessRpId": "", + "webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified", + "webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified", + "webAuthnPolicyPasswordlessRequireResidentKey": "not specified", + "webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified", + "webAuthnPolicyPasswordlessCreateTimeout": 0, + "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false, + "webAuthnPolicyPasswordlessAcceptableAaguids": [], + "users": [ + { + "id": "2da488d4-f934-4cfc-92fe-16bfbfd693e2", + "createdTimestamp": 1625168814915, + "username": "service-account-reader", + "enabled": true, + "totp": false, + "emailVerified": false, + "serviceAccountClientId": "reader", + "disableableCredentialTypes": [], + "requiredActions": [], + "notBefore": 0 + }, + { + "username" : "alice", + "enabled": true, + "email" : "alice@example.org", + "firstName": "Alice", + "lastName": "Alert Analyst", + "credentials" : [ + { "type" : "password", "value" : "alice" } + ] + }, + { + "username" : "bob", + "enabled": true, + "email" : "bob@example.org", + "firstName": "Bob", + "lastName": "Incident Handler", + "credentials" : [ + { "type" : "password", "value" : "bob" } + ] + }, + { + "username" : "carol", + "enabled": true, + "email" : "carol@example.org", + "firstName": "Carol", + "lastName": "Forensicator", + "credentials" : [ + { "type" : "password", "value" : "carol" } + ] + }, + { + "username" : "dave", + "enabled": true, + "email" : "dave@example.org", + "firstName": "Dave", + "lastName": "Admin", + "credentials" : [ + { "type" : "password", "value" : "dave" } + ] + }, + { + "username" : "eve", + "enabled": true, + "email" : "eve@example.org", + "firstName": "Eve", + "lastName": "Team Lead", + "credentials" : [ + { "type" : "password", "value" : "eve" } + ] + } + ], + "scopeMappings": [ + { + "clientScope": "offline_access", + "roles": [ + "offline_access" + ] + } + ], + "clientScopeMappings": { + "account": [ + { + "client": "account-console", + "roles": [ + "manage-account" + ] + } + ] + }, + "clients": [ + { + "id": "86c72872-e504-4a19-89d6-5c3843a107c6", + "clientId": "account", + "name": "${client_account}", + "rootUrl": "${authBaseUrl}", + "baseUrl": "/realms/catalyst/account/", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [ + "/realms/catalyst/account/*" + ], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": [ + "web-origins", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, + { + "id": "50acde65-ed47-42ed-9447-0b4b43983cf9", + "clientId": "account-console", + "name": "${client_account-console}", + "rootUrl": "${authBaseUrl}", + "baseUrl": "/realms/catalyst/account/", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [ + "/realms/catalyst/account/*" + ], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "pkce.code.challenge.method": "S256" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "protocolMappers": [ + { + "id": "8f05de9b-20b0-4cb0-9885-c1f08b16494d", + "name": "audience resolve", + "protocol": "openid-connect", + "protocolMapper": "oidc-audience-resolve-mapper", + "consentRequired": false, + "config": {} + } + ], + "defaultClientScopes": [ + "web-origins", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, + { + "id": "ce10e93d-9e15-4420-a8fd-c8fb8d262596", + "clientId": "admin-cli", + "name": "${client_admin-cli}", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": false, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": true, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": [ + "web-origins", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, + { + "id": "ff18f8fb-27be-47c2-9a76-3ceb17ccccd8", + "clientId": "broker", + "name": "${client_broker}", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": true, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": [ + "web-origins", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, + { + "id": "43419de7-4beb-4401-9a7f-34aedf158305", + "clientId": "reader", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": false, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": true, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "saml.assertion.signature": "false", + "id.token.as.detached.signature": "false", + "saml.multivalued.roles": "false", + "saml.force.post.binding": "false", + "saml.encrypt": "false", + "oauth2.device.authorization.grant.enabled": "false", + "backchannel.logout.revoke.offline.tokens": "false", + "saml.server.signature": "false", + "saml.server.signature.keyinfo.ext": "false", + "use.refresh.tokens": "true", + "exclude.session.state.from.auth.response": "false", + "oidc.ciba.grant.enabled": "false", + "saml.artifact.binding": "false", + "backchannel.logout.session.required": "true", + "client_credentials.use_refresh_token": "false", + "saml_force_name_id_format": "false", + "saml.client.signature": "false", + "tls.client.certificate.bound.access.tokens": "false", + "saml.authnstatement": "false", + "display.on.consent.screen": "false", + "saml.onetimeuse.condition": "false" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": true, + "nodeReRegistrationTimeout": -1, + "protocolMappers": [ + { + "id": "8da9dcd5-8da3-4280-bdaa-24c4c61b46b2", + "name": "Client Host", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientHost", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientHost", + "jsonType.label": "String" + } + }, + { + "id": "1e98ec8d-f131-4ef6-9363-a46930896cd3", + "name": "Client ID", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientId", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientId", + "jsonType.label": "String" + } + }, + { + "id": "85483f67-1ed0-40d1-a67a-29817b99d2b9", + "name": "Client IP Address", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientAddress", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientAddress", + "jsonType.label": "String" + } + } + ], + "defaultClientScopes": [ + "web-origins", + "roles", + "profile", + "groups", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, + { + "id": "d2286137-1944-4a9b-b826-4d5a6f7cdf28", + "clientId": "catalyst", + "rootUrl": "http://catalyst.internal.com/", + "adminUrl": "http://catalyst.internal.com/", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "secret": "d3ec0d91-b6ea-482d-8a4e-2f5a7ca0b4cb", + "redirectUris": [ + "http://catalyst.internal.com/*", + "http://localhost:8000/callback", + "http://localhost/callback" + ], + "webOrigins": [ + "http://catalyst.internal.com", + "http://localhost:8000", + "http://localhost", + "+" + ], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": true, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "id.token.as.detached.signature": "false", + "saml.assertion.signature": "false", + "saml.force.post.binding": "false", + "saml.multivalued.roles": "false", + "saml.encrypt": "false", + "oauth2.device.authorization.grant.enabled": "false", + "backchannel.logout.revoke.offline.tokens": "false", + "saml.server.signature": "false", + "saml.server.signature.keyinfo.ext": "false", + "use.refresh.tokens": "true", + "exclude.session.state.from.auth.response": "false", + "oidc.ciba.grant.enabled": "false", + "saml.artifact.binding": "false", + "backchannel.logout.session.required": "true", + "client_credentials.use_refresh_token": "false", + "saml_force_name_id_format": "false", + "saml.client.signature": "false", + "tls.client.certificate.bound.access.tokens": "false", + "saml.authnstatement": "false", + "display.on.consent.screen": "false", + "saml.onetimeuse.condition": "false" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": true, + "nodeReRegistrationTimeout": -1, + "defaultClientScopes": [ + "web-origins", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, + { + "id": "6cd83d64-0384-4e16-890d-2fa470b144ab", + "clientId": "realm-management", + "name": "${client_realm-management}", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": true, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": [ + "web-origins", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, + { + "id": "31f01a93-e892-4874-92be-62e1ba4c49b5", + "clientId": "security-admin-console", + "name": "${client_security-admin-console}", + "rootUrl": "${authAdminUrl}", + "baseUrl": "/admin/catalyst/console/", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [ + "/admin/catalyst/console/*" + ], + "webOrigins": [ + "+" + ], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "pkce.code.challenge.method": "S256" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "protocolMappers": [ + { + "id": "bff3e1b7-5125-419d-a97b-720622e79a81", + "name": "locale", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "locale", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "locale", + "jsonType.label": "String" + } + } + ], + "defaultClientScopes": [ + "web-origins", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + } + ], + "clientScopes": [ + { + "id": "90b39bdb-75ff-4928-ba7a-085b2f735409", + "name": "roles", + "description": "OpenID Connect scope for add user roles to the access token", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "false", + "display.on.consent.screen": "true", + "consent.screen.text": "${rolesScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "8fbf5a86-4629-4b1a-b66d-d957c8158e77", + "name": "audience resolve", + "protocol": "openid-connect", + "protocolMapper": "oidc-audience-resolve-mapper", + "consentRequired": false, + "config": {} + }, + { + "id": "065c0856-09e2-4b2e-ae83-7ca0edc487ac", + "name": "realm roles", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-realm-role-mapper", + "consentRequired": false, + "config": { + "user.attribute": "foo", + "access.token.claim": "true", + "claim.name": "realm_access.roles", + "jsonType.label": "String", + "multivalued": "true" + } + }, + { + "id": "2fca9b42-c6da-4d6a-94ee-c2c8b2731dfe", + "name": "client roles", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-client-role-mapper", + "consentRequired": false, + "config": { + "user.attribute": "foo", + "access.token.claim": "true", + "claim.name": "resource_access.${client_id}.roles", + "jsonType.label": "String", + "multivalued": "true" + } + } + ] + }, + { + "id": "3b637bf5-80f8-4419-921f-334b2c4dd11f", + "name": "groups", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true" + }, + "protocolMappers": [ + { + "id": "0acdd906-0208-4afa-b33a-01e59b280fac", + "name": "groups", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-realm-role-mapper", + "consentRequired": false, + "config": { + "multivalued": "true", + "user.attribute": "foo", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "groups", + "jsonType.label": "String" + } + } + ] + }, + { + "id": "7afd7e91-0f50-42dc-bfd7-5898ee70b908", + "name": "profile", + "description": "OpenID Connect built-in scope: profile", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${profileScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "975e3e1f-daca-4c91-b0ba-69242bbe0945", + "name": "middle name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "middleName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "middle_name", + "jsonType.label": "String" + } + }, + { + "id": "fef97135-a66c-48d2-a942-6798e387be15", + "name": "username", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "username", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "preferred_username", + "jsonType.label": "String" + } + }, + { + "id": "b3c5f39f-a126-4840-9103-2ae574344049", + "name": "gender", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "gender", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "gender", + "jsonType.label": "String" + } + }, + { + "id": "04a542fe-c6b1-4880-a0a9-e9a6934bf1f3", + "name": "picture", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "picture", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "picture", + "jsonType.label": "String" + } + }, + { + "id": "78d162f9-b23f-45ca-a671-f2f528229da2", + "name": "profile", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "profile", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "profile", + "jsonType.label": "String" + } + }, + { + "id": "30aecb8d-36fc-465e-a141-dc2b58ff675f", + "name": "birthdate", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "birthdate", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "birthdate", + "jsonType.label": "String" + } + }, + { + "id": "b20432db-d804-4821-989e-e48030d8b562", + "name": "locale", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "locale", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "locale", + "jsonType.label": "String" + } + }, + { + "id": "842ee2fa-5ecb-47f6-a890-f8cbd1ee1eb0", + "name": "full name", + "protocol": "openid-connect", + "protocolMapper": "oidc-full-name-mapper", + "consentRequired": false, + "config": { + "id.token.claim": "true", + "access.token.claim": "true", + "userinfo.token.claim": "true" + } + }, + { + "id": "7ca293bf-c6ba-45cc-b49d-a824ae1284b8", + "name": "family name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "lastName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "family_name", + "jsonType.label": "String" + } + }, + { + "id": "4d7f731d-0133-4501-8fd6-3a9918b7d7df", + "name": "nickname", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "nickname", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "nickname", + "jsonType.label": "String" + } + }, + { + "id": "68c7909b-e46d-421e-943d-0fc30d1fa0ab", + "name": "updated at", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "updatedAt", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "updated_at", + "jsonType.label": "String" + } + }, + { + "id": "9f041128-9b6e-4013-af57-e3599ea30465", + "name": "given name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "firstName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "given_name", + "jsonType.label": "String" + } + }, + { + "id": "6cfa184f-1163-4b6a-a4da-a96e4720cec6", + "name": "website", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "website", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "website", + "jsonType.label": "String" + } + }, + { + "id": "8328b25a-9b10-4059-ac90-20ffa2d8d331", + "name": "zoneinfo", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "zoneinfo", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "zoneinfo", + "jsonType.label": "String" + } + } + ] + }, + { + "id": "bcac8ddc-27db-4734-99db-ab9f892ea1a6", + "name": "microprofile-jwt", + "description": "Microprofile - JWT built-in scope", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "false" + }, + "protocolMappers": [ + { + "id": "272bbae0-68d0-4466-a756-742a26ad9e7d", + "name": "upn", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "username", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "upn", + "jsonType.label": "String" + } + }, + { + "id": "df5f04b5-544c-4cd4-8ea6-6ce101a72216", + "name": "groups", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-realm-role-mapper", + "consentRequired": false, + "config": { + "multivalued": "true", + "userinfo.token.claim": "true", + "user.attribute": "foo", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "groups", + "jsonType.label": "String" + } + } + ] + }, + { + "id": "cda6829b-af33-462c-99d1-198bcfe1a648", + "name": "phone", + "description": "OpenID Connect built-in scope: phone", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${phoneScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "834b65c6-72ac-4884-9fc6-d81e68d00e2e", + "name": "phone number verified", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "phoneNumberVerified", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "phone_number_verified", + "jsonType.label": "boolean" + } + }, + { + "id": "1d6d57b3-4500-4888-8473-c10b5c91dbb6", + "name": "phone number", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "phoneNumber", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "phone_number", + "jsonType.label": "String" + } + } + ] + }, + { + "id": "ed16c65e-eede-4dfa-a1c7-332cd0d3d2b0", + "name": "web-origins", + "description": "OpenID Connect scope for add allowed web origins to the access token", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "false", + "display.on.consent.screen": "false", + "consent.screen.text": "" + }, + "protocolMappers": [ + { + "id": "f6507f62-0e6b-4e46-8124-216eed351d9a", + "name": "allowed web origins", + "protocol": "openid-connect", + "protocolMapper": "oidc-allowed-origins-mapper", + "consentRequired": false, + "config": {} + } + ] + }, + { + "id": "22de1ea1-162c-4bca-a864-ce1c41a98984", + "name": "email", + "description": "OpenID Connect built-in scope: email", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${emailScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "5bb8438c-d485-4134-bc7c-006337364a8c", + "name": "email", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "email", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "email", + "jsonType.label": "String" + } + }, + { + "id": "3914a22d-f4f2-4278-8df6-17b3a2d79c11", + "name": "email verified", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "emailVerified", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "email_verified", + "jsonType.label": "boolean" + } + } + ] + }, + { + "id": "44eb06c1-1f84-4f20-9fe5-af2dd2652883", + "name": "role_list", + "description": "SAML role list", + "protocol": "saml", + "attributes": { + "consent.screen.text": "${samlRoleListScopeConsentText}", + "display.on.consent.screen": "true" + }, + "protocolMappers": [ + { + "id": "377fcde9-859d-4022-81e1-b08c523e9eea", + "name": "role list", + "protocol": "saml", + "protocolMapper": "saml-role-list-mapper", + "consentRequired": false, + "config": { + "single": "false", + "attribute.nameformat": "Basic", + "attribute.name": "Role" + } + } + ] + }, + { + "id": "9b141075-26c2-45d9-b4be-fd3c3cbb3c51", + "name": "address", + "description": "OpenID Connect built-in scope: address", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${addressScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "7cec2511-c0ef-4f79-842f-3c68573dc5a7", + "name": "address", + "protocol": "openid-connect", + "protocolMapper": "oidc-address-mapper", + "consentRequired": false, + "config": { + "user.attribute.formatted": "formatted", + "user.attribute.country": "country", + "user.attribute.postal_code": "postal_code", + "userinfo.token.claim": "true", + "user.attribute.street": "street", + "id.token.claim": "true", + "user.attribute.region": "region", + "access.token.claim": "true", + "user.attribute.locality": "locality" + } + } + ] + }, + { + "id": "40730fee-dab9-408b-934d-bc6eeea12ff8", + "name": "offline_access", + "description": "OpenID Connect built-in scope: offline_access", + "protocol": "openid-connect", + "attributes": { + "consent.screen.text": "${offlineAccessScopeConsentText}", + "display.on.consent.screen": "true" + } + } + ], + "defaultDefaultClientScopes": [ + "role_list", + "profile", + "email", + "roles", + "web-origins" + ], + "defaultOptionalClientScopes": [ + "offline_access", + "address", + "phone", + "microprofile-jwt" + ], + "browserSecurityHeaders": { + "contentSecurityPolicyReportOnly": "", + "xContentTypeOptions": "nosniff", + "xRobotsTag": "none", + "xFrameOptions": "SAMEORIGIN", + "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", + "xXSSProtection": "1; mode=block", + "strictTransportSecurity": "max-age=31536000; includeSubDomains" + }, + "smtpServer": {}, + "eventsEnabled": false, + "eventsListeners": [ + "jboss-logging" + ], + "enabledEventTypes": [], + "adminEventsEnabled": false, + "adminEventsDetailsEnabled": false, + "identityProviders": [], + "identityProviderMappers": [], + "components": { + "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [ + { + "id": "4b06a544-5815-47c4-8e21-e5e0c44af05b", + "name": "Trusted Hosts", + "providerId": "trusted-hosts", + "subType": "anonymous", + "subComponents": {}, + "config": { + "host-sending-registration-request-must-match": [ + "true" + ], + "client-uris-must-match": [ + "true" + ] + } + }, + { + "id": "b58228d2-64f7-4880-bdb4-b37902896176", + "name": "Allowed Protocol Mapper Types", + "providerId": "allowed-protocol-mappers", + "subType": "authenticated", + "subComponents": {}, + "config": { + "allowed-protocol-mapper-types": [ + "saml-user-attribute-mapper", + "oidc-sha256-pairwise-sub-mapper", + "oidc-address-mapper", + "oidc-full-name-mapper", + "saml-user-property-mapper", + "oidc-usermodel-property-mapper", + "saml-role-list-mapper", + "oidc-usermodel-attribute-mapper" + ] + } + }, + { + "id": "2122720d-ea69-4bfa-834e-f1dd12ad55df", + "name": "Max Clients Limit", + "providerId": "max-clients", + "subType": "anonymous", + "subComponents": {}, + "config": { + "max-clients": [ + "200" + ] + } + }, + { + "id": "e1a99694-7f99-416d-8e80-2ab92c53034a", + "name": "Consent Required", + "providerId": "consent-required", + "subType": "anonymous", + "subComponents": {}, + "config": {} + }, + { + "id": "83ae6ccc-24c1-47d5-9bae-59879a90e2a4", + "name": "Allowed Client Scopes", + "providerId": "allowed-client-templates", + "subType": "anonymous", + "subComponents": {}, + "config": { + "allow-default-scopes": [ + "true" + ] + } + }, + { + "id": "15dcc7e3-13a1-45d2-b95c-f92cb7b86471", + "name": "Allowed Client Scopes", + "providerId": "allowed-client-templates", + "subType": "authenticated", + "subComponents": {}, + "config": { + "allow-default-scopes": [ + "true" + ] + } + }, + { + "id": "c9f2eefd-43dd-49fb-b143-f61135c4fc9d", + "name": "Full Scope Disabled", + "providerId": "scope", + "subType": "anonymous", + "subComponents": {}, + "config": {} + }, + { + "id": "ef9fa331-eaed-4408-999f-5c2e86e883ea", + "name": "Allowed Protocol Mapper Types", + "providerId": "allowed-protocol-mappers", + "subType": "anonymous", + "subComponents": {}, + "config": { + "allowed-protocol-mapper-types": [ + "saml-user-attribute-mapper", + "oidc-usermodel-property-mapper", + "oidc-address-mapper", + "saml-user-property-mapper", + "oidc-full-name-mapper", + "oidc-usermodel-attribute-mapper", + "oidc-sha256-pairwise-sub-mapper", + "saml-role-list-mapper" + ] + } + } + ], + "org.keycloak.keys.KeyProvider": [ + { + "id": "9681f0d2-cf07-481a-b51b-755824f4c848", + "name": "hmac-generated", + "providerId": "hmac-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ], + "algorithm": [ + "HS256" + ] + } + }, + { + "id": "b7310fea-0031-46be-a62d-bcfc363a6b38", + "name": "rsa-generated", + "providerId": "rsa-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ] + } + }, + { + "id": "e462b05b-9e22-403c-b715-582c2c7d9d31", + "name": "aes-generated", + "providerId": "aes-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ] + } + } + ] + }, + "internationalizationEnabled": false, + "supportedLocales": [], + "authenticationFlows": [ + { + "id": "25cc92da-3b9c-420f-aed4-47fc9a862cf1", + "alias": "Account verification options", + "description": "Method with which to verity the existing account", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "idp-email-verification", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "ALTERNATIVE", + "priority": 20, + "flowAlias": "Verify Existing Account by Re-authentication", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "9a50d2e9-9b6c-43d4-9e96-5e0057b9989e", + "alias": "Authentication Options", + "description": "Authentication options.", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "basic-auth", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "basic-auth-otp", + "authenticatorFlow": false, + "requirement": "DISABLED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "auth-spnego", + "authenticatorFlow": false, + "requirement": "DISABLED", + "priority": 30, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "9c08f7ff-0ae1-4917-acde-a86918c21392", + "alias": "Browser - Conditional OTP", + "description": "Flow to determine if the OTP is required for the authentication", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "auth-otp-form", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "cc263684-5287-48c3-b36f-cf0307e5866f", + "alias": "Direct Grant - Conditional OTP", + "description": "Flow to determine if the OTP is required for the authentication", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "direct-grant-validate-otp", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "2d1b3b73-d844-48e6-9564-ebb612eb1ecd", + "alias": "First broker login - Conditional OTP", + "description": "Flow to determine if the OTP is required for the authentication", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "auth-otp-form", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "05ead699-855a-4a82-a040-93fccf6ddc91", + "alias": "Handle Existing Account", + "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "idp-confirm-link", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "REQUIRED", + "priority": 20, + "flowAlias": "Account verification options", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "2c0e2ddf-4de7-44ff-8e3c-7d547e6cc52b", + "alias": "Reset - Conditional OTP", + "description": "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "reset-otp", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "9ce700a0-743c-42f9-be51-83e11beb1521", + "alias": "User creation or linking", + "description": "Flow for the existing/non-existing user alternatives", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticatorConfig": "create unique user config", + "authenticator": "idp-create-user-if-unique", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "ALTERNATIVE", + "priority": 20, + "flowAlias": "Handle Existing Account", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "f2454788-daaa-4c04-ad4f-b3d686727665", + "alias": "Verify Existing Account by Re-authentication", + "description": "Reauthentication of existing account", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "idp-username-password-form", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 20, + "flowAlias": "First broker login - Conditional OTP", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "fd57d3fe-8353-4d51-ab6b-531f1b6484d0", + "alias": "browser", + "description": "browser based authentication", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "auth-cookie", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "auth-spnego", + "authenticatorFlow": false, + "requirement": "DISABLED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "identity-provider-redirector", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 25, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "ALTERNATIVE", + "priority": 30, + "flowAlias": "forms", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "0895ae02-6132-41aa-8e2a-ae7ef8a1a090", + "alias": "clients", + "description": "Base authentication for clients", + "providerId": "client-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "client-secret", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "client-jwt", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "client-secret-jwt", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 30, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "client-x509", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 40, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "f1cd5fb9-4201-4645-a4f7-72e2404f9b5f", + "alias": "direct grant", + "description": "OpenID Connect Resource Owner Grant", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "direct-grant-validate-username", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "direct-grant-validate-password", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 30, + "flowAlias": "Direct Grant - Conditional OTP", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "34571ce1-2cc9-4ee6-be67-88761c35fb1e", + "alias": "docker auth", + "description": "Used by Docker clients to authenticate against the IDP", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "docker-http-basic-authenticator", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "708e0448-2e55-4e93-8d27-2bcb30fb484e", + "alias": "first broker login", + "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticatorConfig": "review profile config", + "authenticator": "idp-review-profile", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "REQUIRED", + "priority": 20, + "flowAlias": "User creation or linking", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "4e1d40ab-f072-4deb-ba28-3938d306a5e2", + "alias": "forms", + "description": "Username, password, otp and other auth forms.", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "auth-username-password-form", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 20, + "flowAlias": "Browser - Conditional OTP", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "fad42d83-0a6b-441a-a217-73ea14f7460d", + "alias": "http challenge", + "description": "An authentication flow based on challenge-response HTTP Authentication Schemes", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "no-cookie-redirect", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "REQUIRED", + "priority": 20, + "flowAlias": "Authentication Options", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "f44f939f-75c5-4080-880b-00ccb4a7496e", + "alias": "registration", + "description": "registration flow", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "registration-page-form", + "authenticatorFlow": true, + "requirement": "REQUIRED", + "priority": 10, + "flowAlias": "registration form", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "e7350e5b-1f96-4b34-94ac-0fd465f1d7a9", + "alias": "registration form", + "description": "registration form", + "providerId": "form-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "registration-user-creation", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "registration-profile-action", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 40, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "registration-password-action", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 50, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "registration-recaptcha-action", + "authenticatorFlow": false, + "requirement": "DISABLED", + "priority": 60, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "34cc3df0-1908-4a02-89df-08560e2a3e6c", + "alias": "reset credentials", + "description": "Reset credentials for a user if they forgot their password or something", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "reset-credentials-choose-user", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "reset-credential-email", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "reset-password", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 30, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 40, + "flowAlias": "Reset - Conditional OTP", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "d92671ab-6873-4eac-863a-becb6cdaa9f4", + "alias": "saml ecp", + "description": "SAML ECP Profile Authentication Flow", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "http-basic-authenticator", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + } + ], + "authenticatorConfig": [ + { + "id": "d73bbeaf-a93d-4b97-8c6b-d01b015f2861", + "alias": "create unique user config", + "config": { + "require.password.update.after.registration": "false" + } + }, + { + "id": "a459ffde-e6fc-41d8-9ab8-c7b65b4384c3", + "alias": "review profile config", + "config": { + "update.profile.on.first.login": "missing" + } + } + ], + "requiredActions": [ + { + "alias": "CONFIGURE_TOTP", + "name": "Configure OTP", + "providerId": "CONFIGURE_TOTP", + "enabled": true, + "defaultAction": false, + "priority": 10, + "config": {} + }, + { + "alias": "terms_and_conditions", + "name": "Terms and Conditions", + "providerId": "terms_and_conditions", + "enabled": false, + "defaultAction": false, + "priority": 20, + "config": {} + }, + { + "alias": "UPDATE_PASSWORD", + "name": "Update Password", + "providerId": "UPDATE_PASSWORD", + "enabled": true, + "defaultAction": false, + "priority": 30, + "config": {} + }, + { + "alias": "UPDATE_PROFILE", + "name": "Update Profile", + "providerId": "UPDATE_PROFILE", + "enabled": true, + "defaultAction": false, + "priority": 40, + "config": {} + }, + { + "alias": "VERIFY_EMAIL", + "name": "Verify Email", + "providerId": "VERIFY_EMAIL", + "enabled": true, + "defaultAction": false, + "priority": 50, + "config": {} + }, + { + "alias": "delete_account", + "name": "Delete Account", + "providerId": "delete_account", + "enabled": false, + "defaultAction": false, + "priority": 60, + "config": {} + }, + { + "alias": "update_user_locale", + "name": "Update User Locale", + "providerId": "update_user_locale", + "enabled": true, + "defaultAction": false, + "priority": 1000, + "config": {} + } + ], + "browserFlow": "browser", + "registrationFlow": "registration", + "directGrantFlow": "direct grant", + "resetCredentialsFlow": "reset credentials", + "clientAuthenticationFlow": "clients", + "dockerAuthenticationFlow": "docker auth", + "attributes": { + "cibaBackchannelTokenDeliveryMode": "poll", + "cibaExpiresIn": "120", + "cibaAuthRequestedUserHint": "login_hint", + "oauth2DeviceCodeLifespan": "600", + "clientOfflineSessionMaxLifespan": "0", + "oauth2DevicePollingInterval": "5", + "clientSessionIdleTimeout": "0", + "clientSessionMaxLifespan": "0", + "clientOfflineSessionIdleTimeout": "0", + "cibaInterval": "5" + }, + "keycloakVersion": "14.0.0", + "userManagedAccessAllowed": false, + "clientProfiles": { + "profiles": [] + }, + "clientPolicies": { + "policies": [] + } +} diff --git a/dev/nginx.conf b/dev/nginx.conf new file mode 100644 index 0000000..fcb5a48 --- /dev/null +++ b/dev/nginx.conf @@ -0,0 +1,89 @@ +user www-data; +worker_processes 5; +error_log /var/log/nginx/error.log; + +events { + worker_connections 4096; +} + +http { + include mime.types; + index index.html index.htm; + + log_format main '$remote_addr - $remote_user [$time_local] $status ' + '"$request" $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + access_log /var/log/nginx/access.log main; + + server { + listen 80 default_server; + server_name _; + + location / { + resolver 127.0.0.11 valid=30s; + set $upstream_catalyst host.docker.internal; + proxy_pass http://$upstream_catalyst:8000; + } + + location /wss { + resolver 127.0.0.11 valid=30s; + set $upstream_catalyst host.docker.internal; + proxy_pass http://$upstream_catalyst:8000; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_read_timeout 86400; + } + } + + server { + listen 8529 default_server; + server_name _; + + location / { + resolver 127.0.0.11 valid=30s; + set $upstream_arangodb arangodb; + proxy_pass http://$upstream_arangodb:8529; + } + } + + server { + listen 9000 default_server; + server_name _; + + location / { + resolver 127.0.0.11 valid=30s; + set $upstream_minio minio; + proxy_pass http://$upstream_minio:9000; + } + } + + server { + listen 9002 default_server; + server_name _; + + location / { + resolver 127.0.0.11 valid=30s; + set $upstream_keycloak keycloak; + proxy_pass http://$upstream_keycloak:8080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Port $server_port; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + } + } +} + +stream { + server { + listen 9001; + + resolver 127.0.0.11 valid=30s; + set $upstream_emitter emitter; + proxy_pass $upstream_emitter:8080; + } +} diff --git a/docs/screenshots/automation.png b/docs/screenshots/automation.png new file mode 100644 index 0000000..5c011cb Binary files /dev/null and b/docs/screenshots/automation.png differ diff --git a/docs/screenshots/cond_custom_1.png b/docs/screenshots/cond_custom_1.png new file mode 100644 index 0000000..c833337 Binary files /dev/null and b/docs/screenshots/cond_custom_1.png differ diff --git a/docs/screenshots/cond_custom_2.png b/docs/screenshots/cond_custom_2.png new file mode 100644 index 0000000..dff8050 Binary files /dev/null and b/docs/screenshots/cond_custom_2.png differ diff --git a/docs/screenshots/conditional_custom_field_a.png b/docs/screenshots/conditional_custom_field_a.png new file mode 100644 index 0000000..8b16eef Binary files /dev/null and b/docs/screenshots/conditional_custom_field_a.png differ diff --git a/docs/screenshots/conditional_custom_field_b.png b/docs/screenshots/conditional_custom_field_b.png new file mode 100644 index 0000000..86012de Binary files /dev/null and b/docs/screenshots/conditional_custom_field_b.png differ diff --git a/docs/screenshots/details.png b/docs/screenshots/details.png new file mode 100644 index 0000000..7fc82e4 Binary files /dev/null and b/docs/screenshots/details.png differ diff --git a/docs/screenshots/phishing_playbook.png b/docs/screenshots/phishing_playbook.png new file mode 100644 index 0000000..7660390 Binary files /dev/null and b/docs/screenshots/phishing_playbook.png differ diff --git a/docs/screenshots/playbooks.png b/docs/screenshots/playbooks.png new file mode 100644 index 0000000..8394dde Binary files /dev/null and b/docs/screenshots/playbooks.png differ diff --git a/docs/screenshots/playbooks_focus.png b/docs/screenshots/playbooks_focus.png new file mode 100644 index 0000000..f776f24 Binary files /dev/null and b/docs/screenshots/playbooks_focus.png differ diff --git a/docs/screenshots/roles.png b/docs/screenshots/roles.png new file mode 100644 index 0000000..e747945 Binary files /dev/null and b/docs/screenshots/roles.png differ diff --git a/docs/screenshots/script.png b/docs/screenshots/script.png new file mode 100644 index 0000000..51a6d31 Binary files /dev/null and b/docs/screenshots/script.png differ diff --git a/docs/screenshots/template.png b/docs/screenshots/template.png new file mode 100644 index 0000000..12660c7 Binary files /dev/null and b/docs/screenshots/template.png differ diff --git a/docs/screenshots/ticket.png b/docs/screenshots/ticket.png new file mode 100644 index 0000000..8c0c4ef Binary files /dev/null and b/docs/screenshots/ticket.png differ diff --git a/docs/screenshots/user.png b/docs/screenshots/user.png new file mode 100644 index 0000000..63ee377 Binary files /dev/null and b/docs/screenshots/user.png differ diff --git a/file.go b/file.go new file mode 100644 index 0000000..c480775 --- /dev/null +++ b/file.go @@ -0,0 +1,95 @@ +package catalyst + +import ( + "errors" + "fmt" + "io" + "log" + "net/http" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/s3" + "github.com/aws/aws-sdk-go/service/s3/s3manager" + "github.com/gin-gonic/gin" + tusd "github.com/tus/tusd/pkg/handler" + "github.com/tus/tusd/pkg/s3store" + + "github.com/SecurityBrewery/catalyst/storage" +) + +func upload(client *s3.S3, external string) gin.HandlerFunc { + return func(ctx *gin.Context) { + ticketID, exists := ctx.Params.Get("ticketID") + if !exists { + ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "ticketID not given"}) + return + } + + if err := storage.CreateBucket(client, ticketID); err != nil { + ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("could not create bucket: %w", err)}) + return + } + + store := s3store.New("catalyst-"+ticketID, client) + + composer := tusd.NewStoreComposer() + store.UseIn(composer) + + handler, err := tusd.NewUnroutedHandler(tusd.Config{ + BasePath: external + "/api/files/" + ticketID + "/upload/", + StoreComposer: composer, + }) + if err != nil { + ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("could not create tusd handler: %w", err)}) + return + } + + switch ctx.Request.Method { + case http.MethodHead: + gin.WrapF(handler.HeadFile)(ctx) + case http.MethodPost: + gin.WrapF(handler.PostFile)(ctx) + case http.MethodPatch: + gin.WrapF(handler.PatchFile)(ctx) + default: + log.Println(errors.New("unknown method")) + ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "unknown method"}) + } + } +} + +func download(downloader *s3manager.Downloader) gin.HandlerFunc { + return func(ctx *gin.Context) { + ticketID, exists := ctx.Params.Get("ticketID") + if !exists { + ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "ticketID not given"}) + return + } + + key, exists := ctx.Params.Get("key") + if !exists { + ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "key not given"}) + return + } + + buf := sequentialWriter{ctx.Writer} + + downloader.Concurrency = 1 + _, err := downloader.Download(buf, &s3.GetObjectInput{ + Bucket: aws.String("catalyst-" + ticketID), + Key: aws.String(key), + }) + if err != nil { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err}) + return + } + } +} + +type sequentialWriter struct { + w io.Writer +} + +func (fw sequentialWriter) WriteAt(p []byte, _ int64) (n int, err error) { + return fw.w.Write(p) +} diff --git a/generate.sh b/generate.sh new file mode 100644 index 0000000..51ac1ae --- /dev/null +++ b/generate.sh @@ -0,0 +1,37 @@ +set -e + +rm -rf generated + +mkdir generated +spruce merge definition/*.yaml >generated/community.yml +spruce merge definition/*.yaml definition/enterprise/*.yaml >generated/catalyst.yml + +echo generate caql parser and lexer +cd definition || exit +antlr -Dlanguage=Go -o ../generated/caql/parser CAQLParser.g4 CAQLLexer.g4 +antlr -Dlanguage=JavaScript -o ../ui/src/suggestions/grammar CAQLParser.g4 CAQLLexer.g4 +cd .. + +echo generate json +openapi-generator generate -i generated/community.yml -o generated -g openapi +mv generated/openapi.json generated/community.json +openapi-generator generate -i generated/catalyst.yml -o generated -g openapi +mv generated/openapi.json generated/catalyst.json + +# generate python client +# openapi-generator generate -i generated/community.yml -o generated/python -g python --package-name catalystpy --ignore-file-override .openapi-generator-ignore + +echo generate server and tests +go run ./generator/. ./generator + +echo generate typescript client +openapi-generator generate -i generated/catalyst.yml -o ui/src/client -g typescript-axios --artifact-version 1.0.0-SNAPSHOT + +rm -rf gen +rm -rf generated/models/old +rm -rf generated/.openapi-generator generated/.openapi-generator-ignore generated/README.md +# rm -rf generated/python/.openapi-generator generated/python/.gitlab-ci.yml generated/python/git_push.sh generated/python/.travis.yml generated/python/.gitignore generated/python/.openapi-generator-ignore +rm -rf ui/src/client/.openapi-generator ui/src/client/git_push.sh ui/src/client/.gitignore ui/src/client/.openapi-generator-ignore + +go mod tidy +gci -w -local "github.com/SecurityBrewery/catalyst" . diff --git a/generated/caql/parser/caql_lexer.go b/generated/caql/parser/caql_lexer.go new file mode 100644 index 0000000..8e2cd57 --- /dev/null +++ b/generated/caql/parser/caql_lexer.go @@ -0,0 +1,517 @@ +// Code generated from CAQLLexer.g4 by ANTLR 4.9.2. DO NOT EDIT. + +package parser + +import ( + "fmt" + "unicode" + + "github.com/antlr/antlr4/runtime/Go/antlr" +) + +// Suppress unused import error +var _ = fmt.Printf +var _ = unicode.IsLetter + +var serializedLexerAtn = []uint16{ + 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 80, 739, + 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, + 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, + 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, + 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, + 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, + 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, + 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, + 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, + 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, + 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, + 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, + 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, + 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, + 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, + 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, + 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, + 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, + 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, + 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, + 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, + 9, 106, 4, 107, 9, 107, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, + 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, + 3, 9, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, + 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, + 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, + 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 27, + 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, + 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 5, 29, 294, 10, 29, 3, 30, 3, 30, + 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, + 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, + 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, + 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, + 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, + 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, + 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, + 42, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, + 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, + 44, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, + 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, + 48, 5, 48, 414, 10, 48, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, + 3, 50, 3, 50, 3, 50, 5, 50, 426, 10, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, + 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 52, 3, 52, + 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 3, + 54, 3, 54, 3, 54, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, + 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 56, 3, + 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, + 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, + 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, + 3, 61, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, + 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, + 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, + 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, + 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 3, 70, 3, 70, 7, 70, 555, 10, 70, 12, + 70, 14, 70, 558, 11, 70, 3, 71, 3, 71, 7, 71, 562, 10, 71, 12, 71, 14, + 71, 565, 11, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 6, 71, 572, 10, 71, + 13, 71, 14, 71, 573, 3, 71, 3, 71, 3, 71, 3, 71, 6, 71, 580, 10, 71, 13, + 71, 14, 71, 581, 5, 71, 584, 10, 71, 3, 72, 3, 72, 7, 72, 588, 10, 72, + 12, 72, 14, 72, 591, 11, 72, 3, 72, 5, 72, 594, 10, 72, 3, 72, 3, 72, 6, + 72, 598, 10, 72, 13, 72, 14, 72, 599, 3, 72, 3, 72, 5, 72, 604, 10, 72, + 3, 72, 6, 72, 607, 10, 72, 13, 72, 14, 72, 608, 5, 72, 611, 10, 72, 3, + 73, 3, 73, 3, 73, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 7, 74, 622, + 10, 74, 12, 74, 14, 74, 625, 11, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, + 3, 74, 3, 74, 7, 74, 634, 10, 74, 12, 74, 14, 74, 637, 11, 74, 3, 74, 5, + 74, 640, 10, 74, 3, 75, 3, 75, 3, 75, 3, 75, 7, 75, 646, 10, 75, 12, 75, + 14, 75, 649, 11, 75, 3, 75, 5, 75, 652, 10, 75, 3, 75, 3, 75, 5, 75, 656, + 10, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 7, 76, 664, 10, 76, 12, + 76, 14, 76, 667, 11, 76, 3, 76, 3, 76, 3, 76, 3, 76, 3, 76, 3, 77, 3, 77, + 3, 77, 3, 77, 3, 78, 3, 78, 3, 79, 3, 79, 3, 80, 3, 80, 3, 81, 3, 81, 3, + 82, 3, 82, 3, 83, 3, 83, 3, 84, 3, 84, 3, 85, 3, 85, 3, 86, 3, 86, 3, 87, + 3, 87, 3, 88, 3, 88, 3, 89, 3, 89, 3, 90, 3, 90, 3, 91, 3, 91, 3, 92, 3, + 92, 3, 93, 3, 93, 3, 94, 3, 94, 3, 95, 3, 95, 3, 96, 3, 96, 3, 97, 3, 97, + 3, 98, 3, 98, 3, 99, 3, 99, 3, 100, 3, 100, 3, 101, 3, 101, 3, 102, 3, + 102, 3, 103, 3, 103, 3, 104, 3, 104, 3, 105, 3, 105, 3, 106, 3, 106, 3, + 107, 3, 107, 3, 107, 3, 107, 3, 665, 2, 108, 3, 3, 5, 4, 7, 5, 9, 6, 11, + 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, + 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 41, 22, 43, 23, 45, 24, 47, 25, + 49, 26, 51, 27, 53, 28, 55, 29, 57, 30, 59, 31, 61, 32, 63, 33, 65, 34, + 67, 35, 69, 36, 71, 37, 73, 38, 75, 39, 77, 40, 79, 41, 81, 42, 83, 43, + 85, 44, 87, 45, 89, 46, 91, 47, 93, 48, 95, 49, 97, 50, 99, 51, 101, 52, + 103, 53, 105, 54, 107, 55, 109, 56, 111, 57, 113, 58, 115, 59, 117, 60, + 119, 61, 121, 62, 123, 63, 125, 64, 127, 65, 129, 66, 131, 67, 133, 68, + 135, 69, 137, 70, 139, 71, 141, 72, 143, 73, 145, 74, 147, 75, 149, 76, + 151, 77, 153, 78, 155, 79, 157, 2, 159, 2, 161, 2, 163, 2, 165, 2, 167, + 2, 169, 2, 171, 2, 173, 2, 175, 2, 177, 2, 179, 2, 181, 2, 183, 2, 185, + 2, 187, 2, 189, 2, 191, 2, 193, 2, 195, 2, 197, 2, 199, 2, 201, 2, 203, + 2, 205, 2, 207, 2, 209, 2, 211, 2, 213, 80, 3, 2, 39, 5, 2, 67, 92, 97, + 97, 99, 124, 6, 2, 50, 59, 67, 92, 97, 97, 99, 124, 3, 2, 51, 59, 3, 2, + 50, 51, 4, 2, 45, 45, 47, 47, 4, 2, 41, 41, 94, 94, 4, 2, 36, 36, 94, 94, + 4, 2, 12, 12, 15, 15, 5, 2, 11, 13, 15, 15, 34, 34, 5, 2, 50, 59, 67, 72, + 99, 104, 3, 2, 50, 59, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, + 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 71, 71, 103, 103, 4, + 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, + 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 77, 77, 109, 109, 4, + 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, + 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, + 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, + 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, + 2, 90, 90, 122, 122, 4, 2, 91, 91, 123, 123, 4, 2, 92, 92, 124, 124, 2, + 738, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, + 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, + 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, + 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, + 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, + 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, + 2, 2, 49, 3, 2, 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 2, + 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, + 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, + 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, + 79, 3, 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, + 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, + 2, 2, 95, 3, 2, 2, 2, 2, 97, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, + 2, 2, 2, 2, 103, 3, 2, 2, 2, 2, 105, 3, 2, 2, 2, 2, 107, 3, 2, 2, 2, 2, + 109, 3, 2, 2, 2, 2, 111, 3, 2, 2, 2, 2, 113, 3, 2, 2, 2, 2, 115, 3, 2, + 2, 2, 2, 117, 3, 2, 2, 2, 2, 119, 3, 2, 2, 2, 2, 121, 3, 2, 2, 2, 2, 123, + 3, 2, 2, 2, 2, 125, 3, 2, 2, 2, 2, 127, 3, 2, 2, 2, 2, 129, 3, 2, 2, 2, + 2, 131, 3, 2, 2, 2, 2, 133, 3, 2, 2, 2, 2, 135, 3, 2, 2, 2, 2, 137, 3, + 2, 2, 2, 2, 139, 3, 2, 2, 2, 2, 141, 3, 2, 2, 2, 2, 143, 3, 2, 2, 2, 2, + 145, 3, 2, 2, 2, 2, 147, 3, 2, 2, 2, 2, 149, 3, 2, 2, 2, 2, 151, 3, 2, + 2, 2, 2, 153, 3, 2, 2, 2, 2, 155, 3, 2, 2, 2, 2, 213, 3, 2, 2, 2, 3, 215, + 3, 2, 2, 2, 5, 217, 3, 2, 2, 2, 7, 220, 3, 2, 2, 2, 9, 223, 3, 2, 2, 2, + 11, 226, 3, 2, 2, 2, 13, 229, 3, 2, 2, 2, 15, 231, 3, 2, 2, 2, 17, 233, + 3, 2, 2, 2, 19, 236, 3, 2, 2, 2, 21, 239, 3, 2, 2, 2, 23, 241, 3, 2, 2, + 2, 25, 243, 3, 2, 2, 2, 27, 245, 3, 2, 2, 2, 29, 247, 3, 2, 2, 2, 31, 249, + 3, 2, 2, 2, 33, 251, 3, 2, 2, 2, 35, 253, 3, 2, 2, 2, 37, 256, 3, 2, 2, + 2, 39, 259, 3, 2, 2, 2, 41, 261, 3, 2, 2, 2, 43, 263, 3, 2, 2, 2, 45, 265, + 3, 2, 2, 2, 47, 267, 3, 2, 2, 2, 49, 269, 3, 2, 2, 2, 51, 271, 3, 2, 2, + 2, 53, 273, 3, 2, 2, 2, 55, 283, 3, 2, 2, 2, 57, 293, 3, 2, 2, 2, 59, 295, + 3, 2, 2, 2, 61, 299, 3, 2, 2, 2, 63, 303, 3, 2, 2, 2, 65, 311, 3, 2, 2, + 2, 67, 316, 3, 2, 2, 2, 69, 325, 3, 2, 2, 2, 71, 331, 3, 2, 2, 2, 73, 338, + 3, 2, 2, 2, 75, 342, 3, 2, 2, 2, 77, 348, 3, 2, 2, 2, 79, 351, 3, 2, 2, + 2, 81, 359, 3, 2, 2, 2, 83, 366, 3, 2, 2, 2, 85, 371, 3, 2, 2, 2, 87, 388, + 3, 2, 2, 2, 89, 392, 3, 2, 2, 2, 91, 397, 3, 2, 2, 2, 93, 403, 3, 2, 2, + 2, 95, 413, 3, 2, 2, 2, 97, 415, 3, 2, 2, 2, 99, 425, 3, 2, 2, 2, 101, + 427, 3, 2, 2, 2, 103, 436, 3, 2, 2, 2, 105, 443, 3, 2, 2, 2, 107, 451, + 3, 2, 2, 2, 109, 458, 3, 2, 2, 2, 111, 472, 3, 2, 2, 2, 113, 477, 3, 2, + 2, 2, 115, 482, 3, 2, 2, 2, 117, 489, 3, 2, 2, 2, 119, 496, 3, 2, 2, 2, + 121, 501, 3, 2, 2, 2, 123, 506, 3, 2, 2, 2, 125, 512, 3, 2, 2, 2, 127, + 520, 3, 2, 2, 2, 129, 526, 3, 2, 2, 2, 131, 533, 3, 2, 2, 2, 133, 536, + 3, 2, 2, 2, 135, 544, 3, 2, 2, 2, 137, 548, 3, 2, 2, 2, 139, 552, 3, 2, + 2, 2, 141, 583, 3, 2, 2, 2, 143, 593, 3, 2, 2, 2, 145, 612, 3, 2, 2, 2, + 147, 639, 3, 2, 2, 2, 149, 641, 3, 2, 2, 2, 151, 659, 3, 2, 2, 2, 153, + 673, 3, 2, 2, 2, 155, 677, 3, 2, 2, 2, 157, 679, 3, 2, 2, 2, 159, 681, + 3, 2, 2, 2, 161, 683, 3, 2, 2, 2, 163, 685, 3, 2, 2, 2, 165, 687, 3, 2, + 2, 2, 167, 689, 3, 2, 2, 2, 169, 691, 3, 2, 2, 2, 171, 693, 3, 2, 2, 2, + 173, 695, 3, 2, 2, 2, 175, 697, 3, 2, 2, 2, 177, 699, 3, 2, 2, 2, 179, + 701, 3, 2, 2, 2, 181, 703, 3, 2, 2, 2, 183, 705, 3, 2, 2, 2, 185, 707, + 3, 2, 2, 2, 187, 709, 3, 2, 2, 2, 189, 711, 3, 2, 2, 2, 191, 713, 3, 2, + 2, 2, 193, 715, 3, 2, 2, 2, 195, 717, 3, 2, 2, 2, 197, 719, 3, 2, 2, 2, + 199, 721, 3, 2, 2, 2, 201, 723, 3, 2, 2, 2, 203, 725, 3, 2, 2, 2, 205, + 727, 3, 2, 2, 2, 207, 729, 3, 2, 2, 2, 209, 731, 3, 2, 2, 2, 211, 733, + 3, 2, 2, 2, 213, 735, 3, 2, 2, 2, 215, 216, 7, 48, 2, 2, 216, 4, 3, 2, + 2, 2, 217, 218, 7, 63, 2, 2, 218, 219, 7, 128, 2, 2, 219, 6, 3, 2, 2, 2, + 220, 221, 7, 35, 2, 2, 221, 222, 7, 128, 2, 2, 222, 8, 3, 2, 2, 2, 223, + 224, 7, 63, 2, 2, 224, 225, 7, 63, 2, 2, 225, 10, 3, 2, 2, 2, 226, 227, + 7, 35, 2, 2, 227, 228, 7, 63, 2, 2, 228, 12, 3, 2, 2, 2, 229, 230, 7, 62, + 2, 2, 230, 14, 3, 2, 2, 2, 231, 232, 7, 64, 2, 2, 232, 16, 3, 2, 2, 2, + 233, 234, 7, 62, 2, 2, 234, 235, 7, 63, 2, 2, 235, 18, 3, 2, 2, 2, 236, + 237, 7, 64, 2, 2, 237, 238, 7, 63, 2, 2, 238, 20, 3, 2, 2, 2, 239, 240, + 7, 45, 2, 2, 240, 22, 3, 2, 2, 2, 241, 242, 7, 47, 2, 2, 242, 24, 3, 2, + 2, 2, 243, 244, 7, 44, 2, 2, 244, 26, 3, 2, 2, 2, 245, 246, 7, 49, 2, 2, + 246, 28, 3, 2, 2, 2, 247, 248, 7, 39, 2, 2, 248, 30, 3, 2, 2, 2, 249, 250, + 7, 65, 2, 2, 250, 32, 3, 2, 2, 2, 251, 252, 7, 60, 2, 2, 252, 34, 3, 2, + 2, 2, 253, 254, 7, 60, 2, 2, 254, 255, 7, 60, 2, 2, 255, 36, 3, 2, 2, 2, + 256, 257, 7, 48, 2, 2, 257, 258, 7, 48, 2, 2, 258, 38, 3, 2, 2, 2, 259, + 260, 7, 46, 2, 2, 260, 40, 3, 2, 2, 2, 261, 262, 7, 42, 2, 2, 262, 42, + 3, 2, 2, 2, 263, 264, 7, 43, 2, 2, 264, 44, 3, 2, 2, 2, 265, 266, 7, 125, + 2, 2, 266, 46, 3, 2, 2, 2, 267, 268, 7, 127, 2, 2, 268, 48, 3, 2, 2, 2, + 269, 270, 7, 93, 2, 2, 270, 50, 3, 2, 2, 2, 271, 272, 7, 95, 2, 2, 272, + 52, 3, 2, 2, 2, 273, 274, 5, 161, 81, 2, 274, 275, 5, 173, 87, 2, 275, + 276, 5, 173, 87, 2, 276, 277, 5, 195, 98, 2, 277, 278, 5, 169, 85, 2, 278, + 279, 5, 173, 87, 2, 279, 280, 5, 161, 81, 2, 280, 281, 5, 199, 100, 2, + 281, 282, 5, 169, 85, 2, 282, 54, 3, 2, 2, 2, 283, 284, 5, 161, 81, 2, + 284, 285, 5, 183, 92, 2, 285, 286, 5, 183, 92, 2, 286, 56, 3, 2, 2, 2, + 287, 288, 5, 161, 81, 2, 288, 289, 5, 187, 94, 2, 289, 290, 5, 167, 84, + 2, 290, 294, 3, 2, 2, 2, 291, 292, 7, 40, 2, 2, 292, 294, 7, 40, 2, 2, + 293, 287, 3, 2, 2, 2, 293, 291, 3, 2, 2, 2, 294, 58, 3, 2, 2, 2, 295, 296, + 5, 161, 81, 2, 296, 297, 5, 187, 94, 2, 297, 298, 5, 209, 105, 2, 298, + 60, 3, 2, 2, 2, 299, 300, 5, 161, 81, 2, 300, 301, 5, 197, 99, 2, 301, + 302, 5, 165, 83, 2, 302, 62, 3, 2, 2, 2, 303, 304, 5, 165, 83, 2, 304, + 305, 5, 189, 95, 2, 305, 306, 5, 183, 92, 2, 306, 307, 5, 183, 92, 2, 307, + 308, 5, 169, 85, 2, 308, 309, 5, 165, 83, 2, 309, 310, 5, 199, 100, 2, + 310, 64, 3, 2, 2, 2, 311, 312, 5, 167, 84, 2, 312, 313, 5, 169, 85, 2, + 313, 314, 5, 197, 99, 2, 314, 315, 5, 165, 83, 2, 315, 66, 3, 2, 2, 2, + 316, 317, 5, 167, 84, 2, 317, 318, 5, 177, 89, 2, 318, 319, 5, 197, 99, + 2, 319, 320, 5, 199, 100, 2, 320, 321, 5, 177, 89, 2, 321, 322, 5, 187, + 94, 2, 322, 323, 5, 165, 83, 2, 323, 324, 5, 199, 100, 2, 324, 68, 3, 2, + 2, 2, 325, 326, 5, 171, 86, 2, 326, 327, 5, 161, 81, 2, 327, 328, 5, 183, + 92, 2, 328, 329, 5, 197, 99, 2, 329, 330, 5, 169, 85, 2, 330, 70, 3, 2, + 2, 2, 331, 332, 5, 171, 86, 2, 332, 333, 5, 177, 89, 2, 333, 334, 5, 183, + 92, 2, 334, 335, 5, 199, 100, 2, 335, 336, 5, 169, 85, 2, 336, 337, 5, + 195, 98, 2, 337, 72, 3, 2, 2, 2, 338, 339, 5, 171, 86, 2, 339, 340, 5, + 189, 95, 2, 340, 341, 5, 195, 98, 2, 341, 74, 3, 2, 2, 2, 342, 343, 5, + 173, 87, 2, 343, 344, 5, 195, 98, 2, 344, 345, 5, 161, 81, 2, 345, 346, + 5, 191, 96, 2, 346, 347, 5, 175, 88, 2, 347, 76, 3, 2, 2, 2, 348, 349, + 5, 177, 89, 2, 349, 350, 5, 187, 94, 2, 350, 78, 3, 2, 2, 2, 351, 352, + 5, 177, 89, 2, 352, 353, 5, 187, 94, 2, 353, 354, 5, 163, 82, 2, 354, 355, + 5, 189, 95, 2, 355, 356, 5, 201, 101, 2, 356, 357, 5, 187, 94, 2, 357, + 358, 5, 167, 84, 2, 358, 80, 3, 2, 2, 2, 359, 360, 5, 177, 89, 2, 360, + 361, 5, 187, 94, 2, 361, 362, 5, 197, 99, 2, 362, 363, 5, 169, 85, 2, 363, + 364, 5, 195, 98, 2, 364, 365, 5, 199, 100, 2, 365, 82, 3, 2, 2, 2, 366, + 367, 5, 177, 89, 2, 367, 368, 5, 187, 94, 2, 368, 369, 5, 199, 100, 2, + 369, 370, 5, 189, 95, 2, 370, 84, 3, 2, 2, 2, 371, 372, 5, 181, 91, 2, + 372, 373, 7, 97, 2, 2, 373, 374, 5, 197, 99, 2, 374, 375, 5, 175, 88, 2, + 375, 376, 5, 189, 95, 2, 376, 377, 5, 195, 98, 2, 377, 378, 5, 199, 100, + 2, 378, 379, 5, 169, 85, 2, 379, 380, 5, 197, 99, 2, 380, 381, 5, 199, + 100, 2, 381, 382, 7, 97, 2, 2, 382, 383, 5, 191, 96, 2, 383, 384, 5, 161, + 81, 2, 384, 385, 5, 199, 100, 2, 385, 386, 5, 175, 88, 2, 386, 387, 5, + 197, 99, 2, 387, 86, 3, 2, 2, 2, 388, 389, 5, 183, 92, 2, 389, 390, 5, + 169, 85, 2, 390, 391, 5, 199, 100, 2, 391, 88, 3, 2, 2, 2, 392, 393, 5, + 183, 92, 2, 393, 394, 5, 177, 89, 2, 394, 395, 5, 181, 91, 2, 395, 396, + 5, 169, 85, 2, 396, 90, 3, 2, 2, 2, 397, 398, 5, 183, 92, 2, 398, 399, + 5, 177, 89, 2, 399, 400, 5, 185, 93, 2, 400, 401, 5, 177, 89, 2, 401, 402, + 5, 199, 100, 2, 402, 92, 3, 2, 2, 2, 403, 404, 5, 187, 94, 2, 404, 405, + 5, 189, 95, 2, 405, 406, 5, 187, 94, 2, 406, 407, 5, 169, 85, 2, 407, 94, + 3, 2, 2, 2, 408, 409, 5, 187, 94, 2, 409, 410, 5, 189, 95, 2, 410, 411, + 5, 199, 100, 2, 411, 414, 3, 2, 2, 2, 412, 414, 7, 35, 2, 2, 413, 408, + 3, 2, 2, 2, 413, 412, 3, 2, 2, 2, 414, 96, 3, 2, 2, 2, 415, 416, 5, 187, + 94, 2, 416, 417, 5, 201, 101, 2, 417, 418, 5, 183, 92, 2, 418, 419, 5, + 183, 92, 2, 419, 98, 3, 2, 2, 2, 420, 421, 5, 189, 95, 2, 421, 422, 5, + 195, 98, 2, 422, 426, 3, 2, 2, 2, 423, 424, 7, 126, 2, 2, 424, 426, 7, + 126, 2, 2, 425, 420, 3, 2, 2, 2, 425, 423, 3, 2, 2, 2, 426, 100, 3, 2, + 2, 2, 427, 428, 5, 189, 95, 2, 428, 429, 5, 201, 101, 2, 429, 430, 5, 199, + 100, 2, 430, 431, 5, 163, 82, 2, 431, 432, 5, 189, 95, 2, 432, 433, 5, + 201, 101, 2, 433, 434, 5, 187, 94, 2, 434, 435, 5, 167, 84, 2, 435, 102, + 3, 2, 2, 2, 436, 437, 5, 195, 98, 2, 437, 438, 5, 169, 85, 2, 438, 439, + 5, 185, 93, 2, 439, 440, 5, 189, 95, 2, 440, 441, 5, 203, 102, 2, 441, + 442, 5, 169, 85, 2, 442, 104, 3, 2, 2, 2, 443, 444, 5, 195, 98, 2, 444, + 445, 5, 169, 85, 2, 445, 446, 5, 191, 96, 2, 446, 447, 5, 183, 92, 2, 447, + 448, 5, 161, 81, 2, 448, 449, 5, 165, 83, 2, 449, 450, 5, 169, 85, 2, 450, + 106, 3, 2, 2, 2, 451, 452, 5, 195, 98, 2, 452, 453, 5, 169, 85, 2, 453, + 454, 5, 199, 100, 2, 454, 455, 5, 201, 101, 2, 455, 456, 5, 195, 98, 2, + 456, 457, 5, 187, 94, 2, 457, 108, 3, 2, 2, 2, 458, 459, 5, 197, 99, 2, + 459, 460, 5, 175, 88, 2, 460, 461, 5, 189, 95, 2, 461, 462, 5, 195, 98, + 2, 462, 463, 5, 199, 100, 2, 463, 464, 5, 169, 85, 2, 464, 465, 5, 197, + 99, 2, 465, 466, 5, 199, 100, 2, 466, 467, 7, 97, 2, 2, 467, 468, 5, 191, + 96, 2, 468, 469, 5, 161, 81, 2, 469, 470, 5, 199, 100, 2, 470, 471, 5, + 175, 88, 2, 471, 110, 3, 2, 2, 2, 472, 473, 5, 197, 99, 2, 473, 474, 5, + 189, 95, 2, 474, 475, 5, 195, 98, 2, 475, 476, 5, 199, 100, 2, 476, 112, + 3, 2, 2, 2, 477, 478, 5, 199, 100, 2, 478, 479, 5, 195, 98, 2, 479, 480, + 5, 201, 101, 2, 480, 481, 5, 169, 85, 2, 481, 114, 3, 2, 2, 2, 482, 483, + 5, 201, 101, 2, 483, 484, 5, 191, 96, 2, 484, 485, 5, 167, 84, 2, 485, + 486, 5, 161, 81, 2, 486, 487, 5, 199, 100, 2, 487, 488, 5, 169, 85, 2, + 488, 116, 3, 2, 2, 2, 489, 490, 5, 201, 101, 2, 490, 491, 5, 191, 96, 2, + 491, 492, 5, 197, 99, 2, 492, 493, 5, 169, 85, 2, 493, 494, 5, 195, 98, + 2, 494, 495, 5, 199, 100, 2, 495, 118, 3, 2, 2, 2, 496, 497, 5, 205, 103, + 2, 497, 498, 5, 177, 89, 2, 498, 499, 5, 199, 100, 2, 499, 500, 5, 175, + 88, 2, 500, 120, 3, 2, 2, 2, 501, 502, 5, 181, 91, 2, 502, 503, 5, 169, + 85, 2, 503, 504, 5, 169, 85, 2, 504, 505, 5, 191, 96, 2, 505, 122, 3, 2, + 2, 2, 506, 507, 5, 165, 83, 2, 507, 508, 5, 189, 95, 2, 508, 509, 5, 201, + 101, 2, 509, 510, 5, 187, 94, 2, 510, 511, 5, 199, 100, 2, 511, 124, 3, + 2, 2, 2, 512, 513, 5, 189, 95, 2, 513, 514, 5, 191, 96, 2, 514, 515, 5, + 199, 100, 2, 515, 516, 5, 177, 89, 2, 516, 517, 5, 189, 95, 2, 517, 518, + 5, 187, 94, 2, 518, 519, 5, 197, 99, 2, 519, 126, 3, 2, 2, 2, 520, 521, + 5, 191, 96, 2, 521, 522, 5, 195, 98, 2, 522, 523, 5, 201, 101, 2, 523, + 524, 5, 187, 94, 2, 524, 525, 5, 169, 85, 2, 525, 128, 3, 2, 2, 2, 526, + 527, 5, 197, 99, 2, 527, 528, 5, 169, 85, 2, 528, 529, 5, 161, 81, 2, 529, + 530, 5, 195, 98, 2, 530, 531, 5, 165, 83, 2, 531, 532, 5, 175, 88, 2, 532, + 130, 3, 2, 2, 2, 533, 534, 5, 199, 100, 2, 534, 535, 5, 189, 95, 2, 535, + 132, 3, 2, 2, 2, 536, 537, 5, 165, 83, 2, 537, 538, 5, 201, 101, 2, 538, + 539, 5, 195, 98, 2, 539, 540, 5, 195, 98, 2, 540, 541, 5, 169, 85, 2, 541, + 542, 5, 187, 94, 2, 542, 543, 5, 199, 100, 2, 543, 134, 3, 2, 2, 2, 544, + 545, 5, 187, 94, 2, 545, 546, 5, 169, 85, 2, 546, 547, 5, 205, 103, 2, + 547, 136, 3, 2, 2, 2, 548, 549, 5, 189, 95, 2, 549, 550, 5, 183, 92, 2, + 550, 551, 5, 167, 84, 2, 551, 138, 3, 2, 2, 2, 552, 556, 9, 2, 2, 2, 553, + 555, 9, 3, 2, 2, 554, 553, 3, 2, 2, 2, 555, 558, 3, 2, 2, 2, 556, 554, + 3, 2, 2, 2, 556, 557, 3, 2, 2, 2, 557, 140, 3, 2, 2, 2, 558, 556, 3, 2, + 2, 2, 559, 563, 9, 4, 2, 2, 560, 562, 5, 159, 80, 2, 561, 560, 3, 2, 2, + 2, 562, 565, 3, 2, 2, 2, 563, 561, 3, 2, 2, 2, 563, 564, 3, 2, 2, 2, 564, + 584, 3, 2, 2, 2, 565, 563, 3, 2, 2, 2, 566, 584, 7, 50, 2, 2, 567, 568, + 7, 50, 2, 2, 568, 569, 7, 122, 2, 2, 569, 571, 3, 2, 2, 2, 570, 572, 5, + 157, 79, 2, 571, 570, 3, 2, 2, 2, 572, 573, 3, 2, 2, 2, 573, 571, 3, 2, + 2, 2, 573, 574, 3, 2, 2, 2, 574, 584, 3, 2, 2, 2, 575, 576, 7, 50, 2, 2, + 576, 577, 7, 100, 2, 2, 577, 579, 3, 2, 2, 2, 578, 580, 9, 5, 2, 2, 579, + 578, 3, 2, 2, 2, 580, 581, 3, 2, 2, 2, 581, 579, 3, 2, 2, 2, 581, 582, + 3, 2, 2, 2, 582, 584, 3, 2, 2, 2, 583, 559, 3, 2, 2, 2, 583, 566, 3, 2, + 2, 2, 583, 567, 3, 2, 2, 2, 583, 575, 3, 2, 2, 2, 584, 142, 3, 2, 2, 2, + 585, 589, 9, 4, 2, 2, 586, 588, 5, 159, 80, 2, 587, 586, 3, 2, 2, 2, 588, + 591, 3, 2, 2, 2, 589, 587, 3, 2, 2, 2, 589, 590, 3, 2, 2, 2, 590, 594, + 3, 2, 2, 2, 591, 589, 3, 2, 2, 2, 592, 594, 7, 50, 2, 2, 593, 585, 3, 2, + 2, 2, 593, 592, 3, 2, 2, 2, 593, 594, 3, 2, 2, 2, 594, 595, 3, 2, 2, 2, + 595, 597, 7, 48, 2, 2, 596, 598, 5, 159, 80, 2, 597, 596, 3, 2, 2, 2, 598, + 599, 3, 2, 2, 2, 599, 597, 3, 2, 2, 2, 599, 600, 3, 2, 2, 2, 600, 610, + 3, 2, 2, 2, 601, 603, 5, 169, 85, 2, 602, 604, 9, 6, 2, 2, 603, 602, 3, + 2, 2, 2, 603, 604, 3, 2, 2, 2, 604, 606, 3, 2, 2, 2, 605, 607, 5, 159, + 80, 2, 606, 605, 3, 2, 2, 2, 607, 608, 3, 2, 2, 2, 608, 606, 3, 2, 2, 2, + 608, 609, 3, 2, 2, 2, 609, 611, 3, 2, 2, 2, 610, 601, 3, 2, 2, 2, 610, + 611, 3, 2, 2, 2, 611, 144, 3, 2, 2, 2, 612, 613, 7, 66, 2, 2, 613, 614, + 5, 139, 70, 2, 614, 146, 3, 2, 2, 2, 615, 623, 7, 41, 2, 2, 616, 617, 7, + 94, 2, 2, 617, 622, 11, 2, 2, 2, 618, 619, 7, 41, 2, 2, 619, 622, 7, 41, + 2, 2, 620, 622, 10, 7, 2, 2, 621, 616, 3, 2, 2, 2, 621, 618, 3, 2, 2, 2, + 621, 620, 3, 2, 2, 2, 622, 625, 3, 2, 2, 2, 623, 621, 3, 2, 2, 2, 623, + 624, 3, 2, 2, 2, 624, 626, 3, 2, 2, 2, 625, 623, 3, 2, 2, 2, 626, 640, + 7, 41, 2, 2, 627, 635, 7, 36, 2, 2, 628, 629, 7, 94, 2, 2, 629, 634, 11, + 2, 2, 2, 630, 631, 7, 36, 2, 2, 631, 634, 7, 36, 2, 2, 632, 634, 10, 8, + 2, 2, 633, 628, 3, 2, 2, 2, 633, 630, 3, 2, 2, 2, 633, 632, 3, 2, 2, 2, + 634, 637, 3, 2, 2, 2, 635, 633, 3, 2, 2, 2, 635, 636, 3, 2, 2, 2, 636, + 638, 3, 2, 2, 2, 637, 635, 3, 2, 2, 2, 638, 640, 7, 36, 2, 2, 639, 615, + 3, 2, 2, 2, 639, 627, 3, 2, 2, 2, 640, 148, 3, 2, 2, 2, 641, 642, 7, 49, + 2, 2, 642, 643, 7, 49, 2, 2, 643, 647, 3, 2, 2, 2, 644, 646, 10, 9, 2, + 2, 645, 644, 3, 2, 2, 2, 646, 649, 3, 2, 2, 2, 647, 645, 3, 2, 2, 2, 647, + 648, 3, 2, 2, 2, 648, 655, 3, 2, 2, 2, 649, 647, 3, 2, 2, 2, 650, 652, + 7, 15, 2, 2, 651, 650, 3, 2, 2, 2, 651, 652, 3, 2, 2, 2, 652, 653, 3, 2, + 2, 2, 653, 656, 7, 12, 2, 2, 654, 656, 7, 2, 2, 3, 655, 651, 3, 2, 2, 2, + 655, 654, 3, 2, 2, 2, 656, 657, 3, 2, 2, 2, 657, 658, 8, 75, 2, 2, 658, + 150, 3, 2, 2, 2, 659, 660, 7, 49, 2, 2, 660, 661, 7, 44, 2, 2, 661, 665, + 3, 2, 2, 2, 662, 664, 11, 2, 2, 2, 663, 662, 3, 2, 2, 2, 664, 667, 3, 2, + 2, 2, 665, 666, 3, 2, 2, 2, 665, 663, 3, 2, 2, 2, 666, 668, 3, 2, 2, 2, + 667, 665, 3, 2, 2, 2, 668, 669, 7, 44, 2, 2, 669, 670, 7, 49, 2, 2, 670, + 671, 3, 2, 2, 2, 671, 672, 8, 76, 2, 2, 672, 152, 3, 2, 2, 2, 673, 674, + 9, 10, 2, 2, 674, 675, 3, 2, 2, 2, 675, 676, 8, 77, 2, 2, 676, 154, 3, + 2, 2, 2, 677, 678, 11, 2, 2, 2, 678, 156, 3, 2, 2, 2, 679, 680, 9, 11, + 2, 2, 680, 158, 3, 2, 2, 2, 681, 682, 9, 12, 2, 2, 682, 160, 3, 2, 2, 2, + 683, 684, 9, 13, 2, 2, 684, 162, 3, 2, 2, 2, 685, 686, 9, 14, 2, 2, 686, + 164, 3, 2, 2, 2, 687, 688, 9, 15, 2, 2, 688, 166, 3, 2, 2, 2, 689, 690, + 9, 16, 2, 2, 690, 168, 3, 2, 2, 2, 691, 692, 9, 17, 2, 2, 692, 170, 3, + 2, 2, 2, 693, 694, 9, 18, 2, 2, 694, 172, 3, 2, 2, 2, 695, 696, 9, 19, + 2, 2, 696, 174, 3, 2, 2, 2, 697, 698, 9, 20, 2, 2, 698, 176, 3, 2, 2, 2, + 699, 700, 9, 21, 2, 2, 700, 178, 3, 2, 2, 2, 701, 702, 9, 22, 2, 2, 702, + 180, 3, 2, 2, 2, 703, 704, 9, 23, 2, 2, 704, 182, 3, 2, 2, 2, 705, 706, + 9, 24, 2, 2, 706, 184, 3, 2, 2, 2, 707, 708, 9, 25, 2, 2, 708, 186, 3, + 2, 2, 2, 709, 710, 9, 26, 2, 2, 710, 188, 3, 2, 2, 2, 711, 712, 9, 27, + 2, 2, 712, 190, 3, 2, 2, 2, 713, 714, 9, 28, 2, 2, 714, 192, 3, 2, 2, 2, + 715, 716, 9, 29, 2, 2, 716, 194, 3, 2, 2, 2, 717, 718, 9, 30, 2, 2, 718, + 196, 3, 2, 2, 2, 719, 720, 9, 31, 2, 2, 720, 198, 3, 2, 2, 2, 721, 722, + 9, 32, 2, 2, 722, 200, 3, 2, 2, 2, 723, 724, 9, 33, 2, 2, 724, 202, 3, + 2, 2, 2, 725, 726, 9, 34, 2, 2, 726, 204, 3, 2, 2, 2, 727, 728, 9, 35, + 2, 2, 728, 206, 3, 2, 2, 2, 729, 730, 9, 36, 2, 2, 730, 208, 3, 2, 2, 2, + 731, 732, 9, 37, 2, 2, 732, 210, 3, 2, 2, 2, 733, 734, 9, 38, 2, 2, 734, + 212, 3, 2, 2, 2, 735, 736, 11, 2, 2, 2, 736, 737, 3, 2, 2, 2, 737, 738, + 8, 107, 3, 2, 738, 214, 3, 2, 2, 2, 26, 2, 293, 413, 425, 556, 563, 573, + 581, 583, 589, 593, 599, 603, 608, 610, 621, 623, 633, 635, 639, 647, 651, + 655, 665, 4, 2, 3, 2, 2, 4, 2, +} + +var lexerChannelNames = []string{ + "DEFAULT_TOKEN_CHANNEL", "HIDDEN", "ERRORCHANNEL", +} + +var lexerModeNames = []string{ + "DEFAULT_MODE", +} + +var lexerLiteralNames = []string{ + "", "'.'", "'=~'", "'!~'", "'=='", "'!='", "'<'", "'>'", "'<='", "'>='", + "'+'", "'-'", "'*'", "'/'", "'%'", "'?'", "':'", "'::'", "'..'", "','", + "'('", "')'", "'{'", "'}'", "'['", "']'", +} + +var lexerSymbolicNames = []string{ + "", "DOT", "T_REGEX_MATCH", "T_REGEX_NON_MATCH", "T_EQ", "T_NE", "T_LT", + "T_GT", "T_LE", "T_GE", "T_PLUS", "T_MINUS", "T_TIMES", "T_DIV", "T_MOD", + "T_QUESTION", "T_COLON", "T_SCOPE", "T_RANGE", "T_COMMA", "T_OPEN", "T_CLOSE", + "T_OBJECT_OPEN", "T_OBJECT_CLOSE", "T_ARRAY_OPEN", "T_ARRAY_CLOSE", "T_AGGREGATE", + "T_ALL", "T_AND", "T_ANY", "T_ASC", "T_COLLECT", "T_DESC", "T_DISTINCT", + "T_FALSE", "T_FILTER", "T_FOR", "T_GRAPH", "T_IN", "T_INBOUND", "T_INSERT", + "T_INTO", "T_K_SHORTEST_PATHS", "T_LET", "T_LIKE", "T_LIMIT", "T_NONE", + "T_NOT", "T_NULL", "T_OR", "T_OUTBOUND", "T_REMOVE", "T_REPLACE", "T_RETURN", + "T_SHORTEST_PATH", "T_SORT", "T_TRUE", "T_UPDATE", "T_UPSERT", "T_WITH", + "T_KEEP", "T_COUNT", "T_OPTIONS", "T_PRUNE", "T_SEARCH", "T_TO", "T_CURRENT", + "T_NEW", "T_OLD", "T_STRING", "T_INT", "T_FLOAT", "T_PARAMETER", "T_QUOTED_STRING", + "SINGLE_LINE_COMMENT", "MULTILINE_COMMENT", "SPACES", "UNEXPECTED_CHAR", + "ERROR_RECONGNIGION", +} + +var lexerRuleNames = []string{ + "DOT", "T_REGEX_MATCH", "T_REGEX_NON_MATCH", "T_EQ", "T_NE", "T_LT", "T_GT", + "T_LE", "T_GE", "T_PLUS", "T_MINUS", "T_TIMES", "T_DIV", "T_MOD", "T_QUESTION", + "T_COLON", "T_SCOPE", "T_RANGE", "T_COMMA", "T_OPEN", "T_CLOSE", "T_OBJECT_OPEN", + "T_OBJECT_CLOSE", "T_ARRAY_OPEN", "T_ARRAY_CLOSE", "T_AGGREGATE", "T_ALL", + "T_AND", "T_ANY", "T_ASC", "T_COLLECT", "T_DESC", "T_DISTINCT", "T_FALSE", + "T_FILTER", "T_FOR", "T_GRAPH", "T_IN", "T_INBOUND", "T_INSERT", "T_INTO", + "T_K_SHORTEST_PATHS", "T_LET", "T_LIKE", "T_LIMIT", "T_NONE", "T_NOT", + "T_NULL", "T_OR", "T_OUTBOUND", "T_REMOVE", "T_REPLACE", "T_RETURN", "T_SHORTEST_PATH", + "T_SORT", "T_TRUE", "T_UPDATE", "T_UPSERT", "T_WITH", "T_KEEP", "T_COUNT", + "T_OPTIONS", "T_PRUNE", "T_SEARCH", "T_TO", "T_CURRENT", "T_NEW", "T_OLD", + "T_STRING", "T_INT", "T_FLOAT", "T_PARAMETER", "T_QUOTED_STRING", "SINGLE_LINE_COMMENT", + "MULTILINE_COMMENT", "SPACES", "UNEXPECTED_CHAR", "HEX_DIGIT", "DIGIT", + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", + "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "ERROR_RECONGNIGION", +} + +type CAQLLexer struct { + *antlr.BaseLexer + channelNames []string + modeNames []string + // TODO: EOF string +} + +// NewCAQLLexer produces a new lexer instance for the optional input antlr.CharStream. +// +// The *CAQLLexer instance produced may be reused by calling the SetInputStream method. +// The initial lexer configuration is expensive to construct, and the object is not thread-safe; +// however, if used within a Golang sync.Pool, the construction cost amortizes well and the +// objects can be used in a thread-safe manner. +func NewCAQLLexer(input antlr.CharStream) *CAQLLexer { + l := new(CAQLLexer) + lexerDeserializer := antlr.NewATNDeserializer(nil) + lexerAtn := lexerDeserializer.DeserializeFromUInt16(serializedLexerAtn) + lexerDecisionToDFA := make([]*antlr.DFA, len(lexerAtn.DecisionToState)) + for index, ds := range lexerAtn.DecisionToState { + lexerDecisionToDFA[index] = antlr.NewDFA(ds, index) + } + l.BaseLexer = antlr.NewBaseLexer(input) + l.Interpreter = antlr.NewLexerATNSimulator(l, lexerAtn, lexerDecisionToDFA, antlr.NewPredictionContextCache()) + + l.channelNames = lexerChannelNames + l.modeNames = lexerModeNames + l.RuleNames = lexerRuleNames + l.LiteralNames = lexerLiteralNames + l.SymbolicNames = lexerSymbolicNames + l.GrammarFileName = "CAQLLexer.g4" + // TODO: l.EOF = antlr.TokenEOF + + return l +} + +// CAQLLexer tokens. +const ( + CAQLLexerDOT = 1 + CAQLLexerT_REGEX_MATCH = 2 + CAQLLexerT_REGEX_NON_MATCH = 3 + CAQLLexerT_EQ = 4 + CAQLLexerT_NE = 5 + CAQLLexerT_LT = 6 + CAQLLexerT_GT = 7 + CAQLLexerT_LE = 8 + CAQLLexerT_GE = 9 + CAQLLexerT_PLUS = 10 + CAQLLexerT_MINUS = 11 + CAQLLexerT_TIMES = 12 + CAQLLexerT_DIV = 13 + CAQLLexerT_MOD = 14 + CAQLLexerT_QUESTION = 15 + CAQLLexerT_COLON = 16 + CAQLLexerT_SCOPE = 17 + CAQLLexerT_RANGE = 18 + CAQLLexerT_COMMA = 19 + CAQLLexerT_OPEN = 20 + CAQLLexerT_CLOSE = 21 + CAQLLexerT_OBJECT_OPEN = 22 + CAQLLexerT_OBJECT_CLOSE = 23 + CAQLLexerT_ARRAY_OPEN = 24 + CAQLLexerT_ARRAY_CLOSE = 25 + CAQLLexerT_AGGREGATE = 26 + CAQLLexerT_ALL = 27 + CAQLLexerT_AND = 28 + CAQLLexerT_ANY = 29 + CAQLLexerT_ASC = 30 + CAQLLexerT_COLLECT = 31 + CAQLLexerT_DESC = 32 + CAQLLexerT_DISTINCT = 33 + CAQLLexerT_FALSE = 34 + CAQLLexerT_FILTER = 35 + CAQLLexerT_FOR = 36 + CAQLLexerT_GRAPH = 37 + CAQLLexerT_IN = 38 + CAQLLexerT_INBOUND = 39 + CAQLLexerT_INSERT = 40 + CAQLLexerT_INTO = 41 + CAQLLexerT_K_SHORTEST_PATHS = 42 + CAQLLexerT_LET = 43 + CAQLLexerT_LIKE = 44 + CAQLLexerT_LIMIT = 45 + CAQLLexerT_NONE = 46 + CAQLLexerT_NOT = 47 + CAQLLexerT_NULL = 48 + CAQLLexerT_OR = 49 + CAQLLexerT_OUTBOUND = 50 + CAQLLexerT_REMOVE = 51 + CAQLLexerT_REPLACE = 52 + CAQLLexerT_RETURN = 53 + CAQLLexerT_SHORTEST_PATH = 54 + CAQLLexerT_SORT = 55 + CAQLLexerT_TRUE = 56 + CAQLLexerT_UPDATE = 57 + CAQLLexerT_UPSERT = 58 + CAQLLexerT_WITH = 59 + CAQLLexerT_KEEP = 60 + CAQLLexerT_COUNT = 61 + CAQLLexerT_OPTIONS = 62 + CAQLLexerT_PRUNE = 63 + CAQLLexerT_SEARCH = 64 + CAQLLexerT_TO = 65 + CAQLLexerT_CURRENT = 66 + CAQLLexerT_NEW = 67 + CAQLLexerT_OLD = 68 + CAQLLexerT_STRING = 69 + CAQLLexerT_INT = 70 + CAQLLexerT_FLOAT = 71 + CAQLLexerT_PARAMETER = 72 + CAQLLexerT_QUOTED_STRING = 73 + CAQLLexerSINGLE_LINE_COMMENT = 74 + CAQLLexerMULTILINE_COMMENT = 75 + CAQLLexerSPACES = 76 + CAQLLexerUNEXPECTED_CHAR = 77 + CAQLLexerERROR_RECONGNIGION = 78 +) + +// CAQLLexerERRORCHANNEL is the CAQLLexer channel. +const CAQLLexerERRORCHANNEL = 2 diff --git a/generated/caql/parser/caql_parser.go b/generated/caql/parser/caql_parser.go new file mode 100644 index 0000000..31f337c --- /dev/null +++ b/generated/caql/parser/caql_parser.go @@ -0,0 +1,2526 @@ +// Code generated from CAQLParser.g4 by ANTLR 4.9.2. DO NOT EDIT. + +package parser // CAQLParser + +import ( + "fmt" + "reflect" + "strconv" + + "github.com/antlr/antlr4/runtime/Go/antlr" +) + +// Suppress unused import errors +var _ = fmt.Printf +var _ = reflect.Copy +var _ = strconv.Itoa + +var parserATN = []uint16{ + 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 80, 192, + 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, + 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 3, 2, + 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 32, 10, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, + 48, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 66, 10, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 7, 3, 86, 10, 3, 12, 3, 14, 3, 89, 11, 3, 3, 4, 3, 4, + 3, 4, 3, 4, 3, 4, 3, 4, 5, 4, 97, 10, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, + 3, 5, 3, 5, 3, 5, 5, 5, 107, 10, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, + 3, 5, 3, 5, 7, 5, 117, 10, 5, 12, 5, 14, 5, 120, 11, 5, 3, 6, 3, 6, 5, + 6, 124, 10, 6, 3, 7, 3, 7, 3, 7, 5, 7, 129, 10, 7, 3, 7, 3, 7, 7, 7, 133, + 10, 7, 12, 7, 14, 7, 136, 11, 7, 3, 7, 5, 7, 139, 10, 7, 3, 7, 3, 7, 3, + 8, 3, 8, 3, 9, 3, 9, 5, 9, 147, 10, 9, 3, 9, 3, 9, 7, 9, 151, 10, 9, 12, + 9, 14, 9, 154, 11, 9, 3, 9, 5, 9, 157, 10, 9, 3, 9, 3, 9, 3, 10, 3, 10, + 5, 10, 163, 10, 10, 3, 10, 3, 10, 7, 10, 167, 10, 10, 12, 10, 14, 10, 170, + 11, 10, 3, 10, 5, 10, 173, 10, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, + 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 5, 11, 188, 10, 11, + 3, 12, 3, 12, 3, 12, 4, 134, 152, 4, 4, 8, 13, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 2, 11, 3, 2, 12, 13, 3, 2, 14, 16, 3, 2, 8, 11, 3, 2, 6, + 7, 5, 2, 29, 29, 31, 31, 48, 48, 4, 2, 6, 11, 40, 40, 4, 2, 4, 5, 46, 46, + 7, 2, 36, 36, 50, 50, 58, 58, 72, 73, 75, 75, 4, 2, 71, 71, 75, 75, 2, + 216, 2, 24, 3, 2, 2, 2, 4, 31, 3, 2, 2, 2, 6, 96, 3, 2, 2, 2, 8, 106, 3, + 2, 2, 2, 10, 123, 3, 2, 2, 2, 12, 125, 3, 2, 2, 2, 14, 142, 3, 2, 2, 2, + 16, 144, 3, 2, 2, 2, 18, 160, 3, 2, 2, 2, 20, 187, 3, 2, 2, 2, 22, 189, + 3, 2, 2, 2, 24, 25, 5, 4, 3, 2, 25, 26, 7, 2, 2, 3, 26, 3, 3, 2, 2, 2, + 27, 28, 8, 3, 1, 2, 28, 32, 5, 14, 8, 2, 29, 32, 5, 8, 5, 2, 30, 32, 5, + 6, 4, 2, 31, 27, 3, 2, 2, 2, 31, 29, 3, 2, 2, 2, 31, 30, 3, 2, 2, 2, 32, + 87, 3, 2, 2, 2, 33, 34, 12, 15, 2, 2, 34, 35, 9, 2, 2, 2, 35, 86, 5, 4, + 3, 16, 36, 37, 12, 14, 2, 2, 37, 38, 9, 3, 2, 2, 38, 86, 5, 4, 3, 15, 39, + 40, 12, 13, 2, 2, 40, 41, 7, 20, 2, 2, 41, 86, 5, 4, 3, 14, 42, 43, 12, + 12, 2, 2, 43, 44, 9, 4, 2, 2, 44, 86, 5, 4, 3, 13, 45, 47, 12, 11, 2, 2, + 46, 48, 7, 49, 2, 2, 47, 46, 3, 2, 2, 2, 47, 48, 3, 2, 2, 2, 48, 49, 3, + 2, 2, 2, 49, 50, 7, 40, 2, 2, 50, 86, 5, 4, 3, 12, 51, 52, 12, 10, 2, 2, + 52, 53, 9, 5, 2, 2, 53, 86, 5, 4, 3, 11, 54, 55, 12, 9, 2, 2, 55, 56, 9, + 6, 2, 2, 56, 57, 9, 7, 2, 2, 57, 86, 5, 4, 3, 10, 58, 59, 12, 8, 2, 2, + 59, 60, 9, 6, 2, 2, 60, 61, 7, 49, 2, 2, 61, 62, 7, 40, 2, 2, 62, 86, 5, + 4, 3, 9, 63, 65, 12, 7, 2, 2, 64, 66, 7, 49, 2, 2, 65, 64, 3, 2, 2, 2, + 65, 66, 3, 2, 2, 2, 66, 67, 3, 2, 2, 2, 67, 68, 9, 8, 2, 2, 68, 86, 5, + 4, 3, 8, 69, 70, 12, 6, 2, 2, 70, 71, 7, 30, 2, 2, 71, 86, 5, 4, 3, 7, + 72, 73, 12, 5, 2, 2, 73, 74, 7, 51, 2, 2, 74, 86, 5, 4, 3, 6, 75, 76, 12, + 4, 2, 2, 76, 77, 7, 17, 2, 2, 77, 78, 5, 4, 3, 2, 78, 79, 7, 18, 2, 2, + 79, 80, 5, 4, 3, 5, 80, 86, 3, 2, 2, 2, 81, 82, 12, 3, 2, 2, 82, 83, 7, + 17, 2, 2, 83, 84, 7, 18, 2, 2, 84, 86, 5, 4, 3, 4, 85, 33, 3, 2, 2, 2, + 85, 36, 3, 2, 2, 2, 85, 39, 3, 2, 2, 2, 85, 42, 3, 2, 2, 2, 85, 45, 3, + 2, 2, 2, 85, 51, 3, 2, 2, 2, 85, 54, 3, 2, 2, 2, 85, 58, 3, 2, 2, 2, 85, + 63, 3, 2, 2, 2, 85, 69, 3, 2, 2, 2, 85, 72, 3, 2, 2, 2, 85, 75, 3, 2, 2, + 2, 85, 81, 3, 2, 2, 2, 86, 89, 3, 2, 2, 2, 87, 85, 3, 2, 2, 2, 87, 88, + 3, 2, 2, 2, 88, 5, 3, 2, 2, 2, 89, 87, 3, 2, 2, 2, 90, 91, 7, 12, 2, 2, + 91, 97, 5, 4, 3, 2, 92, 93, 7, 13, 2, 2, 93, 97, 5, 4, 3, 2, 94, 95, 7, + 49, 2, 2, 95, 97, 5, 4, 3, 2, 96, 90, 3, 2, 2, 2, 96, 92, 3, 2, 2, 2, 96, + 94, 3, 2, 2, 2, 97, 7, 3, 2, 2, 2, 98, 99, 8, 5, 1, 2, 99, 107, 7, 71, + 2, 2, 100, 107, 5, 10, 6, 2, 101, 107, 5, 12, 7, 2, 102, 103, 7, 22, 2, + 2, 103, 104, 5, 4, 3, 2, 104, 105, 7, 23, 2, 2, 105, 107, 3, 2, 2, 2, 106, + 98, 3, 2, 2, 2, 106, 100, 3, 2, 2, 2, 106, 101, 3, 2, 2, 2, 106, 102, 3, + 2, 2, 2, 107, 118, 3, 2, 2, 2, 108, 109, 12, 4, 2, 2, 109, 110, 7, 3, 2, + 2, 110, 117, 7, 71, 2, 2, 111, 112, 12, 3, 2, 2, 112, 113, 7, 26, 2, 2, + 113, 114, 5, 4, 3, 2, 114, 115, 7, 27, 2, 2, 115, 117, 3, 2, 2, 2, 116, + 108, 3, 2, 2, 2, 116, 111, 3, 2, 2, 2, 117, 120, 3, 2, 2, 2, 118, 116, + 3, 2, 2, 2, 118, 119, 3, 2, 2, 2, 119, 9, 3, 2, 2, 2, 120, 118, 3, 2, 2, + 2, 121, 124, 5, 16, 9, 2, 122, 124, 5, 18, 10, 2, 123, 121, 3, 2, 2, 2, + 123, 122, 3, 2, 2, 2, 124, 11, 3, 2, 2, 2, 125, 126, 7, 71, 2, 2, 126, + 128, 7, 22, 2, 2, 127, 129, 5, 4, 3, 2, 128, 127, 3, 2, 2, 2, 128, 129, + 3, 2, 2, 2, 129, 134, 3, 2, 2, 2, 130, 131, 7, 21, 2, 2, 131, 133, 5, 4, + 3, 2, 132, 130, 3, 2, 2, 2, 133, 136, 3, 2, 2, 2, 134, 135, 3, 2, 2, 2, + 134, 132, 3, 2, 2, 2, 135, 138, 3, 2, 2, 2, 136, 134, 3, 2, 2, 2, 137, + 139, 7, 21, 2, 2, 138, 137, 3, 2, 2, 2, 138, 139, 3, 2, 2, 2, 139, 140, + 3, 2, 2, 2, 140, 141, 7, 23, 2, 2, 141, 13, 3, 2, 2, 2, 142, 143, 9, 9, + 2, 2, 143, 15, 3, 2, 2, 2, 144, 146, 7, 26, 2, 2, 145, 147, 5, 4, 3, 2, + 146, 145, 3, 2, 2, 2, 146, 147, 3, 2, 2, 2, 147, 152, 3, 2, 2, 2, 148, + 149, 7, 21, 2, 2, 149, 151, 5, 4, 3, 2, 150, 148, 3, 2, 2, 2, 151, 154, + 3, 2, 2, 2, 152, 153, 3, 2, 2, 2, 152, 150, 3, 2, 2, 2, 153, 156, 3, 2, + 2, 2, 154, 152, 3, 2, 2, 2, 155, 157, 7, 21, 2, 2, 156, 155, 3, 2, 2, 2, + 156, 157, 3, 2, 2, 2, 157, 158, 3, 2, 2, 2, 158, 159, 7, 27, 2, 2, 159, + 17, 3, 2, 2, 2, 160, 162, 7, 24, 2, 2, 161, 163, 5, 20, 11, 2, 162, 161, + 3, 2, 2, 2, 162, 163, 3, 2, 2, 2, 163, 168, 3, 2, 2, 2, 164, 165, 7, 21, + 2, 2, 165, 167, 5, 20, 11, 2, 166, 164, 3, 2, 2, 2, 167, 170, 3, 2, 2, + 2, 168, 166, 3, 2, 2, 2, 168, 169, 3, 2, 2, 2, 169, 172, 3, 2, 2, 2, 170, + 168, 3, 2, 2, 2, 171, 173, 7, 21, 2, 2, 172, 171, 3, 2, 2, 2, 172, 173, + 3, 2, 2, 2, 173, 174, 3, 2, 2, 2, 174, 175, 7, 25, 2, 2, 175, 19, 3, 2, + 2, 2, 176, 188, 7, 71, 2, 2, 177, 178, 5, 22, 12, 2, 178, 179, 7, 18, 2, + 2, 179, 180, 5, 4, 3, 2, 180, 188, 3, 2, 2, 2, 181, 182, 7, 26, 2, 2, 182, + 183, 5, 4, 3, 2, 183, 184, 7, 27, 2, 2, 184, 185, 7, 18, 2, 2, 185, 186, + 5, 4, 3, 2, 186, 188, 3, 2, 2, 2, 187, 176, 3, 2, 2, 2, 187, 177, 3, 2, + 2, 2, 187, 181, 3, 2, 2, 2, 188, 21, 3, 2, 2, 2, 189, 190, 9, 10, 2, 2, + 190, 23, 3, 2, 2, 2, 22, 31, 47, 65, 85, 87, 96, 106, 116, 118, 123, 128, + 134, 138, 146, 152, 156, 162, 168, 172, 187, +} +var literalNames = []string{ + "", "'.'", "'=~'", "'!~'", "'=='", "'!='", "'<'", "'>'", "'<='", "'>='", + "'+'", "'-'", "'*'", "'/'", "'%'", "'?'", "':'", "'::'", "'..'", "','", + "'('", "')'", "'{'", "'}'", "'['", "']'", +} +var symbolicNames = []string{ + "", "DOT", "T_REGEX_MATCH", "T_REGEX_NON_MATCH", "T_EQ", "T_NE", "T_LT", + "T_GT", "T_LE", "T_GE", "T_PLUS", "T_MINUS", "T_TIMES", "T_DIV", "T_MOD", + "T_QUESTION", "T_COLON", "T_SCOPE", "T_RANGE", "T_COMMA", "T_OPEN", "T_CLOSE", + "T_OBJECT_OPEN", "T_OBJECT_CLOSE", "T_ARRAY_OPEN", "T_ARRAY_CLOSE", "T_AGGREGATE", + "T_ALL", "T_AND", "T_ANY", "T_ASC", "T_COLLECT", "T_DESC", "T_DISTINCT", + "T_FALSE", "T_FILTER", "T_FOR", "T_GRAPH", "T_IN", "T_INBOUND", "T_INSERT", + "T_INTO", "T_K_SHORTEST_PATHS", "T_LET", "T_LIKE", "T_LIMIT", "T_NONE", + "T_NOT", "T_NULL", "T_OR", "T_OUTBOUND", "T_REMOVE", "T_REPLACE", "T_RETURN", + "T_SHORTEST_PATH", "T_SORT", "T_TRUE", "T_UPDATE", "T_UPSERT", "T_WITH", + "T_KEEP", "T_COUNT", "T_OPTIONS", "T_PRUNE", "T_SEARCH", "T_TO", "T_CURRENT", + "T_NEW", "T_OLD", "T_STRING", "T_INT", "T_FLOAT", "T_PARAMETER", "T_QUOTED_STRING", + "SINGLE_LINE_COMMENT", "MULTILINE_COMMENT", "SPACES", "UNEXPECTED_CHAR", + "ERROR_RECONGNIGION", +} + +var ruleNames = []string{ + "parse", "expression", "operator_unary", "reference", "compound_value", + "function_call", "value_literal", "array", "object", "object_element", + "object_element_name", +} + +type CAQLParser struct { + *antlr.BaseParser +} + +// NewCAQLParser produces a new parser instance for the optional input antlr.TokenStream. +// +// The *CAQLParser instance produced may be reused by calling the SetInputStream method. +// The initial parser configuration is expensive to construct, and the object is not thread-safe; +// however, if used within a Golang sync.Pool, the construction cost amortizes well and the +// objects can be used in a thread-safe manner. +func NewCAQLParser(input antlr.TokenStream) *CAQLParser { + this := new(CAQLParser) + deserializer := antlr.NewATNDeserializer(nil) + deserializedATN := deserializer.DeserializeFromUInt16(parserATN) + decisionToDFA := make([]*antlr.DFA, len(deserializedATN.DecisionToState)) + for index, ds := range deserializedATN.DecisionToState { + decisionToDFA[index] = antlr.NewDFA(ds, index) + } + this.BaseParser = antlr.NewBaseParser(input) + + this.Interpreter = antlr.NewParserATNSimulator(this, deserializedATN, decisionToDFA, antlr.NewPredictionContextCache()) + this.RuleNames = ruleNames + this.LiteralNames = literalNames + this.SymbolicNames = symbolicNames + this.GrammarFileName = "CAQLParser.g4" + + return this +} + +// CAQLParser tokens. +const ( + CAQLParserEOF = antlr.TokenEOF + CAQLParserDOT = 1 + CAQLParserT_REGEX_MATCH = 2 + CAQLParserT_REGEX_NON_MATCH = 3 + CAQLParserT_EQ = 4 + CAQLParserT_NE = 5 + CAQLParserT_LT = 6 + CAQLParserT_GT = 7 + CAQLParserT_LE = 8 + CAQLParserT_GE = 9 + CAQLParserT_PLUS = 10 + CAQLParserT_MINUS = 11 + CAQLParserT_TIMES = 12 + CAQLParserT_DIV = 13 + CAQLParserT_MOD = 14 + CAQLParserT_QUESTION = 15 + CAQLParserT_COLON = 16 + CAQLParserT_SCOPE = 17 + CAQLParserT_RANGE = 18 + CAQLParserT_COMMA = 19 + CAQLParserT_OPEN = 20 + CAQLParserT_CLOSE = 21 + CAQLParserT_OBJECT_OPEN = 22 + CAQLParserT_OBJECT_CLOSE = 23 + CAQLParserT_ARRAY_OPEN = 24 + CAQLParserT_ARRAY_CLOSE = 25 + CAQLParserT_AGGREGATE = 26 + CAQLParserT_ALL = 27 + CAQLParserT_AND = 28 + CAQLParserT_ANY = 29 + CAQLParserT_ASC = 30 + CAQLParserT_COLLECT = 31 + CAQLParserT_DESC = 32 + CAQLParserT_DISTINCT = 33 + CAQLParserT_FALSE = 34 + CAQLParserT_FILTER = 35 + CAQLParserT_FOR = 36 + CAQLParserT_GRAPH = 37 + CAQLParserT_IN = 38 + CAQLParserT_INBOUND = 39 + CAQLParserT_INSERT = 40 + CAQLParserT_INTO = 41 + CAQLParserT_K_SHORTEST_PATHS = 42 + CAQLParserT_LET = 43 + CAQLParserT_LIKE = 44 + CAQLParserT_LIMIT = 45 + CAQLParserT_NONE = 46 + CAQLParserT_NOT = 47 + CAQLParserT_NULL = 48 + CAQLParserT_OR = 49 + CAQLParserT_OUTBOUND = 50 + CAQLParserT_REMOVE = 51 + CAQLParserT_REPLACE = 52 + CAQLParserT_RETURN = 53 + CAQLParserT_SHORTEST_PATH = 54 + CAQLParserT_SORT = 55 + CAQLParserT_TRUE = 56 + CAQLParserT_UPDATE = 57 + CAQLParserT_UPSERT = 58 + CAQLParserT_WITH = 59 + CAQLParserT_KEEP = 60 + CAQLParserT_COUNT = 61 + CAQLParserT_OPTIONS = 62 + CAQLParserT_PRUNE = 63 + CAQLParserT_SEARCH = 64 + CAQLParserT_TO = 65 + CAQLParserT_CURRENT = 66 + CAQLParserT_NEW = 67 + CAQLParserT_OLD = 68 + CAQLParserT_STRING = 69 + CAQLParserT_INT = 70 + CAQLParserT_FLOAT = 71 + CAQLParserT_PARAMETER = 72 + CAQLParserT_QUOTED_STRING = 73 + CAQLParserSINGLE_LINE_COMMENT = 74 + CAQLParserMULTILINE_COMMENT = 75 + CAQLParserSPACES = 76 + CAQLParserUNEXPECTED_CHAR = 77 + CAQLParserERROR_RECONGNIGION = 78 +) + +// CAQLParser rules. +const ( + CAQLParserRULE_parse = 0 + CAQLParserRULE_expression = 1 + CAQLParserRULE_operator_unary = 2 + CAQLParserRULE_reference = 3 + CAQLParserRULE_compound_value = 4 + CAQLParserRULE_function_call = 5 + CAQLParserRULE_value_literal = 6 + CAQLParserRULE_array = 7 + CAQLParserRULE_object = 8 + CAQLParserRULE_object_element = 9 + CAQLParserRULE_object_element_name = 10 +) + +// IParseContext is an interface to support dynamic dispatch. +type IParseContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // IsParseContext differentiates from other interfaces. + IsParseContext() +} + +type ParseContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyParseContext() *ParseContext { + var p = new(ParseContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CAQLParserRULE_parse + return p +} + +func (*ParseContext) IsParseContext() {} + +func NewParseContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ParseContext { + var p = new(ParseContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CAQLParserRULE_parse + + return p +} + +func (s *ParseContext) GetParser() antlr.Parser { return s.parser } + +func (s *ParseContext) Expression() IExpressionContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IExpressionContext)(nil)).Elem(), 0) + + if t == nil { + return nil + } + + return t.(IExpressionContext) +} + +func (s *ParseContext) EOF() antlr.TerminalNode { + return s.GetToken(CAQLParserEOF, 0) +} + +func (s *ParseContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *ParseContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *ParseContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CAQLParserListener); ok { + listenerT.EnterParse(s) + } +} + +func (s *ParseContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CAQLParserListener); ok { + listenerT.ExitParse(s) + } +} + +func (p *CAQLParser) Parse() (localctx IParseContext) { + localctx = NewParseContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 0, CAQLParserRULE_parse) + + defer func() { + p.ExitRule() + }() + + defer func() { + if err := recover(); err != nil { + if v, ok := err.(antlr.RecognitionException); ok { + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + } else { + panic(err) + } + } + }() + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(22) + p.expression(0) + } + { + p.SetState(23) + p.Match(CAQLParserEOF) + } + + return localctx +} + +// IExpressionContext is an interface to support dynamic dispatch. +type IExpressionContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // GetEq_op returns the eq_op token. + GetEq_op() antlr.Token + + // SetEq_op sets the eq_op token. + SetEq_op(antlr.Token) + + // IsExpressionContext differentiates from other interfaces. + IsExpressionContext() +} + +type ExpressionContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser + eq_op antlr.Token +} + +func NewEmptyExpressionContext() *ExpressionContext { + var p = new(ExpressionContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CAQLParserRULE_expression + return p +} + +func (*ExpressionContext) IsExpressionContext() {} + +func NewExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ExpressionContext { + var p = new(ExpressionContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CAQLParserRULE_expression + + return p +} + +func (s *ExpressionContext) GetParser() antlr.Parser { return s.parser } + +func (s *ExpressionContext) GetEq_op() antlr.Token { return s.eq_op } + +func (s *ExpressionContext) SetEq_op(v antlr.Token) { s.eq_op = v } + +func (s *ExpressionContext) Value_literal() IValue_literalContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IValue_literalContext)(nil)).Elem(), 0) + + if t == nil { + return nil + } + + return t.(IValue_literalContext) +} + +func (s *ExpressionContext) Reference() IReferenceContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IReferenceContext)(nil)).Elem(), 0) + + if t == nil { + return nil + } + + return t.(IReferenceContext) +} + +func (s *ExpressionContext) Operator_unary() IOperator_unaryContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IOperator_unaryContext)(nil)).Elem(), 0) + + if t == nil { + return nil + } + + return t.(IOperator_unaryContext) +} + +func (s *ExpressionContext) AllExpression() []IExpressionContext { + var ts = s.GetTypedRuleContexts(reflect.TypeOf((*IExpressionContext)(nil)).Elem()) + var tst = make([]IExpressionContext, len(ts)) + + for i, t := range ts { + if t != nil { + tst[i] = t.(IExpressionContext) + } + } + + return tst +} + +func (s *ExpressionContext) Expression(i int) IExpressionContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IExpressionContext)(nil)).Elem(), i) + + if t == nil { + return nil + } + + return t.(IExpressionContext) +} + +func (s *ExpressionContext) T_PLUS() antlr.TerminalNode { + return s.GetToken(CAQLParserT_PLUS, 0) +} + +func (s *ExpressionContext) T_MINUS() antlr.TerminalNode { + return s.GetToken(CAQLParserT_MINUS, 0) +} + +func (s *ExpressionContext) T_TIMES() antlr.TerminalNode { + return s.GetToken(CAQLParserT_TIMES, 0) +} + +func (s *ExpressionContext) T_DIV() antlr.TerminalNode { + return s.GetToken(CAQLParserT_DIV, 0) +} + +func (s *ExpressionContext) T_MOD() antlr.TerminalNode { + return s.GetToken(CAQLParserT_MOD, 0) +} + +func (s *ExpressionContext) T_RANGE() antlr.TerminalNode { + return s.GetToken(CAQLParserT_RANGE, 0) +} + +func (s *ExpressionContext) T_LT() antlr.TerminalNode { + return s.GetToken(CAQLParserT_LT, 0) +} + +func (s *ExpressionContext) T_GT() antlr.TerminalNode { + return s.GetToken(CAQLParserT_GT, 0) +} + +func (s *ExpressionContext) T_LE() antlr.TerminalNode { + return s.GetToken(CAQLParserT_LE, 0) +} + +func (s *ExpressionContext) T_GE() antlr.TerminalNode { + return s.GetToken(CAQLParserT_GE, 0) +} + +func (s *ExpressionContext) T_IN() antlr.TerminalNode { + return s.GetToken(CAQLParserT_IN, 0) +} + +func (s *ExpressionContext) T_NOT() antlr.TerminalNode { + return s.GetToken(CAQLParserT_NOT, 0) +} + +func (s *ExpressionContext) T_EQ() antlr.TerminalNode { + return s.GetToken(CAQLParserT_EQ, 0) +} + +func (s *ExpressionContext) T_NE() antlr.TerminalNode { + return s.GetToken(CAQLParserT_NE, 0) +} + +func (s *ExpressionContext) T_ALL() antlr.TerminalNode { + return s.GetToken(CAQLParserT_ALL, 0) +} + +func (s *ExpressionContext) T_ANY() antlr.TerminalNode { + return s.GetToken(CAQLParserT_ANY, 0) +} + +func (s *ExpressionContext) T_NONE() antlr.TerminalNode { + return s.GetToken(CAQLParserT_NONE, 0) +} + +func (s *ExpressionContext) T_LIKE() antlr.TerminalNode { + return s.GetToken(CAQLParserT_LIKE, 0) +} + +func (s *ExpressionContext) T_REGEX_MATCH() antlr.TerminalNode { + return s.GetToken(CAQLParserT_REGEX_MATCH, 0) +} + +func (s *ExpressionContext) T_REGEX_NON_MATCH() antlr.TerminalNode { + return s.GetToken(CAQLParserT_REGEX_NON_MATCH, 0) +} + +func (s *ExpressionContext) T_AND() antlr.TerminalNode { + return s.GetToken(CAQLParserT_AND, 0) +} + +func (s *ExpressionContext) T_OR() antlr.TerminalNode { + return s.GetToken(CAQLParserT_OR, 0) +} + +func (s *ExpressionContext) T_QUESTION() antlr.TerminalNode { + return s.GetToken(CAQLParserT_QUESTION, 0) +} + +func (s *ExpressionContext) T_COLON() antlr.TerminalNode { + return s.GetToken(CAQLParserT_COLON, 0) +} + +func (s *ExpressionContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *ExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *ExpressionContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CAQLParserListener); ok { + listenerT.EnterExpression(s) + } +} + +func (s *ExpressionContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CAQLParserListener); ok { + listenerT.ExitExpression(s) + } +} + +func (p *CAQLParser) Expression() (localctx IExpressionContext) { + return p.expression(0) +} + +func (p *CAQLParser) expression(_p int) (localctx IExpressionContext) { + var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext() + _parentState := p.GetState() + localctx = NewExpressionContext(p, p.GetParserRuleContext(), _parentState) + var _prevctx IExpressionContext = localctx + var _ antlr.ParserRuleContext = _prevctx // TODO: To prevent unused variable warning. + _startState := 2 + p.EnterRecursionRule(localctx, 2, CAQLParserRULE_expression, _p) + var _la int + + defer func() { + p.UnrollRecursionContexts(_parentctx) + }() + + defer func() { + if err := recover(); err != nil { + if v, ok := err.(antlr.RecognitionException); ok { + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + } else { + panic(err) + } + } + }() + + var _alt int + + p.EnterOuterAlt(localctx, 1) + p.SetState(29) + p.GetErrorHandler().Sync(p) + + switch p.GetTokenStream().LA(1) { + case CAQLParserT_FALSE, CAQLParserT_NULL, CAQLParserT_TRUE, CAQLParserT_INT, CAQLParserT_FLOAT, CAQLParserT_QUOTED_STRING: + { + p.SetState(26) + p.Value_literal() + } + + case CAQLParserT_OPEN, CAQLParserT_OBJECT_OPEN, CAQLParserT_ARRAY_OPEN, CAQLParserT_STRING: + { + p.SetState(27) + p.reference(0) + } + + case CAQLParserT_PLUS, CAQLParserT_MINUS, CAQLParserT_NOT: + { + p.SetState(28) + p.Operator_unary() + } + + default: + panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + } + p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) + p.SetState(85) + p.GetErrorHandler().Sync(p) + _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 4, p.GetParserRuleContext()) + + for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { + if _alt == 1 { + if p.GetParseListeners() != nil { + p.TriggerExitRuleEvent() + } + _prevctx = localctx + p.SetState(83) + p.GetErrorHandler().Sync(p) + switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 3, p.GetParserRuleContext()) { + case 1: + localctx = NewExpressionContext(p, _parentctx, _parentState) + p.PushNewRecursionContext(localctx, _startState, CAQLParserRULE_expression) + p.SetState(31) + + if !(p.Precpred(p.GetParserRuleContext(), 13)) { + panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 13)", "")) + } + { + p.SetState(32) + _la = p.GetTokenStream().LA(1) + + if !(_la == CAQLParserT_PLUS || _la == CAQLParserT_MINUS) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + { + p.SetState(33) + p.expression(14) + } + + case 2: + localctx = NewExpressionContext(p, _parentctx, _parentState) + p.PushNewRecursionContext(localctx, _startState, CAQLParserRULE_expression) + p.SetState(34) + + if !(p.Precpred(p.GetParserRuleContext(), 12)) { + panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 12)", "")) + } + { + p.SetState(35) + _la = p.GetTokenStream().LA(1) + + if !(((_la)&-(0x1f+1)) == 0 && ((1< 5\"\n # sandbox: \"score < 6\" # unknown-malware\n" + }, { + "id" : "phishing", + "name" : "Phishing", + "yaml" : "name: Phishing\ntasks:\n board:\n name: Board Involvement?\n description: Is a board member involved?\n type: input\n schema:\n properties:\n boardInvolved:\n default: false\n title: A board member is involved.\n type: boolean\n required:\n - boardInvolved\n title: Board Involvement?\n type: object\n next:\n escalate: \"boardInvolved == true\"\n mail-available: \"boardInvolved == false\"\n\n escalate:\n name: Escalate to CISO\n description: Please escalate the task to the CISO\n type: task\n\n mail-available:\n name: Mail available\n type: input\n schema:\n oneOf:\n - properties:\n mail:\n title: Mail\n type: string\n x-display: textarea\n schemaKey:\n const: 'yes'\n type: string\n required:\n - mail\n title: 'Yes'\n - properties:\n schemaKey:\n const: 'no'\n type: string\n title: 'No'\n title: Mail available\n type: object\n next:\n block-sender: \"schemaKey == 'yes'\"\n extract-iocs: \"schemaKey == 'yes'\"\n search-email-gateway: \"schemaKey == 'no'\"\n\n search-email-gateway:\n name: Search email gateway\n description: Please search email-gateway for the phishing mail.\n type: task\n next:\n extract-iocs:\n\n block-sender:\n name: Block sender\n type: task\n next:\n extract-iocs:\n\n extract-iocs:\n name: Extract IOCs\n description: Please insert the IOCs\n type: input\n schema:\n properties:\n iocs:\n items:\n type: string\n title: IOCs\n type: array\n title: Extract IOCs\n type: object\n next:\n block-iocs:\n\n block-iocs:\n name: Block IOCs\n type: task\n" + }, { + "id" : "simple", + "name" : "Simple", + "yaml" : "name: Simple\ntasks:\n input:\n name: Enter something to hash\n type: input\n schema:\n title: Something\n type: object\n properties:\n something:\n type: string\n title: Something\n default: \"\"\n next:\n hash: \"something != ''\"\n\n hash:\n name: Hash the something\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['something']\"\n next:\n comment: \"hash != ''\"\n\n comment:\n name: Comment the hash\n type: automation\n automation: comment\n payload:\n default: \"playbook.tasks['hash'].data['hash']\"\n next:\n done: \"done\"\n\n done:\n name: You can close this case now\n type: task\n" + } ] + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "playbook:read" ] + } ], + "summary" : "List playbooks", + "tags" : [ "playbooks" ] + }, + "post" : { + "operationId" : "createPlaybook", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/PlaybookTemplateForm" + } + } + }, + "description" : "New playbook", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/PlaybookTemplateResponse" + }, + "type" : "array" + } + }, + "test" : { + "example" : { + "id" : "simple-2", + "name" : "Simple2", + "yaml" : "name: Simple2\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "playbook:write" ] + } ], + "summary" : "Create a playbook", + "tags" : [ "playbooks" ], + "x-codegen-request-body-name" : "playbook" + } + }, + "/playbooks/{id}" : { + "delete" : { + "operationId" : "deletePlaybook", + "parameters" : [ { + "description" : "Playbook name", + "example" : "simple", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "204" : { + "content" : { }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "playbook:write" ] + } ], + "summary" : "Delete a playbook", + "tags" : [ "playbooks" ] + }, + "get" : { + "operationId" : "getPlaybook", + "parameters" : [ { + "description" : "Playbook name", + "example" : "simple", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/PlaybookTemplateResponse" + } + }, + "test" : { + "example" : { + "id" : "simple", + "name" : "Simple", + "yaml" : "name: Simple\ntasks:\n input:\n name: Enter something to hash\n type: input\n schema:\n title: Something\n type: object\n properties:\n something:\n type: string\n title: Something\n default: \"\"\n next:\n hash: \"something != ''\"\n\n hash:\n name: Hash the something\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['something']\"\n next:\n comment: \"hash != ''\"\n\n comment:\n name: Comment the hash\n type: automation\n automation: comment\n payload:\n default: \"playbook.tasks['hash'].data['hash']\"\n next:\n done: \"done\"\n\n done:\n name: You can close this case now\n type: task\n" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "playbook:read" ] + } ], + "summary" : "Get a single playbook", + "tags" : [ "playbooks" ] + }, + "put" : { + "operationId" : "updatePlaybook", + "parameters" : [ { + "description" : "Playbook ID", + "example" : "simple", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/PlaybookTemplateForm" + } + } + }, + "description" : "Updated playbook", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/PlaybookTemplateResponse" + } + }, + "test" : { + "example" : { + "id" : "simple", + "name" : "Simple", + "yaml" : "name: Simple\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "playbook:write" ] + } ], + "summary" : "Update an existing ticket playbook", + "tags" : [ "playbooks" ], + "x-codegen-request-body-name" : "playbook" + } + }, + "/rules" : { + "get" : { + "operationId" : "listRules", + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/RuleResponse" + }, + "type" : "array" + } + }, + "test" : { + "example" : [ { + "condition" : "type == 'alert'", + "id" : "ignore-alerts", + "name" : "Ignore Alerts", + "update" : { + "status" : "closed" + } + } ] + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "rule:read" ] + } ], + "summary" : "List rules", + "tags" : [ "rules" ] + }, + "post" : { + "operationId" : "createRule", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/RuleForm" + } + } + }, + "description" : "New rule", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/RuleResponse" + }, + "type" : "array" + } + }, + "test" : { + "example" : { + "condition" : "type == 'alert'", + "id" : "ignore-all-alerts", + "name" : "Ignore all Alerts", + "update" : { + "status" : "closed" + } + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "rule:write" ] + } ], + "summary" : "Create a rule", + "tags" : [ "rules" ], + "x-codegen-request-body-name" : "rule" + } + }, + "/rules/{id}" : { + "delete" : { + "operationId" : "deleteRule", + "parameters" : [ { + "description" : "Rule name", + "example" : "ignore-alerts", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "204" : { + "content" : { }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "rule:write" ] + } ], + "summary" : "Delete a rule", + "tags" : [ "rules" ] + }, + "get" : { + "operationId" : "getRule", + "parameters" : [ { + "description" : "Rule name", + "example" : "ignore-alerts", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/RuleResponse" + } + }, + "test" : { + "example" : { + "condition" : "type == 'alert'", + "id" : "ignore-alerts", + "name" : "Ignore Alerts", + "update" : { + "status" : "closed" + } + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "rule:read" ] + } ], + "summary" : "Get a single rule", + "tags" : [ "rules" ] + }, + "put" : { + "operationId" : "updateRule", + "parameters" : [ { + "description" : "Rule ID", + "example" : "ignore-alerts", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/RuleForm" + } + } + }, + "description" : "Updated rule", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/RuleResponse" + } + }, + "test" : { + "example" : { + "condition" : "type == 'alert'", + "id" : "ignore-alerts", + "name" : "Ignore Alerts", + "update" : { + "status" : "invalid" + } + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "rule:write" ] + } ], + "summary" : "Update an existing ticket rule", + "tags" : [ "rules" ], + "x-codegen-request-body-name" : "rule" + } + }, + "/settings" : { + "get" : { + "operationId" : "getSettings", + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Settings" + } + }, + "test" : { + "example" : { + "artifactStates" : [ { + "color" : "info", + "icon" : "mdi-help-circle-outline", + "id" : "unknown", + "name" : "Unknown" + }, { + "color" : "error", + "icon" : "mdi-skull", + "id" : "malicious", + "name" : "Malicious" + }, { + "color" : "success", + "icon" : "mdi-check", + "id" : "clean", + "name" : "Clean" + } ], + "roles" : [ "admin:backup:read", "admin:backup:restore", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ], + "ticketTypes" : [ { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-alert", + "id" : "alert", + "name" : "Alerts" + }, { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-radioactive", + "id" : "incident", + "name" : "Incidents" + }, { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-fingerprint", + "id" : "investigation", + "name" : "Forensic Investigations" + }, { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-target", + "id" : "hunt", + "name" : "Threat Hunting" + } ], + "tier" : "community", + "timeformat" : "YYYY-MM-DDThh:mm:ss", + "version" : "0.0.0-test" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "settings:read" ] + } ], + "summary" : "Get settings", + "tags" : [ "settings" ] + } + }, + "/statistics" : { + "get" : { + "operationId" : "getStatistics", + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Statistics" + } + }, + "test" : { + "example" : { + "open_tickets_per_user" : { }, + "tickets_per_type" : { + "alert" : 2, + "incident" : 1 + }, + "tickets_per_week" : { + "2021-39" : 3 + }, + "unassigned" : 0 + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:read" ] + } ], + "summary" : "Get statistics", + "tags" : [ "statistics" ] + } + }, + "/tasks" : { + "get" : { + "operationId" : "listTasks", + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/TaskResponse" + }, + "type" : "array" + } + }, + "test" : { + "example" : [ ] + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:read" ] + } ], + "summary" : "List tasks", + "tags" : [ "tasks" ] + } + }, + "/templates" : { + "get" : { + "operationId" : "listTemplates", + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/TicketTemplateResponse" + }, + "type" : "array" + } + }, + "test" : { + "example" : [ { + "id" : "default", + "name" : "Default", + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Default\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + } ] + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "template:read" ] + } ], + "summary" : "List templates", + "tags" : [ "templates" ] + }, + "post" : { + "operationId" : "createTemplate", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketTemplateForm" + } + } + }, + "description" : "New template", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketTemplateResponse" + } + }, + "test" : { + "example" : { + "id" : "my-template", + "name" : "My Template", + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "template:write" ] + } ], + "summary" : "Create a new template", + "tags" : [ "templates" ], + "x-codegen-request-body-name" : "template" + } + }, + "/templates/{id}" : { + "delete" : { + "operationId" : "deleteTemplate", + "parameters" : [ { + "description" : "Template ID", + "example" : "default", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "204" : { + "content" : { }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "template:write" ] + } ], + "summary" : "Delete a template", + "tags" : [ "templates" ] + }, + "get" : { + "operationId" : "getTemplate", + "parameters" : [ { + "description" : "Template ID", + "example" : "default", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketTemplateResponse" + } + }, + "test" : { + "example" : { + "id" : "default", + "name" : "Default", + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Default\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "template:read" ] + } ], + "summary" : "Get a single template", + "tags" : [ "templates" ] + }, + "put" : { + "operationId" : "updateTemplate", + "parameters" : [ { + "description" : "Template ID", + "example" : "default", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketTemplateForm" + } + } + }, + "description" : "Template object that needs to be added", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketTemplateResponse" + } + }, + "test" : { + "example" : { + "id" : "default", + "name" : "My Template", + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "template:write" ] + } ], + "summary" : "Update an existing template", + "tags" : [ "templates" ], + "x-codegen-request-body-name" : "template" + } + }, + "/tickets" : { + "get" : { + "operationId" : "listTickets", + "parameters" : [ { + "description" : "Ticket Type", + "in" : "query", + "name" : "type", + "schema" : { + "type" : "string" + } + }, { + "description" : "Offset of the list", + "in" : "query", + "name" : "offset", + "schema" : { + "default" : 0, + "type" : "integer" + } + }, { + "description" : "Number of tickets", + "in" : "query", + "name" : "count", + "schema" : { + "default" : 25, + "maximum" : 100, + "type" : "integer" + } + }, { + "description" : "Sort columns", + "explode" : false, + "in" : "query", + "name" : "sort", + "schema" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "style" : "form" + }, { + "description" : "Sort descending", + "explode" : false, + "in" : "query", + "name" : "desc", + "schema" : { + "items" : { + "type" : "boolean" + }, + "type" : "array" + }, + "style" : "form" + }, { + "description" : "Search query", + "in" : "query", + "name" : "query", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketList" + } + }, + "test" : { + "example" : { + "count" : 3, + "tickets" : [ { + "artifacts" : [ { + "name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status" : "unknown" + }, { + "name" : "http://www.customerviral.io/scalable/vertical/killer", + "status" : "clean" + }, { + "name" : "leadreintermediate.io", + "status" : "malicious" + } ], + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8123, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "live zebra", + "owner" : "demo", + "playbooks" : { + "phishing" : { + "name" : "Phishing", + "tasks" : { + "block-iocs" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block IOCs", + "type" : "task" + }, + "block-sender" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block sender", + "next" : { + "extract-iocs" : "" + }, + "type" : "task" + }, + "board" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Board Involvement?", + "next" : { + "escalate" : "boardInvolved == true", + "mail-available" : "boardInvolved == false" + }, + "schema" : { + "properties" : { + "boardInvolved" : { + "default" : false, + "title" : "A board member is involved.", + "type" : "boolean" + } + }, + "required" : [ "boardInvolved" ], + "title" : "Board Involvement?", + "type" : "object" + }, + "type" : "input" + }, + "escalate" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Escalate to CISO", + "type" : "task" + }, + "extract-iocs" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Extract IOCs", + "next" : { + "block-iocs" : "" + }, + "schema" : { + "properties" : { + "iocs" : { + "items" : { + "type" : "string" + }, + "title" : "IOCs", + "type" : "array" + } + }, + "title" : "Extract IOCs", + "type" : "object" + }, + "type" : "input" + }, + "mail-available" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Mail available", + "next" : { + "block-sender" : "schemaKey == 'yes'", + "extract-iocs" : "schemaKey == 'yes'", + "search-email-gateway" : "schemaKey == 'no'" + }, + "schema" : { + "oneOf" : [ { + "properties" : { + "mail" : { + "title" : "Mail", + "type" : "string", + "x-display" : "textarea" + }, + "schemaKey" : { + "const" : "yes", + "type" : "string" + } + }, + "required" : [ "mail" ], + "title" : "Yes" + }, { + "properties" : { + "schemaKey" : { + "const" : "no", + "type" : "string" + } + }, + "title" : "No" + } ], + "title" : "Mail available", + "type" : "object" + }, + "type" : "input" + }, + "search-email-gateway" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Search email gateway", + "next" : { + "extract-iocs" : "" + }, + "type" : "task" + } + } + } + }, + "references" : [ { + "href" : "https://www.leadmaximize.net/e-services/back-end", + "name" : "performance" + }, { + "href" : "http://www.corporateinteractive.name/rich", + "name" : "autumn" + }, { + "href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name" : "suggest" + } ], + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status" : "closed", + "type" : "incident" + }, { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8125, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "phishing from selenafadel@von.com detected", + "owner" : "demo", + "references" : [ { + "href" : "https://www.seniorleading-edge.name/users/efficient", + "name" : "recovery" + }, { + "href" : "http://www.dynamicseamless.com/clicks-and-mortar", + "name" : "force" + }, { + "href" : "http://www.leadscalable.biz/envisioneer", + "name" : "fund" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + }, { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8126, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "Surfaceintroduce virus detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.centralworld-class.io/synthesize", + "name" : "university" + }, { + "href" : "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name" : "goal" + }, { + "href" : "http://www.chiefsyndicate.io/action-items", + "name" : "unemployment" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + } ] + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:read" ] + } ], + "summary" : "List tickets", + "tags" : [ "tickets" ] + }, + "post" : { + "operationId" : "createTicket", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketForm" + } + } + }, + "description" : "New ticket", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "created" : "1985-04-12T23:20:50.520+0000", + "id" : 123, + "modified" : "1985-04-12T23:20:50.520+0000", + "name" : "Wannacry infection", + "owner" : "bob", + "schema" : "{}", + "status" : "open", + "type" : "incident" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Create a new ticket", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "ticket" + } + }, + "/tickets/{id}" : { + "delete" : { + "operationId" : "deleteTicket", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8125, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "responses" : { + "204" : { + "content" : { }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:delete" ] + } ], + "summary" : "Delete an ticket", + "tags" : [ "tickets" ] + }, + "get" : { + "operationId" : "getTicket", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8125, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8125, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "phishing from selenafadel@von.com detected", + "owner" : "demo", + "references" : [ { + "href" : "https://www.seniorleading-edge.name/users/efficient", + "name" : "recovery" + }, { + "href" : "http://www.dynamicseamless.com/clicks-and-mortar", + "name" : "force" + }, { + "href" : "http://www.leadscalable.biz/envisioneer", + "name" : "fund" + } ], + "schema" : "{}", + "status" : "closed", + "tickets" : [ { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8126, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "Surfaceintroduce virus detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.centralworld-class.io/synthesize", + "name" : "university" + }, { + "href" : "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name" : "goal" + }, { + "href" : "http://www.chiefsyndicate.io/action-items", + "name" : "unemployment" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + } ], + "type" : "alert" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:read" ] + } ], + "summary" : "Get a single ticket", + "tags" : [ "tickets" ] + }, + "put" : { + "operationId" : "updateTicket", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8125, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Ticket" + } + } + }, + "description" : "Updated ticket", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8125, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "phishing from selenafadel@von.org detected", + "owner" : "demo", + "references" : [ { + "href" : "https://www.seniorleading-edge.name/users/efficient", + "name" : "recovery" + }, { + "href" : "http://www.dynamicseamless.com/clicks-and-mortar", + "name" : "force" + }, { + "href" : "http://www.leadscalable.biz/envisioneer", + "name" : "fund" + } ], + "schema" : "{}", + "status" : "closed", + "tickets" : [ { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8126, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "Surfaceintroduce virus detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.centralworld-class.io/synthesize", + "name" : "university" + }, { + "href" : "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name" : "goal" + }, { + "href" : "http://www.chiefsyndicate.io/action-items", + "name" : "unemployment" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + } ], + "type" : "alert" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Update an existing ticket", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "ticket" + } + }, + "/tickets/{id}/artifacts" : { + "post" : { + "operationId" : "addArtifact", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Artifact" + } + } + }, + "description" : "Artifact object that needs to be added", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "artifacts" : [ { + "name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status" : "unknown" + }, { + "name" : "http://www.customerviral.io/scalable/vertical/killer", + "status" : "clean" + }, { + "name" : "leadreintermediate.io", + "status" : "malicious" + }, { + "name" : "2.2.2.2", + "status" : "unknown", + "type" : "ip" + } ], + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8123, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "live zebra", + "owner" : "demo", + "playbooks" : { + "phishing" : { + "name" : "Phishing", + "tasks" : { + "block-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block IOCs", + "order" : 6, + "type" : "task" + }, + "block-sender" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block sender", + "next" : { + "extract-iocs" : "" + }, + "order" : 3, + "type" : "task" + }, + "board" : { + "active" : true, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Board Involvement?", + "next" : { + "escalate" : "boardInvolved == true", + "mail-available" : "boardInvolved == false" + }, + "order" : 0, + "schema" : { + "properties" : { + "boardInvolved" : { + "default" : false, + "title" : "A board member is involved.", + "type" : "boolean" + } + }, + "required" : [ "boardInvolved" ], + "title" : "Board Involvement?", + "type" : "object" + }, + "type" : "input" + }, + "escalate" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Escalate to CISO", + "order" : 1, + "type" : "task" + }, + "extract-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Extract IOCs", + "next" : { + "block-iocs" : "" + }, + "order" : 5, + "schema" : { + "properties" : { + "iocs" : { + "items" : { + "type" : "string" + }, + "title" : "IOCs", + "type" : "array" + } + }, + "title" : "Extract IOCs", + "type" : "object" + }, + "type" : "input" + }, + "mail-available" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Mail available", + "next" : { + "block-sender" : "schemaKey == 'yes'", + "extract-iocs" : "schemaKey == 'yes'", + "search-email-gateway" : "schemaKey == 'no'" + }, + "order" : 2, + "schema" : { + "oneOf" : [ { + "properties" : { + "mail" : { + "title" : "Mail", + "type" : "string", + "x-display" : "textarea" + }, + "schemaKey" : { + "const" : "yes", + "type" : "string" + } + }, + "required" : [ "mail" ], + "title" : "Yes" + }, { + "properties" : { + "schemaKey" : { + "const" : "no", + "type" : "string" + } + }, + "title" : "No" + } ], + "title" : "Mail available", + "type" : "object" + }, + "type" : "input" + }, + "search-email-gateway" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Search email gateway", + "next" : { + "extract-iocs" : "" + }, + "order" : 4, + "type" : "task" + } + } + } + }, + "references" : [ { + "href" : "https://www.leadmaximize.net/e-services/back-end", + "name" : "performance" + }, { + "href" : "http://www.corporateinteractive.name/rich", + "name" : "autumn" + }, { + "href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name" : "suggest" + } ], + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status" : "closed", + "type" : "incident" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Add a single artifact", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "artifact" + } + }, + "/tickets/{id}/artifacts/{name}" : { + "delete" : { + "operationId" : "removeArtifact", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + }, { + "example" : "leadreintermediate.io", + "in" : "path", + "name" : "name", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "artifacts" : [ { + "name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status" : "unknown" + }, { + "name" : "http://www.customerviral.io/scalable/vertical/killer", + "status" : "clean" + } ], + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8123, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "live zebra", + "owner" : "demo", + "playbooks" : { + "phishing" : { + "name" : "Phishing", + "tasks" : { + "block-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block IOCs", + "order" : 6, + "type" : "task" + }, + "block-sender" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block sender", + "next" : { + "extract-iocs" : "" + }, + "order" : 3, + "type" : "task" + }, + "board" : { + "active" : true, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Board Involvement?", + "next" : { + "escalate" : "boardInvolved == true", + "mail-available" : "boardInvolved == false" + }, + "order" : 0, + "schema" : { + "properties" : { + "boardInvolved" : { + "default" : false, + "title" : "A board member is involved.", + "type" : "boolean" + } + }, + "required" : [ "boardInvolved" ], + "title" : "Board Involvement?", + "type" : "object" + }, + "type" : "input" + }, + "escalate" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Escalate to CISO", + "order" : 1, + "type" : "task" + }, + "extract-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Extract IOCs", + "next" : { + "block-iocs" : "" + }, + "order" : 5, + "schema" : { + "properties" : { + "iocs" : { + "items" : { + "type" : "string" + }, + "title" : "IOCs", + "type" : "array" + } + }, + "title" : "Extract IOCs", + "type" : "object" + }, + "type" : "input" + }, + "mail-available" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Mail available", + "next" : { + "block-sender" : "schemaKey == 'yes'", + "extract-iocs" : "schemaKey == 'yes'", + "search-email-gateway" : "schemaKey == 'no'" + }, + "order" : 2, + "schema" : { + "oneOf" : [ { + "properties" : { + "mail" : { + "title" : "Mail", + "type" : "string", + "x-display" : "textarea" + }, + "schemaKey" : { + "const" : "yes", + "type" : "string" + } + }, + "required" : [ "mail" ], + "title" : "Yes" + }, { + "properties" : { + "schemaKey" : { + "const" : "no", + "type" : "string" + } + }, + "title" : "No" + } ], + "title" : "Mail available", + "type" : "object" + }, + "type" : "input" + }, + "search-email-gateway" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Search email gateway", + "next" : { + "extract-iocs" : "" + }, + "order" : 4, + "type" : "task" + } + } + } + }, + "references" : [ { + "href" : "https://www.leadmaximize.net/e-services/back-end", + "name" : "performance" + }, { + "href" : "http://www.corporateinteractive.name/rich", + "name" : "autumn" + }, { + "href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name" : "suggest" + } ], + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status" : "closed", + "type" : "incident" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Remove an artifact", + "tags" : [ "tickets" ] + }, + "get" : { + "operationId" : "getArtifact", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + }, { + "example" : "leadreintermediate.io", + "in" : "path", + "name" : "name", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Artifact" + } + }, + "test" : { + "example" : { + "name" : "leadreintermediate.io", + "status" : "malicious" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Get a single artifact", + "tags" : [ "tickets" ] + }, + "put" : { + "operationId" : "setArtifact", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + }, { + "example" : "leadreintermediate.io", + "in" : "path", + "name" : "name", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Artifact" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "artifacts" : [ { + "name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status" : "unknown" + }, { + "name" : "http://www.customerviral.io/scalable/vertical/killer", + "status" : "clean" + }, { + "name" : "leadreintermediate.io", + "status" : "clean" + } ], + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8123, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "live zebra", + "owner" : "demo", + "playbooks" : { + "phishing" : { + "name" : "Phishing", + "tasks" : { + "block-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block IOCs", + "order" : 6, + "type" : "task" + }, + "block-sender" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block sender", + "next" : { + "extract-iocs" : "" + }, + "order" : 3, + "type" : "task" + }, + "board" : { + "active" : true, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Board Involvement?", + "next" : { + "escalate" : "boardInvolved == true", + "mail-available" : "boardInvolved == false" + }, + "order" : 0, + "schema" : { + "properties" : { + "boardInvolved" : { + "default" : false, + "title" : "A board member is involved.", + "type" : "boolean" + } + }, + "required" : [ "boardInvolved" ], + "title" : "Board Involvement?", + "type" : "object" + }, + "type" : "input" + }, + "escalate" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Escalate to CISO", + "order" : 1, + "type" : "task" + }, + "extract-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Extract IOCs", + "next" : { + "block-iocs" : "" + }, + "order" : 5, + "schema" : { + "properties" : { + "iocs" : { + "items" : { + "type" : "string" + }, + "title" : "IOCs", + "type" : "array" + } + }, + "title" : "Extract IOCs", + "type" : "object" + }, + "type" : "input" + }, + "mail-available" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Mail available", + "next" : { + "block-sender" : "schemaKey == 'yes'", + "extract-iocs" : "schemaKey == 'yes'", + "search-email-gateway" : "schemaKey == 'no'" + }, + "order" : 2, + "schema" : { + "oneOf" : [ { + "properties" : { + "mail" : { + "title" : "Mail", + "type" : "string", + "x-display" : "textarea" + }, + "schemaKey" : { + "const" : "yes", + "type" : "string" + } + }, + "required" : [ "mail" ], + "title" : "Yes" + }, { + "properties" : { + "schemaKey" : { + "const" : "no", + "type" : "string" + } + }, + "title" : "No" + } ], + "title" : "Mail available", + "type" : "object" + }, + "type" : "input" + }, + "search-email-gateway" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Search email gateway", + "next" : { + "extract-iocs" : "" + }, + "order" : 4, + "type" : "task" + } + } + } + }, + "references" : [ { + "href" : "https://www.leadmaximize.net/e-services/back-end", + "name" : "performance" + }, { + "href" : "http://www.corporateinteractive.name/rich", + "name" : "autumn" + }, { + "href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name" : "suggest" + } ], + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status" : "closed", + "type" : "incident" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Set a single artifact", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "artifact" + } + }, + "/tickets/{id}/artifacts/{name}/enrich" : { + "post" : { + "operationId" : "enrichArtifact", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + }, { + "example" : "leadreintermediate.io", + "in" : "path", + "name" : "name", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/EnrichmentForm" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Artifact" + } + }, + "test" : { + "example" : { + "artifacts" : [ { + "name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status" : "unknown" + }, { + "name" : "http://www.customerviral.io/scalable/vertical/killer", + "status" : "clean" + }, { + "enrichments" : { + "hash.sha1" : { + "created" : "2021-10-03T16:44:06.489+0000", + "data" : { + "hash" : "b7a067a742c20d07a7456646de89bc2d408a1153" + }, + "name" : "hash.sha1" + } + }, + "name" : "leadreintermediate.io", + "status" : "malicious" + } ], + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8123, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "live zebra", + "owner" : "demo", + "playbooks" : { + "phishing" : { + "name" : "Phishing", + "tasks" : { + "block-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block IOCs", + "order" : 6, + "type" : "task" + }, + "block-sender" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block sender", + "next" : { + "extract-iocs" : "" + }, + "order" : 3, + "type" : "task" + }, + "board" : { + "active" : true, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Board Involvement?", + "next" : { + "escalate" : "boardInvolved == true", + "mail-available" : "boardInvolved == false" + }, + "order" : 0, + "schema" : { + "properties" : { + "boardInvolved" : { + "default" : false, + "title" : "A board member is involved.", + "type" : "boolean" + } + }, + "required" : [ "boardInvolved" ], + "title" : "Board Involvement?", + "type" : "object" + }, + "type" : "input" + }, + "escalate" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Escalate to CISO", + "order" : 1, + "type" : "task" + }, + "extract-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Extract IOCs", + "next" : { + "block-iocs" : "" + }, + "order" : 5, + "schema" : { + "properties" : { + "iocs" : { + "items" : { + "type" : "string" + }, + "title" : "IOCs", + "type" : "array" + } + }, + "title" : "Extract IOCs", + "type" : "object" + }, + "type" : "input" + }, + "mail-available" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Mail available", + "next" : { + "block-sender" : "schemaKey == 'yes'", + "extract-iocs" : "schemaKey == 'yes'", + "search-email-gateway" : "schemaKey == 'no'" + }, + "order" : 2, + "schema" : { + "oneOf" : [ { + "properties" : { + "mail" : { + "title" : "Mail", + "type" : "string", + "x-display" : "textarea" + }, + "schemaKey" : { + "const" : "yes", + "type" : "string" + } + }, + "required" : [ "mail" ], + "title" : "Yes" + }, { + "properties" : { + "schemaKey" : { + "const" : "no", + "type" : "string" + } + }, + "title" : "No" + } ], + "title" : "Mail available", + "type" : "object" + }, + "type" : "input" + }, + "search-email-gateway" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Search email gateway", + "next" : { + "extract-iocs" : "" + }, + "order" : 4, + "type" : "task" + } + } + } + }, + "references" : [ { + "href" : "https://www.leadmaximize.net/e-services/back-end", + "name" : "performance" + }, { + "href" : "http://www.corporateinteractive.name/rich", + "name" : "autumn" + }, { + "href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name" : "suggest" + } ], + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status" : "closed", + "type" : "incident" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Enrich a single artifact", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "data" + } + }, + "/tickets/{id}/artifacts/{name}/run/{automation}" : { + "post" : { + "operationId" : "runArtifact", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + }, { + "example" : "leadreintermediate.io", + "in" : "path", + "name" : "name", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "example" : "hash.sha1", + "in" : "path", + "name" : "automation", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "204" : { + "content" : { }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Run automation on a single artifact", + "tags" : [ "tickets" ] + } + }, + "/tickets/{id}/comments" : { + "post" : { + "operationId" : "addComment", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8125, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/CommentForm" + } + } + }, + "description" : "Ticket comment", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "comments" : [ { + "created" : "2021-10-02T16:04:59.078+0000", + "creator" : "bob", + "message" : "My first comment" + } ], + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8125, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "phishing from selenafadel@von.com detected", + "owner" : "demo", + "references" : [ { + "href" : "https://www.seniorleading-edge.name/users/efficient", + "name" : "recovery" + }, { + "href" : "http://www.dynamicseamless.com/clicks-and-mortar", + "name" : "force" + }, { + "href" : "http://www.leadscalable.biz/envisioneer", + "name" : "fund" + } ], + "schema" : "{}", + "status" : "closed", + "tickets" : [ { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8126, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "Surfaceintroduce virus detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.centralworld-class.io/synthesize", + "name" : "university" + }, { + "href" : "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name" : "goal" + }, { + "href" : "http://www.chiefsyndicate.io/action-items", + "name" : "unemployment" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + } ], + "type" : "alert" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Add ticket comment", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "comment" + } + }, + "/tickets/{id}/comments/{commentID}" : { + "delete" : { + "description" : "Comment will be removed from the ticket.", + "operationId" : "removeComment", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + }, { + "description" : "Comment ID to remove", + "example" : 0, + "in" : "path", + "name" : "commentID", + "required" : true, + "schema" : { + "type" : "integer" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "artifacts" : [ { + "name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status" : "unknown" + }, { + "name" : "http://www.customerviral.io/scalable/vertical/killer", + "status" : "clean" + }, { + "name" : "leadreintermediate.io", + "status" : "malicious" + } ], + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8123, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "live zebra", + "owner" : "demo", + "playbooks" : { + "phishing" : { + "name" : "Phishing", + "tasks" : { + "block-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block IOCs", + "order" : 6, + "type" : "task" + }, + "block-sender" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block sender", + "next" : { + "extract-iocs" : "" + }, + "order" : 3, + "type" : "task" + }, + "board" : { + "active" : true, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Board Involvement?", + "next" : { + "escalate" : "boardInvolved == true", + "mail-available" : "boardInvolved == false" + }, + "order" : 0, + "schema" : { + "properties" : { + "boardInvolved" : { + "default" : false, + "title" : "A board member is involved.", + "type" : "boolean" + } + }, + "required" : [ "boardInvolved" ], + "title" : "Board Involvement?", + "type" : "object" + }, + "type" : "input" + }, + "escalate" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Escalate to CISO", + "order" : 1, + "type" : "task" + }, + "extract-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Extract IOCs", + "next" : { + "block-iocs" : "" + }, + "order" : 5, + "schema" : { + "properties" : { + "iocs" : { + "items" : { + "type" : "string" + }, + "title" : "IOCs", + "type" : "array" + } + }, + "title" : "Extract IOCs", + "type" : "object" + }, + "type" : "input" + }, + "mail-available" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Mail available", + "next" : { + "block-sender" : "schemaKey == 'yes'", + "extract-iocs" : "schemaKey == 'yes'", + "search-email-gateway" : "schemaKey == 'no'" + }, + "order" : 2, + "schema" : { + "oneOf" : [ { + "properties" : { + "mail" : { + "title" : "Mail", + "type" : "string", + "x-display" : "textarea" + }, + "schemaKey" : { + "const" : "yes", + "type" : "string" + } + }, + "required" : [ "mail" ], + "title" : "Yes" + }, { + "properties" : { + "schemaKey" : { + "const" : "no", + "type" : "string" + } + }, + "title" : "No" + } ], + "title" : "Mail available", + "type" : "object" + }, + "type" : "input" + }, + "search-email-gateway" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Search email gateway", + "next" : { + "extract-iocs" : "" + }, + "order" : 4, + "type" : "task" + } + } + } + }, + "references" : [ { + "href" : "https://www.leadmaximize.net/e-services/back-end", + "name" : "performance" + }, { + "href" : "http://www.corporateinteractive.name/rich", + "name" : "autumn" + }, { + "href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name" : "suggest" + } ], + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status" : "closed", + "type" : "incident" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Remove an comment from an ticket", + "tags" : [ "tickets" ] + } + }, + "/tickets/{id}/files" : { + "put" : { + "description" : "Link files to an ticket. The files themself will be stored in object storage.", + "operationId" : "linkFiles", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8125, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/File" + }, + "type" : "array" + } + } + }, + "description" : "Added files", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "created" : "2021-10-02T16:04:59.078+0000", + "files" : [ { + "key" : "myfile", + "name" : "document.doc" + } ], + "id" : 8125, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "phishing from selenafadel@von.com detected", + "owner" : "demo", + "references" : [ { + "href" : "https://www.seniorleading-edge.name/users/efficient", + "name" : "recovery" + }, { + "href" : "http://www.dynamicseamless.com/clicks-and-mortar", + "name" : "force" + }, { + "href" : "http://www.leadscalable.biz/envisioneer", + "name" : "fund" + } ], + "schema" : "{}", + "status" : "closed", + "tickets" : [ { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8126, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "Surfaceintroduce virus detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.centralworld-class.io/synthesize", + "name" : "university" + }, { + "href" : "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name" : "goal" + }, { + "href" : "http://www.chiefsyndicate.io/action-items", + "name" : "unemployment" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + } ], + "type" : "alert" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Link files to an ticket", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "files" + } + }, + "/tickets/{id}/playbooks" : { + "post" : { + "operationId" : "addTicketPlaybook", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8125, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/PlaybookTemplateForm" + } + } + }, + "description" : "Ticket playbook object that needs to be added", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "created" : "1985-04-12T23:20:50.520+0000", + "id" : 8125, + "modified" : "1985-04-12T23:20:50.520+0000", + "name" : "phishing from selenafadel@von.com detected", + "owner" : "demo", + "playbooks" : { + "simple" : { + "name" : "Simple", + "tasks" : { + "escalate" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Escalate to malware team", + "order" : 2, + "type" : "task" + }, + "hash" : { + "active" : false, + "automation" : "hash.sha1", + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Hash the malware", + "next" : { + "escalate" : "" + }, + "order" : 1, + "payload" : { + "default" : "playbook.tasks['input'].data['malware']" + }, + "type" : "automation" + }, + "input" : { + "active" : true, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Upload malware if possible", + "next" : { + "hash" : "malware != ''" + }, + "order" : 0, + "schema" : { + "properties" : { + "malware" : { + "default" : "", + "title" : "Select malware", + "type" : "string" + } + }, + "title" : "Malware", + "type" : "object" + }, + "type" : "input" + } + } + } + }, + "references" : [ { + "href" : "https://www.seniorleading-edge.name/users/efficient", + "name" : "recovery" + }, { + "href" : "http://www.dynamicseamless.com/clicks-and-mortar", + "name" : "force" + }, { + "href" : "http://www.leadscalable.biz/envisioneer", + "name" : "fund" + } ], + "schema" : "{}", + "status" : "closed", + "tickets" : [ { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8126, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "Surfaceintroduce virus detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.centralworld-class.io/synthesize", + "name" : "university" + }, { + "href" : "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name" : "goal" + }, { + "href" : "http://www.chiefsyndicate.io/action-items", + "name" : "unemployment" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + } ], + "type" : "alert" + } + } + }, + "description" : "successful operation" + } + }, + "summary" : "Add a new ticket playbook", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "playbook" + } + }, + "/tickets/{id}/playbooks/{playbookID}" : { + "delete" : { + "operationId" : "removeTicketPlaybook", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + }, { + "description" : "Playbook ID", + "example" : "phishing", + "in" : "path", + "name" : "playbookID", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "artifacts" : [ { + "name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status" : "unknown" + }, { + "name" : "http://www.customerviral.io/scalable/vertical/killer", + "status" : "clean" + }, { + "name" : "leadreintermediate.io", + "status" : "malicious" + } ], + "created" : "1985-04-12T23:20:50.520+0000", + "id" : 8123, + "modified" : "1985-04-12T23:20:50.520+0000", + "name" : "live zebra", + "owner" : "demo", + "references" : [ { + "href" : "https://www.leadmaximize.net/e-services/back-end", + "name" : "performance" + }, { + "href" : "http://www.corporateinteractive.name/rich", + "name" : "autumn" + }, { + "href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name" : "suggest" + } ], + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status" : "closed", + "type" : "incident" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Remove an ticket playbook", + "tags" : [ "tickets" ] + } + }, + "/tickets/{id}/playbooks/{playbookID}/task/{taskID}" : { + "put" : { + "operationId" : "setTask", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + }, { + "description" : "Playbook ID", + "example" : "phishing", + "in" : "path", + "name" : "playbookID", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "description" : "Task ID", + "example" : "board", + "in" : "path", + "name" : "taskID", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Task" + } + } + }, + "description" : "Task", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "artifacts" : [ { + "name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status" : "unknown" + }, { + "name" : "http://www.customerviral.io/scalable/vertical/killer", + "status" : "clean" + }, { + "name" : "leadreintermediate.io", + "status" : "malicious" + } ], + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8123, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "live zebra", + "owner" : "demo", + "playbooks" : { + "phishing" : { + "name" : "Phishing", + "tasks" : { + "block-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block IOCs", + "order" : 6, + "type" : "task" + }, + "block-sender" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block sender", + "next" : { + "extract-iocs" : "" + }, + "order" : 3, + "type" : "task" + }, + "board" : { + "active" : true, + "created" : "2021-10-02T16:04:59.078+0000", + "data" : { + "boardInvolved" : true + }, + "done" : false, + "name" : "Board Involvement?", + "next" : { + "escalate" : "boardInvolved == true", + "mail-available" : "boardInvolved == false" + }, + "order" : 0, + "schema" : { + "properties" : { + "boardInvolved" : { + "default" : false, + "title" : "A board member is involved.", + "type" : "boolean" + } + }, + "required" : [ "boardInvolved" ], + "title" : "Board Involvement?", + "type" : "object" + }, + "type" : "input" + }, + "escalate" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Escalate to CISO", + "order" : 1, + "type" : "task" + }, + "extract-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Extract IOCs", + "next" : { + "block-iocs" : "" + }, + "order" : 5, + "schema" : { + "properties" : { + "iocs" : { + "items" : { + "type" : "string" + }, + "title" : "IOCs", + "type" : "array" + } + }, + "title" : "Extract IOCs", + "type" : "object" + }, + "type" : "input" + }, + "mail-available" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Mail available", + "next" : { + "block-sender" : "schemaKey == 'yes'", + "extract-iocs" : "schemaKey == 'yes'", + "search-email-gateway" : "schemaKey == 'no'" + }, + "order" : 2, + "schema" : { + "oneOf" : [ { + "properties" : { + "mail" : { + "title" : "Mail", + "type" : "string", + "x-display" : "textarea" + }, + "schemaKey" : { + "const" : "yes", + "type" : "string" + } + }, + "required" : [ "mail" ], + "title" : "Yes" + }, { + "properties" : { + "schemaKey" : { + "const" : "no", + "type" : "string" + } + }, + "title" : "No" + } ], + "title" : "Mail available", + "type" : "object" + }, + "type" : "input" + }, + "search-email-gateway" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Search email gateway", + "next" : { + "extract-iocs" : "" + }, + "order" : 4, + "type" : "task" + } + } + } + }, + "references" : [ { + "href" : "https://www.leadmaximize.net/e-services/back-end", + "name" : "performance" + }, { + "href" : "http://www.corporateinteractive.name/rich", + "name" : "autumn" + }, { + "href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name" : "suggest" + } ], + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status" : "closed", + "type" : "incident" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Set a ticket playbook task", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "task" + } + }, + "/tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete" : { + "put" : { + "operationId" : "completeTask", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + }, { + "description" : "Playbook ID", + "example" : "phishing", + "in" : "path", + "name" : "playbookID", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "description" : "Task ID", + "example" : "board", + "in" : "path", + "name" : "taskID", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "type" : "object" + } + } + }, + "description" : "Ticket playbook object that needs to be added", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "artifacts" : [ { + "name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status" : "unknown" + }, { + "name" : "http://www.customerviral.io/scalable/vertical/killer", + "status" : "clean" + }, { + "name" : "leadreintermediate.io", + "status" : "malicious" + } ], + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8123, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "live zebra", + "owner" : "demo", + "playbooks" : { + "phishing" : { + "name" : "Phishing", + "tasks" : { + "block-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block IOCs", + "order" : 6, + "type" : "task" + }, + "block-sender" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block sender", + "next" : { + "extract-iocs" : "" + }, + "order" : 3, + "type" : "task" + }, + "board" : { + "active" : false, + "closed" : "2021-10-02T16:04:59.078+0000", + "created" : "2021-10-02T16:04:59.078+0000", + "data" : { + "boardInvolved" : true + }, + "done" : true, + "name" : "Board Involvement?", + "next" : { + "escalate" : "boardInvolved == true", + "mail-available" : "boardInvolved == false" + }, + "order" : 0, + "schema" : { + "properties" : { + "boardInvolved" : { + "default" : false, + "title" : "A board member is involved.", + "type" : "boolean" + } + }, + "required" : [ "boardInvolved" ], + "title" : "Board Involvement?", + "type" : "object" + }, + "type" : "input" + }, + "escalate" : { + "active" : true, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Escalate to CISO", + "order" : 1, + "type" : "task" + }, + "extract-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Extract IOCs", + "next" : { + "block-iocs" : "" + }, + "order" : 5, + "schema" : { + "properties" : { + "iocs" : { + "items" : { + "type" : "string" + }, + "title" : "IOCs", + "type" : "array" + } + }, + "title" : "Extract IOCs", + "type" : "object" + }, + "type" : "input" + }, + "mail-available" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Mail available", + "next" : { + "block-sender" : "schemaKey == 'yes'", + "extract-iocs" : "schemaKey == 'yes'", + "search-email-gateway" : "schemaKey == 'no'" + }, + "order" : 2, + "schema" : { + "oneOf" : [ { + "properties" : { + "mail" : { + "title" : "Mail", + "type" : "string", + "x-display" : "textarea" + }, + "schemaKey" : { + "const" : "yes", + "type" : "string" + } + }, + "required" : [ "mail" ], + "title" : "Yes" + }, { + "properties" : { + "schemaKey" : { + "const" : "no", + "type" : "string" + } + }, + "title" : "No" + } ], + "title" : "Mail available", + "type" : "object" + }, + "type" : "input" + }, + "search-email-gateway" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Search email gateway", + "next" : { + "extract-iocs" : "" + }, + "order" : 4, + "type" : "task" + } + } + } + }, + "references" : [ { + "href" : "https://www.leadmaximize.net/e-services/back-end", + "name" : "performance" + }, { + "href" : "http://www.corporateinteractive.name/rich", + "name" : "autumn" + }, { + "href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name" : "suggest" + } ], + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status" : "closed", + "type" : "incident" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Complete ticket playbook task", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "data" + } + }, + "/tickets/{id}/playbooks/{playbookID}/task/{taskID}/run" : { + "post" : { + "operationId" : "runTask", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + }, { + "description" : "Playbook ID", + "example" : "phishing", + "in" : "path", + "name" : "playbookID", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "description" : "Task ID", + "example" : "board", + "in" : "path", + "name" : "taskID", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "204" : { + "content" : { }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Run ticket playbook task", + "tags" : [ "tickets" ] + } + }, + "/tickets/{id}/references" : { + "put" : { + "operationId" : "setReferences", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8125, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/Reference" + }, + "type" : "array" + } + } + }, + "description" : "All ticket references", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8125, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "phishing from selenafadel@von.com detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.leadscalable.biz/envisioneer", + "name" : "fund" + } ], + "schema" : "{}", + "status" : "closed", + "tickets" : [ { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8126, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "Surfaceintroduce virus detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.centralworld-class.io/synthesize", + "name" : "university" + }, { + "href" : "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name" : "goal" + }, { + "href" : "http://www.chiefsyndicate.io/action-items", + "name" : "unemployment" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + } ], + "type" : "alert" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Set ticket references", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "references" + } + }, + "/tickets/{id}/schema" : { + "put" : { + "operationId" : "setSchema", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8125, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "New ticket schema", + "required" : false + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8125, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "phishing from selenafadel@von.com detected", + "owner" : "demo", + "references" : [ { + "href" : "https://www.seniorleading-edge.name/users/efficient", + "name" : "recovery" + }, { + "href" : "http://www.dynamicseamless.com/clicks-and-mortar", + "name" : "force" + }, { + "href" : "http://www.leadscalable.biz/envisioneer", + "name" : "fund" + } ], + "schema" : "{}", + "status" : "closed", + "tickets" : [ { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8126, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "Surfaceintroduce virus detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.centralworld-class.io/synthesize", + "name" : "university" + }, { + "href" : "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name" : "goal" + }, { + "href" : "http://www.chiefsyndicate.io/action-items", + "name" : "unemployment" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + } ], + "type" : "alert" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Set ticket schema", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "schema" + } + }, + "/tickets/{id}/tickets" : { + "delete" : { + "operationId" : "unlinkTicket", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8126, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "format" : "int64", + "type" : "integer" + } + } + }, + "description" : "Added ticket ID", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8126, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "Surfaceintroduce virus detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.centralworld-class.io/synthesize", + "name" : "university" + }, { + "href" : "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name" : "goal" + }, { + "href" : "http://www.chiefsyndicate.io/action-items", + "name" : "unemployment" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Unlink an ticket to an ticket", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "linkedID" + }, + "patch" : { + "operationId" : "linkTicket", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8126, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "format" : "int64", + "type" : "integer" + } + } + }, + "description" : "Added ticket ID", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8126, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "Surfaceintroduce virus detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.centralworld-class.io/synthesize", + "name" : "university" + }, { + "href" : "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name" : "goal" + }, { + "href" : "http://www.chiefsyndicate.io/action-items", + "name" : "unemployment" + } ], + "schema" : "{}", + "status" : "closed", + "tickets" : [ { + "artifacts" : [ { + "name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status" : "unknown" + }, { + "name" : "http://www.customerviral.io/scalable/vertical/killer", + "status" : "clean" + }, { + "name" : "leadreintermediate.io", + "status" : "malicious" + } ], + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8123, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "live zebra", + "owner" : "demo", + "playbooks" : { + "phishing" : { + "name" : "Phishing", + "tasks" : { + "block-iocs" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block IOCs", + "type" : "task" + }, + "block-sender" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block sender", + "next" : { + "extract-iocs" : "" + }, + "type" : "task" + }, + "board" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Board Involvement?", + "next" : { + "escalate" : "boardInvolved == true", + "mail-available" : "boardInvolved == false" + }, + "schema" : { + "properties" : { + "boardInvolved" : { + "default" : false, + "title" : "A board member is involved.", + "type" : "boolean" + } + }, + "required" : [ "boardInvolved" ], + "title" : "Board Involvement?", + "type" : "object" + }, + "type" : "input" + }, + "escalate" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Escalate to CISO", + "type" : "task" + }, + "extract-iocs" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Extract IOCs", + "next" : { + "block-iocs" : "" + }, + "schema" : { + "properties" : { + "iocs" : { + "items" : { + "type" : "string" + }, + "title" : "IOCs", + "type" : "array" + } + }, + "title" : "Extract IOCs", + "type" : "object" + }, + "type" : "input" + }, + "mail-available" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Mail available", + "next" : { + "block-sender" : "schemaKey == 'yes'", + "extract-iocs" : "schemaKey == 'yes'", + "search-email-gateway" : "schemaKey == 'no'" + }, + "schema" : { + "oneOf" : [ { + "properties" : { + "mail" : { + "title" : "Mail", + "type" : "string", + "x-display" : "textarea" + }, + "schemaKey" : { + "const" : "yes", + "type" : "string" + } + }, + "required" : [ "mail" ], + "title" : "Yes" + }, { + "properties" : { + "schemaKey" : { + "const" : "no", + "type" : "string" + } + }, + "title" : "No" + } ], + "title" : "Mail available", + "type" : "object" + }, + "type" : "input" + }, + "search-email-gateway" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Search email gateway", + "next" : { + "extract-iocs" : "" + }, + "type" : "task" + } + } + } + }, + "references" : [ { + "href" : "https://www.leadmaximize.net/e-services/back-end", + "name" : "performance" + }, { + "href" : "http://www.corporateinteractive.name/rich", + "name" : "autumn" + }, { + "href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name" : "suggest" + } ], + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status" : "closed", + "type" : "incident" + }, { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8125, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "phishing from selenafadel@von.com detected", + "owner" : "demo", + "references" : [ { + "href" : "https://www.seniorleading-edge.name/users/efficient", + "name" : "recovery" + }, { + "href" : "http://www.dynamicseamless.com/clicks-and-mortar", + "name" : "force" + }, { + "href" : "http://www.leadscalable.biz/envisioneer", + "name" : "fund" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + } ], + "type" : "alert" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Link an ticket to an ticket", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "linkedID" + } + }, + "/tickets/batch" : { + "post" : { + "operationId" : "createTicketBatch", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/TicketForm" + }, + "type" : "array" + } + } + }, + "description" : "New ticket", + "required" : true + }, + "responses" : { + "204" : { + "content" : { }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Create a new tickets in batch", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "ticket" + } + }, + "/tickettypes" : { + "get" : { + "operationId" : "listTicketTypes", + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/TicketTypeResponse" + }, + "type" : "array" + } + }, + "test" : { + "example" : [ { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-alert", + "id" : "alert", + "name" : "Alerts" + }, { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-radioactive", + "id" : "incident", + "name" : "Incidents" + }, { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-fingerprint", + "id" : "investigation", + "name" : "Forensic Investigations" + }, { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-target", + "id" : "hunt", + "name" : "Threat Hunting" + } ] + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "tickettype:read" ] + } ], + "summary" : "List tickettypes", + "tags" : [ "tickettypes" ] + }, + "post" : { + "operationId" : "createTicketType", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketTypeForm" + } + } + }, + "description" : "New tickettype", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketTypeResponse" + } + }, + "test" : { + "example" : { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-newspaper-variant-outline", + "id" : "ti-tickets", + "name" : "TI Tickets" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "tickettype:write" ] + } ], + "summary" : "Create a new tickettype", + "tags" : [ "tickettypes" ], + "x-codegen-request-body-name" : "tickettype" + } + }, + "/tickettypes/{id}" : { + "delete" : { + "operationId" : "deleteTicketType", + "parameters" : [ { + "description" : "TicketType ID", + "example" : "alert", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "204" : { + "content" : { }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "tickettype:write" ] + } ], + "summary" : "Delete a tickettype", + "tags" : [ "tickettypes" ] + }, + "get" : { + "operationId" : "getTicketType", + "parameters" : [ { + "description" : "TicketType ID", + "example" : "alert", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketTypeResponse" + } + }, + "test" : { + "example" : { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-alert", + "id" : "alert", + "name" : "Alerts" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "tickettype:read" ] + } ], + "summary" : "Get a single tickettype", + "tags" : [ "tickettypes" ] + }, + "put" : { + "operationId" : "updateTicketType", + "parameters" : [ { + "description" : "TicketType ID", + "example" : "alert", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketTypeForm" + } + } + }, + "description" : "TicketType object that needs to be added", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketTypeResponse" + } + }, + "test" : { + "example" : { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-bell", + "id" : "alert", + "name" : "Alerts" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "tickettype:write" ] + } ], + "summary" : "Update an existing tickettype", + "tags" : [ "tickettypes" ], + "x-codegen-request-body-name" : "tickettype" + } + }, + "/userdata" : { + "get" : { + "operationId" : "listUserData", + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/UserDataResponse" + }, + "type" : "array" + } + }, + "test" : { + "example" : [ { + "email" : "bob@example.org", + "id" : "bob", + "name" : "Bob Bad" + } ] + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "userdata:read" ] + } ], + "summary" : "List userdata", + "tags" : [ "userdata" ] + } + }, + "/userdata/{id}" : { + "get" : { + "operationId" : "getUserData", + "parameters" : [ { + "description" : "User Data ID", + "example" : "bob", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserDataResponse" + } + }, + "test" : { + "example" : { + "email" : "bob@example.org", + "id" : "bob", + "name" : "Bob Bad" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "userdata:read" ] + } ], + "summary" : "Get a single user data", + "tags" : [ "userdata" ] + }, + "put" : { + "operationId" : "updateUserData", + "parameters" : [ { + "description" : "User Data ID", + "example" : "bob", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserData" + } + } + }, + "description" : "User data object that needs to be added", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserDataResponse" + } + }, + "test" : { + "example" : { + "email" : "bob@example.org", + "id" : "bob", + "name" : "Bob Bad" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "userdata:write" ] + } ], + "summary" : "Update an existing user data", + "tags" : [ "userdata" ], + "x-codegen-request-body-name" : "userdata" + } + }, + "/users" : { + "get" : { + "operationId" : "listUsers", + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/UserResponse" + }, + "type" : "array" + } + }, + "test" : { + "example" : [ { + "apikey" : false, + "blocked" : false, + "id" : "bob", + "roles" : [ "admin:backup:read", "admin:backup:restore", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + }, { + "apikey" : true, + "blocked" : false, + "id" : "script", + "roles" : [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + } ] + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "user:read" ] + } ], + "summary" : "List users", + "tags" : [ "users" ] + }, + "post" : { + "operationId" : "createUser", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserForm" + } + } + }, + "description" : "user object that needs to be added", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/NewUserResponse" + } + }, + "test" : { + "example" : { + "blocked" : false, + "id" : "syncscript", + "roles" : [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read" ], + "secret" : "v39bOuobnlEljfWzjAgoKzhmnh1xSMxH" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "user:write" ] + } ], + "summary" : "Create user", + "tags" : [ "users" ], + "x-codegen-request-body-name" : "user" + } + }, + "/users/{id}" : { + "delete" : { + "operationId" : "deleteUser", + "parameters" : [ { + "description" : "user ID", + "example" : "script", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "204" : { + "content" : { }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "user:write" ] + } ], + "summary" : "Delete user", + "tags" : [ "users" ] + }, + "get" : { + "operationId" : "getUser", + "parameters" : [ { + "description" : "user ID", + "example" : "script", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserResponse" + } + }, + "test" : { + "example" : { + "apikey" : true, + "blocked" : false, + "id" : "script", + "roles" : [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "user:read" ] + } ], + "summary" : "Get a single user", + "tags" : [ "users" ] + }, + "put" : { + "operationId" : "updateUser", + "parameters" : [ { + "description" : "Template ID", + "example" : "bob", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserForm" + } + } + }, + "description" : "user object that needs to be added", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserResponse" + } + }, + "test" : { + "example" : { + "apikey" : false, + "blocked" : false, + "id" : "bob", + "roles" : [ "admin:backup:read", "admin:backup:restore", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "user:write" ] + } ], + "summary" : "Update user", + "tags" : [ "users" ], + "x-codegen-request-body-name" : "user" + } + } + }, + "components" : { + "schemas" : { + "Artifact" : { + "properties" : { + "enrichments" : { + "additionalProperties" : { + "$ref" : "#/components/schemas/Enrichment" + }, + "type" : "object" + }, + "name" : { + "example" : "2.2.2.2", + "type" : "string" + }, + "status" : { + "example" : "Unknown", + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "required" : [ "name" ], + "type" : "object" + }, + "ArtifactOrigin" : { + "properties" : { + "artifact" : { + "type" : "string" + }, + "ticket_id" : { + "format" : "int64", + "type" : "integer" + } + }, + "required" : [ "artifact", "ticket_id" ], + "type" : "object" + }, + "Automation" : { + "properties" : { + "image" : { + "type" : "string" + }, + "schema" : { + "example" : "{}", + "type" : "string" + }, + "script" : { + "type" : "string" + }, + "type" : { + "items" : { + "enum" : [ "artifact", "playbook", "global" ], + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "image", "script", "type" ], + "type" : "object" + }, + "AutomationForm" : { + "properties" : { + "id" : { + "type" : "string" + }, + "image" : { + "type" : "string" + }, + "schema" : { + "example" : "{}", + "type" : "string" + }, + "script" : { + "type" : "string" + }, + "type" : { + "items" : { + "enum" : [ "artifact", "playbook", "global" ], + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "id", "image", "script", "type" ], + "type" : "object" + }, + "AutomationResponse" : { + "properties" : { + "id" : { + "type" : "string" + }, + "image" : { + "type" : "string" + }, + "schema" : { + "example" : "{}", + "type" : "string" + }, + "script" : { + "type" : "string" + }, + "type" : { + "items" : { + "enum" : [ "artifact", "playbook", "global" ], + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "id", "image", "script", "type" ], + "type" : "object" + }, + "Comment" : { + "properties" : { + "created" : { + "format" : "date-time", + "type" : "string" + }, + "creator" : { + "type" : "string" + }, + "message" : { + "type" : "string" + } + }, + "required" : [ "created", "creator", "message" ], + "type" : "object" + }, + "CommentForm" : { + "properties" : { + "created" : { + "format" : "date-time", + "type" : "string" + }, + "creator" : { + "type" : "string" + }, + "message" : { + "type" : "string" + } + }, + "required" : [ "message" ], + "type" : "object" + }, + "Context" : { + "properties" : { + "artifact" : { + "$ref" : "#/components/schemas/Artifact" + }, + "playbook" : { + "$ref" : "#/components/schemas/PlaybookResponse" + }, + "task" : { + "$ref" : "#/components/schemas/TaskResponse" + }, + "ticket" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "type" : "object" + }, + "Enrichment" : { + "properties" : { + "created" : { + "format" : "date-time", + "type" : "string" + }, + "data" : { + "example" : { + "hash" : "b7a067a742c20d07a7456646de89bc2d408a1153" + }, + "properties" : { }, + "type" : "object" + }, + "name" : { + "example" : "hash.sha1", + "type" : "string" + } + }, + "required" : [ "created", "data", "name" ], + "type" : "object" + }, + "EnrichmentForm" : { + "properties" : { + "data" : { + "example" : { + "hash" : "b7a067a742c20d07a7456646de89bc2d408a1153" + }, + "properties" : { }, + "type" : "object" + }, + "name" : { + "example" : "hash.sha1", + "type" : "string" + } + }, + "required" : [ "data", "name" ], + "type" : "object" + }, + "File" : { + "properties" : { + "key" : { + "example" : "myfile", + "type" : "string" + }, + "name" : { + "example" : "notes.docx", + "type" : "string" + } + }, + "required" : [ "key", "name" ], + "type" : "object" + }, + "Graph" : { + "properties" : { + "links" : { + "items" : { + "$ref" : "#/components/schemas/Link" + }, + "type" : "array" + }, + "nodes" : { + "items" : { + "$ref" : "#/components/schemas/Node" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "Group" : { + "properties" : { + "name" : { + "type" : "string" + }, + "users" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "name", "users" ], + "type" : "object" + }, + "GroupForm" : { + "properties" : { + "id" : { + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "users" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "name", "users" ], + "type" : "object" + }, + "GroupResponse" : { + "properties" : { + "id" : { + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "users" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "id", "name", "users" ], + "type" : "object" + }, + "Job" : { + "properties" : { + "automation" : { + "type" : "string" + }, + "container" : { + "type" : "string" + }, + "log" : { + "type" : "string" + }, + "origin" : { + "$ref" : "#/components/schemas/Origin" + }, + "output" : { + "properties" : { }, + "type" : "object" + }, + "payload" : { + "type" : "object" + }, + "running" : { + "type" : "boolean" + }, + "status" : { + "type" : "string" + } + }, + "required" : [ "automation", "running", "status" ], + "type" : "object" + }, + "JobForm" : { + "properties" : { + "automation" : { + "type" : "string" + }, + "origin" : { + "$ref" : "#/components/schemas/Origin" + }, + "payload" : { + "type" : "object" + } + }, + "required" : [ "automation" ], + "type" : "object" + }, + "JobResponse" : { + "properties" : { + "automation" : { + "type" : "string" + }, + "container" : { + "type" : "string" + }, + "id" : { + "type" : "string" + }, + "log" : { + "type" : "string" + }, + "origin" : { + "$ref" : "#/components/schemas/Origin" + }, + "output" : { + "properties" : { }, + "type" : "object" + }, + "payload" : { + "type" : "object" + }, + "status" : { + "type" : "string" + } + }, + "required" : [ "automation", "id", "status" ], + "type" : "object" + }, + "Link" : { + "properties" : { + "id" : { + "type" : "string" + }, + "sid" : { + "type" : "string" + }, + "tid" : { + "type" : "string" + } + }, + "required" : [ "id", "sid", "tid" ], + "type" : "object" + }, + "LogEntry" : { + "properties" : { + "created" : { + "format" : "date-time", + "type" : "string" + }, + "creator" : { + "type" : "string" + }, + "message" : { + "type" : "string" + }, + "reference" : { + "type" : "string" + } + }, + "required" : [ "created", "creator", "message", "reference" ], + "type" : "object" + }, + "Message" : { + "properties" : { + "context" : { + "$ref" : "#/components/schemas/Context" + }, + "payload" : { + "properties" : { }, + "type" : "object" + }, + "secrets" : { + "additionalProperties" : { + "type" : "string" + }, + "type" : "object" + } + }, + "type" : "object" + }, + "NewUserResponse" : { + "properties" : { + "blocked" : { + "type" : "boolean" + }, + "id" : { + "type" : "string" + }, + "roles" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "secret" : { + "type" : "string" + } + }, + "required" : [ "blocked", "id", "roles" ], + "type" : "object" + }, + "Node" : { + "properties" : { + "id" : { + "type" : "string" + }, + "name" : { + "type" : "string" + } + }, + "required" : [ "id", "name" ], + "type" : "object" + }, + "Origin" : { + "properties" : { + "artifact_origin" : { + "$ref" : "#/components/schemas/ArtifactOrigin" + }, + "task_origin" : { + "$ref" : "#/components/schemas/TaskOrigin" + } + }, + "type" : "object" + }, + "Playbook" : { + "properties" : { + "name" : { + "example" : "Phishing", + "type" : "string" + }, + "tasks" : { + "additionalProperties" : { + "$ref" : "#/components/schemas/Task" + }, + "type" : "object" + } + }, + "required" : [ "name", "tasks" ], + "type" : "object" + }, + "PlaybookResponse" : { + "properties" : { + "name" : { + "example" : "Phishing", + "type" : "string" + }, + "tasks" : { + "additionalProperties" : { + "$ref" : "#/components/schemas/TaskResponse" + }, + "type" : "object" + } + }, + "required" : [ "name", "tasks" ], + "type" : "object" + }, + "PlaybookTemplate" : { + "properties" : { + "name" : { + "type" : "string" + }, + "yaml" : { + "type" : "string" + } + }, + "required" : [ "name", "yaml" ], + "type" : "object" + }, + "PlaybookTemplateForm" : { + "properties" : { + "id" : { + "type" : "string" + }, + "yaml" : { + "type" : "string" + } + }, + "required" : [ "yaml" ], + "type" : "object" + }, + "PlaybookTemplateResponse" : { + "properties" : { + "id" : { + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "yaml" : { + "type" : "string" + } + }, + "required" : [ "id", "name", "yaml" ], + "type" : "object" + }, + "Reference" : { + "properties" : { + "href" : { + "example" : "https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2017-0144", + "type" : "string" + }, + "name" : { + "example" : "CVE-2017-0144", + "type" : "string" + } + }, + "required" : [ "href", "name" ], + "type" : "object" + }, + "Rule" : { + "properties" : { + "condition" : { + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "update" : { + "properties" : { }, + "type" : "object" + } + }, + "required" : [ "condition", "name", "update" ], + "type" : "object" + }, + "RuleForm" : { + "properties" : { + "condition" : { + "type" : "string" + }, + "id" : { + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "update" : { + "properties" : { }, + "type" : "object" + } + }, + "required" : [ "condition", "name", "update" ], + "type" : "object" + }, + "RuleResponse" : { + "properties" : { + "condition" : { + "type" : "string" + }, + "id" : { + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "update" : { + "properties" : { }, + "type" : "object" + } + }, + "required" : [ "condition", "id", "name", "update" ], + "type" : "object" + }, + "Settings" : { + "properties" : { + "artifactStates" : { + "items" : { + "$ref" : "#/components/schemas/Type" + }, + "title" : "Artifact States", + "type" : "array" + }, + "roles" : { + "items" : { + "type" : "string" + }, + "title" : "Roles", + "type" : "array" + }, + "ticketTypes" : { + "items" : { + "$ref" : "#/components/schemas/TicketTypeResponse" + }, + "title" : "Ticket Types", + "type" : "array" + }, + "tier" : { + "enum" : [ "community", "enterprise" ], + "title" : "Tier", + "type" : "string" + }, + "timeformat" : { + "title" : "Time Format", + "type" : "string" + }, + "version" : { + "title" : "Version", + "type" : "string" + } + }, + "required" : [ "artifactStates", "ticketTypes", "tier", "timeformat", "version" ], + "type" : "object" + }, + "Statistics" : { + "properties" : { + "open_tickets_per_user" : { + "additionalProperties" : { + "type" : "integer" + }, + "type" : "object" + }, + "tickets_per_type" : { + "additionalProperties" : { + "type" : "integer" + }, + "type" : "object" + }, + "tickets_per_week" : { + "additionalProperties" : { + "type" : "integer" + }, + "type" : "object" + }, + "unassigned" : { + "type" : "integer" + } + }, + "required" : [ "open_tickets_per_user", "tickets_per_type", "tickets_per_week", "unassigned" ], + "type" : "object" + }, + "Task" : { + "properties" : { + "automation" : { + "type" : "string" + }, + "closed" : { + "format" : "date-time", + "type" : "string" + }, + "created" : { + "format" : "date-time", + "type" : "string" + }, + "data" : { + "properties" : { }, + "type" : "object" + }, + "done" : { + "type" : "boolean" + }, + "join" : { + "example" : false, + "type" : "boolean" + }, + "name" : { + "example" : "Inform user", + "type" : "string" + }, + "next" : { + "additionalProperties" : { + "type" : "string" + }, + "type" : "object" + }, + "owner" : { + "type" : "string" + }, + "payload" : { + "additionalProperties" : { + "type" : "string" + }, + "type" : "object" + }, + "schema" : { + "properties" : { }, + "type" : "object" + }, + "type" : { + "enum" : [ "task", "input", "automation" ], + "example" : "task", + "type" : "string" + } + }, + "required" : [ "created", "done", "name", "type" ], + "type" : "object" + }, + "TaskForm" : { + "properties" : { + "automation" : { + "type" : "string" + }, + "closed" : { + "format" : "date-time", + "type" : "string" + }, + "created" : { + "format" : "date-time", + "type" : "string" + }, + "data" : { + "properties" : { }, + "type" : "object" + }, + "done" : { + "type" : "boolean" + }, + "join" : { + "example" : false, + "type" : "boolean" + }, + "name" : { + "example" : "Inform user", + "type" : "string" + }, + "next" : { + "additionalProperties" : { + "type" : "string" + }, + "type" : "object" + }, + "owner" : { + "type" : "string" + }, + "payload" : { + "additionalProperties" : { + "type" : "string" + }, + "type" : "object" + }, + "schema" : { + "properties" : { }, + "type" : "object" + }, + "type" : { + "enum" : [ "task", "input", "automation" ], + "example" : "task", + "type" : "string" + } + }, + "required" : [ "name", "type" ], + "type" : "object" + }, + "TaskOrigin" : { + "properties" : { + "playbook_id" : { + "type" : "string" + }, + "task_id" : { + "type" : "string" + }, + "ticket_id" : { + "format" : "int64", + "type" : "integer" + } + }, + "required" : [ "playbook_id", "task_id", "ticket_id" ], + "type" : "object" + }, + "TaskResponse" : { + "properties" : { + "active" : { + "example" : false, + "type" : "boolean" + }, + "automation" : { + "type" : "string" + }, + "closed" : { + "format" : "date-time", + "type" : "string" + }, + "created" : { + "format" : "date-time", + "type" : "string" + }, + "data" : { + "properties" : { }, + "type" : "object" + }, + "done" : { + "type" : "boolean" + }, + "join" : { + "example" : false, + "type" : "boolean" + }, + "name" : { + "example" : "Inform user", + "type" : "string" + }, + "next" : { + "additionalProperties" : { + "type" : "string" + }, + "type" : "object" + }, + "order" : { + "example" : 2.0, + "format" : "int64", + "type" : "number" + }, + "owner" : { + "type" : "string" + }, + "payload" : { + "additionalProperties" : { + "type" : "string" + }, + "type" : "object" + }, + "schema" : { + "properties" : { }, + "type" : "object" + }, + "type" : { + "enum" : [ "task", "input", "automation" ], + "example" : "task", + "type" : "string" + } + }, + "required" : [ "active", "created", "done", "name", "order", "type" ], + "type" : "object" + }, + "TaskWithContext" : { + "properties" : { + "playbook_id" : { + "type" : "string" + }, + "playbook_name" : { + "type" : "string" + }, + "task" : { + "$ref" : "#/components/schemas/TaskResponse" + }, + "task_id" : { + "type" : "string" + }, + "ticket_id" : { + "format" : "int64", + "type" : "number" + }, + "ticket_name" : { + "type" : "string" + } + }, + "required" : [ "playbook_id", "playbook_name", "task", "task_id", "ticket_id", "ticket_name" ], + "type" : "object" + }, + "Ticket" : { + "properties" : { + "artifacts" : { + "items" : { + "$ref" : "#/components/schemas/Artifact" + }, + "type" : "array" + }, + "comments" : { + "items" : { + "$ref" : "#/components/schemas/Comment" + }, + "type" : "array" + }, + "created" : { + "format" : "date-time", + "type" : "string" + }, + "details" : { + "example" : { + "description" : "my little incident" + }, + "properties" : { }, + "type" : "object" + }, + "files" : { + "items" : { + "$ref" : "#/components/schemas/File" + }, + "type" : "array" + }, + "modified" : { + "format" : "date-time", + "type" : "string" + }, + "name" : { + "example" : "WannyCry", + "type" : "string" + }, + "owner" : { + "example" : "bob", + "type" : "string" + }, + "playbooks" : { + "additionalProperties" : { + "$ref" : "#/components/schemas/Playbook" + }, + "type" : "object" + }, + "read" : { + "example" : [ "bob" ], + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "references" : { + "items" : { + "$ref" : "#/components/schemas/Reference" + }, + "type" : "array" + }, + "schema" : { + "example" : "{}", + "type" : "string" + }, + "status" : { + "example" : "open", + "type" : "string" + }, + "type" : { + "example" : "incident", + "type" : "string" + }, + "write" : { + "example" : [ "alice" ], + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "created", "modified", "name", "schema", "status", "type" ], + "type" : "object" + }, + "TicketForm" : { + "properties" : { + "artifacts" : { + "items" : { + "$ref" : "#/components/schemas/Artifact" + }, + "type" : "array" + }, + "comments" : { + "items" : { + "$ref" : "#/components/schemas/Comment" + }, + "type" : "array" + }, + "created" : { + "format" : "date-time", + "type" : "string" + }, + "details" : { + "example" : { + "description" : "my little incident" + }, + "properties" : { }, + "type" : "object" + }, + "files" : { + "items" : { + "$ref" : "#/components/schemas/File" + }, + "type" : "array" + }, + "id" : { + "example" : 123, + "format" : "int64", + "type" : "integer" + }, + "modified" : { + "format" : "date-time", + "type" : "string" + }, + "name" : { + "example" : "WannyCry", + "type" : "string" + }, + "owner" : { + "example" : "bob", + "type" : "string" + }, + "playbooks" : { + "items" : { + "$ref" : "#/components/schemas/PlaybookTemplateForm" + }, + "type" : "array" + }, + "read" : { + "example" : [ "bob" ], + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "references" : { + "items" : { + "$ref" : "#/components/schemas/Reference" + }, + "type" : "array" + }, + "schema" : { + "example" : "{}", + "type" : "string" + }, + "status" : { + "example" : "open", + "type" : "string" + }, + "type" : { + "example" : "incident", + "type" : "string" + }, + "write" : { + "example" : [ "alice" ], + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "name", "status", "type" ], + "type" : "object" + }, + "TicketList" : { + "properties" : { + "count" : { + "example" : 3.0, + "type" : "number" + }, + "tickets" : { + "items" : { + "$ref" : "#/components/schemas/TicketSimpleResponse" + }, + "type" : "array" + } + }, + "required" : [ "count", "tickets" ], + "type" : "object" + }, + "TicketResponse" : { + "properties" : { + "artifacts" : { + "items" : { + "$ref" : "#/components/schemas/Artifact" + }, + "type" : "array" + }, + "comments" : { + "items" : { + "$ref" : "#/components/schemas/Comment" + }, + "type" : "array" + }, + "created" : { + "format" : "date-time", + "type" : "string" + }, + "details" : { + "example" : { + "description" : "my little incident" + }, + "properties" : { }, + "type" : "object" + }, + "files" : { + "items" : { + "$ref" : "#/components/schemas/File" + }, + "type" : "array" + }, + "id" : { + "example" : 123, + "format" : "int64", + "type" : "integer" + }, + "modified" : { + "format" : "date-time", + "type" : "string" + }, + "name" : { + "example" : "WannyCry", + "type" : "string" + }, + "owner" : { + "example" : "bob", + "type" : "string" + }, + "playbooks" : { + "additionalProperties" : { + "$ref" : "#/components/schemas/PlaybookResponse" + }, + "type" : "object" + }, + "read" : { + "example" : [ "bob" ], + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "references" : { + "items" : { + "$ref" : "#/components/schemas/Reference" + }, + "type" : "array" + }, + "schema" : { + "example" : "{}", + "type" : "string" + }, + "status" : { + "example" : "open", + "type" : "string" + }, + "type" : { + "example" : "incident", + "type" : "string" + }, + "write" : { + "example" : [ "alice" ], + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "created", "id", "modified", "name", "schema", "status", "type" ], + "type" : "object" + }, + "TicketSimpleResponse" : { + "properties" : { + "artifacts" : { + "items" : { + "$ref" : "#/components/schemas/Artifact" + }, + "type" : "array" + }, + "comments" : { + "items" : { + "$ref" : "#/components/schemas/Comment" + }, + "type" : "array" + }, + "created" : { + "format" : "date-time", + "type" : "string" + }, + "details" : { + "example" : { + "description" : "my little incident" + }, + "properties" : { }, + "type" : "object" + }, + "files" : { + "items" : { + "$ref" : "#/components/schemas/File" + }, + "type" : "array" + }, + "id" : { + "example" : 123, + "format" : "int64", + "type" : "integer" + }, + "modified" : { + "format" : "date-time", + "type" : "string" + }, + "name" : { + "example" : "WannyCry", + "type" : "string" + }, + "owner" : { + "example" : "bob", + "type" : "string" + }, + "playbooks" : { + "additionalProperties" : { + "$ref" : "#/components/schemas/Playbook" + }, + "type" : "object" + }, + "read" : { + "example" : [ "bob" ], + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "references" : { + "items" : { + "$ref" : "#/components/schemas/Reference" + }, + "type" : "array" + }, + "schema" : { + "example" : "{}", + "type" : "string" + }, + "status" : { + "example" : "open", + "type" : "string" + }, + "type" : { + "example" : "incident", + "type" : "string" + }, + "write" : { + "example" : [ "alice" ], + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "created", "id", "modified", "name", "schema", "status", "type" ], + "type" : "object" + }, + "TicketTemplate" : { + "properties" : { + "name" : { + "type" : "string" + }, + "schema" : { + "type" : "string" + } + }, + "required" : [ "name", "schema" ], + "type" : "object" + }, + "TicketTemplateForm" : { + "properties" : { + "id" : { + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "schema" : { + "type" : "string" + } + }, + "required" : [ "name", "schema" ], + "type" : "object" + }, + "TicketTemplateResponse" : { + "properties" : { + "id" : { + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "schema" : { + "type" : "string" + } + }, + "required" : [ "id", "name", "schema" ], + "type" : "object" + }, + "TicketType" : { + "properties" : { + "default_groups" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "default_playbooks" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "default_template" : { + "type" : "string" + }, + "icon" : { + "type" : "string" + }, + "name" : { + "type" : "string" + } + }, + "required" : [ "default_playbooks", "default_template", "icon", "name" ], + "type" : "object" + }, + "TicketTypeForm" : { + "properties" : { + "default_groups" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "default_playbooks" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "default_template" : { + "type" : "string" + }, + "icon" : { + "type" : "string" + }, + "id" : { + "type" : "string" + }, + "name" : { + "type" : "string" + } + }, + "required" : [ "default_playbooks", "default_template", "icon", "name" ], + "type" : "object" + }, + "TicketTypeResponse" : { + "properties" : { + "default_groups" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "default_playbooks" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "default_template" : { + "type" : "string" + }, + "icon" : { + "type" : "string" + }, + "id" : { + "type" : "string" + }, + "name" : { + "type" : "string" + } + }, + "required" : [ "default_playbooks", "default_template", "icon", "id", "name" ], + "type" : "object" + }, + "TicketWithTickets" : { + "properties" : { + "artifacts" : { + "items" : { + "$ref" : "#/components/schemas/Artifact" + }, + "type" : "array" + }, + "comments" : { + "items" : { + "$ref" : "#/components/schemas/Comment" + }, + "type" : "array" + }, + "created" : { + "format" : "date-time", + "type" : "string" + }, + "details" : { + "example" : { + "description" : "my little incident" + }, + "properties" : { }, + "type" : "object" + }, + "files" : { + "items" : { + "$ref" : "#/components/schemas/File" + }, + "type" : "array" + }, + "id" : { + "example" : 123, + "format" : "int64", + "type" : "integer" + }, + "modified" : { + "format" : "date-time", + "type" : "string" + }, + "name" : { + "example" : "WannyCry", + "type" : "string" + }, + "owner" : { + "example" : "bob", + "type" : "string" + }, + "playbooks" : { + "additionalProperties" : { + "$ref" : "#/components/schemas/PlaybookResponse" + }, + "type" : "object" + }, + "read" : { + "example" : [ "bob" ], + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "references" : { + "items" : { + "$ref" : "#/components/schemas/Reference" + }, + "type" : "array" + }, + "schema" : { + "example" : "{}", + "type" : "string" + }, + "status" : { + "example" : "open", + "type" : "string" + }, + "tickets" : { + "items" : { + "$ref" : "#/components/schemas/TicketSimpleResponse" + }, + "type" : "array" + }, + "type" : { + "example" : "incident", + "type" : "string" + }, + "write" : { + "example" : [ "alice" ], + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "created", "id", "modified", "name", "schema", "status", "type" ], + "type" : "object" + }, + "Type" : { + "properties" : { + "color" : { + "enum" : [ "error", "info", "success", "warning" ], + "title" : "Color", + "type" : "string", + "x-cols" : 3 + }, + "icon" : { + "title" : "Icon (https://materialdesignicons.com)", + "type" : "string", + "x-cols" : 3, + "x-class" : "pr-2" + }, + "id" : { + "title" : "ID", + "type" : "string", + "x-cols" : 3, + "x-class" : "pr-2" + }, + "name" : { + "title" : "Name", + "type" : "string", + "x-cols" : 3, + "x-class" : "pr-2" + } + }, + "required" : [ "icon", "id", "name" ], + "type" : "object" + }, + "User" : { + "properties" : { + "apikey" : { + "type" : "boolean" + }, + "blocked" : { + "type" : "boolean" + }, + "roles" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "sha256" : { + "type" : "string" + } + }, + "required" : [ "apikey", "blocked", "roles" ], + "type" : "object" + }, + "UserData" : { + "properties" : { + "email" : { + "type" : "string" + }, + "image" : { + "type" : "string", + "x-display" : "custom-avatar" + }, + "name" : { + "type" : "string" + }, + "timeformat" : { + "title" : "Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens)", + "type" : "string" + } + }, + "type" : "object" + }, + "UserDataResponse" : { + "properties" : { + "email" : { + "type" : "string" + }, + "id" : { + "type" : "string" + }, + "image" : { + "type" : "string", + "x-display" : "custom-avatar" + }, + "name" : { + "type" : "string" + }, + "timeformat" : { + "title" : "Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens)", + "type" : "string" + } + }, + "required" : [ "id" ], + "type" : "object" + }, + "UserForm" : { + "properties" : { + "apikey" : { + "type" : "boolean" + }, + "blocked" : { + "type" : "boolean" + }, + "id" : { + "type" : "string" + }, + "roles" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "apikey", "blocked", "id", "roles" ], + "type" : "object" + }, + "UserResponse" : { + "properties" : { + "apikey" : { + "type" : "boolean" + }, + "blocked" : { + "type" : "boolean" + }, + "id" : { + "type" : "string" + }, + "roles" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "apikey", "blocked", "id", "roles" ], + "type" : "object" + } + } + }, + "x-original-swagger-version" : "2.0" +} \ No newline at end of file diff --git a/generated/catalyst.yml b/generated/catalyst.yml new file mode 100644 index 0000000..338752b --- /dev/null +++ b/generated/catalyst.yml @@ -0,0 +1,7058 @@ +basePath: /api +consumes: +- application/json +definitions: + Artifact: + properties: + enrichments: + additionalProperties: + $ref: '#/definitions/Enrichment' + type: object + name: + example: 2.2.2.2 + type: string + status: + example: Unknown + type: string + type: + type: string + required: + - name + type: object + ArtifactOrigin: + properties: + artifact: + type: string + ticket_id: + format: int64 + type: integer + required: + - ticket_id + - artifact + type: object + Automation: + properties: + image: + type: string + schema: + example: '{}' + type: string + script: + type: string + type: + items: + enum: + - artifact + - playbook + - global + type: string + type: array + required: + - image + - script + - type + type: object + AutomationForm: + properties: + id: + type: string + image: + type: string + schema: + example: '{}' + type: string + script: + type: string + type: + items: + enum: + - artifact + - playbook + - global + type: string + type: array + required: + - id + - image + - script + - type + type: object + AutomationResponse: + properties: + id: + type: string + image: + type: string + schema: + example: '{}' + type: string + script: + type: string + type: + items: + enum: + - artifact + - playbook + - global + type: string + type: array + required: + - id + - image + - script + - type + type: object + Comment: + properties: + created: + format: date-time + type: string + creator: + type: string + message: + type: string + required: + - creator + - created + - message + type: object + CommentForm: + properties: + created: + format: date-time + type: string + creator: + type: string + message: + type: string + required: + - message + type: object + Context: + properties: + artifact: + $ref: '#/definitions/Artifact' + playbook: + $ref: '#/definitions/PlaybookResponse' + task: + $ref: '#/definitions/TaskResponse' + ticket: + $ref: '#/definitions/TicketResponse' + type: object + Enrichment: + properties: + created: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + data: + example: + hash: b7a067a742c20d07a7456646de89bc2d408a1153 + type: object + name: + example: hash.sha1 + type: string + required: + - name + - data + - created + type: object + EnrichmentForm: + properties: + data: + example: + hash: b7a067a742c20d07a7456646de89bc2d408a1153 + type: object + name: + example: hash.sha1 + type: string + required: + - name + - data + type: object + File: + properties: + key: + example: myfile + type: string + name: + example: notes.docx + type: string + required: + - key + - name + type: object + Graph: + properties: + links: + items: + $ref: '#/definitions/Link' + type: array + nodes: + items: + $ref: '#/definitions/Node' + type: array + type: object + Group: + properties: + name: + type: string + users: + items: + type: string + type: array + required: + - name + - users + type: object + GroupForm: + properties: + id: + type: string + name: + type: string + users: + items: + type: string + type: array + required: + - name + - users + type: object + GroupResponse: + properties: + id: + type: string + name: + type: string + users: + items: + type: string + type: array + required: + - id + - name + - users + type: object + Job: + properties: + automation: + type: string + container: + type: string + log: + type: string + origin: + $ref: '#/definitions/Origin' + output: + type: object + payload: {} + running: + type: boolean + status: + type: string + required: + - automation + - running + - status + type: object + JobForm: + properties: + automation: + type: string + origin: + $ref: '#/definitions/Origin' + payload: {} + required: + - automation + type: object + JobResponse: + properties: + automation: + type: string + container: + type: string + id: + type: string + log: + type: string + origin: + $ref: '#/definitions/Origin' + output: + type: object + payload: {} + status: + type: string + required: + - id + - automation + - status + type: object + Link: + properties: + id: + type: string + sid: + type: string + tid: + type: string + required: + - id + - tid + - sid + type: object + LogEntry: + properties: + created: + format: date-time + type: string + creator: + type: string + message: + type: string + reference: + type: string + required: + - reference + - creator + - created + - message + type: object + Message: + properties: + context: + $ref: '#/definitions/Context' + payload: + type: object + secrets: + additionalProperties: + type: string + type: object + type: object + NewUserResponse: + properties: + blocked: + type: boolean + id: + type: string + roles: + items: + type: string + type: array + secret: + type: string + required: + - id + - blocked + - roles + type: object + Node: + properties: + id: + type: string + name: + type: string + required: + - id + - name + type: object + Origin: + properties: + artifact_origin: + $ref: '#/definitions/ArtifactOrigin' + task_origin: + $ref: '#/definitions/TaskOrigin' + type: object + Playbook: + properties: + name: + example: Phishing + type: string + tasks: + additionalProperties: + $ref: '#/definitions/Task' + type: object + required: + - name + - tasks + type: object + PlaybookResponse: + properties: + name: + example: Phishing + type: string + tasks: + additionalProperties: + $ref: '#/definitions/TaskResponse' + type: object + required: + - name + - tasks + type: object + PlaybookTemplate: + properties: + name: + type: string + yaml: + type: string + required: + - name + - yaml + type: object + PlaybookTemplateForm: + properties: + id: + type: string + yaml: + type: string + required: + - yaml + type: object + PlaybookTemplateResponse: + properties: + id: + type: string + name: + type: string + yaml: + type: string + required: + - id + - name + - yaml + type: object + Reference: + properties: + href: + example: https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2017-0144 + type: string + name: + example: CVE-2017-0144 + type: string + required: + - name + - href + type: object + Rule: + properties: + condition: + type: string + name: + type: string + update: + type: object + required: + - name + - condition + - update + type: object + RuleForm: + properties: + condition: + type: string + id: + type: string + name: + type: string + update: + type: object + required: + - name + - condition + - update + type: object + RuleResponse: + properties: + condition: + type: string + id: + type: string + name: + type: string + update: + type: object + required: + - id + - name + - condition + - update + type: object + Settings: + properties: + artifactStates: + items: + $ref: '#/definitions/Type' + title: Artifact States + type: array + roles: + items: + type: string + title: Roles + type: array + ticketTypes: + items: + $ref: '#/definitions/TicketTypeResponse' + title: Ticket Types + type: array + tier: + enum: + - community + - enterprise + title: Tier + type: string + timeformat: + title: Time Format + type: string + version: + title: Version + type: string + required: + - version + - tier + - timeformat + - ticketTypes + - artifactStates + type: object + Statistics: + properties: + open_tickets_per_user: + additionalProperties: + type: integer + type: object + tickets_per_type: + additionalProperties: + type: integer + type: object + tickets_per_week: + additionalProperties: + type: integer + type: object + unassigned: + type: integer + required: + - unassigned + - open_tickets_per_user + - tickets_per_week + - tickets_per_type + type: object + Task: + properties: + automation: + type: string + closed: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + created: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + data: + type: object + done: + type: boolean + join: + example: false + type: boolean + name: + example: Inform user + type: string + next: + additionalProperties: + type: string + type: object + owner: + type: string + payload: + additionalProperties: + type: string + type: object + schema: + type: object + type: + enum: + - task + - input + - automation + example: task + type: string + required: + - name + - type + - done + - created + type: object + TaskForm: + properties: + automation: + type: string + closed: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + created: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + data: + type: object + done: + type: boolean + join: + example: false + type: boolean + name: + example: Inform user + type: string + next: + additionalProperties: + type: string + type: object + owner: + type: string + payload: + additionalProperties: + type: string + type: object + schema: + type: object + type: + enum: + - task + - input + - automation + example: task + type: string + required: + - name + - type + type: object + TaskOrigin: + properties: + playbook_id: + type: string + task_id: + type: string + ticket_id: + format: int64 + type: integer + required: + - ticket_id + - playbook_id + - task_id + type: object + TaskResponse: + properties: + active: + example: false + type: boolean + automation: + type: string + closed: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + created: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + data: + type: object + done: + type: boolean + join: + example: false + type: boolean + name: + example: Inform user + type: string + next: + additionalProperties: + type: string + type: object + order: + example: 2 + format: int64 + type: number + owner: + type: string + payload: + additionalProperties: + type: string + type: object + schema: + type: object + type: + enum: + - task + - input + - automation + example: task + type: string + required: + - name + - type + - done + - created + - order + - active + type: object + TaskWithContext: + properties: + playbook_id: + type: string + playbook_name: + type: string + task: + $ref: '#/definitions/TaskResponse' + task_id: + type: string + ticket_id: + format: int64 + type: number + ticket_name: + type: string + required: + - ticket_id + - ticket_name + - playbook_id + - playbook_name + - task_id + - task + type: object + Ticket: + properties: + artifacts: + items: + $ref: '#/definitions/Artifact' + type: array + comments: + items: + $ref: '#/definitions/Comment' + type: array + created: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + details: + example: + description: my little incident + type: object + files: + items: + $ref: '#/definitions/File' + type: array + modified: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + name: + example: WannyCry + type: string + owner: + example: bob + type: string + playbooks: + additionalProperties: + $ref: '#/definitions/Playbook' + type: object + read: + example: + - bob + items: + type: string + type: array + references: + items: + $ref: '#/definitions/Reference' + type: array + schema: + example: '{}' + type: string + status: + example: open + type: string + type: + example: incident + type: string + write: + example: + - alice + items: + type: string + type: array + required: + - name + - type + - status + - created + - modified + - schema + type: object + TicketForm: + properties: + artifacts: + items: + $ref: '#/definitions/Artifact' + type: array + comments: + items: + $ref: '#/definitions/Comment' + type: array + created: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + details: + example: + description: my little incident + type: object + files: + items: + $ref: '#/definitions/File' + type: array + id: + example: 123 + format: int64 + type: integer + modified: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + name: + example: WannyCry + type: string + owner: + example: bob + type: string + playbooks: + items: + $ref: '#/definitions/PlaybookTemplateForm' + type: array + read: + example: + - bob + items: + type: string + type: array + references: + items: + $ref: '#/definitions/Reference' + type: array + schema: + example: '{}' + type: string + status: + example: open + type: string + type: + example: incident + type: string + write: + example: + - alice + items: + type: string + type: array + required: + - name + - type + - status + type: object + TicketList: + properties: + count: + example: 3 + type: number + tickets: + items: + $ref: '#/definitions/TicketSimpleResponse' + type: array + required: + - tickets + - count + type: object + TicketResponse: + properties: + artifacts: + items: + $ref: '#/definitions/Artifact' + type: array + comments: + items: + $ref: '#/definitions/Comment' + type: array + created: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + details: + example: + description: my little incident + type: object + files: + items: + $ref: '#/definitions/File' + type: array + id: + example: 123 + format: int64 + type: integer + modified: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + name: + example: WannyCry + type: string + owner: + example: bob + type: string + playbooks: + additionalProperties: + $ref: '#/definitions/PlaybookResponse' + type: object + read: + example: + - bob + items: + type: string + type: array + references: + items: + $ref: '#/definitions/Reference' + type: array + schema: + example: '{}' + type: string + status: + example: open + type: string + type: + example: incident + type: string + write: + example: + - alice + items: + type: string + type: array + required: + - id + - name + - type + - status + - created + - modified + - schema + type: object + TicketSimpleResponse: + properties: + artifacts: + items: + $ref: '#/definitions/Artifact' + type: array + comments: + items: + $ref: '#/definitions/Comment' + type: array + created: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + details: + example: + description: my little incident + type: object + files: + items: + $ref: '#/definitions/File' + type: array + id: + example: 123 + format: int64 + type: integer + modified: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + name: + example: WannyCry + type: string + owner: + example: bob + type: string + playbooks: + additionalProperties: + $ref: '#/definitions/Playbook' + type: object + read: + example: + - bob + items: + type: string + type: array + references: + items: + $ref: '#/definitions/Reference' + type: array + schema: + example: '{}' + type: string + status: + example: open + type: string + type: + example: incident + type: string + write: + example: + - alice + items: + type: string + type: array + required: + - id + - name + - type + - status + - created + - modified + - schema + type: object + TicketTemplate: + properties: + name: + type: string + schema: + type: string + required: + - name + - schema + type: object + TicketTemplateForm: + properties: + id: + type: string + name: + type: string + schema: + type: string + required: + - name + - schema + type: object + TicketTemplateResponse: + properties: + id: + type: string + name: + type: string + schema: + type: string + required: + - id + - name + - schema + type: object + TicketType: + properties: + default_groups: + items: + type: string + type: array + default_playbooks: + items: + type: string + type: array + default_template: + type: string + icon: + type: string + name: + type: string + required: + - name + - icon + - default_template + - default_playbooks + type: object + TicketTypeForm: + properties: + default_groups: + items: + type: string + type: array + default_playbooks: + items: + type: string + type: array + default_template: + type: string + icon: + type: string + id: + type: string + name: + type: string + required: + - name + - icon + - default_template + - default_playbooks + type: object + TicketTypeResponse: + properties: + default_groups: + items: + type: string + type: array + default_playbooks: + items: + type: string + type: array + default_template: + type: string + icon: + type: string + id: + type: string + name: + type: string + required: + - id + - name + - icon + - default_template + - default_playbooks + type: object + TicketWithTickets: + properties: + artifacts: + items: + $ref: '#/definitions/Artifact' + type: array + comments: + items: + $ref: '#/definitions/Comment' + type: array + created: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + details: + example: + description: my little incident + type: object + files: + items: + $ref: '#/definitions/File' + type: array + id: + example: 123 + format: int64 + type: integer + modified: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + name: + example: WannyCry + type: string + owner: + example: bob + type: string + playbooks: + additionalProperties: + $ref: '#/definitions/PlaybookResponse' + type: object + read: + example: + - bob + items: + type: string + type: array + references: + items: + $ref: '#/definitions/Reference' + type: array + schema: + example: '{}' + type: string + status: + example: open + type: string + tickets: + items: + $ref: '#/definitions/TicketSimpleResponse' + type: array + type: + example: incident + type: string + write: + example: + - alice + items: + type: string + type: array + required: + - id + - name + - type + - status + - created + - modified + - schema + type: object + Type: + properties: + color: + enum: + - error + - info + - success + - warning + title: Color + type: string + x-cols: 3 + icon: + title: Icon (https://materialdesignicons.com) + type: string + x-class: pr-2 + x-cols: 3 + id: + title: ID + type: string + x-class: pr-2 + x-cols: 3 + name: + title: Name + type: string + x-class: pr-2 + x-cols: 3 + required: + - id + - name + - icon + type: object + User: + properties: + apikey: + type: boolean + blocked: + type: boolean + roles: + items: + type: string + type: array + sha256: + type: string + required: + - blocked + - apikey + - roles + type: object + UserData: + properties: + email: + type: string + x-example: bob@example.org + image: + type: string + x-display: custom-avatar + name: + type: string + x-example: Robert Smith + timeformat: + title: Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens) + type: string + type: object + UserDataResponse: + properties: + email: + type: string + x-example: bob@example.org + id: + type: string + image: + type: string + x-display: custom-avatar + name: + type: string + x-example: Robert Smith + timeformat: + title: Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens) + type: string + required: + - id + type: object + UserForm: + properties: + apikey: + type: boolean + blocked: + type: boolean + id: + type: string + roles: + items: + type: string + type: array + required: + - id + - blocked + - roles + - apikey + type: object + UserResponse: + properties: + apikey: + type: boolean + blocked: + type: boolean + id: + type: string + roles: + items: + type: string + type: array + required: + - id + - blocked + - roles + - apikey + type: object +host: . +info: + description: API for the catalyst incident response platform. + title: "" + version: "" +paths: + /automations: + get: + operationId: listAutomations + responses: + "200": + description: successful operation + examples: + test: + - id: comment + image: docker.io/python:3 + script: "" + type: + - playbook + - id: hash.sha1 + image: docker.io/python:3 + schema: '{"title":"Input","type":"object","properties":{"default":{"type":"string","title":"Value"}},"required":["default"]}' + script: "" + type: + - global + - artifact + - playbook + - id: thehive + image: docker.io/python:3 + schema: '{"title":"TheHive credentials","type":"object","properties":{"thehiveurl":{"type":"string","title":"TheHive + URL (e.g. ''https://thehive.example.org'')"},"thehivekey":{"type":"string","title":"TheHive + API Key"},"skip_files":{"type":"boolean", "default": true, "title":"Skip + Files (much faster)"},"keep_ids":{"type":"boolean", "default": true, + "title":"Keep IDs and overwrite existing IDs"}},"required":["thehiveurl", + "thehivekey", "skip_files", "keep_ids"]}' + script: "" + type: + - global + - id: vt.hash + image: docker.io/python:3 + schema: '{"title":"Input","type":"object","properties":{"default":{"type":"string","title":"Value"}},"required":["default"]}' + script: "" + type: + - global + - artifact + - playbook + schema: + items: + $ref: '#/definitions/AutomationResponse' + type: array + security: + - roles: + - automation:read + summary: List automations + tags: + - automations + post: + operationId: createAutomation + parameters: + - description: New automation + in: body + name: automation + required: true + schema: + $ref: '#/definitions/AutomationForm' + x-example: + id: hash-sha-256 + image: docker.io/python:3 + script: | + import sys + import json + import hashlib + + + def run(msg): + sha256 = hashlib.sha256(msg['payload']['default'].encode('utf-8')) + return {'hash': sha256.hexdigest()} + + + print(json.dumps(run(json.loads(sys.argv[1])))) + type: + - global + responses: + "200": + description: successful operation + examples: + test: + id: hash-sha-256 + image: docker.io/python:3 + script: | + import sys + import json + import hashlib + + + def run(msg): + sha256 = hashlib.sha256(msg['payload']['default'].encode('utf-8')) + return {'hash': sha256.hexdigest()} + + + print(json.dumps(run(json.loads(sys.argv[1])))) + type: + - global + schema: + $ref: '#/definitions/AutomationResponse' + security: + - roles: + - automation:write + summary: Create a new automation + tags: + - automations + /automations/{id}: + delete: + operationId: deleteAutomation + parameters: + - description: Automation ID + in: path + name: id + required: true + type: string + x-example: hash.sha1 + responses: + "204": + description: successful operation + security: + - roles: + - automation:write + summary: Delete a automation + tags: + - automations + get: + operationId: getAutomation + parameters: + - description: Automation ID + in: path + name: id + required: true + type: string + x-example: hash.sha1 + responses: + "200": + description: successful operation + examples: + test: + id: hash.sha1 + image: docker.io/python:3 + schema: '{"title":"Input","type":"object","properties":{"default":{"type":"string","title":"Value"}},"required":["default"]}' + script: | + #!/usr/bin/env python + + import sys + import json + import hashlib + + + def run(msg): + sha1 = hashlib.sha1(msg['payload']['default'].encode('utf-8')) + return {"hash": sha1.hexdigest()} + + + print(json.dumps(run(json.loads(sys.argv[1])))) + type: + - global + - artifact + - playbook + schema: + $ref: '#/definitions/AutomationResponse' + security: + - roles: + - automation:read + summary: Get a single automation + tags: + - automations + put: + operationId: updateAutomation + parameters: + - description: Automation ID + in: path + name: id + required: true + type: string + x-example: hash.sha1 + - description: Automation object that needs to be added + in: body + name: automation + required: true + schema: + $ref: '#/definitions/AutomationForm' + x-example: + id: hash.sha1 + image: docker.io/python:3 + script: | + import sys + import json + import hashlib + + + def run(msg): + sha1 = hashlib.sha1(msg['payload'].encode('utf-8')) + return {'hash': sha1.hexdigest()} + + + print(json.dumps(run(json.loads(sys.argv[1])))) + type: + - global + - artifact + - playbook + responses: + "200": + description: successful operation + examples: + test: + id: hash.sha1 + image: docker.io/python:3 + script: | + import sys + import json + import hashlib + + + def run(msg): + sha1 = hashlib.sha1(msg['payload'].encode('utf-8')) + return {'hash': sha1.hexdigest()} + + + print(json.dumps(run(json.loads(sys.argv[1])))) + type: + - global + - artifact + - playbook + schema: + $ref: '#/definitions/AutomationResponse' + security: + - roles: + - automation:write + summary: Update an existing automation + tags: + - automations + /currentuser: + get: + operationId: currentUser + responses: + "200": + description: successful operation + examples: + test: + apikey: false + blocked: false + id: bob + roles: + - admin:backup:read + - admin:backup:restore + - admin:group:write + - admin:job:read + - admin:job:write + - admin:log:read + - admin:ticket:delete + - admin:user:write + - admin:userdata:read + - admin:userdata:write + - analyst:automation:read + - analyst:currentsettings:write + - analyst:currentuser:read + - analyst:currentuserdata:read + - analyst:file + - analyst:group:read + - analyst:playbook:read + - analyst:rule:read + - analyst:settings:read + - analyst:template:read + - analyst:ticket:read + - analyst:ticket:write + - analyst:tickettype:read + - analyst:user:read + - engineer:automation:write + - engineer:playbook:write + - engineer:rule:write + - engineer:template:write + - engineer:tickettype:write + schema: + $ref: '#/definitions/UserResponse' + security: + - roles: + - currentuser:read + summary: Get current user + tags: + - users + /currentuserdata: + get: + operationId: currentUserData + responses: + "200": + description: successful operation + examples: + test: + email: bob@example.org + id: bob + name: Bob Bad + schema: + $ref: '#/definitions/UserDataResponse' + security: + - roles: + - currentuserdata:read + summary: Get current user data + tags: + - userdata + put: + operationId: updateCurrentUserData + parameters: + - description: User data object that needs to be added + in: body + name: userdata + required: true + schema: + $ref: '#/definitions/UserData' + x-example: + email: bob@example.org + name: Bob Bad + responses: + "200": + description: successful operation + examples: + test: + email: bob@example.org + id: bob + name: Bob Bad + schema: + $ref: '#/definitions/UserDataResponse' + security: + - roles: + - currentuserdata:write + summary: Update current user data + tags: + - userdata + /graph/{col}/{id}: + get: + operationId: graph + parameters: + - description: Graph Start + in: path + name: col + required: true + type: string + x-example: tickets + - description: Graph Start + in: path + name: id + required: true + type: string + x-example: "88" + - description: Graph Start + in: query + name: depth + required: true + type: integer + x-example: 1 + responses: + "200": + description: successful operation + examples: + test: + links: + - id: "296239" + sid: tickets/88 + tid: artifacts/http%3A%2F%2Fwww.customerviral.io%2Fscalable%2Fvertical%2Fkiller + - id: "296240" + sid: tickets/88 + tid: artifacts/leadreintermediate.io + - id: "296242" + sid: tickets/88 + tid: artifacts/94d5cab6f5fe3422a447ab15436e7a672bc0c09a + nodes: + - id: artifacts/94d5cab6f5fe3422a447ab15436e7a672bc0c09a + name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + - id: artifacts/http%3A%2F%2Fwww.customerviral.io%2Fscalable%2Fvertical%2Fkiller + name: http://www.customerviral.io/scalable/vertical/killer + - id: artifacts/leadreintermediate.io + name: leadreintermediate.io + - id: tickets/88 + name: live zebra + schema: + $ref: '#/definitions/Graph' + security: + - roles: + - ticket:read + summary: Graph + tags: + - graph + /groups: + get: + operationId: listGroups + responses: + "200": + description: successful operation + schema: + items: + $ref: '#/definitions/Group' + type: array + security: + - roles: + - group:read + summary: List groups + tags: + - groups + post: + operationId: createGroup + parameters: + - description: New group + in: body + name: group + required: true + schema: + $ref: '#/definitions/GroupForm' + responses: + "200": + description: successful operation + schema: + $ref: '#/definitions/GroupResponse' + security: + - roles: + - group:write + summary: Create a new group + tags: + - groups + /groups/{id}: + delete: + operationId: deleteGroup + parameters: + - description: Group ID + in: path + name: id + required: true + type: string + responses: + "204": + description: successful operation + security: + - roles: + - group:write + summary: Delete a group + tags: + - groups + get: + operationId: getGroup + parameters: + - description: Group ID + in: path + name: id + required: true + type: string + responses: + "200": + description: successful operation + schema: + $ref: '#/definitions/GroupResponse' + security: + - roles: + - group:read + summary: Get a single group + tags: + - groups + put: + operationId: updateGroup + parameters: + - description: Group ID + in: path + name: id + required: true + type: string + - description: Group object that needs to be added + in: body + name: group + required: true + schema: + $ref: '#/definitions/Group' + responses: + "200": + description: successful operation + schema: + $ref: '#/definitions/Group' + security: + - roles: + - group:write + summary: Update an existing group + tags: + - groups + /jobs: + get: + operationId: listJobs + responses: + "200": + description: successful operation + examples: + test: + - automation: hash.sha1 + id: 99cd67131b48 + payload: test + status: created + schema: + items: + $ref: '#/definitions/JobResponse' + type: array + security: + - roles: + - job:read + summary: List jobs + tags: + - jobs + post: + operationId: runJob + parameters: + - description: New job + in: body + name: job + required: true + schema: + $ref: '#/definitions/JobForm' + x-example: + automation: hash.sha1 + message: + payload: test + responses: + "204": + description: successful operation + security: + - roles: + - job:write + summary: Start a new job + tags: + - jobs + /jobs/{id}: + get: + operationId: getJob + parameters: + - description: Job ID + in: path + name: id + required: true + type: string + x-example: 99cd67131b48 + responses: + "200": + description: successful operation + examples: + test: + automation: hash.sha1 + id: 99cd67131b48 + payload: test + status: created + schema: + $ref: '#/definitions/JobResponse' + security: + - roles: + - job:read + summary: Get a single job + tags: + - jobs + put: + operationId: updateJob + parameters: + - description: Job ID + in: path + name: id + required: true + type: string + x-example: 99cd67131b48 + - description: Job object that needs to be added + in: body + name: job + required: true + schema: + $ref: '#/definitions/Job' + x-example: + automation: hash.sha1 + id: 99cd67131b48 + payload: test + status: failed + responses: + "200": + description: successful operation + examples: + test: + automation: hash.sha1 + id: 99cd67131b48 + payload: test + status: failed + schema: + $ref: '#/definitions/JobResponse' + security: + - roles: + - job:write + summary: Update an existing job + tags: + - jobs + /logs/{reference}: + get: + operationId: getLogs + parameters: + - description: Reference + in: path + name: reference + required: true + type: string + x-example: tickets%2F294511 + responses: + "200": + description: successful operation + examples: + test: + - created: 2021-10-02T18:05:00.333535+02:00 + creator: bob + message: Fail run account resist lend solve incident centre priority + temperature. Cause change distribution examine location technique + shape partner milk customer. Rail tea plate soil report cook railway + interpretation breath action. Exercise dream accept park conclusion + addition shoot assistance may answer. Gold writer link stop combine + hear power name commitment operation. Determine lifespan support grow + degree henry exclude detail set religion. Direct library policy convention + chain retain discover ride walk student. Gather proposal select march + aspect play noise avoid encourage employ. Assessment preserve transport + combine wish influence income guess run stand. Charge limit crime + ignore statement foundation study issue stop claim. + reference: tickets/294511 + schema: + items: + $ref: '#/definitions/LogEntry' + type: array + security: + - roles: + - log:read + summary: Get log entries + tags: + - logs + /playbooks: + get: + operationId: listPlaybooks + responses: + "200": + description: successful operation + examples: + test: + - id: malware + name: Malware + yaml: | + name: Malware + tasks: + file-or-hash: + name: Do you have the file or the hash? + type: input + schema: + title: Malware + type: object + properties: + file: + type: string + title: "I have the" + enum: [ "File", "Hash" ] + next: + enter-hash: "file == 'Hash'" + upload: "file == 'File'" + + enter-hash: + name: Please enter the hash + type: input + schema: + title: Malware + type: object + properties: + hash: + type: string + title: Please enter the hash value + minlength: 32 + next: + virustotal: "hash != ''" + + upload: + name: Upload the malware + type: input + schema: + title: Malware + type: object + properties: + malware: + type: object + x-display: file + title: Please upload the malware + next: + hash: "malware" + + hash: + name: Hash the malware + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['upload'].data['malware']" + next: + virustotal: + + virustotal: + name: Send hash to VirusTotal + type: automation + automation: vt.hash + args: + hash: "playbook.tasks['enter-hash'].data['hash'] || playbook.tasks['hash'].data['hash']" + # next: + # known-malware: "score > 5" + # sandbox: "score < 6" # unknown-malware + - id: phishing + name: Phishing + yaml: | + name: Phishing + tasks: + board: + name: Board Involvement? + description: Is a board member involved? + type: input + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + next: + escalate: "boardInvolved == true" + mail-available: "boardInvolved == false" + + escalate: + name: Escalate to CISO + description: Please escalate the task to the CISO + type: task + + mail-available: + name: Mail available + type: input + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: 'yes' + type: string + required: + - mail + title: 'Yes' + - properties: + schemaKey: + const: 'no' + type: string + title: 'No' + title: Mail available + type: object + next: + block-sender: "schemaKey == 'yes'" + extract-iocs: "schemaKey == 'yes'" + search-email-gateway: "schemaKey == 'no'" + + search-email-gateway: + name: Search email gateway + description: Please search email-gateway for the phishing mail. + type: task + next: + extract-iocs: + + block-sender: + name: Block sender + type: task + next: + extract-iocs: + + extract-iocs: + name: Extract IOCs + description: Please insert the IOCs + type: input + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + next: + block-iocs: + + block-iocs: + name: Block IOCs + type: task + - id: simple + name: Simple + yaml: | + name: Simple + tasks: + input: + name: Enter something to hash + type: input + schema: + title: Something + type: object + properties: + something: + type: string + title: Something + default: "" + next: + hash: "something != ''" + + hash: + name: Hash the something + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['input'].data['something']" + next: + comment: "hash != ''" + + comment: + name: Comment the hash + type: automation + automation: comment + payload: + default: "playbook.tasks['hash'].data['hash']" + next: + done: "done" + + done: + name: You can close this case now + type: task + schema: + items: + $ref: '#/definitions/PlaybookTemplateResponse' + type: array + security: + - roles: + - playbook:read + summary: List playbooks + tags: + - playbooks + post: + operationId: createPlaybook + parameters: + - description: New playbook + in: body + name: playbook + required: true + schema: + $ref: '#/definitions/PlaybookTemplateForm' + x-example: + yaml: | + name: Simple2 + tasks: + input: + name: Upload malware if possible + type: input + schema: + title: Malware + type: object + properties: + malware: + type: string + title: Select malware + default: "" + next: + hash: "malware != ''" + + hash: + name: Hash the malware + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['input'].data['malware']" + next: + escalate: + + escalate: + name: Escalate to malware team + type: task + responses: + "200": + description: successful operation + examples: + test: + id: simple-2 + name: Simple2 + yaml: | + name: Simple2 + tasks: + input: + name: Upload malware if possible + type: input + schema: + title: Malware + type: object + properties: + malware: + type: string + title: Select malware + default: "" + next: + hash: "malware != ''" + + hash: + name: Hash the malware + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['input'].data['malware']" + next: + escalate: + + escalate: + name: Escalate to malware team + type: task + schema: + items: + $ref: '#/definitions/PlaybookTemplateResponse' + type: array + security: + - roles: + - playbook:write + summary: Create a playbook + tags: + - playbooks + /playbooks/{id}: + delete: + operationId: deletePlaybook + parameters: + - description: Playbook name + in: path + name: id + required: true + type: string + x-example: simple + responses: + "204": + description: successful operation + security: + - roles: + - playbook:write + summary: Delete a playbook + tags: + - playbooks + get: + operationId: getPlaybook + parameters: + - description: Playbook name + in: path + name: id + required: true + type: string + x-example: simple + responses: + "200": + description: successful operation + examples: + test: + id: simple + name: Simple + yaml: | + name: Simple + tasks: + input: + name: Enter something to hash + type: input + schema: + title: Something + type: object + properties: + something: + type: string + title: Something + default: "" + next: + hash: "something != ''" + + hash: + name: Hash the something + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['input'].data['something']" + next: + comment: "hash != ''" + + comment: + name: Comment the hash + type: automation + automation: comment + payload: + default: "playbook.tasks['hash'].data['hash']" + next: + done: "done" + + done: + name: You can close this case now + type: task + schema: + $ref: '#/definitions/PlaybookTemplateResponse' + security: + - roles: + - playbook:read + summary: Get a single playbook + tags: + - playbooks + put: + operationId: updatePlaybook + parameters: + - description: Playbook ID + in: path + name: id + required: true + type: string + x-example: simple + - description: Updated playbook + in: body + name: playbook + required: true + schema: + $ref: '#/definitions/PlaybookTemplateForm' + x-example: + yaml: | + name: Simple + tasks: + input: + name: Upload malware if possible + type: input + schema: + title: Malware + type: object + properties: + malware: + type: string + title: Select malware + default: "" + next: + hash: "malware != ''" + + hash: + name: Hash the malware + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['input'].data['malware']" + next: + escalate: + + escalate: + name: Escalate to malware team + type: task + responses: + "200": + description: successful operation + examples: + test: + id: simple + name: Simple + yaml: | + name: Simple + tasks: + input: + name: Upload malware if possible + type: input + schema: + title: Malware + type: object + properties: + malware: + type: string + title: Select malware + default: "" + next: + hash: "malware != ''" + + hash: + name: Hash the malware + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['input'].data['malware']" + next: + escalate: + + escalate: + name: Escalate to malware team + type: task + schema: + $ref: '#/definitions/PlaybookTemplateResponse' + security: + - roles: + - playbook:write + summary: Update an existing ticket playbook + tags: + - playbooks + /rules: + get: + operationId: listRules + responses: + "200": + description: successful operation + examples: + test: + - condition: type == 'alert' + id: ignore-alerts + name: Ignore Alerts + update: + status: closed + schema: + items: + $ref: '#/definitions/RuleResponse' + type: array + security: + - roles: + - rule:read + summary: List rules + tags: + - rules + post: + operationId: createRule + parameters: + - description: New rule + in: body + name: rule + required: true + schema: + $ref: '#/definitions/RuleForm' + x-example: + condition: type == 'alert' + name: Ignore all Alerts + update: + status: closed + responses: + "200": + description: successful operation + examples: + test: + condition: type == 'alert' + id: ignore-all-alerts + name: Ignore all Alerts + update: + status: closed + schema: + items: + $ref: '#/definitions/RuleResponse' + type: array + security: + - roles: + - rule:write + summary: Create a rule + tags: + - rules + /rules/{id}: + delete: + operationId: deleteRule + parameters: + - description: Rule name + in: path + name: id + required: true + type: string + x-example: ignore-alerts + responses: + "204": + description: successful operation + security: + - roles: + - rule:write + summary: Delete a rule + tags: + - rules + get: + operationId: getRule + parameters: + - description: Rule name + in: path + name: id + required: true + type: string + x-example: ignore-alerts + responses: + "200": + description: successful operation + examples: + test: + condition: type == 'alert' + id: ignore-alerts + name: Ignore Alerts + update: + status: closed + schema: + $ref: '#/definitions/RuleResponse' + security: + - roles: + - rule:read + summary: Get a single rule + tags: + - rules + put: + operationId: updateRule + parameters: + - description: Rule ID + in: path + name: id + required: true + type: string + x-example: ignore-alerts + - description: Updated rule + in: body + name: rule + required: true + schema: + $ref: '#/definitions/RuleForm' + x-example: + condition: type == 'alert' + name: Ignore Alerts + update: + status: invalid + responses: + "200": + description: successful operation + examples: + test: + condition: type == 'alert' + id: ignore-alerts + name: Ignore Alerts + update: + status: invalid + schema: + $ref: '#/definitions/RuleResponse' + security: + - roles: + - rule:write + summary: Update an existing ticket rule + tags: + - rules + /settings: + get: + operationId: getSettings + responses: + "200": + description: successful operation + examples: + test: + artifactStates: + - color: info + icon: mdi-help-circle-outline + id: unknown + name: Unknown + - color: error + icon: mdi-skull + id: malicious + name: Malicious + - color: success + icon: mdi-check + id: clean + name: Clean + roles: + - admin:backup:read + - admin:backup:restore + - admin:group:write + - admin:job:read + - admin:job:write + - admin:log:read + - admin:ticket:delete + - admin:user:write + - admin:userdata:read + - admin:userdata:write + - analyst:automation:read + - analyst:currentsettings:write + - analyst:currentuser:read + - analyst:currentuserdata:read + - analyst:file + - analyst:group:read + - analyst:playbook:read + - analyst:rule:read + - analyst:settings:read + - analyst:template:read + - analyst:ticket:read + - analyst:ticket:write + - analyst:tickettype:read + - analyst:user:read + - engineer:automation:write + - engineer:playbook:write + - engineer:rule:write + - engineer:template:write + - engineer:tickettype:write + ticketTypes: + - default_playbooks: [] + default_template: default + icon: mdi-alert + id: alert + name: Alerts + - default_playbooks: [] + default_template: default + icon: mdi-radioactive + id: incident + name: Incidents + - default_playbooks: [] + default_template: default + icon: mdi-fingerprint + id: investigation + name: Forensic Investigations + - default_playbooks: [] + default_template: default + icon: mdi-target + id: hunt + name: Threat Hunting + tier: community + timeformat: YYYY-MM-DDThh:mm:ss + version: 0.0.0-test + schema: + $ref: '#/definitions/Settings' + security: + - roles: + - settings:read + summary: Get settings + tags: + - settings + /statistics: + get: + operationId: getStatistics + responses: + "200": + description: successful operation + examples: + test: + open_tickets_per_user: {} + tickets_per_type: + alert: 2 + incident: 1 + tickets_per_week: + 2021-39: 3 + unassigned: 0 + schema: + $ref: '#/definitions/Statistics' + security: + - roles: + - ticket:read + summary: Get statistics + tags: + - statistics + /tasks: + get: + operationId: listTasks + responses: + "200": + description: successful operation + examples: + test: [] + schema: + items: + $ref: '#/definitions/TaskResponse' + type: array + security: + - roles: + - ticket:read + summary: List tasks + tags: + - tasks + /templates: + get: + operationId: listTemplates + responses: + "200": + description: successful operation + examples: + test: + - id: default + name: Default + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Default", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + schema: + items: + $ref: '#/definitions/TicketTemplateResponse' + type: array + security: + - roles: + - template:read + summary: List templates + tags: + - templates + post: + operationId: createTemplate + parameters: + - description: New template + in: body + name: template + required: true + schema: + $ref: '#/definitions/TicketTemplateForm' + x-example: + name: My Template + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + responses: + "200": + description: successful operation + examples: + test: + id: my-template + name: My Template + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + schema: + $ref: '#/definitions/TicketTemplateResponse' + security: + - roles: + - template:write + summary: Create a new template + tags: + - templates + /templates/{id}: + delete: + operationId: deleteTemplate + parameters: + - description: Template ID + in: path + name: id + required: true + type: string + x-example: default + responses: + "204": + description: successful operation + security: + - roles: + - template:write + summary: Delete a template + tags: + - templates + get: + operationId: getTemplate + parameters: + - description: Template ID + in: path + name: id + required: true + type: string + x-example: default + responses: + "200": + description: successful operation + examples: + test: + id: default + name: Default + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Default", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + schema: + $ref: '#/definitions/TicketTemplateResponse' + security: + - roles: + - template:read + summary: Get a single template + tags: + - templates + put: + operationId: updateTemplate + parameters: + - description: Template ID + in: path + name: id + required: true + type: string + x-example: default + - description: Template object that needs to be added + in: body + name: template + required: true + schema: + $ref: '#/definitions/TicketTemplateForm' + x-example: + name: My Template + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + responses: + "200": + description: successful operation + examples: + test: + id: default + name: My Template + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + schema: + $ref: '#/definitions/TicketTemplateResponse' + security: + - roles: + - template:write + summary: Update an existing template + tags: + - templates + /tickets: + get: + operationId: listTickets + parameters: + - description: Ticket Type + in: query + name: type + type: string + - default: 0 + description: Offset of the list + in: query + name: offset + type: integer + - default: 25 + description: Number of tickets + in: query + maximum: 100 + name: count + type: integer + - description: Sort columns + in: query + items: + type: string + name: sort + type: array + - description: Sort descending + in: query + items: + type: boolean + name: desc + type: array + - description: Search query + in: query + name: query + type: string + responses: + "200": + description: successful operation + examples: + test: + count: 3 + tickets: + - artifacts: + - name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + status: unknown + - name: http://www.customerviral.io/scalable/vertical/killer + status: clean + - name: leadreintermediate.io + status: malicious + created: 2021-10-02T18:04:59.078206+02:00 + id: 8123 + modified: 2021-10-02T18:04:59.078206+02:00 + name: live zebra + owner: demo + playbooks: + phishing: + name: Phishing + tasks: + block-iocs: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block IOCs + type: task + block-sender: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block sender + next: + extract-iocs: "" + type: task + board: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Board Involvement? + next: + escalate: boardInvolved == true + mail-available: boardInvolved == false + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + type: input + escalate: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Escalate to CISO + type: task + extract-iocs: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Extract IOCs + next: + block-iocs: "" + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + type: input + mail-available: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Mail available + next: + block-sender: schemaKey == 'yes' + extract-iocs: schemaKey == 'yes' + search-email-gateway: schemaKey == 'no' + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: "yes" + type: string + required: + - mail + title: "Yes" + - properties: + schemaKey: + const: "no" + type: string + title: "No" + title: Mail available + type: object + type: input + search-email-gateway: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Search email gateway + next: + extract-iocs: "" + type: task + references: + - href: https://www.leadmaximize.net/e-services/back-end + name: performance + - href: http://www.corporateinteractive.name/rich + name: autumn + - href: https://www.corporateintuitive.org/intuitive/platforms/integrate + name: suggest + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + status: closed + type: incident + - created: 2021-10-02T18:04:59.078186+02:00 + id: 8125 + modified: 2021-10-02T18:04:59.078186+02:00 + name: phishing from selenafadel@von.com detected + owner: demo + references: + - href: https://www.seniorleading-edge.name/users/efficient + name: recovery + - href: http://www.dynamicseamless.com/clicks-and-mortar + name: force + - href: http://www.leadscalable.biz/envisioneer + name: fund + schema: '{}' + status: closed + type: alert + - created: 2021-10-02T18:04:59.078186+02:00 + id: 8126 + modified: 2021-10-02T18:04:59.078186+02:00 + name: Surfaceintroduce virus detected + owner: demo + references: + - href: http://www.centralworld-class.io/synthesize + name: university + - href: https://www.futurevirtual.org/supply-chains/markets/sticky/iterate + name: goal + - href: http://www.chiefsyndicate.io/action-items + name: unemployment + schema: '{}' + status: closed + type: alert + schema: + $ref: '#/definitions/TicketList' + security: + - roles: + - ticket:read + summary: List tickets + tags: + - tickets + post: + operationId: createTicket + parameters: + - description: New ticket + in: body + name: ticket + required: true + schema: + $ref: '#/definitions/TicketForm' + x-example: + id: 123 + name: Wannacry infection + owner: bob + status: open + type: incident + responses: + "200": + description: successful operation + examples: + test: + created: 1985-04-12T23:20:50.52Z + id: 123 + modified: 1985-04-12T23:20:50.52Z + name: Wannacry infection + owner: bob + schema: '{}' + status: open + type: incident + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Create a new ticket + tags: + - tickets + /tickets/{id}: + delete: + operationId: deleteTicket + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8125 + responses: + "204": + description: successful operation + security: + - roles: + - ticket:delete + summary: Delete an ticket + tags: + - tickets + get: + operationId: getTicket + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8125 + responses: + "200": + description: successful operation + examples: + test: + created: 2021-10-02T18:04:59.078186+02:00 + id: 8125 + modified: 2021-10-02T18:04:59.078186+02:00 + name: phishing from selenafadel@von.com detected + owner: demo + references: + - href: https://www.seniorleading-edge.name/users/efficient + name: recovery + - href: http://www.dynamicseamless.com/clicks-and-mortar + name: force + - href: http://www.leadscalable.biz/envisioneer + name: fund + schema: '{}' + status: closed + tickets: + - created: 2021-10-02T18:04:59.078186+02:00 + id: 8126 + modified: 2021-10-02T18:04:59.078186+02:00 + name: Surfaceintroduce virus detected + owner: demo + references: + - href: http://www.centralworld-class.io/synthesize + name: university + - href: https://www.futurevirtual.org/supply-chains/markets/sticky/iterate + name: goal + - href: http://www.chiefsyndicate.io/action-items + name: unemployment + schema: '{}' + status: closed + type: alert + type: alert + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:read + summary: Get a single ticket + tags: + - tickets + put: + operationId: updateTicket + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8125 + - description: Updated ticket + in: body + name: ticket + required: true + schema: + $ref: '#/definitions/Ticket' + x-example: + created: 2021-10-02T18:04:59.078186+02:00 + modified: 2021-10-02T18:04:59.078186+02:00 + name: phishing from selenafadel@von.org detected + owner: demo + references: + - href: https://www.seniorleading-edge.name/users/efficient + name: recovery + - href: http://www.dynamicseamless.com/clicks-and-mortar + name: force + - href: http://www.leadscalable.biz/envisioneer + name: fund + schema: '{}' + status: closed + type: alert + responses: + "200": + description: successful operation + examples: + test: + created: 2021-10-02T18:04:59.078186+02:00 + id: 8125 + modified: 2021-10-02T18:04:59.078186+02:00 + name: phishing from selenafadel@von.org detected + owner: demo + references: + - href: https://www.seniorleading-edge.name/users/efficient + name: recovery + - href: http://www.dynamicseamless.com/clicks-and-mortar + name: force + - href: http://www.leadscalable.biz/envisioneer + name: fund + schema: '{}' + status: closed + tickets: + - created: 2021-10-02T18:04:59.078186+02:00 + id: 8126 + modified: 2021-10-02T18:04:59.078186+02:00 + name: Surfaceintroduce virus detected + owner: demo + references: + - href: http://www.centralworld-class.io/synthesize + name: university + - href: https://www.futurevirtual.org/supply-chains/markets/sticky/iterate + name: goal + - href: http://www.chiefsyndicate.io/action-items + name: unemployment + schema: '{}' + status: closed + type: alert + type: alert + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Update an existing ticket + tags: + - tickets + /tickets/{id}/artifacts: + post: + operationId: addArtifact + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - description: Artifact object that needs to be added + in: body + name: artifact + required: true + schema: + $ref: '#/definitions/Artifact' + x-example: + name: 2.2.2.2 + responses: + "200": + description: successful operation + examples: + test: + artifacts: + - name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + status: unknown + - name: http://www.customerviral.io/scalable/vertical/killer + status: clean + - name: leadreintermediate.io + status: malicious + - name: 2.2.2.2 + status: unknown + type: ip + created: 2021-10-02T18:04:59.078206+02:00 + id: 8123 + modified: 2021-10-02T18:04:59.078206+02:00 + name: live zebra + owner: demo + playbooks: + phishing: + name: Phishing + tasks: + block-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block IOCs + order: 6 + type: task + block-sender: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block sender + next: + extract-iocs: "" + order: 3 + type: task + board: + active: true + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Board Involvement? + next: + escalate: boardInvolved == true + mail-available: boardInvolved == false + order: 0 + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + type: input + escalate: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Escalate to CISO + order: 1 + type: task + extract-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Extract IOCs + next: + block-iocs: "" + order: 5 + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + type: input + mail-available: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Mail available + next: + block-sender: schemaKey == 'yes' + extract-iocs: schemaKey == 'yes' + search-email-gateway: schemaKey == 'no' + order: 2 + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: "yes" + type: string + required: + - mail + title: "Yes" + - properties: + schemaKey: + const: "no" + type: string + title: "No" + title: Mail available + type: object + type: input + search-email-gateway: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Search email gateway + next: + extract-iocs: "" + order: 4 + type: task + references: + - href: https://www.leadmaximize.net/e-services/back-end + name: performance + - href: http://www.corporateinteractive.name/rich + name: autumn + - href: https://www.corporateintuitive.org/intuitive/platforms/integrate + name: suggest + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + status: closed + type: incident + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Add a single artifact + tags: + - tickets + /tickets/{id}/artifacts/{name}: + delete: + operationId: removeArtifact + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - in: path + name: name + required: true + type: string + x-example: leadreintermediate.io + responses: + "200": + description: successful operation + examples: + test: + artifacts: + - name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + status: unknown + - name: http://www.customerviral.io/scalable/vertical/killer + status: clean + created: 2021-10-02T18:04:59.078206+02:00 + id: 8123 + modified: 2021-10-02T18:04:59.078206+02:00 + name: live zebra + owner: demo + playbooks: + phishing: + name: Phishing + tasks: + block-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block IOCs + order: 6 + type: task + block-sender: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block sender + next: + extract-iocs: "" + order: 3 + type: task + board: + active: true + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Board Involvement? + next: + escalate: boardInvolved == true + mail-available: boardInvolved == false + order: 0 + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + type: input + escalate: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Escalate to CISO + order: 1 + type: task + extract-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Extract IOCs + next: + block-iocs: "" + order: 5 + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + type: input + mail-available: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Mail available + next: + block-sender: schemaKey == 'yes' + extract-iocs: schemaKey == 'yes' + search-email-gateway: schemaKey == 'no' + order: 2 + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: "yes" + type: string + required: + - mail + title: "Yes" + - properties: + schemaKey: + const: "no" + type: string + title: "No" + title: Mail available + type: object + type: input + search-email-gateway: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Search email gateway + next: + extract-iocs: "" + order: 4 + type: task + references: + - href: https://www.leadmaximize.net/e-services/back-end + name: performance + - href: http://www.corporateinteractive.name/rich + name: autumn + - href: https://www.corporateintuitive.org/intuitive/platforms/integrate + name: suggest + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + status: closed + type: incident + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Remove an artifact + tags: + - tickets + get: + operationId: getArtifact + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - in: path + name: name + required: true + type: string + x-example: leadreintermediate.io + responses: + "200": + description: successful operation + examples: + test: + name: leadreintermediate.io + status: malicious + schema: + $ref: '#/definitions/Artifact' + security: + - roles: + - ticket:write + summary: Get a single artifact + tags: + - tickets + put: + operationId: setArtifact + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - in: path + name: name + required: true + type: string + x-example: leadreintermediate.io + - in: body + name: artifact + required: true + schema: + $ref: '#/definitions/Artifact' + x-example: + name: leadreintermediate.io + status: clean + responses: + "200": + description: successful operation + examples: + test: + artifacts: + - name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + status: unknown + - name: http://www.customerviral.io/scalable/vertical/killer + status: clean + - name: leadreintermediate.io + status: clean + created: 2021-10-02T18:04:59.078206+02:00 + id: 8123 + modified: 2021-10-02T18:04:59.078206+02:00 + name: live zebra + owner: demo + playbooks: + phishing: + name: Phishing + tasks: + block-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block IOCs + order: 6 + type: task + block-sender: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block sender + next: + extract-iocs: "" + order: 3 + type: task + board: + active: true + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Board Involvement? + next: + escalate: boardInvolved == true + mail-available: boardInvolved == false + order: 0 + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + type: input + escalate: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Escalate to CISO + order: 1 + type: task + extract-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Extract IOCs + next: + block-iocs: "" + order: 5 + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + type: input + mail-available: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Mail available + next: + block-sender: schemaKey == 'yes' + extract-iocs: schemaKey == 'yes' + search-email-gateway: schemaKey == 'no' + order: 2 + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: "yes" + type: string + required: + - mail + title: "Yes" + - properties: + schemaKey: + const: "no" + type: string + title: "No" + title: Mail available + type: object + type: input + search-email-gateway: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Search email gateway + next: + extract-iocs: "" + order: 4 + type: task + references: + - href: https://www.leadmaximize.net/e-services/back-end + name: performance + - href: http://www.corporateinteractive.name/rich + name: autumn + - href: https://www.corporateintuitive.org/intuitive/platforms/integrate + name: suggest + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + status: closed + type: incident + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Set a single artifact + tags: + - tickets + /tickets/{id}/artifacts/{name}/enrich: + post: + operationId: enrichArtifact + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - in: path + name: name + required: true + type: string + x-example: leadreintermediate.io + - in: body + name: data + required: true + schema: + $ref: '#/definitions/EnrichmentForm' + x-example: + data: + hash: b7a067a742c20d07a7456646de89bc2d408a1153 + name: hash.sha1 + responses: + "200": + description: successful operation + examples: + test: + artifacts: + - name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + status: unknown + - name: http://www.customerviral.io/scalable/vertical/killer + status: clean + - enrichments: + hash.sha1: + created: 2021-10-03T18:44:06.488923+02:00 + data: + hash: b7a067a742c20d07a7456646de89bc2d408a1153 + name: hash.sha1 + name: leadreintermediate.io + status: malicious + created: 2021-10-02T18:04:59.078206+02:00 + id: 8123 + modified: 2021-10-02T18:04:59.078206+02:00 + name: live zebra + owner: demo + playbooks: + phishing: + name: Phishing + tasks: + block-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block IOCs + order: 6 + type: task + block-sender: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block sender + next: + extract-iocs: "" + order: 3 + type: task + board: + active: true + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Board Involvement? + next: + escalate: boardInvolved == true + mail-available: boardInvolved == false + order: 0 + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + type: input + escalate: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Escalate to CISO + order: 1 + type: task + extract-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Extract IOCs + next: + block-iocs: "" + order: 5 + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + type: input + mail-available: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Mail available + next: + block-sender: schemaKey == 'yes' + extract-iocs: schemaKey == 'yes' + search-email-gateway: schemaKey == 'no' + order: 2 + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: "yes" + type: string + required: + - mail + title: "Yes" + - properties: + schemaKey: + const: "no" + type: string + title: "No" + title: Mail available + type: object + type: input + search-email-gateway: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Search email gateway + next: + extract-iocs: "" + order: 4 + type: task + references: + - href: https://www.leadmaximize.net/e-services/back-end + name: performance + - href: http://www.corporateinteractive.name/rich + name: autumn + - href: https://www.corporateintuitive.org/intuitive/platforms/integrate + name: suggest + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + status: closed + type: incident + schema: + $ref: '#/definitions/Artifact' + security: + - roles: + - ticket:write + summary: Enrich a single artifact + tags: + - tickets + /tickets/{id}/artifacts/{name}/run/{automation}: + post: + operationId: runArtifact + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - in: path + name: name + required: true + type: string + x-example: leadreintermediate.io + - in: path + name: automation + required: true + type: string + x-example: hash.sha1 + responses: + "204": + description: successful operation + security: + - roles: + - ticket:write + summary: Run automation on a single artifact + tags: + - tickets + /tickets/{id}/comments: + post: + operationId: addComment + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8125 + - description: Ticket comment + in: body + name: comment + required: true + schema: + $ref: '#/definitions/CommentForm' + x-example: + message: My first comment + responses: + "200": + description: successful operation + examples: + test: + comments: + - created: 2021-10-02T18:04:59.078186+02:00 + creator: bob + message: My first comment + created: 2021-10-02T18:04:59.078186+02:00 + id: 8125 + modified: 2021-10-02T18:04:59.078186+02:00 + name: phishing from selenafadel@von.com detected + owner: demo + references: + - href: https://www.seniorleading-edge.name/users/efficient + name: recovery + - href: http://www.dynamicseamless.com/clicks-and-mortar + name: force + - href: http://www.leadscalable.biz/envisioneer + name: fund + schema: '{}' + status: closed + tickets: + - created: 2021-10-02T18:04:59.078186+02:00 + id: 8126 + modified: 2021-10-02T18:04:59.078186+02:00 + name: Surfaceintroduce virus detected + owner: demo + references: + - href: http://www.centralworld-class.io/synthesize + name: university + - href: https://www.futurevirtual.org/supply-chains/markets/sticky/iterate + name: goal + - href: http://www.chiefsyndicate.io/action-items + name: unemployment + schema: '{}' + status: closed + type: alert + type: alert + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Add ticket comment + tags: + - tickets + /tickets/{id}/comments/{commentID}: + delete: + description: Comment will be removed from the ticket. + operationId: removeComment + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - description: Comment ID to remove + in: path + name: commentID + required: true + type: integer + x-example: 0 + responses: + "200": + description: successful operation + examples: + test: + artifacts: + - name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + status: unknown + - name: http://www.customerviral.io/scalable/vertical/killer + status: clean + - name: leadreintermediate.io + status: malicious + created: 2021-10-02T18:04:59.078206+02:00 + id: 8123 + modified: 2021-10-02T18:04:59.078206+02:00 + name: live zebra + owner: demo + playbooks: + phishing: + name: Phishing + tasks: + block-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block IOCs + order: 6 + type: task + block-sender: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block sender + next: + extract-iocs: "" + order: 3 + type: task + board: + active: true + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Board Involvement? + next: + escalate: boardInvolved == true + mail-available: boardInvolved == false + order: 0 + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + type: input + escalate: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Escalate to CISO + order: 1 + type: task + extract-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Extract IOCs + next: + block-iocs: "" + order: 5 + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + type: input + mail-available: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Mail available + next: + block-sender: schemaKey == 'yes' + extract-iocs: schemaKey == 'yes' + search-email-gateway: schemaKey == 'no' + order: 2 + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: "yes" + type: string + required: + - mail + title: "Yes" + - properties: + schemaKey: + const: "no" + type: string + title: "No" + title: Mail available + type: object + type: input + search-email-gateway: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Search email gateway + next: + extract-iocs: "" + order: 4 + type: task + references: + - href: https://www.leadmaximize.net/e-services/back-end + name: performance + - href: http://www.corporateinteractive.name/rich + name: autumn + - href: https://www.corporateintuitive.org/intuitive/platforms/integrate + name: suggest + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + status: closed + type: incident + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Remove an comment from an ticket + tags: + - tickets + /tickets/{id}/files: + put: + description: Link files to an ticket. The files themself will be stored in object + storage. + operationId: linkFiles + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8125 + - description: Added files + in: body + name: files + required: true + schema: + items: + $ref: '#/definitions/File' + type: array + x-example: + - key: myfile + name: document.doc + responses: + "200": + description: successful operation + examples: + test: + created: 2021-10-02T18:04:59.078186+02:00 + files: + - key: myfile + name: document.doc + id: 8125 + modified: 2021-10-02T18:04:59.078186+02:00 + name: phishing from selenafadel@von.com detected + owner: demo + references: + - href: https://www.seniorleading-edge.name/users/efficient + name: recovery + - href: http://www.dynamicseamless.com/clicks-and-mortar + name: force + - href: http://www.leadscalable.biz/envisioneer + name: fund + schema: '{}' + status: closed + tickets: + - created: 2021-10-02T18:04:59.078186+02:00 + id: 8126 + modified: 2021-10-02T18:04:59.078186+02:00 + name: Surfaceintroduce virus detected + owner: demo + references: + - href: http://www.centralworld-class.io/synthesize + name: university + - href: https://www.futurevirtual.org/supply-chains/markets/sticky/iterate + name: goal + - href: http://www.chiefsyndicate.io/action-items + name: unemployment + schema: '{}' + status: closed + type: alert + type: alert + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Link files to an ticket + tags: + - tickets + /tickets/{id}/playbooks: + post: + operationId: addTicketPlaybook + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8125 + - description: Ticket playbook object that needs to be added + in: body + name: playbook + required: true + schema: + $ref: '#/definitions/PlaybookTemplateForm' + x-example: + yaml: | + name: Simple + tasks: + input: + name: Upload malware if possible + type: input + schema: + title: Malware + type: object + properties: + malware: + type: string + title: Select malware + default: "" + next: + hash: "malware != ''" + + hash: + name: Hash the malware + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['input'].data['malware']" + next: + escalate: + + escalate: + name: Escalate to malware team + type: task + responses: + "200": + description: successful operation + examples: + test: + created: 1985-04-12T23:20:50.52Z + id: 8125 + modified: 1985-04-12T23:20:50.52Z + name: phishing from selenafadel@von.com detected + owner: demo + playbooks: + simple: + name: Simple + tasks: + escalate: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Escalate to malware team + order: 2 + type: task + hash: + active: false + automation: hash.sha1 + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Hash the malware + next: + escalate: "" + order: 1 + payload: + default: playbook.tasks['input'].data['malware'] + type: automation + input: + active: true + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Upload malware if possible + next: + hash: malware != '' + order: 0 + schema: + properties: + malware: + default: "" + title: Select malware + type: string + title: Malware + type: object + type: input + references: + - href: https://www.seniorleading-edge.name/users/efficient + name: recovery + - href: http://www.dynamicseamless.com/clicks-and-mortar + name: force + - href: http://www.leadscalable.biz/envisioneer + name: fund + schema: '{}' + status: closed + tickets: + - created: 2021-10-02T18:04:59.078186+02:00 + id: 8126 + modified: 2021-10-02T18:04:59.078186+02:00 + name: Surfaceintroduce virus detected + owner: demo + references: + - href: http://www.centralworld-class.io/synthesize + name: university + - href: https://www.futurevirtual.org/supply-chains/markets/sticky/iterate + name: goal + - href: http://www.chiefsyndicate.io/action-items + name: unemployment + schema: '{}' + status: closed + type: alert + type: alert + schema: + $ref: '#/definitions/TicketResponse' + summary: Add a new ticket playbook + tags: + - tickets + /tickets/{id}/playbooks/{playbookID}: + delete: + operationId: removeTicketPlaybook + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - description: Playbook ID + in: path + name: playbookID + required: true + type: string + x-example: phishing + responses: + "200": + description: successful operation + examples: + test: + artifacts: + - name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + status: unknown + - name: http://www.customerviral.io/scalable/vertical/killer + status: clean + - name: leadreintermediate.io + status: malicious + created: 1985-04-12T23:20:50.52Z + id: 8123 + modified: 1985-04-12T23:20:50.52Z + name: live zebra + owner: demo + references: + - href: https://www.leadmaximize.net/e-services/back-end + name: performance + - href: http://www.corporateinteractive.name/rich + name: autumn + - href: https://www.corporateintuitive.org/intuitive/platforms/integrate + name: suggest + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + status: closed + type: incident + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Remove an ticket playbook + tags: + - tickets + /tickets/{id}/playbooks/{playbookID}/task/{taskID}: + put: + operationId: setTask + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - description: Playbook ID + in: path + name: playbookID + required: true + type: string + x-example: phishing + - description: Task ID + in: path + name: taskID + required: true + type: string + x-example: board + - description: Task + in: body + name: task + required: true + schema: + $ref: '#/definitions/Task' + x-example: + active: true + data: + boardInvolved: true + done: false + name: Board Involvement? + next: + escalate: boardInvolved == true + mail-available: boardInvolved == false + order: 0 + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + type: input + responses: + "200": + description: successful operation + examples: + test: + artifacts: + - name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + status: unknown + - name: http://www.customerviral.io/scalable/vertical/killer + status: clean + - name: leadreintermediate.io + status: malicious + created: 2021-10-02T18:04:59.078206+02:00 + id: 8123 + modified: 2021-10-02T18:04:59.078206+02:00 + name: live zebra + owner: demo + playbooks: + phishing: + name: Phishing + tasks: + block-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block IOCs + order: 6 + type: task + block-sender: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block sender + next: + extract-iocs: "" + order: 3 + type: task + board: + active: true + created: 2021-10-02T18:04:59.078186+02:00 + data: + boardInvolved: true + done: false + name: Board Involvement? + next: + escalate: boardInvolved == true + mail-available: boardInvolved == false + order: 0 + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + type: input + escalate: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Escalate to CISO + order: 1 + type: task + extract-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Extract IOCs + next: + block-iocs: "" + order: 5 + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + type: input + mail-available: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Mail available + next: + block-sender: schemaKey == 'yes' + extract-iocs: schemaKey == 'yes' + search-email-gateway: schemaKey == 'no' + order: 2 + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: "yes" + type: string + required: + - mail + title: "Yes" + - properties: + schemaKey: + const: "no" + type: string + title: "No" + title: Mail available + type: object + type: input + search-email-gateway: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Search email gateway + next: + extract-iocs: "" + order: 4 + type: task + references: + - href: https://www.leadmaximize.net/e-services/back-end + name: performance + - href: http://www.corporateinteractive.name/rich + name: autumn + - href: https://www.corporateintuitive.org/intuitive/platforms/integrate + name: suggest + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + status: closed + type: incident + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Set a ticket playbook task + tags: + - tickets + /tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete: + put: + operationId: completeTask + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - description: Playbook ID + in: path + name: playbookID + required: true + type: string + x-example: phishing + - description: Task ID + in: path + name: taskID + required: true + type: string + x-example: board + - description: Ticket playbook object that needs to be added + in: body + name: data + required: true + schema: + type: object + x-example: + boardInvolved: true + responses: + "200": + description: successful operation + examples: + test: + artifacts: + - name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + status: unknown + - name: http://www.customerviral.io/scalable/vertical/killer + status: clean + - name: leadreintermediate.io + status: malicious + created: 2021-10-02T18:04:59.078206+02:00 + id: 8123 + modified: 2021-10-02T18:04:59.078206+02:00 + name: live zebra + owner: demo + playbooks: + phishing: + name: Phishing + tasks: + block-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block IOCs + order: 6 + type: task + block-sender: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block sender + next: + extract-iocs: "" + order: 3 + type: task + board: + active: false + closed: 2021-10-02T18:04:59.078186+02:00 + created: 2021-10-02T18:04:59.078186+02:00 + data: + boardInvolved: true + done: true + name: Board Involvement? + next: + escalate: boardInvolved == true + mail-available: boardInvolved == false + order: 0 + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + type: input + escalate: + active: true + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Escalate to CISO + order: 1 + type: task + extract-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Extract IOCs + next: + block-iocs: "" + order: 5 + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + type: input + mail-available: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Mail available + next: + block-sender: schemaKey == 'yes' + extract-iocs: schemaKey == 'yes' + search-email-gateway: schemaKey == 'no' + order: 2 + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: "yes" + type: string + required: + - mail + title: "Yes" + - properties: + schemaKey: + const: "no" + type: string + title: "No" + title: Mail available + type: object + type: input + search-email-gateway: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Search email gateway + next: + extract-iocs: "" + order: 4 + type: task + references: + - href: https://www.leadmaximize.net/e-services/back-end + name: performance + - href: http://www.corporateinteractive.name/rich + name: autumn + - href: https://www.corporateintuitive.org/intuitive/platforms/integrate + name: suggest + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + status: closed + type: incident + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Complete ticket playbook task + tags: + - tickets + /tickets/{id}/playbooks/{playbookID}/task/{taskID}/run: + post: + operationId: runTask + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - description: Playbook ID + in: path + name: playbookID + required: true + type: string + x-example: phishing + - description: Task ID + in: path + name: taskID + required: true + type: string + x-example: board + responses: + "204": + description: successful operation + security: + - roles: + - ticket:write + summary: Run ticket playbook task + tags: + - tickets + /tickets/{id}/references: + put: + operationId: setReferences + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8125 + - description: All ticket references + in: body + name: references + required: true + schema: + items: + $ref: '#/definitions/Reference' + type: array + x-example: + - href: http://www.leadscalable.biz/envisioneer + name: fund + responses: + "200": + description: successful operation + examples: + test: + created: 2021-10-02T18:04:59.078186+02:00 + id: 8125 + modified: 2021-10-02T18:04:59.078186+02:00 + name: phishing from selenafadel@von.com detected + owner: demo + references: + - href: http://www.leadscalable.biz/envisioneer + name: fund + schema: '{}' + status: closed + tickets: + - created: 2021-10-02T18:04:59.078186+02:00 + id: 8126 + modified: 2021-10-02T18:04:59.078186+02:00 + name: Surfaceintroduce virus detected + owner: demo + references: + - href: http://www.centralworld-class.io/synthesize + name: university + - href: https://www.futurevirtual.org/supply-chains/markets/sticky/iterate + name: goal + - href: http://www.chiefsyndicate.io/action-items + name: unemployment + schema: '{}' + status: closed + type: alert + type: alert + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Set ticket references + tags: + - tickets + /tickets/{id}/schema: + put: + operationId: setSchema + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8125 + - description: New ticket schema + in: body + name: schema + schema: + type: string + x-example: '{}' + responses: + "200": + description: successful operation + examples: + test: + created: 2021-10-02T18:04:59.078186+02:00 + id: 8125 + modified: 2021-10-02T18:04:59.078186+02:00 + name: phishing from selenafadel@von.com detected + owner: demo + references: + - href: https://www.seniorleading-edge.name/users/efficient + name: recovery + - href: http://www.dynamicseamless.com/clicks-and-mortar + name: force + - href: http://www.leadscalable.biz/envisioneer + name: fund + schema: '{}' + status: closed + tickets: + - created: 2021-10-02T18:04:59.078186+02:00 + id: 8126 + modified: 2021-10-02T18:04:59.078186+02:00 + name: Surfaceintroduce virus detected + owner: demo + references: + - href: http://www.centralworld-class.io/synthesize + name: university + - href: https://www.futurevirtual.org/supply-chains/markets/sticky/iterate + name: goal + - href: http://www.chiefsyndicate.io/action-items + name: unemployment + schema: '{}' + status: closed + type: alert + type: alert + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Set ticket schema + tags: + - tickets + /tickets/{id}/tickets: + delete: + operationId: unlinkTicket + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8126 + - description: Added ticket ID + in: body + name: linkedID + required: true + schema: + format: int64 + type: integer + x-example: 8125 + responses: + "200": + description: successful operation + examples: + test: + created: 2021-10-02T18:04:59.078186+02:00 + id: 8126 + modified: 2021-10-02T18:04:59.078186+02:00 + name: Surfaceintroduce virus detected + owner: demo + references: + - href: http://www.centralworld-class.io/synthesize + name: university + - href: https://www.futurevirtual.org/supply-chains/markets/sticky/iterate + name: goal + - href: http://www.chiefsyndicate.io/action-items + name: unemployment + schema: '{}' + status: closed + type: alert + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Unlink an ticket to an ticket + tags: + - tickets + patch: + operationId: linkTicket + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8126 + - description: Added ticket ID + in: body + name: linkedID + required: true + schema: + format: int64 + type: integer + x-example: 8123 + responses: + "200": + description: successful operation + examples: + test: + created: 2021-10-02T18:04:59.078186+02:00 + id: 8126 + modified: 2021-10-02T18:04:59.078186+02:00 + name: Surfaceintroduce virus detected + owner: demo + references: + - href: http://www.centralworld-class.io/synthesize + name: university + - href: https://www.futurevirtual.org/supply-chains/markets/sticky/iterate + name: goal + - href: http://www.chiefsyndicate.io/action-items + name: unemployment + schema: '{}' + status: closed + tickets: + - artifacts: + - name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + status: unknown + - name: http://www.customerviral.io/scalable/vertical/killer + status: clean + - name: leadreintermediate.io + status: malicious + created: 2021-10-02T18:04:59.078206+02:00 + id: 8123 + modified: 2021-10-02T18:04:59.078206+02:00 + name: live zebra + owner: demo + playbooks: + phishing: + name: Phishing + tasks: + block-iocs: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block IOCs + type: task + block-sender: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block sender + next: + extract-iocs: "" + type: task + board: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Board Involvement? + next: + escalate: boardInvolved == true + mail-available: boardInvolved == false + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + type: input + escalate: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Escalate to CISO + type: task + extract-iocs: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Extract IOCs + next: + block-iocs: "" + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + type: input + mail-available: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Mail available + next: + block-sender: schemaKey == 'yes' + extract-iocs: schemaKey == 'yes' + search-email-gateway: schemaKey == 'no' + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: "yes" + type: string + required: + - mail + title: "Yes" + - properties: + schemaKey: + const: "no" + type: string + title: "No" + title: Mail available + type: object + type: input + search-email-gateway: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Search email gateway + next: + extract-iocs: "" + type: task + references: + - href: https://www.leadmaximize.net/e-services/back-end + name: performance + - href: http://www.corporateinteractive.name/rich + name: autumn + - href: https://www.corporateintuitive.org/intuitive/platforms/integrate + name: suggest + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + status: closed + type: incident + - created: 2021-10-02T18:04:59.078186+02:00 + id: 8125 + modified: 2021-10-02T18:04:59.078186+02:00 + name: phishing from selenafadel@von.com detected + owner: demo + references: + - href: https://www.seniorleading-edge.name/users/efficient + name: recovery + - href: http://www.dynamicseamless.com/clicks-and-mortar + name: force + - href: http://www.leadscalable.biz/envisioneer + name: fund + schema: '{}' + status: closed + type: alert + type: alert + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Link an ticket to an ticket + tags: + - tickets + /tickets/batch: + post: + operationId: createTicketBatch + parameters: + - description: New ticket + in: body + name: ticket + required: true + schema: + items: + $ref: '#/definitions/TicketForm' + type: array + x-example: + - id: 123 + name: Wannacry infection + owner: bob + status: open + type: incident + responses: + "204": + description: successful operation + security: + - roles: + - ticket:write + summary: Create a new tickets in batch + tags: + - tickets + /tickettypes: + get: + operationId: listTicketTypes + responses: + "200": + description: successful operation + examples: + test: + - default_playbooks: [] + default_template: default + icon: mdi-alert + id: alert + name: Alerts + - default_playbooks: [] + default_template: default + icon: mdi-radioactive + id: incident + name: Incidents + - default_playbooks: [] + default_template: default + icon: mdi-fingerprint + id: investigation + name: Forensic Investigations + - default_playbooks: [] + default_template: default + icon: mdi-target + id: hunt + name: Threat Hunting + schema: + items: + $ref: '#/definitions/TicketTypeResponse' + type: array + security: + - roles: + - tickettype:read + summary: List tickettypes + tags: + - tickettypes + post: + operationId: createTicketType + parameters: + - description: New tickettype + in: body + name: tickettype + required: true + schema: + $ref: '#/definitions/TicketTypeForm' + x-example: + default_playbooks: [] + default_template: default + icon: mdi-newspaper-variant-outline + name: TI Tickets + responses: + "200": + description: successful operation + examples: + test: + default_playbooks: [] + default_template: default + icon: mdi-newspaper-variant-outline + id: ti-tickets + name: TI Tickets + schema: + $ref: '#/definitions/TicketTypeResponse' + security: + - roles: + - tickettype:write + summary: Create a new tickettype + tags: + - tickettypes + /tickettypes/{id}: + delete: + operationId: deleteTicketType + parameters: + - description: TicketType ID + in: path + name: id + required: true + type: string + x-example: alert + responses: + "204": + description: successful operation + security: + - roles: + - tickettype:write + summary: Delete a tickettype + tags: + - tickettypes + get: + operationId: getTicketType + parameters: + - description: TicketType ID + in: path + name: id + required: true + type: string + x-example: alert + responses: + "200": + description: successful operation + examples: + test: + default_playbooks: [] + default_template: default + icon: mdi-alert + id: alert + name: Alerts + schema: + $ref: '#/definitions/TicketTypeResponse' + security: + - roles: + - tickettype:read + summary: Get a single tickettype + tags: + - tickettypes + put: + operationId: updateTicketType + parameters: + - description: TicketType ID + in: path + name: id + required: true + type: string + x-example: alert + - description: TicketType object that needs to be added + in: body + name: tickettype + required: true + schema: + $ref: '#/definitions/TicketTypeForm' + x-example: + default_playbooks: [] + default_template: default + icon: mdi-bell + id: alert + name: Alerts + responses: + "200": + description: successful operation + examples: + test: + default_playbooks: [] + default_template: default + icon: mdi-bell + id: alert + name: Alerts + schema: + $ref: '#/definitions/TicketTypeResponse' + security: + - roles: + - tickettype:write + summary: Update an existing tickettype + tags: + - tickettypes + /userdata: + get: + operationId: listUserData + responses: + "200": + description: successful operation + examples: + test: + - email: bob@example.org + id: bob + name: Bob Bad + schema: + items: + $ref: '#/definitions/UserDataResponse' + type: array + security: + - roles: + - userdata:read + summary: List userdata + tags: + - userdata + /userdata/{id}: + get: + operationId: getUserData + parameters: + - description: User Data ID + in: path + name: id + required: true + type: string + x-example: bob + responses: + "200": + description: successful operation + examples: + test: + email: bob@example.org + id: bob + name: Bob Bad + schema: + $ref: '#/definitions/UserDataResponse' + security: + - roles: + - userdata:read + summary: Get a single user data + tags: + - userdata + put: + operationId: updateUserData + parameters: + - description: User Data ID + in: path + name: id + required: true + type: string + x-example: bob + - description: User data object that needs to be added + in: body + name: userdata + required: true + schema: + $ref: '#/definitions/UserData' + x-example: + blocked: false + email: bob@example.org + name: Bob Bad + responses: + "200": + description: successful operation + examples: + test: + email: bob@example.org + id: bob + name: Bob Bad + schema: + $ref: '#/definitions/UserDataResponse' + security: + - roles: + - userdata:write + summary: Update an existing user data + tags: + - userdata + /users: + get: + operationId: listUsers + responses: + "200": + description: successful operation + examples: + test: + - apikey: false + blocked: false + id: bob + roles: + - admin:backup:read + - admin:backup:restore + - admin:group:write + - admin:job:read + - admin:job:write + - admin:log:read + - admin:ticket:delete + - admin:user:write + - admin:userdata:read + - admin:userdata:write + - analyst:automation:read + - analyst:currentsettings:write + - analyst:currentuser:read + - analyst:currentuserdata:read + - analyst:file + - analyst:group:read + - analyst:playbook:read + - analyst:rule:read + - analyst:settings:read + - analyst:template:read + - analyst:ticket:read + - analyst:ticket:write + - analyst:tickettype:read + - analyst:user:read + - engineer:automation:write + - engineer:playbook:write + - engineer:rule:write + - engineer:template:write + - engineer:tickettype:write + - apikey: true + blocked: false + id: script + roles: + - analyst:automation:read + - analyst:currentsettings:write + - analyst:currentuser:read + - analyst:currentuserdata:read + - analyst:file + - analyst:group:read + - analyst:playbook:read + - analyst:rule:read + - analyst:settings:read + - analyst:template:read + - analyst:ticket:read + - analyst:ticket:write + - analyst:tickettype:read + - analyst:user:read + - engineer:automation:write + - engineer:playbook:write + - engineer:rule:write + - engineer:template:write + - engineer:tickettype:write + schema: + items: + $ref: '#/definitions/UserResponse' + type: array + security: + - roles: + - user:read + summary: List users + tags: + - users + post: + operationId: createUser + parameters: + - description: user object that needs to be added + in: body + name: user + required: true + schema: + $ref: '#/definitions/UserForm' + x-example: + id: syncscript + roles: + - analyst + responses: + "200": + description: successful operation + examples: + test: + blocked: false + id: syncscript + roles: + - analyst:automation:read + - analyst:currentsettings:write + - analyst:currentuser:read + - analyst:currentuserdata:read + - analyst:file + - analyst:group:read + - analyst:playbook:read + - analyst:rule:read + - analyst:settings:read + - analyst:template:read + - analyst:ticket:read + - analyst:ticket:write + - analyst:tickettype:read + - analyst:user:read + secret: v39bOuobnlEljfWzjAgoKzhmnh1xSMxH + schema: + $ref: '#/definitions/NewUserResponse' + security: + - roles: + - user:write + summary: Create user + tags: + - users + /users/{id}: + delete: + operationId: deleteUser + parameters: + - description: user ID + in: path + name: id + required: true + type: string + x-example: script + responses: + "204": + description: successful operation + security: + - roles: + - user:write + summary: Delete user + tags: + - users + get: + operationId: getUser + parameters: + - description: user ID + in: path + name: id + required: true + type: string + x-example: script + responses: + "200": + description: successful operation + examples: + test: + apikey: true + blocked: false + id: script + roles: + - analyst:automation:read + - analyst:currentsettings:write + - analyst:currentuser:read + - analyst:currentuserdata:read + - analyst:file + - analyst:group:read + - analyst:playbook:read + - analyst:rule:read + - analyst:settings:read + - analyst:template:read + - analyst:ticket:read + - analyst:ticket:write + - analyst:tickettype:read + - analyst:user:read + - engineer:automation:write + - engineer:playbook:write + - engineer:rule:write + - engineer:template:write + - engineer:tickettype:write + schema: + $ref: '#/definitions/UserResponse' + security: + - roles: + - user:read + summary: Get a single user + tags: + - users + put: + operationId: updateUser + parameters: + - description: Template ID + in: path + name: id + required: true + type: string + x-example: bob + - description: user object that needs to be added + in: body + name: user + required: true + schema: + $ref: '#/definitions/UserForm' + x-example: + roles: + - analyst + - admin + responses: + "200": + description: successful operation + examples: + test: + apikey: false + blocked: false + id: bob + roles: + - admin:backup:read + - admin:backup:restore + - admin:group:write + - admin:job:read + - admin:job:write + - admin:log:read + - admin:ticket:delete + - admin:user:write + - admin:userdata:read + - admin:userdata:write + - analyst:automation:read + - analyst:currentsettings:write + - analyst:currentuser:read + - analyst:currentuserdata:read + - analyst:file + - analyst:group:read + - analyst:playbook:read + - analyst:rule:read + - analyst:settings:read + - analyst:template:read + - analyst:ticket:read + - analyst:ticket:write + - analyst:tickettype:read + - analyst:user:read + - engineer:automation:write + - engineer:playbook:write + - engineer:rule:write + - engineer:template:write + - engineer:tickettype:write + schema: + $ref: '#/definitions/UserResponse' + security: + - roles: + - user:write + summary: Update user + tags: + - users +produces: +- application/json +schemes: +- http +swagger: "2.0" + diff --git a/generated/community.json b/generated/community.json new file mode 100644 index 0000000..b5eac50 --- /dev/null +++ b/generated/community.json @@ -0,0 +1,6067 @@ +{ + "openapi" : "3.0.1", + "info" : { + "description" : "API for the catalyst incident response platform.", + "title" : "", + "version" : "" + }, + "servers" : [ { + "url" : "http://./api" + } ], + "paths" : { + "/automations" : { + "get" : { + "operationId" : "listAutomations", + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/AutomationResponse" + }, + "type" : "array" + } + }, + "test" : { + "example" : [ { + "id" : "comment", + "image" : "docker.io/python:3", + "script" : "", + "type" : [ "playbook" ] + }, { + "id" : "hash.sha1", + "image" : "docker.io/python:3", + "schema" : "{\"title\":\"Input\",\"type\":\"object\",\"properties\":{\"default\":{\"type\":\"string\",\"title\":\"Value\"}},\"required\":[\"default\"]}", + "script" : "", + "type" : [ "global", "artifact", "playbook" ] + }, { + "id" : "thehive", + "image" : "docker.io/python:3", + "schema" : "{\"title\":\"TheHive credentials\",\"type\":\"object\",\"properties\":{\"thehiveurl\":{\"type\":\"string\",\"title\":\"TheHive URL (e.g. 'https://thehive.example.org')\"},\"thehivekey\":{\"type\":\"string\",\"title\":\"TheHive API Key\"},\"skip_files\":{\"type\":\"boolean\", \"default\": true, \"title\":\"Skip Files (much faster)\"},\"keep_ids\":{\"type\":\"boolean\", \"default\": true, \"title\":\"Keep IDs and overwrite existing IDs\"}},\"required\":[\"thehiveurl\", \"thehivekey\", \"skip_files\", \"keep_ids\"]}", + "script" : "", + "type" : [ "global" ] + }, { + "id" : "vt.hash", + "image" : "docker.io/python:3", + "schema" : "{\"title\":\"Input\",\"type\":\"object\",\"properties\":{\"default\":{\"type\":\"string\",\"title\":\"Value\"}},\"required\":[\"default\"]}", + "script" : "", + "type" : [ "global", "artifact", "playbook" ] + } ] + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "automation:read" ] + } ], + "summary" : "List automations", + "tags" : [ "automations" ] + }, + "post" : { + "operationId" : "createAutomation", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/AutomationForm" + } + } + }, + "description" : "New automation", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/AutomationResponse" + } + }, + "test" : { + "example" : { + "id" : "hash-sha-256", + "image" : "docker.io/python:3", + "script" : "import sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha256 = hashlib.sha256(msg['payload']['default'].encode('utf-8'))\n return {'hash': sha256.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", + "type" : [ "global" ] + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "automation:write" ] + } ], + "summary" : "Create a new automation", + "tags" : [ "automations" ], + "x-codegen-request-body-name" : "automation" + } + }, + "/automations/{id}" : { + "delete" : { + "operationId" : "deleteAutomation", + "parameters" : [ { + "description" : "Automation ID", + "example" : "hash.sha1", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "204" : { + "content" : { }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "automation:write" ] + } ], + "summary" : "Delete a automation", + "tags" : [ "automations" ] + }, + "get" : { + "operationId" : "getAutomation", + "parameters" : [ { + "description" : "Automation ID", + "example" : "hash.sha1", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/AutomationResponse" + } + }, + "test" : { + "example" : { + "id" : "hash.sha1", + "image" : "docker.io/python:3", + "schema" : "{\"title\":\"Input\",\"type\":\"object\",\"properties\":{\"default\":{\"type\":\"string\",\"title\":\"Value\"}},\"required\":[\"default\"]}", + "script" : "#!/usr/bin/env python\n\nimport sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha1 = hashlib.sha1(msg['payload']['default'].encode('utf-8'))\n return {\"hash\": sha1.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", + "type" : [ "global", "artifact", "playbook" ] + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "automation:read" ] + } ], + "summary" : "Get a single automation", + "tags" : [ "automations" ] + }, + "put" : { + "operationId" : "updateAutomation", + "parameters" : [ { + "description" : "Automation ID", + "example" : "hash.sha1", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/AutomationForm" + } + } + }, + "description" : "Automation object that needs to be added", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/AutomationResponse" + } + }, + "test" : { + "example" : { + "id" : "hash.sha1", + "image" : "docker.io/python:3", + "script" : "import sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha1 = hashlib.sha1(msg['payload'].encode('utf-8'))\n return {'hash': sha1.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", + "type" : [ "global", "artifact", "playbook" ] + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "automation:write" ] + } ], + "summary" : "Update an existing automation", + "tags" : [ "automations" ], + "x-codegen-request-body-name" : "automation" + } + }, + "/currentuser" : { + "get" : { + "operationId" : "currentUser", + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserResponse" + } + }, + "test" : { + "example" : { + "apikey" : false, + "blocked" : false, + "id" : "bob", + "roles" : [ "admin:backup:read", "admin:backup:restore", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "currentuser:read" ] + } ], + "summary" : "Get current user", + "tags" : [ "users" ] + } + }, + "/currentuserdata" : { + "get" : { + "operationId" : "currentUserData", + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserDataResponse" + } + }, + "test" : { + "example" : { + "email" : "bob@example.org", + "id" : "bob", + "name" : "Bob Bad" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "currentuserdata:read" ] + } ], + "summary" : "Get current user data", + "tags" : [ "userdata" ] + }, + "put" : { + "operationId" : "updateCurrentUserData", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserData" + } + } + }, + "description" : "User data object that needs to be added", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserDataResponse" + } + }, + "test" : { + "example" : { + "email" : "bob@example.org", + "id" : "bob", + "name" : "Bob Bad" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "currentuserdata:write" ] + } ], + "summary" : "Update current user data", + "tags" : [ "userdata" ], + "x-codegen-request-body-name" : "userdata" + } + }, + "/jobs" : { + "get" : { + "operationId" : "listJobs", + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/JobResponse" + }, + "type" : "array" + } + }, + "test" : { + "example" : [ { + "automation" : "hash.sha1", + "id" : "99cd67131b48", + "payload" : "test", + "status" : "created" + } ] + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "job:read" ] + } ], + "summary" : "List jobs", + "tags" : [ "jobs" ] + }, + "post" : { + "operationId" : "runJob", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/JobForm" + } + } + }, + "description" : "New job", + "required" : true + }, + "responses" : { + "204" : { + "content" : { }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "job:write" ] + } ], + "summary" : "Start a new job", + "tags" : [ "jobs" ], + "x-codegen-request-body-name" : "job" + } + }, + "/jobs/{id}" : { + "get" : { + "operationId" : "getJob", + "parameters" : [ { + "description" : "Job ID", + "example" : "99cd67131b48", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/JobResponse" + } + }, + "test" : { + "example" : { + "automation" : "hash.sha1", + "id" : "99cd67131b48", + "payload" : "test", + "status" : "created" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "job:read" ] + } ], + "summary" : "Get a single job", + "tags" : [ "jobs" ] + }, + "put" : { + "operationId" : "updateJob", + "parameters" : [ { + "description" : "Job ID", + "example" : "99cd67131b48", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Job" + } + } + }, + "description" : "Job object that needs to be added", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/JobResponse" + } + }, + "test" : { + "example" : { + "automation" : "hash.sha1", + "id" : "99cd67131b48", + "payload" : "test", + "status" : "failed" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "job:write" ] + } ], + "summary" : "Update an existing job", + "tags" : [ "jobs" ], + "x-codegen-request-body-name" : "job" + } + }, + "/logs/{reference}" : { + "get" : { + "operationId" : "getLogs", + "parameters" : [ { + "description" : "Reference", + "example" : "tickets%2F294511", + "in" : "path", + "name" : "reference", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/LogEntry" + }, + "type" : "array" + } + }, + "test" : { + "example" : [ { + "created" : "2021-10-02T16:05:00.334+0000", + "creator" : "bob", + "message" : "Fail run account resist lend solve incident centre priority temperature. Cause change distribution examine location technique shape partner milk customer. Rail tea plate soil report cook railway interpretation breath action. Exercise dream accept park conclusion addition shoot assistance may answer. Gold writer link stop combine hear power name commitment operation. Determine lifespan support grow degree henry exclude detail set religion. Direct library policy convention chain retain discover ride walk student. Gather proposal select march aspect play noise avoid encourage employ. Assessment preserve transport combine wish influence income guess run stand. Charge limit crime ignore statement foundation study issue stop claim.", + "reference" : "tickets/294511" + } ] + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "log:read" ] + } ], + "summary" : "Get log entries", + "tags" : [ "logs" ] + } + }, + "/playbooks" : { + "get" : { + "operationId" : "listPlaybooks", + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/PlaybookTemplateResponse" + }, + "type" : "array" + } + }, + "test" : { + "example" : [ { + "id" : "malware", + "name" : "Malware", + "yaml" : "name: Malware\ntasks:\n file-or-hash:\n name: Do you have the file or the hash?\n type: input\n schema:\n title: Malware\n type: object\n properties:\n file:\n type: string\n title: \"I have the\"\n enum: [ \"File\", \"Hash\" ]\n next:\n enter-hash: \"file == 'Hash'\"\n upload: \"file == 'File'\"\n\n enter-hash:\n name: Please enter the hash\n type: input\n schema:\n title: Malware\n type: object\n properties:\n hash:\n type: string\n title: Please enter the hash value\n minlength: 32\n next:\n virustotal: \"hash != ''\"\n\n upload:\n name: Upload the malware\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: object\n x-display: file\n title: Please upload the malware\n next:\n hash: \"malware\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['upload'].data['malware']\"\n next:\n virustotal:\n\n virustotal:\n name: Send hash to VirusTotal\n type: automation\n automation: vt.hash\n args:\n hash: \"playbook.tasks['enter-hash'].data['hash'] || playbook.tasks['hash'].data['hash']\"\n # next:\n # known-malware: \"score > 5\"\n # sandbox: \"score < 6\" # unknown-malware\n" + }, { + "id" : "phishing", + "name" : "Phishing", + "yaml" : "name: Phishing\ntasks:\n board:\n name: Board Involvement?\n description: Is a board member involved?\n type: input\n schema:\n properties:\n boardInvolved:\n default: false\n title: A board member is involved.\n type: boolean\n required:\n - boardInvolved\n title: Board Involvement?\n type: object\n next:\n escalate: \"boardInvolved == true\"\n mail-available: \"boardInvolved == false\"\n\n escalate:\n name: Escalate to CISO\n description: Please escalate the task to the CISO\n type: task\n\n mail-available:\n name: Mail available\n type: input\n schema:\n oneOf:\n - properties:\n mail:\n title: Mail\n type: string\n x-display: textarea\n schemaKey:\n const: 'yes'\n type: string\n required:\n - mail\n title: 'Yes'\n - properties:\n schemaKey:\n const: 'no'\n type: string\n title: 'No'\n title: Mail available\n type: object\n next:\n block-sender: \"schemaKey == 'yes'\"\n extract-iocs: \"schemaKey == 'yes'\"\n search-email-gateway: \"schemaKey == 'no'\"\n\n search-email-gateway:\n name: Search email gateway\n description: Please search email-gateway for the phishing mail.\n type: task\n next:\n extract-iocs:\n\n block-sender:\n name: Block sender\n type: task\n next:\n extract-iocs:\n\n extract-iocs:\n name: Extract IOCs\n description: Please insert the IOCs\n type: input\n schema:\n properties:\n iocs:\n items:\n type: string\n title: IOCs\n type: array\n title: Extract IOCs\n type: object\n next:\n block-iocs:\n\n block-iocs:\n name: Block IOCs\n type: task\n" + }, { + "id" : "simple", + "name" : "Simple", + "yaml" : "name: Simple\ntasks:\n input:\n name: Enter something to hash\n type: input\n schema:\n title: Something\n type: object\n properties:\n something:\n type: string\n title: Something\n default: \"\"\n next:\n hash: \"something != ''\"\n\n hash:\n name: Hash the something\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['something']\"\n next:\n comment: \"hash != ''\"\n\n comment:\n name: Comment the hash\n type: automation\n automation: comment\n payload:\n default: \"playbook.tasks['hash'].data['hash']\"\n next:\n done: \"done\"\n\n done:\n name: You can close this case now\n type: task\n" + } ] + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "playbook:read" ] + } ], + "summary" : "List playbooks", + "tags" : [ "playbooks" ] + }, + "post" : { + "operationId" : "createPlaybook", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/PlaybookTemplateForm" + } + } + }, + "description" : "New playbook", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/PlaybookTemplateResponse" + }, + "type" : "array" + } + }, + "test" : { + "example" : { + "id" : "simple-2", + "name" : "Simple2", + "yaml" : "name: Simple2\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "playbook:write" ] + } ], + "summary" : "Create a playbook", + "tags" : [ "playbooks" ], + "x-codegen-request-body-name" : "playbook" + } + }, + "/playbooks/{id}" : { + "delete" : { + "operationId" : "deletePlaybook", + "parameters" : [ { + "description" : "Playbook name", + "example" : "simple", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "204" : { + "content" : { }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "playbook:write" ] + } ], + "summary" : "Delete a playbook", + "tags" : [ "playbooks" ] + }, + "get" : { + "operationId" : "getPlaybook", + "parameters" : [ { + "description" : "Playbook name", + "example" : "simple", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/PlaybookTemplateResponse" + } + }, + "test" : { + "example" : { + "id" : "simple", + "name" : "Simple", + "yaml" : "name: Simple\ntasks:\n input:\n name: Enter something to hash\n type: input\n schema:\n title: Something\n type: object\n properties:\n something:\n type: string\n title: Something\n default: \"\"\n next:\n hash: \"something != ''\"\n\n hash:\n name: Hash the something\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['something']\"\n next:\n comment: \"hash != ''\"\n\n comment:\n name: Comment the hash\n type: automation\n automation: comment\n payload:\n default: \"playbook.tasks['hash'].data['hash']\"\n next:\n done: \"done\"\n\n done:\n name: You can close this case now\n type: task\n" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "playbook:read" ] + } ], + "summary" : "Get a single playbook", + "tags" : [ "playbooks" ] + }, + "put" : { + "operationId" : "updatePlaybook", + "parameters" : [ { + "description" : "Playbook ID", + "example" : "simple", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/PlaybookTemplateForm" + } + } + }, + "description" : "Updated playbook", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/PlaybookTemplateResponse" + } + }, + "test" : { + "example" : { + "id" : "simple", + "name" : "Simple", + "yaml" : "name: Simple\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "playbook:write" ] + } ], + "summary" : "Update an existing ticket playbook", + "tags" : [ "playbooks" ], + "x-codegen-request-body-name" : "playbook" + } + }, + "/settings" : { + "get" : { + "operationId" : "getSettings", + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Settings" + } + }, + "test" : { + "example" : { + "artifactStates" : [ { + "color" : "info", + "icon" : "mdi-help-circle-outline", + "id" : "unknown", + "name" : "Unknown" + }, { + "color" : "error", + "icon" : "mdi-skull", + "id" : "malicious", + "name" : "Malicious" + }, { + "color" : "success", + "icon" : "mdi-check", + "id" : "clean", + "name" : "Clean" + } ], + "roles" : [ "admin:backup:read", "admin:backup:restore", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ], + "ticketTypes" : [ { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-alert", + "id" : "alert", + "name" : "Alerts" + }, { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-radioactive", + "id" : "incident", + "name" : "Incidents" + }, { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-fingerprint", + "id" : "investigation", + "name" : "Forensic Investigations" + }, { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-target", + "id" : "hunt", + "name" : "Threat Hunting" + } ], + "tier" : "community", + "timeformat" : "YYYY-MM-DDThh:mm:ss", + "version" : "0.0.0-test" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "settings:read" ] + } ], + "summary" : "Get settings", + "tags" : [ "settings" ] + } + }, + "/statistics" : { + "get" : { + "operationId" : "getStatistics", + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Statistics" + } + }, + "test" : { + "example" : { + "open_tickets_per_user" : { }, + "tickets_per_type" : { + "alert" : 2, + "incident" : 1 + }, + "tickets_per_week" : { + "2021-39" : 3 + }, + "unassigned" : 0 + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:read" ] + } ], + "summary" : "Get statistics", + "tags" : [ "statistics" ] + } + }, + "/tasks" : { + "get" : { + "operationId" : "listTasks", + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/TaskResponse" + }, + "type" : "array" + } + }, + "test" : { + "example" : [ ] + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:read" ] + } ], + "summary" : "List tasks", + "tags" : [ "tasks" ] + } + }, + "/templates" : { + "get" : { + "operationId" : "listTemplates", + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/TicketTemplateResponse" + }, + "type" : "array" + } + }, + "test" : { + "example" : [ { + "id" : "default", + "name" : "Default", + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Default\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + } ] + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "template:read" ] + } ], + "summary" : "List templates", + "tags" : [ "templates" ] + }, + "post" : { + "operationId" : "createTemplate", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketTemplateForm" + } + } + }, + "description" : "New template", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketTemplateResponse" + } + }, + "test" : { + "example" : { + "id" : "my-template", + "name" : "My Template", + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "template:write" ] + } ], + "summary" : "Create a new template", + "tags" : [ "templates" ], + "x-codegen-request-body-name" : "template" + } + }, + "/templates/{id}" : { + "delete" : { + "operationId" : "deleteTemplate", + "parameters" : [ { + "description" : "Template ID", + "example" : "default", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "204" : { + "content" : { }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "template:write" ] + } ], + "summary" : "Delete a template", + "tags" : [ "templates" ] + }, + "get" : { + "operationId" : "getTemplate", + "parameters" : [ { + "description" : "Template ID", + "example" : "default", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketTemplateResponse" + } + }, + "test" : { + "example" : { + "id" : "default", + "name" : "Default", + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Default\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "template:read" ] + } ], + "summary" : "Get a single template", + "tags" : [ "templates" ] + }, + "put" : { + "operationId" : "updateTemplate", + "parameters" : [ { + "description" : "Template ID", + "example" : "default", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketTemplateForm" + } + } + }, + "description" : "Template object that needs to be added", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketTemplateResponse" + } + }, + "test" : { + "example" : { + "id" : "default", + "name" : "My Template", + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "template:write" ] + } ], + "summary" : "Update an existing template", + "tags" : [ "templates" ], + "x-codegen-request-body-name" : "template" + } + }, + "/tickets" : { + "get" : { + "operationId" : "listTickets", + "parameters" : [ { + "description" : "Ticket Type", + "in" : "query", + "name" : "type", + "schema" : { + "type" : "string" + } + }, { + "description" : "Offset of the list", + "in" : "query", + "name" : "offset", + "schema" : { + "default" : 0, + "type" : "integer" + } + }, { + "description" : "Number of tickets", + "in" : "query", + "name" : "count", + "schema" : { + "default" : 25, + "maximum" : 100, + "type" : "integer" + } + }, { + "description" : "Sort columns", + "explode" : false, + "in" : "query", + "name" : "sort", + "schema" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "style" : "form" + }, { + "description" : "Sort descending", + "explode" : false, + "in" : "query", + "name" : "desc", + "schema" : { + "items" : { + "type" : "boolean" + }, + "type" : "array" + }, + "style" : "form" + }, { + "description" : "Search query", + "in" : "query", + "name" : "query", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketList" + } + }, + "test" : { + "example" : { + "count" : 3, + "tickets" : [ { + "artifacts" : [ { + "name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status" : "unknown" + }, { + "name" : "http://www.customerviral.io/scalable/vertical/killer", + "status" : "clean" + }, { + "name" : "leadreintermediate.io", + "status" : "malicious" + } ], + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8123, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "live zebra", + "owner" : "demo", + "playbooks" : { + "phishing" : { + "name" : "Phishing", + "tasks" : { + "block-iocs" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block IOCs", + "type" : "task" + }, + "block-sender" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block sender", + "next" : { + "extract-iocs" : "" + }, + "type" : "task" + }, + "board" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Board Involvement?", + "next" : { + "escalate" : "boardInvolved == true", + "mail-available" : "boardInvolved == false" + }, + "schema" : { + "properties" : { + "boardInvolved" : { + "default" : false, + "title" : "A board member is involved.", + "type" : "boolean" + } + }, + "required" : [ "boardInvolved" ], + "title" : "Board Involvement?", + "type" : "object" + }, + "type" : "input" + }, + "escalate" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Escalate to CISO", + "type" : "task" + }, + "extract-iocs" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Extract IOCs", + "next" : { + "block-iocs" : "" + }, + "schema" : { + "properties" : { + "iocs" : { + "items" : { + "type" : "string" + }, + "title" : "IOCs", + "type" : "array" + } + }, + "title" : "Extract IOCs", + "type" : "object" + }, + "type" : "input" + }, + "mail-available" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Mail available", + "next" : { + "block-sender" : "schemaKey == 'yes'", + "extract-iocs" : "schemaKey == 'yes'", + "search-email-gateway" : "schemaKey == 'no'" + }, + "schema" : { + "oneOf" : [ { + "properties" : { + "mail" : { + "title" : "Mail", + "type" : "string", + "x-display" : "textarea" + }, + "schemaKey" : { + "const" : "yes", + "type" : "string" + } + }, + "required" : [ "mail" ], + "title" : "Yes" + }, { + "properties" : { + "schemaKey" : { + "const" : "no", + "type" : "string" + } + }, + "title" : "No" + } ], + "title" : "Mail available", + "type" : "object" + }, + "type" : "input" + }, + "search-email-gateway" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Search email gateway", + "next" : { + "extract-iocs" : "" + }, + "type" : "task" + } + } + } + }, + "references" : [ { + "href" : "https://www.leadmaximize.net/e-services/back-end", + "name" : "performance" + }, { + "href" : "http://www.corporateinteractive.name/rich", + "name" : "autumn" + }, { + "href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name" : "suggest" + } ], + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status" : "closed", + "type" : "incident" + }, { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8125, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "phishing from selenafadel@von.com detected", + "owner" : "demo", + "references" : [ { + "href" : "https://www.seniorleading-edge.name/users/efficient", + "name" : "recovery" + }, { + "href" : "http://www.dynamicseamless.com/clicks-and-mortar", + "name" : "force" + }, { + "href" : "http://www.leadscalable.biz/envisioneer", + "name" : "fund" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + }, { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8126, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "Surfaceintroduce virus detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.centralworld-class.io/synthesize", + "name" : "university" + }, { + "href" : "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name" : "goal" + }, { + "href" : "http://www.chiefsyndicate.io/action-items", + "name" : "unemployment" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + } ] + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:read" ] + } ], + "summary" : "List tickets", + "tags" : [ "tickets" ] + }, + "post" : { + "operationId" : "createTicket", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketForm" + } + } + }, + "description" : "New ticket", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "created" : "1985-04-12T23:20:50.520+0000", + "id" : 123, + "modified" : "1985-04-12T23:20:50.520+0000", + "name" : "Wannacry infection", + "owner" : "bob", + "schema" : "{}", + "status" : "open", + "type" : "incident" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Create a new ticket", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "ticket" + } + }, + "/tickets/{id}" : { + "delete" : { + "operationId" : "deleteTicket", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8125, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "responses" : { + "204" : { + "content" : { }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:delete" ] + } ], + "summary" : "Delete an ticket", + "tags" : [ "tickets" ] + }, + "get" : { + "operationId" : "getTicket", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8125, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8125, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "phishing from selenafadel@von.com detected", + "owner" : "demo", + "references" : [ { + "href" : "https://www.seniorleading-edge.name/users/efficient", + "name" : "recovery" + }, { + "href" : "http://www.dynamicseamless.com/clicks-and-mortar", + "name" : "force" + }, { + "href" : "http://www.leadscalable.biz/envisioneer", + "name" : "fund" + } ], + "schema" : "{}", + "status" : "closed", + "tickets" : [ { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8126, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "Surfaceintroduce virus detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.centralworld-class.io/synthesize", + "name" : "university" + }, { + "href" : "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name" : "goal" + }, { + "href" : "http://www.chiefsyndicate.io/action-items", + "name" : "unemployment" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + } ], + "type" : "alert" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:read" ] + } ], + "summary" : "Get a single ticket", + "tags" : [ "tickets" ] + }, + "put" : { + "operationId" : "updateTicket", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8125, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Ticket" + } + } + }, + "description" : "Updated ticket", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8125, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "phishing from selenafadel@von.org detected", + "owner" : "demo", + "references" : [ { + "href" : "https://www.seniorleading-edge.name/users/efficient", + "name" : "recovery" + }, { + "href" : "http://www.dynamicseamless.com/clicks-and-mortar", + "name" : "force" + }, { + "href" : "http://www.leadscalable.biz/envisioneer", + "name" : "fund" + } ], + "schema" : "{}", + "status" : "closed", + "tickets" : [ { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8126, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "Surfaceintroduce virus detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.centralworld-class.io/synthesize", + "name" : "university" + }, { + "href" : "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name" : "goal" + }, { + "href" : "http://www.chiefsyndicate.io/action-items", + "name" : "unemployment" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + } ], + "type" : "alert" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Update an existing ticket", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "ticket" + } + }, + "/tickets/{id}/artifacts" : { + "post" : { + "operationId" : "addArtifact", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Artifact" + } + } + }, + "description" : "Artifact object that needs to be added", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "artifacts" : [ { + "name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status" : "unknown" + }, { + "name" : "http://www.customerviral.io/scalable/vertical/killer", + "status" : "clean" + }, { + "name" : "leadreintermediate.io", + "status" : "malicious" + }, { + "name" : "2.2.2.2", + "status" : "unknown", + "type" : "ip" + } ], + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8123, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "live zebra", + "owner" : "demo", + "playbooks" : { + "phishing" : { + "name" : "Phishing", + "tasks" : { + "block-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block IOCs", + "order" : 6, + "type" : "task" + }, + "block-sender" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block sender", + "next" : { + "extract-iocs" : "" + }, + "order" : 3, + "type" : "task" + }, + "board" : { + "active" : true, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Board Involvement?", + "next" : { + "escalate" : "boardInvolved == true", + "mail-available" : "boardInvolved == false" + }, + "order" : 0, + "schema" : { + "properties" : { + "boardInvolved" : { + "default" : false, + "title" : "A board member is involved.", + "type" : "boolean" + } + }, + "required" : [ "boardInvolved" ], + "title" : "Board Involvement?", + "type" : "object" + }, + "type" : "input" + }, + "escalate" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Escalate to CISO", + "order" : 1, + "type" : "task" + }, + "extract-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Extract IOCs", + "next" : { + "block-iocs" : "" + }, + "order" : 5, + "schema" : { + "properties" : { + "iocs" : { + "items" : { + "type" : "string" + }, + "title" : "IOCs", + "type" : "array" + } + }, + "title" : "Extract IOCs", + "type" : "object" + }, + "type" : "input" + }, + "mail-available" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Mail available", + "next" : { + "block-sender" : "schemaKey == 'yes'", + "extract-iocs" : "schemaKey == 'yes'", + "search-email-gateway" : "schemaKey == 'no'" + }, + "order" : 2, + "schema" : { + "oneOf" : [ { + "properties" : { + "mail" : { + "title" : "Mail", + "type" : "string", + "x-display" : "textarea" + }, + "schemaKey" : { + "const" : "yes", + "type" : "string" + } + }, + "required" : [ "mail" ], + "title" : "Yes" + }, { + "properties" : { + "schemaKey" : { + "const" : "no", + "type" : "string" + } + }, + "title" : "No" + } ], + "title" : "Mail available", + "type" : "object" + }, + "type" : "input" + }, + "search-email-gateway" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Search email gateway", + "next" : { + "extract-iocs" : "" + }, + "order" : 4, + "type" : "task" + } + } + } + }, + "references" : [ { + "href" : "https://www.leadmaximize.net/e-services/back-end", + "name" : "performance" + }, { + "href" : "http://www.corporateinteractive.name/rich", + "name" : "autumn" + }, { + "href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name" : "suggest" + } ], + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status" : "closed", + "type" : "incident" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Add a single artifact", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "artifact" + } + }, + "/tickets/{id}/artifacts/{name}" : { + "delete" : { + "operationId" : "removeArtifact", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + }, { + "example" : "leadreintermediate.io", + "in" : "path", + "name" : "name", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "artifacts" : [ { + "name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status" : "unknown" + }, { + "name" : "http://www.customerviral.io/scalable/vertical/killer", + "status" : "clean" + } ], + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8123, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "live zebra", + "owner" : "demo", + "playbooks" : { + "phishing" : { + "name" : "Phishing", + "tasks" : { + "block-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block IOCs", + "order" : 6, + "type" : "task" + }, + "block-sender" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block sender", + "next" : { + "extract-iocs" : "" + }, + "order" : 3, + "type" : "task" + }, + "board" : { + "active" : true, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Board Involvement?", + "next" : { + "escalate" : "boardInvolved == true", + "mail-available" : "boardInvolved == false" + }, + "order" : 0, + "schema" : { + "properties" : { + "boardInvolved" : { + "default" : false, + "title" : "A board member is involved.", + "type" : "boolean" + } + }, + "required" : [ "boardInvolved" ], + "title" : "Board Involvement?", + "type" : "object" + }, + "type" : "input" + }, + "escalate" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Escalate to CISO", + "order" : 1, + "type" : "task" + }, + "extract-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Extract IOCs", + "next" : { + "block-iocs" : "" + }, + "order" : 5, + "schema" : { + "properties" : { + "iocs" : { + "items" : { + "type" : "string" + }, + "title" : "IOCs", + "type" : "array" + } + }, + "title" : "Extract IOCs", + "type" : "object" + }, + "type" : "input" + }, + "mail-available" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Mail available", + "next" : { + "block-sender" : "schemaKey == 'yes'", + "extract-iocs" : "schemaKey == 'yes'", + "search-email-gateway" : "schemaKey == 'no'" + }, + "order" : 2, + "schema" : { + "oneOf" : [ { + "properties" : { + "mail" : { + "title" : "Mail", + "type" : "string", + "x-display" : "textarea" + }, + "schemaKey" : { + "const" : "yes", + "type" : "string" + } + }, + "required" : [ "mail" ], + "title" : "Yes" + }, { + "properties" : { + "schemaKey" : { + "const" : "no", + "type" : "string" + } + }, + "title" : "No" + } ], + "title" : "Mail available", + "type" : "object" + }, + "type" : "input" + }, + "search-email-gateway" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Search email gateway", + "next" : { + "extract-iocs" : "" + }, + "order" : 4, + "type" : "task" + } + } + } + }, + "references" : [ { + "href" : "https://www.leadmaximize.net/e-services/back-end", + "name" : "performance" + }, { + "href" : "http://www.corporateinteractive.name/rich", + "name" : "autumn" + }, { + "href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name" : "suggest" + } ], + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status" : "closed", + "type" : "incident" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Remove an artifact", + "tags" : [ "tickets" ] + }, + "get" : { + "operationId" : "getArtifact", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + }, { + "example" : "leadreintermediate.io", + "in" : "path", + "name" : "name", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Artifact" + } + }, + "test" : { + "example" : { + "name" : "leadreintermediate.io", + "status" : "malicious" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Get a single artifact", + "tags" : [ "tickets" ] + }, + "put" : { + "operationId" : "setArtifact", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + }, { + "example" : "leadreintermediate.io", + "in" : "path", + "name" : "name", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Artifact" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "artifacts" : [ { + "name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status" : "unknown" + }, { + "name" : "http://www.customerviral.io/scalable/vertical/killer", + "status" : "clean" + }, { + "name" : "leadreintermediate.io", + "status" : "clean" + } ], + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8123, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "live zebra", + "owner" : "demo", + "playbooks" : { + "phishing" : { + "name" : "Phishing", + "tasks" : { + "block-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block IOCs", + "order" : 6, + "type" : "task" + }, + "block-sender" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block sender", + "next" : { + "extract-iocs" : "" + }, + "order" : 3, + "type" : "task" + }, + "board" : { + "active" : true, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Board Involvement?", + "next" : { + "escalate" : "boardInvolved == true", + "mail-available" : "boardInvolved == false" + }, + "order" : 0, + "schema" : { + "properties" : { + "boardInvolved" : { + "default" : false, + "title" : "A board member is involved.", + "type" : "boolean" + } + }, + "required" : [ "boardInvolved" ], + "title" : "Board Involvement?", + "type" : "object" + }, + "type" : "input" + }, + "escalate" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Escalate to CISO", + "order" : 1, + "type" : "task" + }, + "extract-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Extract IOCs", + "next" : { + "block-iocs" : "" + }, + "order" : 5, + "schema" : { + "properties" : { + "iocs" : { + "items" : { + "type" : "string" + }, + "title" : "IOCs", + "type" : "array" + } + }, + "title" : "Extract IOCs", + "type" : "object" + }, + "type" : "input" + }, + "mail-available" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Mail available", + "next" : { + "block-sender" : "schemaKey == 'yes'", + "extract-iocs" : "schemaKey == 'yes'", + "search-email-gateway" : "schemaKey == 'no'" + }, + "order" : 2, + "schema" : { + "oneOf" : [ { + "properties" : { + "mail" : { + "title" : "Mail", + "type" : "string", + "x-display" : "textarea" + }, + "schemaKey" : { + "const" : "yes", + "type" : "string" + } + }, + "required" : [ "mail" ], + "title" : "Yes" + }, { + "properties" : { + "schemaKey" : { + "const" : "no", + "type" : "string" + } + }, + "title" : "No" + } ], + "title" : "Mail available", + "type" : "object" + }, + "type" : "input" + }, + "search-email-gateway" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Search email gateway", + "next" : { + "extract-iocs" : "" + }, + "order" : 4, + "type" : "task" + } + } + } + }, + "references" : [ { + "href" : "https://www.leadmaximize.net/e-services/back-end", + "name" : "performance" + }, { + "href" : "http://www.corporateinteractive.name/rich", + "name" : "autumn" + }, { + "href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name" : "suggest" + } ], + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status" : "closed", + "type" : "incident" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Set a single artifact", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "artifact" + } + }, + "/tickets/{id}/artifacts/{name}/enrich" : { + "post" : { + "operationId" : "enrichArtifact", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + }, { + "example" : "leadreintermediate.io", + "in" : "path", + "name" : "name", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/EnrichmentForm" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Artifact" + } + }, + "test" : { + "example" : { + "artifacts" : [ { + "name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status" : "unknown" + }, { + "name" : "http://www.customerviral.io/scalable/vertical/killer", + "status" : "clean" + }, { + "enrichments" : { + "hash.sha1" : { + "created" : "2021-10-03T16:44:06.489+0000", + "data" : { + "hash" : "b7a067a742c20d07a7456646de89bc2d408a1153" + }, + "name" : "hash.sha1" + } + }, + "name" : "leadreintermediate.io", + "status" : "malicious" + } ], + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8123, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "live zebra", + "owner" : "demo", + "playbooks" : { + "phishing" : { + "name" : "Phishing", + "tasks" : { + "block-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block IOCs", + "order" : 6, + "type" : "task" + }, + "block-sender" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block sender", + "next" : { + "extract-iocs" : "" + }, + "order" : 3, + "type" : "task" + }, + "board" : { + "active" : true, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Board Involvement?", + "next" : { + "escalate" : "boardInvolved == true", + "mail-available" : "boardInvolved == false" + }, + "order" : 0, + "schema" : { + "properties" : { + "boardInvolved" : { + "default" : false, + "title" : "A board member is involved.", + "type" : "boolean" + } + }, + "required" : [ "boardInvolved" ], + "title" : "Board Involvement?", + "type" : "object" + }, + "type" : "input" + }, + "escalate" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Escalate to CISO", + "order" : 1, + "type" : "task" + }, + "extract-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Extract IOCs", + "next" : { + "block-iocs" : "" + }, + "order" : 5, + "schema" : { + "properties" : { + "iocs" : { + "items" : { + "type" : "string" + }, + "title" : "IOCs", + "type" : "array" + } + }, + "title" : "Extract IOCs", + "type" : "object" + }, + "type" : "input" + }, + "mail-available" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Mail available", + "next" : { + "block-sender" : "schemaKey == 'yes'", + "extract-iocs" : "schemaKey == 'yes'", + "search-email-gateway" : "schemaKey == 'no'" + }, + "order" : 2, + "schema" : { + "oneOf" : [ { + "properties" : { + "mail" : { + "title" : "Mail", + "type" : "string", + "x-display" : "textarea" + }, + "schemaKey" : { + "const" : "yes", + "type" : "string" + } + }, + "required" : [ "mail" ], + "title" : "Yes" + }, { + "properties" : { + "schemaKey" : { + "const" : "no", + "type" : "string" + } + }, + "title" : "No" + } ], + "title" : "Mail available", + "type" : "object" + }, + "type" : "input" + }, + "search-email-gateway" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Search email gateway", + "next" : { + "extract-iocs" : "" + }, + "order" : 4, + "type" : "task" + } + } + } + }, + "references" : [ { + "href" : "https://www.leadmaximize.net/e-services/back-end", + "name" : "performance" + }, { + "href" : "http://www.corporateinteractive.name/rich", + "name" : "autumn" + }, { + "href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name" : "suggest" + } ], + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status" : "closed", + "type" : "incident" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Enrich a single artifact", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "data" + } + }, + "/tickets/{id}/artifacts/{name}/run/{automation}" : { + "post" : { + "operationId" : "runArtifact", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + }, { + "example" : "leadreintermediate.io", + "in" : "path", + "name" : "name", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "example" : "hash.sha1", + "in" : "path", + "name" : "automation", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "204" : { + "content" : { }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Run automation on a single artifact", + "tags" : [ "tickets" ] + } + }, + "/tickets/{id}/comments" : { + "post" : { + "operationId" : "addComment", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8125, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/CommentForm" + } + } + }, + "description" : "Ticket comment", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "comments" : [ { + "created" : "2021-10-02T16:04:59.078+0000", + "creator" : "bob", + "message" : "My first comment" + } ], + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8125, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "phishing from selenafadel@von.com detected", + "owner" : "demo", + "references" : [ { + "href" : "https://www.seniorleading-edge.name/users/efficient", + "name" : "recovery" + }, { + "href" : "http://www.dynamicseamless.com/clicks-and-mortar", + "name" : "force" + }, { + "href" : "http://www.leadscalable.biz/envisioneer", + "name" : "fund" + } ], + "schema" : "{}", + "status" : "closed", + "tickets" : [ { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8126, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "Surfaceintroduce virus detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.centralworld-class.io/synthesize", + "name" : "university" + }, { + "href" : "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name" : "goal" + }, { + "href" : "http://www.chiefsyndicate.io/action-items", + "name" : "unemployment" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + } ], + "type" : "alert" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Add ticket comment", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "comment" + } + }, + "/tickets/{id}/comments/{commentID}" : { + "delete" : { + "description" : "Comment will be removed from the ticket.", + "operationId" : "removeComment", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + }, { + "description" : "Comment ID to remove", + "example" : 0, + "in" : "path", + "name" : "commentID", + "required" : true, + "schema" : { + "type" : "integer" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "artifacts" : [ { + "name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status" : "unknown" + }, { + "name" : "http://www.customerviral.io/scalable/vertical/killer", + "status" : "clean" + }, { + "name" : "leadreintermediate.io", + "status" : "malicious" + } ], + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8123, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "live zebra", + "owner" : "demo", + "playbooks" : { + "phishing" : { + "name" : "Phishing", + "tasks" : { + "block-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block IOCs", + "order" : 6, + "type" : "task" + }, + "block-sender" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block sender", + "next" : { + "extract-iocs" : "" + }, + "order" : 3, + "type" : "task" + }, + "board" : { + "active" : true, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Board Involvement?", + "next" : { + "escalate" : "boardInvolved == true", + "mail-available" : "boardInvolved == false" + }, + "order" : 0, + "schema" : { + "properties" : { + "boardInvolved" : { + "default" : false, + "title" : "A board member is involved.", + "type" : "boolean" + } + }, + "required" : [ "boardInvolved" ], + "title" : "Board Involvement?", + "type" : "object" + }, + "type" : "input" + }, + "escalate" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Escalate to CISO", + "order" : 1, + "type" : "task" + }, + "extract-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Extract IOCs", + "next" : { + "block-iocs" : "" + }, + "order" : 5, + "schema" : { + "properties" : { + "iocs" : { + "items" : { + "type" : "string" + }, + "title" : "IOCs", + "type" : "array" + } + }, + "title" : "Extract IOCs", + "type" : "object" + }, + "type" : "input" + }, + "mail-available" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Mail available", + "next" : { + "block-sender" : "schemaKey == 'yes'", + "extract-iocs" : "schemaKey == 'yes'", + "search-email-gateway" : "schemaKey == 'no'" + }, + "order" : 2, + "schema" : { + "oneOf" : [ { + "properties" : { + "mail" : { + "title" : "Mail", + "type" : "string", + "x-display" : "textarea" + }, + "schemaKey" : { + "const" : "yes", + "type" : "string" + } + }, + "required" : [ "mail" ], + "title" : "Yes" + }, { + "properties" : { + "schemaKey" : { + "const" : "no", + "type" : "string" + } + }, + "title" : "No" + } ], + "title" : "Mail available", + "type" : "object" + }, + "type" : "input" + }, + "search-email-gateway" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Search email gateway", + "next" : { + "extract-iocs" : "" + }, + "order" : 4, + "type" : "task" + } + } + } + }, + "references" : [ { + "href" : "https://www.leadmaximize.net/e-services/back-end", + "name" : "performance" + }, { + "href" : "http://www.corporateinteractive.name/rich", + "name" : "autumn" + }, { + "href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name" : "suggest" + } ], + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status" : "closed", + "type" : "incident" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Remove an comment from an ticket", + "tags" : [ "tickets" ] + } + }, + "/tickets/{id}/files" : { + "put" : { + "description" : "Link files to an ticket. The files themself will be stored in object storage.", + "operationId" : "linkFiles", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8125, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/File" + }, + "type" : "array" + } + } + }, + "description" : "Added files", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "created" : "2021-10-02T16:04:59.078+0000", + "files" : [ { + "key" : "myfile", + "name" : "document.doc" + } ], + "id" : 8125, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "phishing from selenafadel@von.com detected", + "owner" : "demo", + "references" : [ { + "href" : "https://www.seniorleading-edge.name/users/efficient", + "name" : "recovery" + }, { + "href" : "http://www.dynamicseamless.com/clicks-and-mortar", + "name" : "force" + }, { + "href" : "http://www.leadscalable.biz/envisioneer", + "name" : "fund" + } ], + "schema" : "{}", + "status" : "closed", + "tickets" : [ { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8126, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "Surfaceintroduce virus detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.centralworld-class.io/synthesize", + "name" : "university" + }, { + "href" : "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name" : "goal" + }, { + "href" : "http://www.chiefsyndicate.io/action-items", + "name" : "unemployment" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + } ], + "type" : "alert" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Link files to an ticket", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "files" + } + }, + "/tickets/{id}/playbooks" : { + "post" : { + "operationId" : "addTicketPlaybook", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8125, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/PlaybookTemplateForm" + } + } + }, + "description" : "Ticket playbook object that needs to be added", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "created" : "1985-04-12T23:20:50.520+0000", + "id" : 8125, + "modified" : "1985-04-12T23:20:50.520+0000", + "name" : "phishing from selenafadel@von.com detected", + "owner" : "demo", + "playbooks" : { + "simple" : { + "name" : "Simple", + "tasks" : { + "escalate" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Escalate to malware team", + "order" : 2, + "type" : "task" + }, + "hash" : { + "active" : false, + "automation" : "hash.sha1", + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Hash the malware", + "next" : { + "escalate" : "" + }, + "order" : 1, + "payload" : { + "default" : "playbook.tasks['input'].data['malware']" + }, + "type" : "automation" + }, + "input" : { + "active" : true, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Upload malware if possible", + "next" : { + "hash" : "malware != ''" + }, + "order" : 0, + "schema" : { + "properties" : { + "malware" : { + "default" : "", + "title" : "Select malware", + "type" : "string" + } + }, + "title" : "Malware", + "type" : "object" + }, + "type" : "input" + } + } + } + }, + "references" : [ { + "href" : "https://www.seniorleading-edge.name/users/efficient", + "name" : "recovery" + }, { + "href" : "http://www.dynamicseamless.com/clicks-and-mortar", + "name" : "force" + }, { + "href" : "http://www.leadscalable.biz/envisioneer", + "name" : "fund" + } ], + "schema" : "{}", + "status" : "closed", + "tickets" : [ { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8126, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "Surfaceintroduce virus detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.centralworld-class.io/synthesize", + "name" : "university" + }, { + "href" : "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name" : "goal" + }, { + "href" : "http://www.chiefsyndicate.io/action-items", + "name" : "unemployment" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + } ], + "type" : "alert" + } + } + }, + "description" : "successful operation" + } + }, + "summary" : "Add a new ticket playbook", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "playbook" + } + }, + "/tickets/{id}/playbooks/{playbookID}" : { + "delete" : { + "operationId" : "removeTicketPlaybook", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + }, { + "description" : "Playbook ID", + "example" : "phishing", + "in" : "path", + "name" : "playbookID", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "artifacts" : [ { + "name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status" : "unknown" + }, { + "name" : "http://www.customerviral.io/scalable/vertical/killer", + "status" : "clean" + }, { + "name" : "leadreintermediate.io", + "status" : "malicious" + } ], + "created" : "1985-04-12T23:20:50.520+0000", + "id" : 8123, + "modified" : "1985-04-12T23:20:50.520+0000", + "name" : "live zebra", + "owner" : "demo", + "references" : [ { + "href" : "https://www.leadmaximize.net/e-services/back-end", + "name" : "performance" + }, { + "href" : "http://www.corporateinteractive.name/rich", + "name" : "autumn" + }, { + "href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name" : "suggest" + } ], + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status" : "closed", + "type" : "incident" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Remove an ticket playbook", + "tags" : [ "tickets" ] + } + }, + "/tickets/{id}/playbooks/{playbookID}/task/{taskID}" : { + "put" : { + "operationId" : "setTask", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + }, { + "description" : "Playbook ID", + "example" : "phishing", + "in" : "path", + "name" : "playbookID", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "description" : "Task ID", + "example" : "board", + "in" : "path", + "name" : "taskID", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Task" + } + } + }, + "description" : "Task", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "artifacts" : [ { + "name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status" : "unknown" + }, { + "name" : "http://www.customerviral.io/scalable/vertical/killer", + "status" : "clean" + }, { + "name" : "leadreintermediate.io", + "status" : "malicious" + } ], + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8123, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "live zebra", + "owner" : "demo", + "playbooks" : { + "phishing" : { + "name" : "Phishing", + "tasks" : { + "block-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block IOCs", + "order" : 6, + "type" : "task" + }, + "block-sender" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block sender", + "next" : { + "extract-iocs" : "" + }, + "order" : 3, + "type" : "task" + }, + "board" : { + "active" : true, + "created" : "2021-10-02T16:04:59.078+0000", + "data" : { + "boardInvolved" : true + }, + "done" : false, + "name" : "Board Involvement?", + "next" : { + "escalate" : "boardInvolved == true", + "mail-available" : "boardInvolved == false" + }, + "order" : 0, + "schema" : { + "properties" : { + "boardInvolved" : { + "default" : false, + "title" : "A board member is involved.", + "type" : "boolean" + } + }, + "required" : [ "boardInvolved" ], + "title" : "Board Involvement?", + "type" : "object" + }, + "type" : "input" + }, + "escalate" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Escalate to CISO", + "order" : 1, + "type" : "task" + }, + "extract-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Extract IOCs", + "next" : { + "block-iocs" : "" + }, + "order" : 5, + "schema" : { + "properties" : { + "iocs" : { + "items" : { + "type" : "string" + }, + "title" : "IOCs", + "type" : "array" + } + }, + "title" : "Extract IOCs", + "type" : "object" + }, + "type" : "input" + }, + "mail-available" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Mail available", + "next" : { + "block-sender" : "schemaKey == 'yes'", + "extract-iocs" : "schemaKey == 'yes'", + "search-email-gateway" : "schemaKey == 'no'" + }, + "order" : 2, + "schema" : { + "oneOf" : [ { + "properties" : { + "mail" : { + "title" : "Mail", + "type" : "string", + "x-display" : "textarea" + }, + "schemaKey" : { + "const" : "yes", + "type" : "string" + } + }, + "required" : [ "mail" ], + "title" : "Yes" + }, { + "properties" : { + "schemaKey" : { + "const" : "no", + "type" : "string" + } + }, + "title" : "No" + } ], + "title" : "Mail available", + "type" : "object" + }, + "type" : "input" + }, + "search-email-gateway" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Search email gateway", + "next" : { + "extract-iocs" : "" + }, + "order" : 4, + "type" : "task" + } + } + } + }, + "references" : [ { + "href" : "https://www.leadmaximize.net/e-services/back-end", + "name" : "performance" + }, { + "href" : "http://www.corporateinteractive.name/rich", + "name" : "autumn" + }, { + "href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name" : "suggest" + } ], + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status" : "closed", + "type" : "incident" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Set a ticket playbook task", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "task" + } + }, + "/tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete" : { + "put" : { + "operationId" : "completeTask", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + }, { + "description" : "Playbook ID", + "example" : "phishing", + "in" : "path", + "name" : "playbookID", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "description" : "Task ID", + "example" : "board", + "in" : "path", + "name" : "taskID", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "type" : "object" + } + } + }, + "description" : "Ticket playbook object that needs to be added", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "artifacts" : [ { + "name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status" : "unknown" + }, { + "name" : "http://www.customerviral.io/scalable/vertical/killer", + "status" : "clean" + }, { + "name" : "leadreintermediate.io", + "status" : "malicious" + } ], + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8123, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "live zebra", + "owner" : "demo", + "playbooks" : { + "phishing" : { + "name" : "Phishing", + "tasks" : { + "block-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block IOCs", + "order" : 6, + "type" : "task" + }, + "block-sender" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block sender", + "next" : { + "extract-iocs" : "" + }, + "order" : 3, + "type" : "task" + }, + "board" : { + "active" : false, + "closed" : "2021-10-02T16:04:59.078+0000", + "created" : "2021-10-02T16:04:59.078+0000", + "data" : { + "boardInvolved" : true + }, + "done" : true, + "name" : "Board Involvement?", + "next" : { + "escalate" : "boardInvolved == true", + "mail-available" : "boardInvolved == false" + }, + "order" : 0, + "schema" : { + "properties" : { + "boardInvolved" : { + "default" : false, + "title" : "A board member is involved.", + "type" : "boolean" + } + }, + "required" : [ "boardInvolved" ], + "title" : "Board Involvement?", + "type" : "object" + }, + "type" : "input" + }, + "escalate" : { + "active" : true, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Escalate to CISO", + "order" : 1, + "type" : "task" + }, + "extract-iocs" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Extract IOCs", + "next" : { + "block-iocs" : "" + }, + "order" : 5, + "schema" : { + "properties" : { + "iocs" : { + "items" : { + "type" : "string" + }, + "title" : "IOCs", + "type" : "array" + } + }, + "title" : "Extract IOCs", + "type" : "object" + }, + "type" : "input" + }, + "mail-available" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Mail available", + "next" : { + "block-sender" : "schemaKey == 'yes'", + "extract-iocs" : "schemaKey == 'yes'", + "search-email-gateway" : "schemaKey == 'no'" + }, + "order" : 2, + "schema" : { + "oneOf" : [ { + "properties" : { + "mail" : { + "title" : "Mail", + "type" : "string", + "x-display" : "textarea" + }, + "schemaKey" : { + "const" : "yes", + "type" : "string" + } + }, + "required" : [ "mail" ], + "title" : "Yes" + }, { + "properties" : { + "schemaKey" : { + "const" : "no", + "type" : "string" + } + }, + "title" : "No" + } ], + "title" : "Mail available", + "type" : "object" + }, + "type" : "input" + }, + "search-email-gateway" : { + "active" : false, + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Search email gateway", + "next" : { + "extract-iocs" : "" + }, + "order" : 4, + "type" : "task" + } + } + } + }, + "references" : [ { + "href" : "https://www.leadmaximize.net/e-services/back-end", + "name" : "performance" + }, { + "href" : "http://www.corporateinteractive.name/rich", + "name" : "autumn" + }, { + "href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name" : "suggest" + } ], + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status" : "closed", + "type" : "incident" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Complete ticket playbook task", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "data" + } + }, + "/tickets/{id}/playbooks/{playbookID}/task/{taskID}/run" : { + "post" : { + "operationId" : "runTask", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8123, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + }, { + "description" : "Playbook ID", + "example" : "phishing", + "in" : "path", + "name" : "playbookID", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "description" : "Task ID", + "example" : "board", + "in" : "path", + "name" : "taskID", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "204" : { + "content" : { }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Run ticket playbook task", + "tags" : [ "tickets" ] + } + }, + "/tickets/{id}/references" : { + "put" : { + "operationId" : "setReferences", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8125, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/Reference" + }, + "type" : "array" + } + } + }, + "description" : "All ticket references", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8125, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "phishing from selenafadel@von.com detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.leadscalable.biz/envisioneer", + "name" : "fund" + } ], + "schema" : "{}", + "status" : "closed", + "tickets" : [ { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8126, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "Surfaceintroduce virus detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.centralworld-class.io/synthesize", + "name" : "university" + }, { + "href" : "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name" : "goal" + }, { + "href" : "http://www.chiefsyndicate.io/action-items", + "name" : "unemployment" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + } ], + "type" : "alert" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Set ticket references", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "references" + } + }, + "/tickets/{id}/schema" : { + "put" : { + "operationId" : "setSchema", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8125, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "New ticket schema", + "required" : false + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8125, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "phishing from selenafadel@von.com detected", + "owner" : "demo", + "references" : [ { + "href" : "https://www.seniorleading-edge.name/users/efficient", + "name" : "recovery" + }, { + "href" : "http://www.dynamicseamless.com/clicks-and-mortar", + "name" : "force" + }, { + "href" : "http://www.leadscalable.biz/envisioneer", + "name" : "fund" + } ], + "schema" : "{}", + "status" : "closed", + "tickets" : [ { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8126, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "Surfaceintroduce virus detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.centralworld-class.io/synthesize", + "name" : "university" + }, { + "href" : "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name" : "goal" + }, { + "href" : "http://www.chiefsyndicate.io/action-items", + "name" : "unemployment" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + } ], + "type" : "alert" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Set ticket schema", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "schema" + } + }, + "/tickets/{id}/tickets" : { + "delete" : { + "operationId" : "unlinkTicket", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8126, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "format" : "int64", + "type" : "integer" + } + } + }, + "description" : "Added ticket ID", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8126, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "Surfaceintroduce virus detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.centralworld-class.io/synthesize", + "name" : "university" + }, { + "href" : "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name" : "goal" + }, { + "href" : "http://www.chiefsyndicate.io/action-items", + "name" : "unemployment" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Unlink an ticket to an ticket", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "linkedID" + }, + "patch" : { + "operationId" : "linkTicket", + "parameters" : [ { + "description" : "Ticket ID", + "example" : 8126, + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "format" : "int64", + "type" : "integer" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "format" : "int64", + "type" : "integer" + } + } + }, + "description" : "Added ticket ID", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "test" : { + "example" : { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8126, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "Surfaceintroduce virus detected", + "owner" : "demo", + "references" : [ { + "href" : "http://www.centralworld-class.io/synthesize", + "name" : "university" + }, { + "href" : "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name" : "goal" + }, { + "href" : "http://www.chiefsyndicate.io/action-items", + "name" : "unemployment" + } ], + "schema" : "{}", + "status" : "closed", + "tickets" : [ { + "artifacts" : [ { + "name" : "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status" : "unknown" + }, { + "name" : "http://www.customerviral.io/scalable/vertical/killer", + "status" : "clean" + }, { + "name" : "leadreintermediate.io", + "status" : "malicious" + } ], + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8123, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "live zebra", + "owner" : "demo", + "playbooks" : { + "phishing" : { + "name" : "Phishing", + "tasks" : { + "block-iocs" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block IOCs", + "type" : "task" + }, + "block-sender" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Block sender", + "next" : { + "extract-iocs" : "" + }, + "type" : "task" + }, + "board" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Board Involvement?", + "next" : { + "escalate" : "boardInvolved == true", + "mail-available" : "boardInvolved == false" + }, + "schema" : { + "properties" : { + "boardInvolved" : { + "default" : false, + "title" : "A board member is involved.", + "type" : "boolean" + } + }, + "required" : [ "boardInvolved" ], + "title" : "Board Involvement?", + "type" : "object" + }, + "type" : "input" + }, + "escalate" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Escalate to CISO", + "type" : "task" + }, + "extract-iocs" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Extract IOCs", + "next" : { + "block-iocs" : "" + }, + "schema" : { + "properties" : { + "iocs" : { + "items" : { + "type" : "string" + }, + "title" : "IOCs", + "type" : "array" + } + }, + "title" : "Extract IOCs", + "type" : "object" + }, + "type" : "input" + }, + "mail-available" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Mail available", + "next" : { + "block-sender" : "schemaKey == 'yes'", + "extract-iocs" : "schemaKey == 'yes'", + "search-email-gateway" : "schemaKey == 'no'" + }, + "schema" : { + "oneOf" : [ { + "properties" : { + "mail" : { + "title" : "Mail", + "type" : "string", + "x-display" : "textarea" + }, + "schemaKey" : { + "const" : "yes", + "type" : "string" + } + }, + "required" : [ "mail" ], + "title" : "Yes" + }, { + "properties" : { + "schemaKey" : { + "const" : "no", + "type" : "string" + } + }, + "title" : "No" + } ], + "title" : "Mail available", + "type" : "object" + }, + "type" : "input" + }, + "search-email-gateway" : { + "created" : "2021-10-02T16:04:59.078+0000", + "done" : false, + "name" : "Search email gateway", + "next" : { + "extract-iocs" : "" + }, + "type" : "task" + } + } + } + }, + "references" : [ { + "href" : "https://www.leadmaximize.net/e-services/back-end", + "name" : "performance" + }, { + "href" : "http://www.corporateinteractive.name/rich", + "name" : "autumn" + }, { + "href" : "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name" : "suggest" + } ], + "schema" : "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status" : "closed", + "type" : "incident" + }, { + "created" : "2021-10-02T16:04:59.078+0000", + "id" : 8125, + "modified" : "2021-10-02T16:04:59.078+0000", + "name" : "phishing from selenafadel@von.com detected", + "owner" : "demo", + "references" : [ { + "href" : "https://www.seniorleading-edge.name/users/efficient", + "name" : "recovery" + }, { + "href" : "http://www.dynamicseamless.com/clicks-and-mortar", + "name" : "force" + }, { + "href" : "http://www.leadscalable.biz/envisioneer", + "name" : "fund" + } ], + "schema" : "{}", + "status" : "closed", + "type" : "alert" + } ], + "type" : "alert" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Link an ticket to an ticket", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "linkedID" + } + }, + "/tickets/batch" : { + "post" : { + "operationId" : "createTicketBatch", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/TicketForm" + }, + "type" : "array" + } + } + }, + "description" : "New ticket", + "required" : true + }, + "responses" : { + "204" : { + "content" : { }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "ticket:write" ] + } ], + "summary" : "Create a new tickets in batch", + "tags" : [ "tickets" ], + "x-codegen-request-body-name" : "ticket" + } + }, + "/tickettypes" : { + "get" : { + "operationId" : "listTicketTypes", + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/TicketTypeResponse" + }, + "type" : "array" + } + }, + "test" : { + "example" : [ { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-alert", + "id" : "alert", + "name" : "Alerts" + }, { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-radioactive", + "id" : "incident", + "name" : "Incidents" + }, { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-fingerprint", + "id" : "investigation", + "name" : "Forensic Investigations" + }, { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-target", + "id" : "hunt", + "name" : "Threat Hunting" + } ] + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "tickettype:read" ] + } ], + "summary" : "List tickettypes", + "tags" : [ "tickettypes" ] + }, + "post" : { + "operationId" : "createTicketType", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketTypeForm" + } + } + }, + "description" : "New tickettype", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketTypeResponse" + } + }, + "test" : { + "example" : { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-newspaper-variant-outline", + "id" : "ti-tickets", + "name" : "TI Tickets" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "tickettype:write" ] + } ], + "summary" : "Create a new tickettype", + "tags" : [ "tickettypes" ], + "x-codegen-request-body-name" : "tickettype" + } + }, + "/tickettypes/{id}" : { + "delete" : { + "operationId" : "deleteTicketType", + "parameters" : [ { + "description" : "TicketType ID", + "example" : "alert", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "204" : { + "content" : { }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "tickettype:write" ] + } ], + "summary" : "Delete a tickettype", + "tags" : [ "tickettypes" ] + }, + "get" : { + "operationId" : "getTicketType", + "parameters" : [ { + "description" : "TicketType ID", + "example" : "alert", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketTypeResponse" + } + }, + "test" : { + "example" : { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-alert", + "id" : "alert", + "name" : "Alerts" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "tickettype:read" ] + } ], + "summary" : "Get a single tickettype", + "tags" : [ "tickettypes" ] + }, + "put" : { + "operationId" : "updateTicketType", + "parameters" : [ { + "description" : "TicketType ID", + "example" : "alert", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketTypeForm" + } + } + }, + "description" : "TicketType object that needs to be added", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/TicketTypeResponse" + } + }, + "test" : { + "example" : { + "default_playbooks" : [ ], + "default_template" : "default", + "icon" : "mdi-bell", + "id" : "alert", + "name" : "Alerts" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "tickettype:write" ] + } ], + "summary" : "Update an existing tickettype", + "tags" : [ "tickettypes" ], + "x-codegen-request-body-name" : "tickettype" + } + }, + "/userdata" : { + "get" : { + "operationId" : "listUserData", + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/UserDataResponse" + }, + "type" : "array" + } + }, + "test" : { + "example" : [ { + "email" : "bob@example.org", + "id" : "bob", + "name" : "Bob Bad" + } ] + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "userdata:read" ] + } ], + "summary" : "List userdata", + "tags" : [ "userdata" ] + } + }, + "/userdata/{id}" : { + "get" : { + "operationId" : "getUserData", + "parameters" : [ { + "description" : "User Data ID", + "example" : "bob", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserDataResponse" + } + }, + "test" : { + "example" : { + "email" : "bob@example.org", + "id" : "bob", + "name" : "Bob Bad" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "userdata:read" ] + } ], + "summary" : "Get a single user data", + "tags" : [ "userdata" ] + }, + "put" : { + "operationId" : "updateUserData", + "parameters" : [ { + "description" : "User Data ID", + "example" : "bob", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserData" + } + } + }, + "description" : "User data object that needs to be added", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserDataResponse" + } + }, + "test" : { + "example" : { + "email" : "bob@example.org", + "id" : "bob", + "name" : "Bob Bad" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "userdata:write" ] + } ], + "summary" : "Update an existing user data", + "tags" : [ "userdata" ], + "x-codegen-request-body-name" : "userdata" + } + }, + "/users" : { + "get" : { + "operationId" : "listUsers", + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/UserResponse" + }, + "type" : "array" + } + }, + "test" : { + "example" : [ { + "apikey" : false, + "blocked" : false, + "id" : "bob", + "roles" : [ "admin:backup:read", "admin:backup:restore", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + }, { + "apikey" : true, + "blocked" : false, + "id" : "script", + "roles" : [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + } ] + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "user:read" ] + } ], + "summary" : "List users", + "tags" : [ "users" ] + }, + "post" : { + "operationId" : "createUser", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserForm" + } + } + }, + "description" : "user object that needs to be added", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/NewUserResponse" + } + }, + "test" : { + "example" : { + "blocked" : false, + "id" : "syncscript", + "roles" : [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read" ], + "secret" : "v39bOuobnlEljfWzjAgoKzhmnh1xSMxH" + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "user:write" ] + } ], + "summary" : "Create user", + "tags" : [ "users" ], + "x-codegen-request-body-name" : "user" + } + }, + "/users/{id}" : { + "delete" : { + "operationId" : "deleteUser", + "parameters" : [ { + "description" : "user ID", + "example" : "script", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "204" : { + "content" : { }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "user:write" ] + } ], + "summary" : "Delete user", + "tags" : [ "users" ] + }, + "get" : { + "operationId" : "getUser", + "parameters" : [ { + "description" : "user ID", + "example" : "script", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserResponse" + } + }, + "test" : { + "example" : { + "apikey" : true, + "blocked" : false, + "id" : "script", + "roles" : [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "user:read" ] + } ], + "summary" : "Get a single user", + "tags" : [ "users" ] + }, + "put" : { + "operationId" : "updateUser", + "parameters" : [ { + "description" : "Template ID", + "example" : "bob", + "in" : "path", + "name" : "id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserForm" + } + } + }, + "description" : "user object that needs to be added", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserResponse" + } + }, + "test" : { + "example" : { + "apikey" : false, + "blocked" : false, + "id" : "bob", + "roles" : [ "admin:backup:read", "admin:backup:restore", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + } + } + }, + "description" : "successful operation" + } + }, + "security" : [ { + "roles" : [ "user:write" ] + } ], + "summary" : "Update user", + "tags" : [ "users" ], + "x-codegen-request-body-name" : "user" + } + } + }, + "components" : { + "schemas" : { + "Artifact" : { + "properties" : { + "enrichments" : { + "additionalProperties" : { + "$ref" : "#/components/schemas/Enrichment" + }, + "type" : "object" + }, + "name" : { + "example" : "2.2.2.2", + "type" : "string" + }, + "status" : { + "example" : "Unknown", + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "required" : [ "name" ], + "type" : "object" + }, + "ArtifactOrigin" : { + "properties" : { + "artifact" : { + "type" : "string" + }, + "ticket_id" : { + "format" : "int64", + "type" : "integer" + } + }, + "required" : [ "artifact", "ticket_id" ], + "type" : "object" + }, + "Automation" : { + "properties" : { + "image" : { + "type" : "string" + }, + "schema" : { + "example" : "{}", + "type" : "string" + }, + "script" : { + "type" : "string" + }, + "type" : { + "items" : { + "enum" : [ "artifact", "playbook", "global" ], + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "image", "script", "type" ], + "type" : "object" + }, + "AutomationForm" : { + "properties" : { + "id" : { + "type" : "string" + }, + "image" : { + "type" : "string" + }, + "schema" : { + "example" : "{}", + "type" : "string" + }, + "script" : { + "type" : "string" + }, + "type" : { + "items" : { + "enum" : [ "artifact", "playbook", "global" ], + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "id", "image", "script", "type" ], + "type" : "object" + }, + "AutomationResponse" : { + "properties" : { + "id" : { + "type" : "string" + }, + "image" : { + "type" : "string" + }, + "schema" : { + "example" : "{}", + "type" : "string" + }, + "script" : { + "type" : "string" + }, + "type" : { + "items" : { + "enum" : [ "artifact", "playbook", "global" ], + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "id", "image", "script", "type" ], + "type" : "object" + }, + "Comment" : { + "properties" : { + "created" : { + "format" : "date-time", + "type" : "string" + }, + "creator" : { + "type" : "string" + }, + "message" : { + "type" : "string" + } + }, + "required" : [ "created", "creator", "message" ], + "type" : "object" + }, + "CommentForm" : { + "properties" : { + "created" : { + "format" : "date-time", + "type" : "string" + }, + "creator" : { + "type" : "string" + }, + "message" : { + "type" : "string" + } + }, + "required" : [ "message" ], + "type" : "object" + }, + "Context" : { + "properties" : { + "artifact" : { + "$ref" : "#/components/schemas/Artifact" + }, + "playbook" : { + "$ref" : "#/components/schemas/PlaybookResponse" + }, + "task" : { + "$ref" : "#/components/schemas/TaskResponse" + }, + "ticket" : { + "$ref" : "#/components/schemas/TicketResponse" + } + }, + "type" : "object" + }, + "Enrichment" : { + "properties" : { + "created" : { + "format" : "date-time", + "type" : "string" + }, + "data" : { + "example" : { + "hash" : "b7a067a742c20d07a7456646de89bc2d408a1153" + }, + "properties" : { }, + "type" : "object" + }, + "name" : { + "example" : "hash.sha1", + "type" : "string" + } + }, + "required" : [ "created", "data", "name" ], + "type" : "object" + }, + "EnrichmentForm" : { + "properties" : { + "data" : { + "example" : { + "hash" : "b7a067a742c20d07a7456646de89bc2d408a1153" + }, + "properties" : { }, + "type" : "object" + }, + "name" : { + "example" : "hash.sha1", + "type" : "string" + } + }, + "required" : [ "data", "name" ], + "type" : "object" + }, + "File" : { + "properties" : { + "key" : { + "example" : "myfile", + "type" : "string" + }, + "name" : { + "example" : "notes.docx", + "type" : "string" + } + }, + "required" : [ "key", "name" ], + "type" : "object" + }, + "Job" : { + "properties" : { + "automation" : { + "type" : "string" + }, + "container" : { + "type" : "string" + }, + "log" : { + "type" : "string" + }, + "origin" : { + "$ref" : "#/components/schemas/Origin" + }, + "output" : { + "properties" : { }, + "type" : "object" + }, + "payload" : { + "type" : "object" + }, + "running" : { + "type" : "boolean" + }, + "status" : { + "type" : "string" + } + }, + "required" : [ "automation", "running", "status" ], + "type" : "object" + }, + "JobForm" : { + "properties" : { + "automation" : { + "type" : "string" + }, + "origin" : { + "$ref" : "#/components/schemas/Origin" + }, + "payload" : { + "type" : "object" + } + }, + "required" : [ "automation" ], + "type" : "object" + }, + "JobResponse" : { + "properties" : { + "automation" : { + "type" : "string" + }, + "container" : { + "type" : "string" + }, + "id" : { + "type" : "string" + }, + "log" : { + "type" : "string" + }, + "origin" : { + "$ref" : "#/components/schemas/Origin" + }, + "output" : { + "properties" : { }, + "type" : "object" + }, + "payload" : { + "type" : "object" + }, + "status" : { + "type" : "string" + } + }, + "required" : [ "automation", "id", "status" ], + "type" : "object" + }, + "LogEntry" : { + "properties" : { + "created" : { + "format" : "date-time", + "type" : "string" + }, + "creator" : { + "type" : "string" + }, + "message" : { + "type" : "string" + }, + "reference" : { + "type" : "string" + } + }, + "required" : [ "created", "creator", "message", "reference" ], + "type" : "object" + }, + "Message" : { + "properties" : { + "context" : { + "$ref" : "#/components/schemas/Context" + }, + "payload" : { + "properties" : { }, + "type" : "object" + }, + "secrets" : { + "additionalProperties" : { + "type" : "string" + }, + "type" : "object" + } + }, + "type" : "object" + }, + "NewUserResponse" : { + "properties" : { + "blocked" : { + "type" : "boolean" + }, + "id" : { + "type" : "string" + }, + "roles" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "secret" : { + "type" : "string" + } + }, + "required" : [ "blocked", "id", "roles" ], + "type" : "object" + }, + "Origin" : { + "properties" : { + "artifact_origin" : { + "$ref" : "#/components/schemas/ArtifactOrigin" + }, + "task_origin" : { + "$ref" : "#/components/schemas/TaskOrigin" + } + }, + "type" : "object" + }, + "Playbook" : { + "properties" : { + "name" : { + "example" : "Phishing", + "type" : "string" + }, + "tasks" : { + "additionalProperties" : { + "$ref" : "#/components/schemas/Task" + }, + "type" : "object" + } + }, + "required" : [ "name", "tasks" ], + "type" : "object" + }, + "PlaybookResponse" : { + "properties" : { + "name" : { + "example" : "Phishing", + "type" : "string" + }, + "tasks" : { + "additionalProperties" : { + "$ref" : "#/components/schemas/TaskResponse" + }, + "type" : "object" + } + }, + "required" : [ "name", "tasks" ], + "type" : "object" + }, + "PlaybookTemplate" : { + "properties" : { + "name" : { + "type" : "string" + }, + "yaml" : { + "type" : "string" + } + }, + "required" : [ "name", "yaml" ], + "type" : "object" + }, + "PlaybookTemplateForm" : { + "properties" : { + "id" : { + "type" : "string" + }, + "yaml" : { + "type" : "string" + } + }, + "required" : [ "yaml" ], + "type" : "object" + }, + "PlaybookTemplateResponse" : { + "properties" : { + "id" : { + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "yaml" : { + "type" : "string" + } + }, + "required" : [ "id", "name", "yaml" ], + "type" : "object" + }, + "Reference" : { + "properties" : { + "href" : { + "example" : "https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2017-0144", + "type" : "string" + }, + "name" : { + "example" : "CVE-2017-0144", + "type" : "string" + } + }, + "required" : [ "href", "name" ], + "type" : "object" + }, + "Settings" : { + "properties" : { + "artifactStates" : { + "items" : { + "$ref" : "#/components/schemas/Type" + }, + "title" : "Artifact States", + "type" : "array" + }, + "roles" : { + "items" : { + "type" : "string" + }, + "title" : "Roles", + "type" : "array" + }, + "ticketTypes" : { + "items" : { + "$ref" : "#/components/schemas/TicketTypeResponse" + }, + "title" : "Ticket Types", + "type" : "array" + }, + "tier" : { + "enum" : [ "community", "enterprise" ], + "title" : "Tier", + "type" : "string" + }, + "timeformat" : { + "title" : "Time Format", + "type" : "string" + }, + "version" : { + "title" : "Version", + "type" : "string" + } + }, + "required" : [ "artifactStates", "ticketTypes", "tier", "timeformat", "version" ], + "type" : "object" + }, + "Statistics" : { + "properties" : { + "open_tickets_per_user" : { + "additionalProperties" : { + "type" : "integer" + }, + "type" : "object" + }, + "tickets_per_type" : { + "additionalProperties" : { + "type" : "integer" + }, + "type" : "object" + }, + "tickets_per_week" : { + "additionalProperties" : { + "type" : "integer" + }, + "type" : "object" + }, + "unassigned" : { + "type" : "integer" + } + }, + "required" : [ "open_tickets_per_user", "tickets_per_type", "tickets_per_week", "unassigned" ], + "type" : "object" + }, + "Task" : { + "properties" : { + "automation" : { + "type" : "string" + }, + "closed" : { + "format" : "date-time", + "type" : "string" + }, + "created" : { + "format" : "date-time", + "type" : "string" + }, + "data" : { + "properties" : { }, + "type" : "object" + }, + "done" : { + "type" : "boolean" + }, + "join" : { + "example" : false, + "type" : "boolean" + }, + "name" : { + "example" : "Inform user", + "type" : "string" + }, + "next" : { + "additionalProperties" : { + "type" : "string" + }, + "type" : "object" + }, + "owner" : { + "type" : "string" + }, + "payload" : { + "additionalProperties" : { + "type" : "string" + }, + "type" : "object" + }, + "schema" : { + "properties" : { }, + "type" : "object" + }, + "type" : { + "enum" : [ "task", "input", "automation" ], + "example" : "task", + "type" : "string" + } + }, + "required" : [ "created", "done", "name", "type" ], + "type" : "object" + }, + "TaskForm" : { + "properties" : { + "automation" : { + "type" : "string" + }, + "closed" : { + "format" : "date-time", + "type" : "string" + }, + "created" : { + "format" : "date-time", + "type" : "string" + }, + "data" : { + "properties" : { }, + "type" : "object" + }, + "done" : { + "type" : "boolean" + }, + "join" : { + "example" : false, + "type" : "boolean" + }, + "name" : { + "example" : "Inform user", + "type" : "string" + }, + "next" : { + "additionalProperties" : { + "type" : "string" + }, + "type" : "object" + }, + "owner" : { + "type" : "string" + }, + "payload" : { + "additionalProperties" : { + "type" : "string" + }, + "type" : "object" + }, + "schema" : { + "properties" : { }, + "type" : "object" + }, + "type" : { + "enum" : [ "task", "input", "automation" ], + "example" : "task", + "type" : "string" + } + }, + "required" : [ "name", "type" ], + "type" : "object" + }, + "TaskOrigin" : { + "properties" : { + "playbook_id" : { + "type" : "string" + }, + "task_id" : { + "type" : "string" + }, + "ticket_id" : { + "format" : "int64", + "type" : "integer" + } + }, + "required" : [ "playbook_id", "task_id", "ticket_id" ], + "type" : "object" + }, + "TaskResponse" : { + "properties" : { + "active" : { + "example" : false, + "type" : "boolean" + }, + "automation" : { + "type" : "string" + }, + "closed" : { + "format" : "date-time", + "type" : "string" + }, + "created" : { + "format" : "date-time", + "type" : "string" + }, + "data" : { + "properties" : { }, + "type" : "object" + }, + "done" : { + "type" : "boolean" + }, + "join" : { + "example" : false, + "type" : "boolean" + }, + "name" : { + "example" : "Inform user", + "type" : "string" + }, + "next" : { + "additionalProperties" : { + "type" : "string" + }, + "type" : "object" + }, + "order" : { + "example" : 2.0, + "format" : "int64", + "type" : "number" + }, + "owner" : { + "type" : "string" + }, + "payload" : { + "additionalProperties" : { + "type" : "string" + }, + "type" : "object" + }, + "schema" : { + "properties" : { }, + "type" : "object" + }, + "type" : { + "enum" : [ "task", "input", "automation" ], + "example" : "task", + "type" : "string" + } + }, + "required" : [ "active", "created", "done", "name", "order", "type" ], + "type" : "object" + }, + "TaskWithContext" : { + "properties" : { + "playbook_id" : { + "type" : "string" + }, + "playbook_name" : { + "type" : "string" + }, + "task" : { + "$ref" : "#/components/schemas/TaskResponse" + }, + "task_id" : { + "type" : "string" + }, + "ticket_id" : { + "format" : "int64", + "type" : "number" + }, + "ticket_name" : { + "type" : "string" + } + }, + "required" : [ "playbook_id", "playbook_name", "task", "task_id", "ticket_id", "ticket_name" ], + "type" : "object" + }, + "Ticket" : { + "properties" : { + "artifacts" : { + "items" : { + "$ref" : "#/components/schemas/Artifact" + }, + "type" : "array" + }, + "comments" : { + "items" : { + "$ref" : "#/components/schemas/Comment" + }, + "type" : "array" + }, + "created" : { + "format" : "date-time", + "type" : "string" + }, + "details" : { + "example" : { + "description" : "my little incident" + }, + "properties" : { }, + "type" : "object" + }, + "files" : { + "items" : { + "$ref" : "#/components/schemas/File" + }, + "type" : "array" + }, + "modified" : { + "format" : "date-time", + "type" : "string" + }, + "name" : { + "example" : "WannyCry", + "type" : "string" + }, + "owner" : { + "example" : "bob", + "type" : "string" + }, + "playbooks" : { + "additionalProperties" : { + "$ref" : "#/components/schemas/Playbook" + }, + "type" : "object" + }, + "read" : { + "example" : [ "bob" ], + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "references" : { + "items" : { + "$ref" : "#/components/schemas/Reference" + }, + "type" : "array" + }, + "schema" : { + "example" : "{}", + "type" : "string" + }, + "status" : { + "example" : "open", + "type" : "string" + }, + "type" : { + "example" : "incident", + "type" : "string" + }, + "write" : { + "example" : [ "alice" ], + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "created", "modified", "name", "schema", "status", "type" ], + "type" : "object" + }, + "TicketForm" : { + "properties" : { + "artifacts" : { + "items" : { + "$ref" : "#/components/schemas/Artifact" + }, + "type" : "array" + }, + "comments" : { + "items" : { + "$ref" : "#/components/schemas/Comment" + }, + "type" : "array" + }, + "created" : { + "format" : "date-time", + "type" : "string" + }, + "details" : { + "example" : { + "description" : "my little incident" + }, + "properties" : { }, + "type" : "object" + }, + "files" : { + "items" : { + "$ref" : "#/components/schemas/File" + }, + "type" : "array" + }, + "id" : { + "example" : 123, + "format" : "int64", + "type" : "integer" + }, + "modified" : { + "format" : "date-time", + "type" : "string" + }, + "name" : { + "example" : "WannyCry", + "type" : "string" + }, + "owner" : { + "example" : "bob", + "type" : "string" + }, + "playbooks" : { + "items" : { + "$ref" : "#/components/schemas/PlaybookTemplateForm" + }, + "type" : "array" + }, + "read" : { + "example" : [ "bob" ], + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "references" : { + "items" : { + "$ref" : "#/components/schemas/Reference" + }, + "type" : "array" + }, + "schema" : { + "example" : "{}", + "type" : "string" + }, + "status" : { + "example" : "open", + "type" : "string" + }, + "type" : { + "example" : "incident", + "type" : "string" + }, + "write" : { + "example" : [ "alice" ], + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "name", "status", "type" ], + "type" : "object" + }, + "TicketList" : { + "properties" : { + "count" : { + "example" : 3.0, + "type" : "number" + }, + "tickets" : { + "items" : { + "$ref" : "#/components/schemas/TicketSimpleResponse" + }, + "type" : "array" + } + }, + "required" : [ "count", "tickets" ], + "type" : "object" + }, + "TicketResponse" : { + "properties" : { + "artifacts" : { + "items" : { + "$ref" : "#/components/schemas/Artifact" + }, + "type" : "array" + }, + "comments" : { + "items" : { + "$ref" : "#/components/schemas/Comment" + }, + "type" : "array" + }, + "created" : { + "format" : "date-time", + "type" : "string" + }, + "details" : { + "example" : { + "description" : "my little incident" + }, + "properties" : { }, + "type" : "object" + }, + "files" : { + "items" : { + "$ref" : "#/components/schemas/File" + }, + "type" : "array" + }, + "id" : { + "example" : 123, + "format" : "int64", + "type" : "integer" + }, + "modified" : { + "format" : "date-time", + "type" : "string" + }, + "name" : { + "example" : "WannyCry", + "type" : "string" + }, + "owner" : { + "example" : "bob", + "type" : "string" + }, + "playbooks" : { + "additionalProperties" : { + "$ref" : "#/components/schemas/PlaybookResponse" + }, + "type" : "object" + }, + "read" : { + "example" : [ "bob" ], + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "references" : { + "items" : { + "$ref" : "#/components/schemas/Reference" + }, + "type" : "array" + }, + "schema" : { + "example" : "{}", + "type" : "string" + }, + "status" : { + "example" : "open", + "type" : "string" + }, + "type" : { + "example" : "incident", + "type" : "string" + }, + "write" : { + "example" : [ "alice" ], + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "created", "id", "modified", "name", "schema", "status", "type" ], + "type" : "object" + }, + "TicketSimpleResponse" : { + "properties" : { + "artifacts" : { + "items" : { + "$ref" : "#/components/schemas/Artifact" + }, + "type" : "array" + }, + "comments" : { + "items" : { + "$ref" : "#/components/schemas/Comment" + }, + "type" : "array" + }, + "created" : { + "format" : "date-time", + "type" : "string" + }, + "details" : { + "example" : { + "description" : "my little incident" + }, + "properties" : { }, + "type" : "object" + }, + "files" : { + "items" : { + "$ref" : "#/components/schemas/File" + }, + "type" : "array" + }, + "id" : { + "example" : 123, + "format" : "int64", + "type" : "integer" + }, + "modified" : { + "format" : "date-time", + "type" : "string" + }, + "name" : { + "example" : "WannyCry", + "type" : "string" + }, + "owner" : { + "example" : "bob", + "type" : "string" + }, + "playbooks" : { + "additionalProperties" : { + "$ref" : "#/components/schemas/Playbook" + }, + "type" : "object" + }, + "read" : { + "example" : [ "bob" ], + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "references" : { + "items" : { + "$ref" : "#/components/schemas/Reference" + }, + "type" : "array" + }, + "schema" : { + "example" : "{}", + "type" : "string" + }, + "status" : { + "example" : "open", + "type" : "string" + }, + "type" : { + "example" : "incident", + "type" : "string" + }, + "write" : { + "example" : [ "alice" ], + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "created", "id", "modified", "name", "schema", "status", "type" ], + "type" : "object" + }, + "TicketTemplate" : { + "properties" : { + "name" : { + "type" : "string" + }, + "schema" : { + "type" : "string" + } + }, + "required" : [ "name", "schema" ], + "type" : "object" + }, + "TicketTemplateForm" : { + "properties" : { + "id" : { + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "schema" : { + "type" : "string" + } + }, + "required" : [ "name", "schema" ], + "type" : "object" + }, + "TicketTemplateResponse" : { + "properties" : { + "id" : { + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "schema" : { + "type" : "string" + } + }, + "required" : [ "id", "name", "schema" ], + "type" : "object" + }, + "TicketType" : { + "properties" : { + "default_groups" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "default_playbooks" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "default_template" : { + "type" : "string" + }, + "icon" : { + "type" : "string" + }, + "name" : { + "type" : "string" + } + }, + "required" : [ "default_playbooks", "default_template", "icon", "name" ], + "type" : "object" + }, + "TicketTypeForm" : { + "properties" : { + "default_groups" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "default_playbooks" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "default_template" : { + "type" : "string" + }, + "icon" : { + "type" : "string" + }, + "id" : { + "type" : "string" + }, + "name" : { + "type" : "string" + } + }, + "required" : [ "default_playbooks", "default_template", "icon", "name" ], + "type" : "object" + }, + "TicketTypeResponse" : { + "properties" : { + "default_groups" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "default_playbooks" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "default_template" : { + "type" : "string" + }, + "icon" : { + "type" : "string" + }, + "id" : { + "type" : "string" + }, + "name" : { + "type" : "string" + } + }, + "required" : [ "default_playbooks", "default_template", "icon", "id", "name" ], + "type" : "object" + }, + "TicketWithTickets" : { + "properties" : { + "artifacts" : { + "items" : { + "$ref" : "#/components/schemas/Artifact" + }, + "type" : "array" + }, + "comments" : { + "items" : { + "$ref" : "#/components/schemas/Comment" + }, + "type" : "array" + }, + "created" : { + "format" : "date-time", + "type" : "string" + }, + "details" : { + "example" : { + "description" : "my little incident" + }, + "properties" : { }, + "type" : "object" + }, + "files" : { + "items" : { + "$ref" : "#/components/schemas/File" + }, + "type" : "array" + }, + "id" : { + "example" : 123, + "format" : "int64", + "type" : "integer" + }, + "modified" : { + "format" : "date-time", + "type" : "string" + }, + "name" : { + "example" : "WannyCry", + "type" : "string" + }, + "owner" : { + "example" : "bob", + "type" : "string" + }, + "playbooks" : { + "additionalProperties" : { + "$ref" : "#/components/schemas/PlaybookResponse" + }, + "type" : "object" + }, + "read" : { + "example" : [ "bob" ], + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "references" : { + "items" : { + "$ref" : "#/components/schemas/Reference" + }, + "type" : "array" + }, + "schema" : { + "example" : "{}", + "type" : "string" + }, + "status" : { + "example" : "open", + "type" : "string" + }, + "tickets" : { + "items" : { + "$ref" : "#/components/schemas/TicketSimpleResponse" + }, + "type" : "array" + }, + "type" : { + "example" : "incident", + "type" : "string" + }, + "write" : { + "example" : [ "alice" ], + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "created", "id", "modified", "name", "schema", "status", "type" ], + "type" : "object" + }, + "Type" : { + "properties" : { + "color" : { + "enum" : [ "error", "info", "success", "warning" ], + "title" : "Color", + "type" : "string", + "x-cols" : 3 + }, + "icon" : { + "title" : "Icon (https://materialdesignicons.com)", + "type" : "string", + "x-cols" : 3, + "x-class" : "pr-2" + }, + "id" : { + "title" : "ID", + "type" : "string", + "x-cols" : 3, + "x-class" : "pr-2" + }, + "name" : { + "title" : "Name", + "type" : "string", + "x-cols" : 3, + "x-class" : "pr-2" + } + }, + "required" : [ "icon", "id", "name" ], + "type" : "object" + }, + "User" : { + "properties" : { + "apikey" : { + "type" : "boolean" + }, + "blocked" : { + "type" : "boolean" + }, + "roles" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "sha256" : { + "type" : "string" + } + }, + "required" : [ "apikey", "blocked", "roles" ], + "type" : "object" + }, + "UserData" : { + "properties" : { + "email" : { + "type" : "string" + }, + "image" : { + "type" : "string", + "x-display" : "custom-avatar" + }, + "name" : { + "type" : "string" + }, + "timeformat" : { + "title" : "Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens)", + "type" : "string" + } + }, + "type" : "object" + }, + "UserDataResponse" : { + "properties" : { + "email" : { + "type" : "string" + }, + "id" : { + "type" : "string" + }, + "image" : { + "type" : "string", + "x-display" : "custom-avatar" + }, + "name" : { + "type" : "string" + }, + "timeformat" : { + "title" : "Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens)", + "type" : "string" + } + }, + "required" : [ "id" ], + "type" : "object" + }, + "UserForm" : { + "properties" : { + "apikey" : { + "type" : "boolean" + }, + "blocked" : { + "type" : "boolean" + }, + "id" : { + "type" : "string" + }, + "roles" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "apikey", "blocked", "id", "roles" ], + "type" : "object" + }, + "UserResponse" : { + "properties" : { + "apikey" : { + "type" : "boolean" + }, + "blocked" : { + "type" : "boolean" + }, + "id" : { + "type" : "string" + }, + "roles" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ "apikey", "blocked", "id", "roles" ], + "type" : "object" + } + } + }, + "x-original-swagger-version" : "2.0" +} \ No newline at end of file diff --git a/generated/community.yml b/generated/community.yml new file mode 100644 index 0000000..26fbae4 --- /dev/null +++ b/generated/community.yml @@ -0,0 +1,6646 @@ +basePath: /api +consumes: +- application/json +definitions: + Artifact: + properties: + enrichments: + additionalProperties: + $ref: '#/definitions/Enrichment' + type: object + name: + example: 2.2.2.2 + type: string + status: + example: Unknown + type: string + type: + type: string + required: + - name + type: object + ArtifactOrigin: + properties: + artifact: + type: string + ticket_id: + format: int64 + type: integer + required: + - ticket_id + - artifact + type: object + Automation: + properties: + image: + type: string + schema: + example: '{}' + type: string + script: + type: string + type: + items: + enum: + - artifact + - playbook + - global + type: string + type: array + required: + - image + - script + - type + type: object + AutomationForm: + properties: + id: + type: string + image: + type: string + schema: + example: '{}' + type: string + script: + type: string + type: + items: + enum: + - artifact + - playbook + - global + type: string + type: array + required: + - id + - image + - script + - type + type: object + AutomationResponse: + properties: + id: + type: string + image: + type: string + schema: + example: '{}' + type: string + script: + type: string + type: + items: + enum: + - artifact + - playbook + - global + type: string + type: array + required: + - id + - image + - script + - type + type: object + Comment: + properties: + created: + format: date-time + type: string + creator: + type: string + message: + type: string + required: + - creator + - created + - message + type: object + CommentForm: + properties: + created: + format: date-time + type: string + creator: + type: string + message: + type: string + required: + - message + type: object + Context: + properties: + artifact: + $ref: '#/definitions/Artifact' + playbook: + $ref: '#/definitions/PlaybookResponse' + task: + $ref: '#/definitions/TaskResponse' + ticket: + $ref: '#/definitions/TicketResponse' + type: object + Enrichment: + properties: + created: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + data: + example: + hash: b7a067a742c20d07a7456646de89bc2d408a1153 + type: object + name: + example: hash.sha1 + type: string + required: + - name + - data + - created + type: object + EnrichmentForm: + properties: + data: + example: + hash: b7a067a742c20d07a7456646de89bc2d408a1153 + type: object + name: + example: hash.sha1 + type: string + required: + - name + - data + type: object + File: + properties: + key: + example: myfile + type: string + name: + example: notes.docx + type: string + required: + - key + - name + type: object + Job: + properties: + automation: + type: string + container: + type: string + log: + type: string + origin: + $ref: '#/definitions/Origin' + output: + type: object + payload: {} + running: + type: boolean + status: + type: string + required: + - automation + - running + - status + type: object + JobForm: + properties: + automation: + type: string + origin: + $ref: '#/definitions/Origin' + payload: {} + required: + - automation + type: object + JobResponse: + properties: + automation: + type: string + container: + type: string + id: + type: string + log: + type: string + origin: + $ref: '#/definitions/Origin' + output: + type: object + payload: {} + status: + type: string + required: + - id + - automation + - status + type: object + LogEntry: + properties: + created: + format: date-time + type: string + creator: + type: string + message: + type: string + reference: + type: string + required: + - reference + - creator + - created + - message + type: object + Message: + properties: + context: + $ref: '#/definitions/Context' + payload: + type: object + secrets: + additionalProperties: + type: string + type: object + type: object + NewUserResponse: + properties: + blocked: + type: boolean + id: + type: string + roles: + items: + type: string + type: array + secret: + type: string + required: + - id + - blocked + - roles + type: object + Origin: + properties: + artifact_origin: + $ref: '#/definitions/ArtifactOrigin' + task_origin: + $ref: '#/definitions/TaskOrigin' + type: object + Playbook: + properties: + name: + example: Phishing + type: string + tasks: + additionalProperties: + $ref: '#/definitions/Task' + type: object + required: + - name + - tasks + type: object + PlaybookResponse: + properties: + name: + example: Phishing + type: string + tasks: + additionalProperties: + $ref: '#/definitions/TaskResponse' + type: object + required: + - name + - tasks + type: object + PlaybookTemplate: + properties: + name: + type: string + yaml: + type: string + required: + - name + - yaml + type: object + PlaybookTemplateForm: + properties: + id: + type: string + yaml: + type: string + required: + - yaml + type: object + PlaybookTemplateResponse: + properties: + id: + type: string + name: + type: string + yaml: + type: string + required: + - id + - name + - yaml + type: object + Reference: + properties: + href: + example: https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2017-0144 + type: string + name: + example: CVE-2017-0144 + type: string + required: + - name + - href + type: object + Settings: + properties: + artifactStates: + items: + $ref: '#/definitions/Type' + title: Artifact States + type: array + roles: + items: + type: string + title: Roles + type: array + ticketTypes: + items: + $ref: '#/definitions/TicketTypeResponse' + title: Ticket Types + type: array + tier: + enum: + - community + - enterprise + title: Tier + type: string + timeformat: + title: Time Format + type: string + version: + title: Version + type: string + required: + - version + - tier + - timeformat + - ticketTypes + - artifactStates + type: object + Statistics: + properties: + open_tickets_per_user: + additionalProperties: + type: integer + type: object + tickets_per_type: + additionalProperties: + type: integer + type: object + tickets_per_week: + additionalProperties: + type: integer + type: object + unassigned: + type: integer + required: + - unassigned + - open_tickets_per_user + - tickets_per_week + - tickets_per_type + type: object + Task: + properties: + automation: + type: string + closed: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + created: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + data: + type: object + done: + type: boolean + join: + example: false + type: boolean + name: + example: Inform user + type: string + next: + additionalProperties: + type: string + type: object + owner: + type: string + payload: + additionalProperties: + type: string + type: object + schema: + type: object + type: + enum: + - task + - input + - automation + example: task + type: string + required: + - name + - type + - done + - created + type: object + TaskForm: + properties: + automation: + type: string + closed: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + created: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + data: + type: object + done: + type: boolean + join: + example: false + type: boolean + name: + example: Inform user + type: string + next: + additionalProperties: + type: string + type: object + owner: + type: string + payload: + additionalProperties: + type: string + type: object + schema: + type: object + type: + enum: + - task + - input + - automation + example: task + type: string + required: + - name + - type + type: object + TaskOrigin: + properties: + playbook_id: + type: string + task_id: + type: string + ticket_id: + format: int64 + type: integer + required: + - ticket_id + - playbook_id + - task_id + type: object + TaskResponse: + properties: + active: + example: false + type: boolean + automation: + type: string + closed: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + created: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + data: + type: object + done: + type: boolean + join: + example: false + type: boolean + name: + example: Inform user + type: string + next: + additionalProperties: + type: string + type: object + order: + example: 2 + format: int64 + type: number + owner: + type: string + payload: + additionalProperties: + type: string + type: object + schema: + type: object + type: + enum: + - task + - input + - automation + example: task + type: string + required: + - name + - type + - done + - created + - order + - active + type: object + TaskWithContext: + properties: + playbook_id: + type: string + playbook_name: + type: string + task: + $ref: '#/definitions/TaskResponse' + task_id: + type: string + ticket_id: + format: int64 + type: number + ticket_name: + type: string + required: + - ticket_id + - ticket_name + - playbook_id + - playbook_name + - task_id + - task + type: object + Ticket: + properties: + artifacts: + items: + $ref: '#/definitions/Artifact' + type: array + comments: + items: + $ref: '#/definitions/Comment' + type: array + created: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + details: + example: + description: my little incident + type: object + files: + items: + $ref: '#/definitions/File' + type: array + modified: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + name: + example: WannyCry + type: string + owner: + example: bob + type: string + playbooks: + additionalProperties: + $ref: '#/definitions/Playbook' + type: object + read: + example: + - bob + items: + type: string + type: array + references: + items: + $ref: '#/definitions/Reference' + type: array + schema: + example: '{}' + type: string + status: + example: open + type: string + type: + example: incident + type: string + write: + example: + - alice + items: + type: string + type: array + required: + - name + - type + - status + - created + - modified + - schema + type: object + TicketForm: + properties: + artifacts: + items: + $ref: '#/definitions/Artifact' + type: array + comments: + items: + $ref: '#/definitions/Comment' + type: array + created: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + details: + example: + description: my little incident + type: object + files: + items: + $ref: '#/definitions/File' + type: array + id: + example: 123 + format: int64 + type: integer + modified: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + name: + example: WannyCry + type: string + owner: + example: bob + type: string + playbooks: + items: + $ref: '#/definitions/PlaybookTemplateForm' + type: array + read: + example: + - bob + items: + type: string + type: array + references: + items: + $ref: '#/definitions/Reference' + type: array + schema: + example: '{}' + type: string + status: + example: open + type: string + type: + example: incident + type: string + write: + example: + - alice + items: + type: string + type: array + required: + - name + - type + - status + type: object + TicketList: + properties: + count: + example: 3 + type: number + tickets: + items: + $ref: '#/definitions/TicketSimpleResponse' + type: array + required: + - tickets + - count + type: object + TicketResponse: + properties: + artifacts: + items: + $ref: '#/definitions/Artifact' + type: array + comments: + items: + $ref: '#/definitions/Comment' + type: array + created: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + details: + example: + description: my little incident + type: object + files: + items: + $ref: '#/definitions/File' + type: array + id: + example: 123 + format: int64 + type: integer + modified: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + name: + example: WannyCry + type: string + owner: + example: bob + type: string + playbooks: + additionalProperties: + $ref: '#/definitions/PlaybookResponse' + type: object + read: + example: + - bob + items: + type: string + type: array + references: + items: + $ref: '#/definitions/Reference' + type: array + schema: + example: '{}' + type: string + status: + example: open + type: string + type: + example: incident + type: string + write: + example: + - alice + items: + type: string + type: array + required: + - id + - name + - type + - status + - created + - modified + - schema + type: object + TicketSimpleResponse: + properties: + artifacts: + items: + $ref: '#/definitions/Artifact' + type: array + comments: + items: + $ref: '#/definitions/Comment' + type: array + created: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + details: + example: + description: my little incident + type: object + files: + items: + $ref: '#/definitions/File' + type: array + id: + example: 123 + format: int64 + type: integer + modified: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + name: + example: WannyCry + type: string + owner: + example: bob + type: string + playbooks: + additionalProperties: + $ref: '#/definitions/Playbook' + type: object + read: + example: + - bob + items: + type: string + type: array + references: + items: + $ref: '#/definitions/Reference' + type: array + schema: + example: '{}' + type: string + status: + example: open + type: string + type: + example: incident + type: string + write: + example: + - alice + items: + type: string + type: array + required: + - id + - name + - type + - status + - created + - modified + - schema + type: object + TicketTemplate: + properties: + name: + type: string + schema: + type: string + required: + - name + - schema + type: object + TicketTemplateForm: + properties: + id: + type: string + name: + type: string + schema: + type: string + required: + - name + - schema + type: object + TicketTemplateResponse: + properties: + id: + type: string + name: + type: string + schema: + type: string + required: + - id + - name + - schema + type: object + TicketType: + properties: + default_groups: + items: + type: string + type: array + default_playbooks: + items: + type: string + type: array + default_template: + type: string + icon: + type: string + name: + type: string + required: + - name + - icon + - default_template + - default_playbooks + type: object + TicketTypeForm: + properties: + default_groups: + items: + type: string + type: array + default_playbooks: + items: + type: string + type: array + default_template: + type: string + icon: + type: string + id: + type: string + name: + type: string + required: + - name + - icon + - default_template + - default_playbooks + type: object + TicketTypeResponse: + properties: + default_groups: + items: + type: string + type: array + default_playbooks: + items: + type: string + type: array + default_template: + type: string + icon: + type: string + id: + type: string + name: + type: string + required: + - id + - name + - icon + - default_template + - default_playbooks + type: object + TicketWithTickets: + properties: + artifacts: + items: + $ref: '#/definitions/Artifact' + type: array + comments: + items: + $ref: '#/definitions/Comment' + type: array + created: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + details: + example: + description: my little incident + type: object + files: + items: + $ref: '#/definitions/File' + type: array + id: + example: 123 + format: int64 + type: integer + modified: + example: 1985-04-12T23:20:50.52Z + format: date-time + type: string + name: + example: WannyCry + type: string + owner: + example: bob + type: string + playbooks: + additionalProperties: + $ref: '#/definitions/PlaybookResponse' + type: object + read: + example: + - bob + items: + type: string + type: array + references: + items: + $ref: '#/definitions/Reference' + type: array + schema: + example: '{}' + type: string + status: + example: open + type: string + tickets: + items: + $ref: '#/definitions/TicketSimpleResponse' + type: array + type: + example: incident + type: string + write: + example: + - alice + items: + type: string + type: array + required: + - id + - name + - type + - status + - created + - modified + - schema + type: object + Type: + properties: + color: + enum: + - error + - info + - success + - warning + title: Color + type: string + x-cols: 3 + icon: + title: Icon (https://materialdesignicons.com) + type: string + x-class: pr-2 + x-cols: 3 + id: + title: ID + type: string + x-class: pr-2 + x-cols: 3 + name: + title: Name + type: string + x-class: pr-2 + x-cols: 3 + required: + - id + - name + - icon + type: object + User: + properties: + apikey: + type: boolean + blocked: + type: boolean + roles: + items: + type: string + type: array + sha256: + type: string + required: + - blocked + - apikey + - roles + type: object + UserData: + properties: + email: + type: string + x-example: bob@example.org + image: + type: string + x-display: custom-avatar + name: + type: string + x-example: Robert Smith + timeformat: + title: Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens) + type: string + type: object + UserDataResponse: + properties: + email: + type: string + x-example: bob@example.org + id: + type: string + image: + type: string + x-display: custom-avatar + name: + type: string + x-example: Robert Smith + timeformat: + title: Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens) + type: string + required: + - id + type: object + UserForm: + properties: + apikey: + type: boolean + blocked: + type: boolean + id: + type: string + roles: + items: + type: string + type: array + required: + - id + - blocked + - roles + - apikey + type: object + UserResponse: + properties: + apikey: + type: boolean + blocked: + type: boolean + id: + type: string + roles: + items: + type: string + type: array + required: + - id + - blocked + - roles + - apikey + type: object +host: . +info: + description: API for the catalyst incident response platform. + title: "" + version: "" +paths: + /automations: + get: + operationId: listAutomations + responses: + "200": + description: successful operation + examples: + test: + - id: comment + image: docker.io/python:3 + script: "" + type: + - playbook + - id: hash.sha1 + image: docker.io/python:3 + schema: '{"title":"Input","type":"object","properties":{"default":{"type":"string","title":"Value"}},"required":["default"]}' + script: "" + type: + - global + - artifact + - playbook + - id: thehive + image: docker.io/python:3 + schema: '{"title":"TheHive credentials","type":"object","properties":{"thehiveurl":{"type":"string","title":"TheHive + URL (e.g. ''https://thehive.example.org'')"},"thehivekey":{"type":"string","title":"TheHive + API Key"},"skip_files":{"type":"boolean", "default": true, "title":"Skip + Files (much faster)"},"keep_ids":{"type":"boolean", "default": true, + "title":"Keep IDs and overwrite existing IDs"}},"required":["thehiveurl", + "thehivekey", "skip_files", "keep_ids"]}' + script: "" + type: + - global + - id: vt.hash + image: docker.io/python:3 + schema: '{"title":"Input","type":"object","properties":{"default":{"type":"string","title":"Value"}},"required":["default"]}' + script: "" + type: + - global + - artifact + - playbook + schema: + items: + $ref: '#/definitions/AutomationResponse' + type: array + security: + - roles: + - automation:read + summary: List automations + tags: + - automations + post: + operationId: createAutomation + parameters: + - description: New automation + in: body + name: automation + required: true + schema: + $ref: '#/definitions/AutomationForm' + x-example: + id: hash-sha-256 + image: docker.io/python:3 + script: | + import sys + import json + import hashlib + + + def run(msg): + sha256 = hashlib.sha256(msg['payload']['default'].encode('utf-8')) + return {'hash': sha256.hexdigest()} + + + print(json.dumps(run(json.loads(sys.argv[1])))) + type: + - global + responses: + "200": + description: successful operation + examples: + test: + id: hash-sha-256 + image: docker.io/python:3 + script: | + import sys + import json + import hashlib + + + def run(msg): + sha256 = hashlib.sha256(msg['payload']['default'].encode('utf-8')) + return {'hash': sha256.hexdigest()} + + + print(json.dumps(run(json.loads(sys.argv[1])))) + type: + - global + schema: + $ref: '#/definitions/AutomationResponse' + security: + - roles: + - automation:write + summary: Create a new automation + tags: + - automations + /automations/{id}: + delete: + operationId: deleteAutomation + parameters: + - description: Automation ID + in: path + name: id + required: true + type: string + x-example: hash.sha1 + responses: + "204": + description: successful operation + security: + - roles: + - automation:write + summary: Delete a automation + tags: + - automations + get: + operationId: getAutomation + parameters: + - description: Automation ID + in: path + name: id + required: true + type: string + x-example: hash.sha1 + responses: + "200": + description: successful operation + examples: + test: + id: hash.sha1 + image: docker.io/python:3 + schema: '{"title":"Input","type":"object","properties":{"default":{"type":"string","title":"Value"}},"required":["default"]}' + script: | + #!/usr/bin/env python + + import sys + import json + import hashlib + + + def run(msg): + sha1 = hashlib.sha1(msg['payload']['default'].encode('utf-8')) + return {"hash": sha1.hexdigest()} + + + print(json.dumps(run(json.loads(sys.argv[1])))) + type: + - global + - artifact + - playbook + schema: + $ref: '#/definitions/AutomationResponse' + security: + - roles: + - automation:read + summary: Get a single automation + tags: + - automations + put: + operationId: updateAutomation + parameters: + - description: Automation ID + in: path + name: id + required: true + type: string + x-example: hash.sha1 + - description: Automation object that needs to be added + in: body + name: automation + required: true + schema: + $ref: '#/definitions/AutomationForm' + x-example: + id: hash.sha1 + image: docker.io/python:3 + script: | + import sys + import json + import hashlib + + + def run(msg): + sha1 = hashlib.sha1(msg['payload'].encode('utf-8')) + return {'hash': sha1.hexdigest()} + + + print(json.dumps(run(json.loads(sys.argv[1])))) + type: + - global + - artifact + - playbook + responses: + "200": + description: successful operation + examples: + test: + id: hash.sha1 + image: docker.io/python:3 + script: | + import sys + import json + import hashlib + + + def run(msg): + sha1 = hashlib.sha1(msg['payload'].encode('utf-8')) + return {'hash': sha1.hexdigest()} + + + print(json.dumps(run(json.loads(sys.argv[1])))) + type: + - global + - artifact + - playbook + schema: + $ref: '#/definitions/AutomationResponse' + security: + - roles: + - automation:write + summary: Update an existing automation + tags: + - automations + /currentuser: + get: + operationId: currentUser + responses: + "200": + description: successful operation + examples: + test: + apikey: false + blocked: false + id: bob + roles: + - admin:backup:read + - admin:backup:restore + - admin:group:write + - admin:job:read + - admin:job:write + - admin:log:read + - admin:ticket:delete + - admin:user:write + - admin:userdata:read + - admin:userdata:write + - analyst:automation:read + - analyst:currentsettings:write + - analyst:currentuser:read + - analyst:currentuserdata:read + - analyst:file + - analyst:group:read + - analyst:playbook:read + - analyst:rule:read + - analyst:settings:read + - analyst:template:read + - analyst:ticket:read + - analyst:ticket:write + - analyst:tickettype:read + - analyst:user:read + - engineer:automation:write + - engineer:playbook:write + - engineer:rule:write + - engineer:template:write + - engineer:tickettype:write + schema: + $ref: '#/definitions/UserResponse' + security: + - roles: + - currentuser:read + summary: Get current user + tags: + - users + /currentuserdata: + get: + operationId: currentUserData + responses: + "200": + description: successful operation + examples: + test: + email: bob@example.org + id: bob + name: Bob Bad + schema: + $ref: '#/definitions/UserDataResponse' + security: + - roles: + - currentuserdata:read + summary: Get current user data + tags: + - userdata + put: + operationId: updateCurrentUserData + parameters: + - description: User data object that needs to be added + in: body + name: userdata + required: true + schema: + $ref: '#/definitions/UserData' + x-example: + email: bob@example.org + name: Bob Bad + responses: + "200": + description: successful operation + examples: + test: + email: bob@example.org + id: bob + name: Bob Bad + schema: + $ref: '#/definitions/UserDataResponse' + security: + - roles: + - currentuserdata:write + summary: Update current user data + tags: + - userdata + /jobs: + get: + operationId: listJobs + responses: + "200": + description: successful operation + examples: + test: + - automation: hash.sha1 + id: 99cd67131b48 + payload: test + status: created + schema: + items: + $ref: '#/definitions/JobResponse' + type: array + security: + - roles: + - job:read + summary: List jobs + tags: + - jobs + post: + operationId: runJob + parameters: + - description: New job + in: body + name: job + required: true + schema: + $ref: '#/definitions/JobForm' + x-example: + automation: hash.sha1 + message: + payload: test + responses: + "204": + description: successful operation + security: + - roles: + - job:write + summary: Start a new job + tags: + - jobs + /jobs/{id}: + get: + operationId: getJob + parameters: + - description: Job ID + in: path + name: id + required: true + type: string + x-example: 99cd67131b48 + responses: + "200": + description: successful operation + examples: + test: + automation: hash.sha1 + id: 99cd67131b48 + payload: test + status: created + schema: + $ref: '#/definitions/JobResponse' + security: + - roles: + - job:read + summary: Get a single job + tags: + - jobs + put: + operationId: updateJob + parameters: + - description: Job ID + in: path + name: id + required: true + type: string + x-example: 99cd67131b48 + - description: Job object that needs to be added + in: body + name: job + required: true + schema: + $ref: '#/definitions/Job' + x-example: + automation: hash.sha1 + id: 99cd67131b48 + payload: test + status: failed + responses: + "200": + description: successful operation + examples: + test: + automation: hash.sha1 + id: 99cd67131b48 + payload: test + status: failed + schema: + $ref: '#/definitions/JobResponse' + security: + - roles: + - job:write + summary: Update an existing job + tags: + - jobs + /logs/{reference}: + get: + operationId: getLogs + parameters: + - description: Reference + in: path + name: reference + required: true + type: string + x-example: tickets%2F294511 + responses: + "200": + description: successful operation + examples: + test: + - created: 2021-10-02T18:05:00.333535+02:00 + creator: bob + message: Fail run account resist lend solve incident centre priority + temperature. Cause change distribution examine location technique + shape partner milk customer. Rail tea plate soil report cook railway + interpretation breath action. Exercise dream accept park conclusion + addition shoot assistance may answer. Gold writer link stop combine + hear power name commitment operation. Determine lifespan support grow + degree henry exclude detail set religion. Direct library policy convention + chain retain discover ride walk student. Gather proposal select march + aspect play noise avoid encourage employ. Assessment preserve transport + combine wish influence income guess run stand. Charge limit crime + ignore statement foundation study issue stop claim. + reference: tickets/294511 + schema: + items: + $ref: '#/definitions/LogEntry' + type: array + security: + - roles: + - log:read + summary: Get log entries + tags: + - logs + /playbooks: + get: + operationId: listPlaybooks + responses: + "200": + description: successful operation + examples: + test: + - id: malware + name: Malware + yaml: | + name: Malware + tasks: + file-or-hash: + name: Do you have the file or the hash? + type: input + schema: + title: Malware + type: object + properties: + file: + type: string + title: "I have the" + enum: [ "File", "Hash" ] + next: + enter-hash: "file == 'Hash'" + upload: "file == 'File'" + + enter-hash: + name: Please enter the hash + type: input + schema: + title: Malware + type: object + properties: + hash: + type: string + title: Please enter the hash value + minlength: 32 + next: + virustotal: "hash != ''" + + upload: + name: Upload the malware + type: input + schema: + title: Malware + type: object + properties: + malware: + type: object + x-display: file + title: Please upload the malware + next: + hash: "malware" + + hash: + name: Hash the malware + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['upload'].data['malware']" + next: + virustotal: + + virustotal: + name: Send hash to VirusTotal + type: automation + automation: vt.hash + args: + hash: "playbook.tasks['enter-hash'].data['hash'] || playbook.tasks['hash'].data['hash']" + # next: + # known-malware: "score > 5" + # sandbox: "score < 6" # unknown-malware + - id: phishing + name: Phishing + yaml: | + name: Phishing + tasks: + board: + name: Board Involvement? + description: Is a board member involved? + type: input + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + next: + escalate: "boardInvolved == true" + mail-available: "boardInvolved == false" + + escalate: + name: Escalate to CISO + description: Please escalate the task to the CISO + type: task + + mail-available: + name: Mail available + type: input + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: 'yes' + type: string + required: + - mail + title: 'Yes' + - properties: + schemaKey: + const: 'no' + type: string + title: 'No' + title: Mail available + type: object + next: + block-sender: "schemaKey == 'yes'" + extract-iocs: "schemaKey == 'yes'" + search-email-gateway: "schemaKey == 'no'" + + search-email-gateway: + name: Search email gateway + description: Please search email-gateway for the phishing mail. + type: task + next: + extract-iocs: + + block-sender: + name: Block sender + type: task + next: + extract-iocs: + + extract-iocs: + name: Extract IOCs + description: Please insert the IOCs + type: input + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + next: + block-iocs: + + block-iocs: + name: Block IOCs + type: task + - id: simple + name: Simple + yaml: | + name: Simple + tasks: + input: + name: Enter something to hash + type: input + schema: + title: Something + type: object + properties: + something: + type: string + title: Something + default: "" + next: + hash: "something != ''" + + hash: + name: Hash the something + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['input'].data['something']" + next: + comment: "hash != ''" + + comment: + name: Comment the hash + type: automation + automation: comment + payload: + default: "playbook.tasks['hash'].data['hash']" + next: + done: "done" + + done: + name: You can close this case now + type: task + schema: + items: + $ref: '#/definitions/PlaybookTemplateResponse' + type: array + security: + - roles: + - playbook:read + summary: List playbooks + tags: + - playbooks + post: + operationId: createPlaybook + parameters: + - description: New playbook + in: body + name: playbook + required: true + schema: + $ref: '#/definitions/PlaybookTemplateForm' + x-example: + yaml: | + name: Simple2 + tasks: + input: + name: Upload malware if possible + type: input + schema: + title: Malware + type: object + properties: + malware: + type: string + title: Select malware + default: "" + next: + hash: "malware != ''" + + hash: + name: Hash the malware + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['input'].data['malware']" + next: + escalate: + + escalate: + name: Escalate to malware team + type: task + responses: + "200": + description: successful operation + examples: + test: + id: simple-2 + name: Simple2 + yaml: | + name: Simple2 + tasks: + input: + name: Upload malware if possible + type: input + schema: + title: Malware + type: object + properties: + malware: + type: string + title: Select malware + default: "" + next: + hash: "malware != ''" + + hash: + name: Hash the malware + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['input'].data['malware']" + next: + escalate: + + escalate: + name: Escalate to malware team + type: task + schema: + items: + $ref: '#/definitions/PlaybookTemplateResponse' + type: array + security: + - roles: + - playbook:write + summary: Create a playbook + tags: + - playbooks + /playbooks/{id}: + delete: + operationId: deletePlaybook + parameters: + - description: Playbook name + in: path + name: id + required: true + type: string + x-example: simple + responses: + "204": + description: successful operation + security: + - roles: + - playbook:write + summary: Delete a playbook + tags: + - playbooks + get: + operationId: getPlaybook + parameters: + - description: Playbook name + in: path + name: id + required: true + type: string + x-example: simple + responses: + "200": + description: successful operation + examples: + test: + id: simple + name: Simple + yaml: | + name: Simple + tasks: + input: + name: Enter something to hash + type: input + schema: + title: Something + type: object + properties: + something: + type: string + title: Something + default: "" + next: + hash: "something != ''" + + hash: + name: Hash the something + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['input'].data['something']" + next: + comment: "hash != ''" + + comment: + name: Comment the hash + type: automation + automation: comment + payload: + default: "playbook.tasks['hash'].data['hash']" + next: + done: "done" + + done: + name: You can close this case now + type: task + schema: + $ref: '#/definitions/PlaybookTemplateResponse' + security: + - roles: + - playbook:read + summary: Get a single playbook + tags: + - playbooks + put: + operationId: updatePlaybook + parameters: + - description: Playbook ID + in: path + name: id + required: true + type: string + x-example: simple + - description: Updated playbook + in: body + name: playbook + required: true + schema: + $ref: '#/definitions/PlaybookTemplateForm' + x-example: + yaml: | + name: Simple + tasks: + input: + name: Upload malware if possible + type: input + schema: + title: Malware + type: object + properties: + malware: + type: string + title: Select malware + default: "" + next: + hash: "malware != ''" + + hash: + name: Hash the malware + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['input'].data['malware']" + next: + escalate: + + escalate: + name: Escalate to malware team + type: task + responses: + "200": + description: successful operation + examples: + test: + id: simple + name: Simple + yaml: | + name: Simple + tasks: + input: + name: Upload malware if possible + type: input + schema: + title: Malware + type: object + properties: + malware: + type: string + title: Select malware + default: "" + next: + hash: "malware != ''" + + hash: + name: Hash the malware + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['input'].data['malware']" + next: + escalate: + + escalate: + name: Escalate to malware team + type: task + schema: + $ref: '#/definitions/PlaybookTemplateResponse' + security: + - roles: + - playbook:write + summary: Update an existing ticket playbook + tags: + - playbooks + /settings: + get: + operationId: getSettings + responses: + "200": + description: successful operation + examples: + test: + artifactStates: + - color: info + icon: mdi-help-circle-outline + id: unknown + name: Unknown + - color: error + icon: mdi-skull + id: malicious + name: Malicious + - color: success + icon: mdi-check + id: clean + name: Clean + roles: + - admin:backup:read + - admin:backup:restore + - admin:group:write + - admin:job:read + - admin:job:write + - admin:log:read + - admin:ticket:delete + - admin:user:write + - admin:userdata:read + - admin:userdata:write + - analyst:automation:read + - analyst:currentsettings:write + - analyst:currentuser:read + - analyst:currentuserdata:read + - analyst:file + - analyst:group:read + - analyst:playbook:read + - analyst:rule:read + - analyst:settings:read + - analyst:template:read + - analyst:ticket:read + - analyst:ticket:write + - analyst:tickettype:read + - analyst:user:read + - engineer:automation:write + - engineer:playbook:write + - engineer:rule:write + - engineer:template:write + - engineer:tickettype:write + ticketTypes: + - default_playbooks: [] + default_template: default + icon: mdi-alert + id: alert + name: Alerts + - default_playbooks: [] + default_template: default + icon: mdi-radioactive + id: incident + name: Incidents + - default_playbooks: [] + default_template: default + icon: mdi-fingerprint + id: investigation + name: Forensic Investigations + - default_playbooks: [] + default_template: default + icon: mdi-target + id: hunt + name: Threat Hunting + tier: community + timeformat: YYYY-MM-DDThh:mm:ss + version: 0.0.0-test + schema: + $ref: '#/definitions/Settings' + security: + - roles: + - settings:read + summary: Get settings + tags: + - settings + /statistics: + get: + operationId: getStatistics + responses: + "200": + description: successful operation + examples: + test: + open_tickets_per_user: {} + tickets_per_type: + alert: 2 + incident: 1 + tickets_per_week: + 2021-39: 3 + unassigned: 0 + schema: + $ref: '#/definitions/Statistics' + security: + - roles: + - ticket:read + summary: Get statistics + tags: + - statistics + /tasks: + get: + operationId: listTasks + responses: + "200": + description: successful operation + examples: + test: [] + schema: + items: + $ref: '#/definitions/TaskResponse' + type: array + security: + - roles: + - ticket:read + summary: List tasks + tags: + - tasks + /templates: + get: + operationId: listTemplates + responses: + "200": + description: successful operation + examples: + test: + - id: default + name: Default + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Default", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + schema: + items: + $ref: '#/definitions/TicketTemplateResponse' + type: array + security: + - roles: + - template:read + summary: List templates + tags: + - templates + post: + operationId: createTemplate + parameters: + - description: New template + in: body + name: template + required: true + schema: + $ref: '#/definitions/TicketTemplateForm' + x-example: + name: My Template + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + responses: + "200": + description: successful operation + examples: + test: + id: my-template + name: My Template + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + schema: + $ref: '#/definitions/TicketTemplateResponse' + security: + - roles: + - template:write + summary: Create a new template + tags: + - templates + /templates/{id}: + delete: + operationId: deleteTemplate + parameters: + - description: Template ID + in: path + name: id + required: true + type: string + x-example: default + responses: + "204": + description: successful operation + security: + - roles: + - template:write + summary: Delete a template + tags: + - templates + get: + operationId: getTemplate + parameters: + - description: Template ID + in: path + name: id + required: true + type: string + x-example: default + responses: + "200": + description: successful operation + examples: + test: + id: default + name: Default + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Default", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + schema: + $ref: '#/definitions/TicketTemplateResponse' + security: + - roles: + - template:read + summary: Get a single template + tags: + - templates + put: + operationId: updateTemplate + parameters: + - description: Template ID + in: path + name: id + required: true + type: string + x-example: default + - description: Template object that needs to be added + in: body + name: template + required: true + schema: + $ref: '#/definitions/TicketTemplateForm' + x-example: + name: My Template + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + responses: + "200": + description: successful operation + examples: + test: + id: default + name: My Template + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + schema: + $ref: '#/definitions/TicketTemplateResponse' + security: + - roles: + - template:write + summary: Update an existing template + tags: + - templates + /tickets: + get: + operationId: listTickets + parameters: + - description: Ticket Type + in: query + name: type + type: string + - default: 0 + description: Offset of the list + in: query + name: offset + type: integer + - default: 25 + description: Number of tickets + in: query + maximum: 100 + name: count + type: integer + - description: Sort columns + in: query + items: + type: string + name: sort + type: array + - description: Sort descending + in: query + items: + type: boolean + name: desc + type: array + - description: Search query + in: query + name: query + type: string + responses: + "200": + description: successful operation + examples: + test: + count: 3 + tickets: + - artifacts: + - name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + status: unknown + - name: http://www.customerviral.io/scalable/vertical/killer + status: clean + - name: leadreintermediate.io + status: malicious + created: 2021-10-02T18:04:59.078206+02:00 + id: 8123 + modified: 2021-10-02T18:04:59.078206+02:00 + name: live zebra + owner: demo + playbooks: + phishing: + name: Phishing + tasks: + block-iocs: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block IOCs + type: task + block-sender: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block sender + next: + extract-iocs: "" + type: task + board: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Board Involvement? + next: + escalate: boardInvolved == true + mail-available: boardInvolved == false + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + type: input + escalate: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Escalate to CISO + type: task + extract-iocs: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Extract IOCs + next: + block-iocs: "" + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + type: input + mail-available: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Mail available + next: + block-sender: schemaKey == 'yes' + extract-iocs: schemaKey == 'yes' + search-email-gateway: schemaKey == 'no' + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: "yes" + type: string + required: + - mail + title: "Yes" + - properties: + schemaKey: + const: "no" + type: string + title: "No" + title: Mail available + type: object + type: input + search-email-gateway: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Search email gateway + next: + extract-iocs: "" + type: task + references: + - href: https://www.leadmaximize.net/e-services/back-end + name: performance + - href: http://www.corporateinteractive.name/rich + name: autumn + - href: https://www.corporateintuitive.org/intuitive/platforms/integrate + name: suggest + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + status: closed + type: incident + - created: 2021-10-02T18:04:59.078186+02:00 + id: 8125 + modified: 2021-10-02T18:04:59.078186+02:00 + name: phishing from selenafadel@von.com detected + owner: demo + references: + - href: https://www.seniorleading-edge.name/users/efficient + name: recovery + - href: http://www.dynamicseamless.com/clicks-and-mortar + name: force + - href: http://www.leadscalable.biz/envisioneer + name: fund + schema: '{}' + status: closed + type: alert + - created: 2021-10-02T18:04:59.078186+02:00 + id: 8126 + modified: 2021-10-02T18:04:59.078186+02:00 + name: Surfaceintroduce virus detected + owner: demo + references: + - href: http://www.centralworld-class.io/synthesize + name: university + - href: https://www.futurevirtual.org/supply-chains/markets/sticky/iterate + name: goal + - href: http://www.chiefsyndicate.io/action-items + name: unemployment + schema: '{}' + status: closed + type: alert + schema: + $ref: '#/definitions/TicketList' + security: + - roles: + - ticket:read + summary: List tickets + tags: + - tickets + post: + operationId: createTicket + parameters: + - description: New ticket + in: body + name: ticket + required: true + schema: + $ref: '#/definitions/TicketForm' + x-example: + id: 123 + name: Wannacry infection + owner: bob + status: open + type: incident + responses: + "200": + description: successful operation + examples: + test: + created: 1985-04-12T23:20:50.52Z + id: 123 + modified: 1985-04-12T23:20:50.52Z + name: Wannacry infection + owner: bob + schema: '{}' + status: open + type: incident + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Create a new ticket + tags: + - tickets + /tickets/{id}: + delete: + operationId: deleteTicket + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8125 + responses: + "204": + description: successful operation + security: + - roles: + - ticket:delete + summary: Delete an ticket + tags: + - tickets + get: + operationId: getTicket + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8125 + responses: + "200": + description: successful operation + examples: + test: + created: 2021-10-02T18:04:59.078186+02:00 + id: 8125 + modified: 2021-10-02T18:04:59.078186+02:00 + name: phishing from selenafadel@von.com detected + owner: demo + references: + - href: https://www.seniorleading-edge.name/users/efficient + name: recovery + - href: http://www.dynamicseamless.com/clicks-and-mortar + name: force + - href: http://www.leadscalable.biz/envisioneer + name: fund + schema: '{}' + status: closed + tickets: + - created: 2021-10-02T18:04:59.078186+02:00 + id: 8126 + modified: 2021-10-02T18:04:59.078186+02:00 + name: Surfaceintroduce virus detected + owner: demo + references: + - href: http://www.centralworld-class.io/synthesize + name: university + - href: https://www.futurevirtual.org/supply-chains/markets/sticky/iterate + name: goal + - href: http://www.chiefsyndicate.io/action-items + name: unemployment + schema: '{}' + status: closed + type: alert + type: alert + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:read + summary: Get a single ticket + tags: + - tickets + put: + operationId: updateTicket + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8125 + - description: Updated ticket + in: body + name: ticket + required: true + schema: + $ref: '#/definitions/Ticket' + x-example: + created: 2021-10-02T18:04:59.078186+02:00 + modified: 2021-10-02T18:04:59.078186+02:00 + name: phishing from selenafadel@von.org detected + owner: demo + references: + - href: https://www.seniorleading-edge.name/users/efficient + name: recovery + - href: http://www.dynamicseamless.com/clicks-and-mortar + name: force + - href: http://www.leadscalable.biz/envisioneer + name: fund + schema: '{}' + status: closed + type: alert + responses: + "200": + description: successful operation + examples: + test: + created: 2021-10-02T18:04:59.078186+02:00 + id: 8125 + modified: 2021-10-02T18:04:59.078186+02:00 + name: phishing from selenafadel@von.org detected + owner: demo + references: + - href: https://www.seniorleading-edge.name/users/efficient + name: recovery + - href: http://www.dynamicseamless.com/clicks-and-mortar + name: force + - href: http://www.leadscalable.biz/envisioneer + name: fund + schema: '{}' + status: closed + tickets: + - created: 2021-10-02T18:04:59.078186+02:00 + id: 8126 + modified: 2021-10-02T18:04:59.078186+02:00 + name: Surfaceintroduce virus detected + owner: demo + references: + - href: http://www.centralworld-class.io/synthesize + name: university + - href: https://www.futurevirtual.org/supply-chains/markets/sticky/iterate + name: goal + - href: http://www.chiefsyndicate.io/action-items + name: unemployment + schema: '{}' + status: closed + type: alert + type: alert + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Update an existing ticket + tags: + - tickets + /tickets/{id}/artifacts: + post: + operationId: addArtifact + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - description: Artifact object that needs to be added + in: body + name: artifact + required: true + schema: + $ref: '#/definitions/Artifact' + x-example: + name: 2.2.2.2 + responses: + "200": + description: successful operation + examples: + test: + artifacts: + - name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + status: unknown + - name: http://www.customerviral.io/scalable/vertical/killer + status: clean + - name: leadreintermediate.io + status: malicious + - name: 2.2.2.2 + status: unknown + type: ip + created: 2021-10-02T18:04:59.078206+02:00 + id: 8123 + modified: 2021-10-02T18:04:59.078206+02:00 + name: live zebra + owner: demo + playbooks: + phishing: + name: Phishing + tasks: + block-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block IOCs + order: 6 + type: task + block-sender: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block sender + next: + extract-iocs: "" + order: 3 + type: task + board: + active: true + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Board Involvement? + next: + escalate: boardInvolved == true + mail-available: boardInvolved == false + order: 0 + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + type: input + escalate: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Escalate to CISO + order: 1 + type: task + extract-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Extract IOCs + next: + block-iocs: "" + order: 5 + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + type: input + mail-available: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Mail available + next: + block-sender: schemaKey == 'yes' + extract-iocs: schemaKey == 'yes' + search-email-gateway: schemaKey == 'no' + order: 2 + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: "yes" + type: string + required: + - mail + title: "Yes" + - properties: + schemaKey: + const: "no" + type: string + title: "No" + title: Mail available + type: object + type: input + search-email-gateway: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Search email gateway + next: + extract-iocs: "" + order: 4 + type: task + references: + - href: https://www.leadmaximize.net/e-services/back-end + name: performance + - href: http://www.corporateinteractive.name/rich + name: autumn + - href: https://www.corporateintuitive.org/intuitive/platforms/integrate + name: suggest + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + status: closed + type: incident + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Add a single artifact + tags: + - tickets + /tickets/{id}/artifacts/{name}: + delete: + operationId: removeArtifact + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - in: path + name: name + required: true + type: string + x-example: leadreintermediate.io + responses: + "200": + description: successful operation + examples: + test: + artifacts: + - name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + status: unknown + - name: http://www.customerviral.io/scalable/vertical/killer + status: clean + created: 2021-10-02T18:04:59.078206+02:00 + id: 8123 + modified: 2021-10-02T18:04:59.078206+02:00 + name: live zebra + owner: demo + playbooks: + phishing: + name: Phishing + tasks: + block-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block IOCs + order: 6 + type: task + block-sender: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block sender + next: + extract-iocs: "" + order: 3 + type: task + board: + active: true + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Board Involvement? + next: + escalate: boardInvolved == true + mail-available: boardInvolved == false + order: 0 + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + type: input + escalate: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Escalate to CISO + order: 1 + type: task + extract-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Extract IOCs + next: + block-iocs: "" + order: 5 + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + type: input + mail-available: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Mail available + next: + block-sender: schemaKey == 'yes' + extract-iocs: schemaKey == 'yes' + search-email-gateway: schemaKey == 'no' + order: 2 + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: "yes" + type: string + required: + - mail + title: "Yes" + - properties: + schemaKey: + const: "no" + type: string + title: "No" + title: Mail available + type: object + type: input + search-email-gateway: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Search email gateway + next: + extract-iocs: "" + order: 4 + type: task + references: + - href: https://www.leadmaximize.net/e-services/back-end + name: performance + - href: http://www.corporateinteractive.name/rich + name: autumn + - href: https://www.corporateintuitive.org/intuitive/platforms/integrate + name: suggest + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + status: closed + type: incident + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Remove an artifact + tags: + - tickets + get: + operationId: getArtifact + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - in: path + name: name + required: true + type: string + x-example: leadreintermediate.io + responses: + "200": + description: successful operation + examples: + test: + name: leadreintermediate.io + status: malicious + schema: + $ref: '#/definitions/Artifact' + security: + - roles: + - ticket:write + summary: Get a single artifact + tags: + - tickets + put: + operationId: setArtifact + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - in: path + name: name + required: true + type: string + x-example: leadreintermediate.io + - in: body + name: artifact + required: true + schema: + $ref: '#/definitions/Artifact' + x-example: + name: leadreintermediate.io + status: clean + responses: + "200": + description: successful operation + examples: + test: + artifacts: + - name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + status: unknown + - name: http://www.customerviral.io/scalable/vertical/killer + status: clean + - name: leadreintermediate.io + status: clean + created: 2021-10-02T18:04:59.078206+02:00 + id: 8123 + modified: 2021-10-02T18:04:59.078206+02:00 + name: live zebra + owner: demo + playbooks: + phishing: + name: Phishing + tasks: + block-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block IOCs + order: 6 + type: task + block-sender: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block sender + next: + extract-iocs: "" + order: 3 + type: task + board: + active: true + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Board Involvement? + next: + escalate: boardInvolved == true + mail-available: boardInvolved == false + order: 0 + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + type: input + escalate: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Escalate to CISO + order: 1 + type: task + extract-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Extract IOCs + next: + block-iocs: "" + order: 5 + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + type: input + mail-available: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Mail available + next: + block-sender: schemaKey == 'yes' + extract-iocs: schemaKey == 'yes' + search-email-gateway: schemaKey == 'no' + order: 2 + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: "yes" + type: string + required: + - mail + title: "Yes" + - properties: + schemaKey: + const: "no" + type: string + title: "No" + title: Mail available + type: object + type: input + search-email-gateway: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Search email gateway + next: + extract-iocs: "" + order: 4 + type: task + references: + - href: https://www.leadmaximize.net/e-services/back-end + name: performance + - href: http://www.corporateinteractive.name/rich + name: autumn + - href: https://www.corporateintuitive.org/intuitive/platforms/integrate + name: suggest + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + status: closed + type: incident + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Set a single artifact + tags: + - tickets + /tickets/{id}/artifacts/{name}/enrich: + post: + operationId: enrichArtifact + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - in: path + name: name + required: true + type: string + x-example: leadreintermediate.io + - in: body + name: data + required: true + schema: + $ref: '#/definitions/EnrichmentForm' + x-example: + data: + hash: b7a067a742c20d07a7456646de89bc2d408a1153 + name: hash.sha1 + responses: + "200": + description: successful operation + examples: + test: + artifacts: + - name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + status: unknown + - name: http://www.customerviral.io/scalable/vertical/killer + status: clean + - enrichments: + hash.sha1: + created: 2021-10-03T18:44:06.488923+02:00 + data: + hash: b7a067a742c20d07a7456646de89bc2d408a1153 + name: hash.sha1 + name: leadreintermediate.io + status: malicious + created: 2021-10-02T18:04:59.078206+02:00 + id: 8123 + modified: 2021-10-02T18:04:59.078206+02:00 + name: live zebra + owner: demo + playbooks: + phishing: + name: Phishing + tasks: + block-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block IOCs + order: 6 + type: task + block-sender: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block sender + next: + extract-iocs: "" + order: 3 + type: task + board: + active: true + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Board Involvement? + next: + escalate: boardInvolved == true + mail-available: boardInvolved == false + order: 0 + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + type: input + escalate: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Escalate to CISO + order: 1 + type: task + extract-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Extract IOCs + next: + block-iocs: "" + order: 5 + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + type: input + mail-available: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Mail available + next: + block-sender: schemaKey == 'yes' + extract-iocs: schemaKey == 'yes' + search-email-gateway: schemaKey == 'no' + order: 2 + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: "yes" + type: string + required: + - mail + title: "Yes" + - properties: + schemaKey: + const: "no" + type: string + title: "No" + title: Mail available + type: object + type: input + search-email-gateway: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Search email gateway + next: + extract-iocs: "" + order: 4 + type: task + references: + - href: https://www.leadmaximize.net/e-services/back-end + name: performance + - href: http://www.corporateinteractive.name/rich + name: autumn + - href: https://www.corporateintuitive.org/intuitive/platforms/integrate + name: suggest + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + status: closed + type: incident + schema: + $ref: '#/definitions/Artifact' + security: + - roles: + - ticket:write + summary: Enrich a single artifact + tags: + - tickets + /tickets/{id}/artifacts/{name}/run/{automation}: + post: + operationId: runArtifact + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - in: path + name: name + required: true + type: string + x-example: leadreintermediate.io + - in: path + name: automation + required: true + type: string + x-example: hash.sha1 + responses: + "204": + description: successful operation + security: + - roles: + - ticket:write + summary: Run automation on a single artifact + tags: + - tickets + /tickets/{id}/comments: + post: + operationId: addComment + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8125 + - description: Ticket comment + in: body + name: comment + required: true + schema: + $ref: '#/definitions/CommentForm' + x-example: + message: My first comment + responses: + "200": + description: successful operation + examples: + test: + comments: + - created: 2021-10-02T18:04:59.078186+02:00 + creator: bob + message: My first comment + created: 2021-10-02T18:04:59.078186+02:00 + id: 8125 + modified: 2021-10-02T18:04:59.078186+02:00 + name: phishing from selenafadel@von.com detected + owner: demo + references: + - href: https://www.seniorleading-edge.name/users/efficient + name: recovery + - href: http://www.dynamicseamless.com/clicks-and-mortar + name: force + - href: http://www.leadscalable.biz/envisioneer + name: fund + schema: '{}' + status: closed + tickets: + - created: 2021-10-02T18:04:59.078186+02:00 + id: 8126 + modified: 2021-10-02T18:04:59.078186+02:00 + name: Surfaceintroduce virus detected + owner: demo + references: + - href: http://www.centralworld-class.io/synthesize + name: university + - href: https://www.futurevirtual.org/supply-chains/markets/sticky/iterate + name: goal + - href: http://www.chiefsyndicate.io/action-items + name: unemployment + schema: '{}' + status: closed + type: alert + type: alert + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Add ticket comment + tags: + - tickets + /tickets/{id}/comments/{commentID}: + delete: + description: Comment will be removed from the ticket. + operationId: removeComment + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - description: Comment ID to remove + in: path + name: commentID + required: true + type: integer + x-example: 0 + responses: + "200": + description: successful operation + examples: + test: + artifacts: + - name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + status: unknown + - name: http://www.customerviral.io/scalable/vertical/killer + status: clean + - name: leadreintermediate.io + status: malicious + created: 2021-10-02T18:04:59.078206+02:00 + id: 8123 + modified: 2021-10-02T18:04:59.078206+02:00 + name: live zebra + owner: demo + playbooks: + phishing: + name: Phishing + tasks: + block-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block IOCs + order: 6 + type: task + block-sender: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block sender + next: + extract-iocs: "" + order: 3 + type: task + board: + active: true + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Board Involvement? + next: + escalate: boardInvolved == true + mail-available: boardInvolved == false + order: 0 + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + type: input + escalate: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Escalate to CISO + order: 1 + type: task + extract-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Extract IOCs + next: + block-iocs: "" + order: 5 + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + type: input + mail-available: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Mail available + next: + block-sender: schemaKey == 'yes' + extract-iocs: schemaKey == 'yes' + search-email-gateway: schemaKey == 'no' + order: 2 + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: "yes" + type: string + required: + - mail + title: "Yes" + - properties: + schemaKey: + const: "no" + type: string + title: "No" + title: Mail available + type: object + type: input + search-email-gateway: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Search email gateway + next: + extract-iocs: "" + order: 4 + type: task + references: + - href: https://www.leadmaximize.net/e-services/back-end + name: performance + - href: http://www.corporateinteractive.name/rich + name: autumn + - href: https://www.corporateintuitive.org/intuitive/platforms/integrate + name: suggest + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + status: closed + type: incident + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Remove an comment from an ticket + tags: + - tickets + /tickets/{id}/files: + put: + description: Link files to an ticket. The files themself will be stored in object + storage. + operationId: linkFiles + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8125 + - description: Added files + in: body + name: files + required: true + schema: + items: + $ref: '#/definitions/File' + type: array + x-example: + - key: myfile + name: document.doc + responses: + "200": + description: successful operation + examples: + test: + created: 2021-10-02T18:04:59.078186+02:00 + files: + - key: myfile + name: document.doc + id: 8125 + modified: 2021-10-02T18:04:59.078186+02:00 + name: phishing from selenafadel@von.com detected + owner: demo + references: + - href: https://www.seniorleading-edge.name/users/efficient + name: recovery + - href: http://www.dynamicseamless.com/clicks-and-mortar + name: force + - href: http://www.leadscalable.biz/envisioneer + name: fund + schema: '{}' + status: closed + tickets: + - created: 2021-10-02T18:04:59.078186+02:00 + id: 8126 + modified: 2021-10-02T18:04:59.078186+02:00 + name: Surfaceintroduce virus detected + owner: demo + references: + - href: http://www.centralworld-class.io/synthesize + name: university + - href: https://www.futurevirtual.org/supply-chains/markets/sticky/iterate + name: goal + - href: http://www.chiefsyndicate.io/action-items + name: unemployment + schema: '{}' + status: closed + type: alert + type: alert + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Link files to an ticket + tags: + - tickets + /tickets/{id}/playbooks: + post: + operationId: addTicketPlaybook + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8125 + - description: Ticket playbook object that needs to be added + in: body + name: playbook + required: true + schema: + $ref: '#/definitions/PlaybookTemplateForm' + x-example: + yaml: | + name: Simple + tasks: + input: + name: Upload malware if possible + type: input + schema: + title: Malware + type: object + properties: + malware: + type: string + title: Select malware + default: "" + next: + hash: "malware != ''" + + hash: + name: Hash the malware + type: automation + automation: hash.sha1 + payload: + default: "playbook.tasks['input'].data['malware']" + next: + escalate: + + escalate: + name: Escalate to malware team + type: task + responses: + "200": + description: successful operation + examples: + test: + created: 1985-04-12T23:20:50.52Z + id: 8125 + modified: 1985-04-12T23:20:50.52Z + name: phishing from selenafadel@von.com detected + owner: demo + playbooks: + simple: + name: Simple + tasks: + escalate: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Escalate to malware team + order: 2 + type: task + hash: + active: false + automation: hash.sha1 + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Hash the malware + next: + escalate: "" + order: 1 + payload: + default: playbook.tasks['input'].data['malware'] + type: automation + input: + active: true + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Upload malware if possible + next: + hash: malware != '' + order: 0 + schema: + properties: + malware: + default: "" + title: Select malware + type: string + title: Malware + type: object + type: input + references: + - href: https://www.seniorleading-edge.name/users/efficient + name: recovery + - href: http://www.dynamicseamless.com/clicks-and-mortar + name: force + - href: http://www.leadscalable.biz/envisioneer + name: fund + schema: '{}' + status: closed + tickets: + - created: 2021-10-02T18:04:59.078186+02:00 + id: 8126 + modified: 2021-10-02T18:04:59.078186+02:00 + name: Surfaceintroduce virus detected + owner: demo + references: + - href: http://www.centralworld-class.io/synthesize + name: university + - href: https://www.futurevirtual.org/supply-chains/markets/sticky/iterate + name: goal + - href: http://www.chiefsyndicate.io/action-items + name: unemployment + schema: '{}' + status: closed + type: alert + type: alert + schema: + $ref: '#/definitions/TicketResponse' + summary: Add a new ticket playbook + tags: + - tickets + /tickets/{id}/playbooks/{playbookID}: + delete: + operationId: removeTicketPlaybook + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - description: Playbook ID + in: path + name: playbookID + required: true + type: string + x-example: phishing + responses: + "200": + description: successful operation + examples: + test: + artifacts: + - name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + status: unknown + - name: http://www.customerviral.io/scalable/vertical/killer + status: clean + - name: leadreintermediate.io + status: malicious + created: 1985-04-12T23:20:50.52Z + id: 8123 + modified: 1985-04-12T23:20:50.52Z + name: live zebra + owner: demo + references: + - href: https://www.leadmaximize.net/e-services/back-end + name: performance + - href: http://www.corporateinteractive.name/rich + name: autumn + - href: https://www.corporateintuitive.org/intuitive/platforms/integrate + name: suggest + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + status: closed + type: incident + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Remove an ticket playbook + tags: + - tickets + /tickets/{id}/playbooks/{playbookID}/task/{taskID}: + put: + operationId: setTask + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - description: Playbook ID + in: path + name: playbookID + required: true + type: string + x-example: phishing + - description: Task ID + in: path + name: taskID + required: true + type: string + x-example: board + - description: Task + in: body + name: task + required: true + schema: + $ref: '#/definitions/Task' + x-example: + active: true + data: + boardInvolved: true + done: false + name: Board Involvement? + next: + escalate: boardInvolved == true + mail-available: boardInvolved == false + order: 0 + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + type: input + responses: + "200": + description: successful operation + examples: + test: + artifacts: + - name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + status: unknown + - name: http://www.customerviral.io/scalable/vertical/killer + status: clean + - name: leadreintermediate.io + status: malicious + created: 2021-10-02T18:04:59.078206+02:00 + id: 8123 + modified: 2021-10-02T18:04:59.078206+02:00 + name: live zebra + owner: demo + playbooks: + phishing: + name: Phishing + tasks: + block-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block IOCs + order: 6 + type: task + block-sender: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block sender + next: + extract-iocs: "" + order: 3 + type: task + board: + active: true + created: 2021-10-02T18:04:59.078186+02:00 + data: + boardInvolved: true + done: false + name: Board Involvement? + next: + escalate: boardInvolved == true + mail-available: boardInvolved == false + order: 0 + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + type: input + escalate: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Escalate to CISO + order: 1 + type: task + extract-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Extract IOCs + next: + block-iocs: "" + order: 5 + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + type: input + mail-available: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Mail available + next: + block-sender: schemaKey == 'yes' + extract-iocs: schemaKey == 'yes' + search-email-gateway: schemaKey == 'no' + order: 2 + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: "yes" + type: string + required: + - mail + title: "Yes" + - properties: + schemaKey: + const: "no" + type: string + title: "No" + title: Mail available + type: object + type: input + search-email-gateway: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Search email gateway + next: + extract-iocs: "" + order: 4 + type: task + references: + - href: https://www.leadmaximize.net/e-services/back-end + name: performance + - href: http://www.corporateinteractive.name/rich + name: autumn + - href: https://www.corporateintuitive.org/intuitive/platforms/integrate + name: suggest + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + status: closed + type: incident + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Set a ticket playbook task + tags: + - tickets + /tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete: + put: + operationId: completeTask + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - description: Playbook ID + in: path + name: playbookID + required: true + type: string + x-example: phishing + - description: Task ID + in: path + name: taskID + required: true + type: string + x-example: board + - description: Ticket playbook object that needs to be added + in: body + name: data + required: true + schema: + type: object + x-example: + boardInvolved: true + responses: + "200": + description: successful operation + examples: + test: + artifacts: + - name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + status: unknown + - name: http://www.customerviral.io/scalable/vertical/killer + status: clean + - name: leadreintermediate.io + status: malicious + created: 2021-10-02T18:04:59.078206+02:00 + id: 8123 + modified: 2021-10-02T18:04:59.078206+02:00 + name: live zebra + owner: demo + playbooks: + phishing: + name: Phishing + tasks: + block-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block IOCs + order: 6 + type: task + block-sender: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block sender + next: + extract-iocs: "" + order: 3 + type: task + board: + active: false + closed: 2021-10-02T18:04:59.078186+02:00 + created: 2021-10-02T18:04:59.078186+02:00 + data: + boardInvolved: true + done: true + name: Board Involvement? + next: + escalate: boardInvolved == true + mail-available: boardInvolved == false + order: 0 + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + type: input + escalate: + active: true + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Escalate to CISO + order: 1 + type: task + extract-iocs: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Extract IOCs + next: + block-iocs: "" + order: 5 + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + type: input + mail-available: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Mail available + next: + block-sender: schemaKey == 'yes' + extract-iocs: schemaKey == 'yes' + search-email-gateway: schemaKey == 'no' + order: 2 + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: "yes" + type: string + required: + - mail + title: "Yes" + - properties: + schemaKey: + const: "no" + type: string + title: "No" + title: Mail available + type: object + type: input + search-email-gateway: + active: false + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Search email gateway + next: + extract-iocs: "" + order: 4 + type: task + references: + - href: https://www.leadmaximize.net/e-services/back-end + name: performance + - href: http://www.corporateinteractive.name/rich + name: autumn + - href: https://www.corporateintuitive.org/intuitive/platforms/integrate + name: suggest + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + status: closed + type: incident + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Complete ticket playbook task + tags: + - tickets + /tickets/{id}/playbooks/{playbookID}/task/{taskID}/run: + post: + operationId: runTask + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8123 + - description: Playbook ID + in: path + name: playbookID + required: true + type: string + x-example: phishing + - description: Task ID + in: path + name: taskID + required: true + type: string + x-example: board + responses: + "204": + description: successful operation + security: + - roles: + - ticket:write + summary: Run ticket playbook task + tags: + - tickets + /tickets/{id}/references: + put: + operationId: setReferences + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8125 + - description: All ticket references + in: body + name: references + required: true + schema: + items: + $ref: '#/definitions/Reference' + type: array + x-example: + - href: http://www.leadscalable.biz/envisioneer + name: fund + responses: + "200": + description: successful operation + examples: + test: + created: 2021-10-02T18:04:59.078186+02:00 + id: 8125 + modified: 2021-10-02T18:04:59.078186+02:00 + name: phishing from selenafadel@von.com detected + owner: demo + references: + - href: http://www.leadscalable.biz/envisioneer + name: fund + schema: '{}' + status: closed + tickets: + - created: 2021-10-02T18:04:59.078186+02:00 + id: 8126 + modified: 2021-10-02T18:04:59.078186+02:00 + name: Surfaceintroduce virus detected + owner: demo + references: + - href: http://www.centralworld-class.io/synthesize + name: university + - href: https://www.futurevirtual.org/supply-chains/markets/sticky/iterate + name: goal + - href: http://www.chiefsyndicate.io/action-items + name: unemployment + schema: '{}' + status: closed + type: alert + type: alert + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Set ticket references + tags: + - tickets + /tickets/{id}/schema: + put: + operationId: setSchema + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8125 + - description: New ticket schema + in: body + name: schema + schema: + type: string + x-example: '{}' + responses: + "200": + description: successful operation + examples: + test: + created: 2021-10-02T18:04:59.078186+02:00 + id: 8125 + modified: 2021-10-02T18:04:59.078186+02:00 + name: phishing from selenafadel@von.com detected + owner: demo + references: + - href: https://www.seniorleading-edge.name/users/efficient + name: recovery + - href: http://www.dynamicseamless.com/clicks-and-mortar + name: force + - href: http://www.leadscalable.biz/envisioneer + name: fund + schema: '{}' + status: closed + tickets: + - created: 2021-10-02T18:04:59.078186+02:00 + id: 8126 + modified: 2021-10-02T18:04:59.078186+02:00 + name: Surfaceintroduce virus detected + owner: demo + references: + - href: http://www.centralworld-class.io/synthesize + name: university + - href: https://www.futurevirtual.org/supply-chains/markets/sticky/iterate + name: goal + - href: http://www.chiefsyndicate.io/action-items + name: unemployment + schema: '{}' + status: closed + type: alert + type: alert + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Set ticket schema + tags: + - tickets + /tickets/{id}/tickets: + delete: + operationId: unlinkTicket + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8126 + - description: Added ticket ID + in: body + name: linkedID + required: true + schema: + format: int64 + type: integer + x-example: 8125 + responses: + "200": + description: successful operation + examples: + test: + created: 2021-10-02T18:04:59.078186+02:00 + id: 8126 + modified: 2021-10-02T18:04:59.078186+02:00 + name: Surfaceintroduce virus detected + owner: demo + references: + - href: http://www.centralworld-class.io/synthesize + name: university + - href: https://www.futurevirtual.org/supply-chains/markets/sticky/iterate + name: goal + - href: http://www.chiefsyndicate.io/action-items + name: unemployment + schema: '{}' + status: closed + type: alert + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Unlink an ticket to an ticket + tags: + - tickets + patch: + operationId: linkTicket + parameters: + - description: Ticket ID + format: int64 + in: path + name: id + required: true + type: integer + x-example: 8126 + - description: Added ticket ID + in: body + name: linkedID + required: true + schema: + format: int64 + type: integer + x-example: 8123 + responses: + "200": + description: successful operation + examples: + test: + created: 2021-10-02T18:04:59.078186+02:00 + id: 8126 + modified: 2021-10-02T18:04:59.078186+02:00 + name: Surfaceintroduce virus detected + owner: demo + references: + - href: http://www.centralworld-class.io/synthesize + name: university + - href: https://www.futurevirtual.org/supply-chains/markets/sticky/iterate + name: goal + - href: http://www.chiefsyndicate.io/action-items + name: unemployment + schema: '{}' + status: closed + tickets: + - artifacts: + - name: 94d5cab6f5fe3422a447ab15436e7a672bc0c09a + status: unknown + - name: http://www.customerviral.io/scalable/vertical/killer + status: clean + - name: leadreintermediate.io + status: malicious + created: 2021-10-02T18:04:59.078206+02:00 + id: 8123 + modified: 2021-10-02T18:04:59.078206+02:00 + name: live zebra + owner: demo + playbooks: + phishing: + name: Phishing + tasks: + block-iocs: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block IOCs + type: task + block-sender: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Block sender + next: + extract-iocs: "" + type: task + board: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Board Involvement? + next: + escalate: boardInvolved == true + mail-available: boardInvolved == false + schema: + properties: + boardInvolved: + default: false + title: A board member is involved. + type: boolean + required: + - boardInvolved + title: Board Involvement? + type: object + type: input + escalate: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Escalate to CISO + type: task + extract-iocs: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Extract IOCs + next: + block-iocs: "" + schema: + properties: + iocs: + items: + type: string + title: IOCs + type: array + title: Extract IOCs + type: object + type: input + mail-available: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Mail available + next: + block-sender: schemaKey == 'yes' + extract-iocs: schemaKey == 'yes' + search-email-gateway: schemaKey == 'no' + schema: + oneOf: + - properties: + mail: + title: Mail + type: string + x-display: textarea + schemaKey: + const: "yes" + type: string + required: + - mail + title: "Yes" + - properties: + schemaKey: + const: "no" + type: string + title: "No" + title: Mail available + type: object + type: input + search-email-gateway: + created: 2021-10-02T18:04:59.078186+02:00 + done: false + name: Search email gateway + next: + extract-iocs: "" + type: task + references: + - href: https://www.leadmaximize.net/e-services/back-end + name: performance + - href: http://www.corporateinteractive.name/rich + name: autumn + - href: https://www.corporateintuitive.org/intuitive/platforms/integrate + name: suggest + schema: | + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/object1618746510.json", + "title": "Event", + "type": "object", + "required": [ + "severity", + "description", + "tlp" + ], + "properties": { + "severity": { + "$id": "#root/severity", + "title": "Severity", + "type": "string", + "default": "Medium", + "nx-enum": [ + "Low", + "Medium", + "High" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "Low", + "title": "Low", + "icon": "mdi-chevron-up" + }, + { + "const": "Medium", + "title": "Medium", + "icon": "mdi-chevron-double-up" + }, + { + "const": "High", + "title": "High", + "icon": "mdi-chevron-triple-up" + } + ] + }, + "tlp": { + "$id": "#root/tlp", + "title": "TLP", + "type": "string", + "nx-enum": [ + "White", + "Green", + "Amber", + "Red" + ], + "x-cols": 6, + "x-class": "pr-2", + "x-display": "icon", + "x-itemIcon": "icon", + "oneOf": [ + { + "const": "White", + "title": "White", + "icon": "mdi-alpha-w" + }, + { + "const": "Green", + "title": "Green", + "icon": "mdi-alpha-g" + }, + { + "const": "Amber", + "title": "Amber", + "icon": "mdi-alpha-a" + }, + { + "const": "Red", + "title": "Red", + "icon": "mdi-alpha-r" + } + ] + }, + "description": { + "$id": "#root/description", + "title": "Description", + "type": "string", + "x-display": "textarea", + "x-class": "pr-2" + } + } + } + status: closed + type: incident + - created: 2021-10-02T18:04:59.078186+02:00 + id: 8125 + modified: 2021-10-02T18:04:59.078186+02:00 + name: phishing from selenafadel@von.com detected + owner: demo + references: + - href: https://www.seniorleading-edge.name/users/efficient + name: recovery + - href: http://www.dynamicseamless.com/clicks-and-mortar + name: force + - href: http://www.leadscalable.biz/envisioneer + name: fund + schema: '{}' + status: closed + type: alert + type: alert + schema: + $ref: '#/definitions/TicketResponse' + security: + - roles: + - ticket:write + summary: Link an ticket to an ticket + tags: + - tickets + /tickets/batch: + post: + operationId: createTicketBatch + parameters: + - description: New ticket + in: body + name: ticket + required: true + schema: + items: + $ref: '#/definitions/TicketForm' + type: array + x-example: + - id: 123 + name: Wannacry infection + owner: bob + status: open + type: incident + responses: + "204": + description: successful operation + security: + - roles: + - ticket:write + summary: Create a new tickets in batch + tags: + - tickets + /tickettypes: + get: + operationId: listTicketTypes + responses: + "200": + description: successful operation + examples: + test: + - default_playbooks: [] + default_template: default + icon: mdi-alert + id: alert + name: Alerts + - default_playbooks: [] + default_template: default + icon: mdi-radioactive + id: incident + name: Incidents + - default_playbooks: [] + default_template: default + icon: mdi-fingerprint + id: investigation + name: Forensic Investigations + - default_playbooks: [] + default_template: default + icon: mdi-target + id: hunt + name: Threat Hunting + schema: + items: + $ref: '#/definitions/TicketTypeResponse' + type: array + security: + - roles: + - tickettype:read + summary: List tickettypes + tags: + - tickettypes + post: + operationId: createTicketType + parameters: + - description: New tickettype + in: body + name: tickettype + required: true + schema: + $ref: '#/definitions/TicketTypeForm' + x-example: + default_playbooks: [] + default_template: default + icon: mdi-newspaper-variant-outline + name: TI Tickets + responses: + "200": + description: successful operation + examples: + test: + default_playbooks: [] + default_template: default + icon: mdi-newspaper-variant-outline + id: ti-tickets + name: TI Tickets + schema: + $ref: '#/definitions/TicketTypeResponse' + security: + - roles: + - tickettype:write + summary: Create a new tickettype + tags: + - tickettypes + /tickettypes/{id}: + delete: + operationId: deleteTicketType + parameters: + - description: TicketType ID + in: path + name: id + required: true + type: string + x-example: alert + responses: + "204": + description: successful operation + security: + - roles: + - tickettype:write + summary: Delete a tickettype + tags: + - tickettypes + get: + operationId: getTicketType + parameters: + - description: TicketType ID + in: path + name: id + required: true + type: string + x-example: alert + responses: + "200": + description: successful operation + examples: + test: + default_playbooks: [] + default_template: default + icon: mdi-alert + id: alert + name: Alerts + schema: + $ref: '#/definitions/TicketTypeResponse' + security: + - roles: + - tickettype:read + summary: Get a single tickettype + tags: + - tickettypes + put: + operationId: updateTicketType + parameters: + - description: TicketType ID + in: path + name: id + required: true + type: string + x-example: alert + - description: TicketType object that needs to be added + in: body + name: tickettype + required: true + schema: + $ref: '#/definitions/TicketTypeForm' + x-example: + default_playbooks: [] + default_template: default + icon: mdi-bell + id: alert + name: Alerts + responses: + "200": + description: successful operation + examples: + test: + default_playbooks: [] + default_template: default + icon: mdi-bell + id: alert + name: Alerts + schema: + $ref: '#/definitions/TicketTypeResponse' + security: + - roles: + - tickettype:write + summary: Update an existing tickettype + tags: + - tickettypes + /userdata: + get: + operationId: listUserData + responses: + "200": + description: successful operation + examples: + test: + - email: bob@example.org + id: bob + name: Bob Bad + schema: + items: + $ref: '#/definitions/UserDataResponse' + type: array + security: + - roles: + - userdata:read + summary: List userdata + tags: + - userdata + /userdata/{id}: + get: + operationId: getUserData + parameters: + - description: User Data ID + in: path + name: id + required: true + type: string + x-example: bob + responses: + "200": + description: successful operation + examples: + test: + email: bob@example.org + id: bob + name: Bob Bad + schema: + $ref: '#/definitions/UserDataResponse' + security: + - roles: + - userdata:read + summary: Get a single user data + tags: + - userdata + put: + operationId: updateUserData + parameters: + - description: User Data ID + in: path + name: id + required: true + type: string + x-example: bob + - description: User data object that needs to be added + in: body + name: userdata + required: true + schema: + $ref: '#/definitions/UserData' + x-example: + blocked: false + email: bob@example.org + name: Bob Bad + responses: + "200": + description: successful operation + examples: + test: + email: bob@example.org + id: bob + name: Bob Bad + schema: + $ref: '#/definitions/UserDataResponse' + security: + - roles: + - userdata:write + summary: Update an existing user data + tags: + - userdata + /users: + get: + operationId: listUsers + responses: + "200": + description: successful operation + examples: + test: + - apikey: false + blocked: false + id: bob + roles: + - admin:backup:read + - admin:backup:restore + - admin:group:write + - admin:job:read + - admin:job:write + - admin:log:read + - admin:ticket:delete + - admin:user:write + - admin:userdata:read + - admin:userdata:write + - analyst:automation:read + - analyst:currentsettings:write + - analyst:currentuser:read + - analyst:currentuserdata:read + - analyst:file + - analyst:group:read + - analyst:playbook:read + - analyst:rule:read + - analyst:settings:read + - analyst:template:read + - analyst:ticket:read + - analyst:ticket:write + - analyst:tickettype:read + - analyst:user:read + - engineer:automation:write + - engineer:playbook:write + - engineer:rule:write + - engineer:template:write + - engineer:tickettype:write + - apikey: true + blocked: false + id: script + roles: + - analyst:automation:read + - analyst:currentsettings:write + - analyst:currentuser:read + - analyst:currentuserdata:read + - analyst:file + - analyst:group:read + - analyst:playbook:read + - analyst:rule:read + - analyst:settings:read + - analyst:template:read + - analyst:ticket:read + - analyst:ticket:write + - analyst:tickettype:read + - analyst:user:read + - engineer:automation:write + - engineer:playbook:write + - engineer:rule:write + - engineer:template:write + - engineer:tickettype:write + schema: + items: + $ref: '#/definitions/UserResponse' + type: array + security: + - roles: + - user:read + summary: List users + tags: + - users + post: + operationId: createUser + parameters: + - description: user object that needs to be added + in: body + name: user + required: true + schema: + $ref: '#/definitions/UserForm' + x-example: + id: syncscript + roles: + - analyst + responses: + "200": + description: successful operation + examples: + test: + blocked: false + id: syncscript + roles: + - analyst:automation:read + - analyst:currentsettings:write + - analyst:currentuser:read + - analyst:currentuserdata:read + - analyst:file + - analyst:group:read + - analyst:playbook:read + - analyst:rule:read + - analyst:settings:read + - analyst:template:read + - analyst:ticket:read + - analyst:ticket:write + - analyst:tickettype:read + - analyst:user:read + secret: v39bOuobnlEljfWzjAgoKzhmnh1xSMxH + schema: + $ref: '#/definitions/NewUserResponse' + security: + - roles: + - user:write + summary: Create user + tags: + - users + /users/{id}: + delete: + operationId: deleteUser + parameters: + - description: user ID + in: path + name: id + required: true + type: string + x-example: script + responses: + "204": + description: successful operation + security: + - roles: + - user:write + summary: Delete user + tags: + - users + get: + operationId: getUser + parameters: + - description: user ID + in: path + name: id + required: true + type: string + x-example: script + responses: + "200": + description: successful operation + examples: + test: + apikey: true + blocked: false + id: script + roles: + - analyst:automation:read + - analyst:currentsettings:write + - analyst:currentuser:read + - analyst:currentuserdata:read + - analyst:file + - analyst:group:read + - analyst:playbook:read + - analyst:rule:read + - analyst:settings:read + - analyst:template:read + - analyst:ticket:read + - analyst:ticket:write + - analyst:tickettype:read + - analyst:user:read + - engineer:automation:write + - engineer:playbook:write + - engineer:rule:write + - engineer:template:write + - engineer:tickettype:write + schema: + $ref: '#/definitions/UserResponse' + security: + - roles: + - user:read + summary: Get a single user + tags: + - users + put: + operationId: updateUser + parameters: + - description: Template ID + in: path + name: id + required: true + type: string + x-example: bob + - description: user object that needs to be added + in: body + name: user + required: true + schema: + $ref: '#/definitions/UserForm' + x-example: + roles: + - analyst + - admin + responses: + "200": + description: successful operation + examples: + test: + apikey: false + blocked: false + id: bob + roles: + - admin:backup:read + - admin:backup:restore + - admin:group:write + - admin:job:read + - admin:job:write + - admin:log:read + - admin:ticket:delete + - admin:user:write + - admin:userdata:read + - admin:userdata:write + - analyst:automation:read + - analyst:currentsettings:write + - analyst:currentuser:read + - analyst:currentuserdata:read + - analyst:file + - analyst:group:read + - analyst:playbook:read + - analyst:rule:read + - analyst:settings:read + - analyst:template:read + - analyst:ticket:read + - analyst:ticket:write + - analyst:tickettype:read + - analyst:user:read + - engineer:automation:write + - engineer:playbook:write + - engineer:rule:write + - engineer:template:write + - engineer:tickettype:write + schema: + $ref: '#/definitions/UserResponse' + security: + - roles: + - user:write + summary: Update user + tags: + - users +produces: +- application/json +schemes: +- http +swagger: "2.0" + diff --git a/generated/models/models.go b/generated/models/models.go new file mode 100755 index 0000000..3cb7667 --- /dev/null +++ b/generated/models/models.go @@ -0,0 +1,643 @@ +package models + +import ( + "fmt" + "strings" + "time" + + "github.com/xeipuuv/gojsonschema" +) + +var ( + schemaLoader = gojsonschema.NewSchemaLoader() + ArtifactSchema = new(gojsonschema.Schema) + ArtifactOriginSchema = new(gojsonschema.Schema) + AutomationSchema = new(gojsonschema.Schema) + AutomationFormSchema = new(gojsonschema.Schema) + AutomationResponseSchema = new(gojsonschema.Schema) + CommentSchema = new(gojsonschema.Schema) + CommentFormSchema = new(gojsonschema.Schema) + ContextSchema = new(gojsonschema.Schema) + EnrichmentSchema = new(gojsonschema.Schema) + EnrichmentFormSchema = new(gojsonschema.Schema) + FileSchema = new(gojsonschema.Schema) + JobSchema = new(gojsonschema.Schema) + JobFormSchema = new(gojsonschema.Schema) + JobResponseSchema = new(gojsonschema.Schema) + LogEntrySchema = new(gojsonschema.Schema) + MessageSchema = new(gojsonschema.Schema) + NewUserResponseSchema = new(gojsonschema.Schema) + OriginSchema = new(gojsonschema.Schema) + PlaybookSchema = new(gojsonschema.Schema) + PlaybookResponseSchema = new(gojsonschema.Schema) + PlaybookTemplateSchema = new(gojsonschema.Schema) + PlaybookTemplateFormSchema = new(gojsonschema.Schema) + PlaybookTemplateResponseSchema = new(gojsonschema.Schema) + ReferenceSchema = new(gojsonschema.Schema) + SettingsSchema = new(gojsonschema.Schema) + StatisticsSchema = new(gojsonschema.Schema) + TaskSchema = new(gojsonschema.Schema) + TaskFormSchema = new(gojsonschema.Schema) + TaskOriginSchema = new(gojsonschema.Schema) + TaskResponseSchema = new(gojsonschema.Schema) + TaskWithContextSchema = new(gojsonschema.Schema) + TicketSchema = new(gojsonschema.Schema) + TicketFormSchema = new(gojsonschema.Schema) + TicketListSchema = new(gojsonschema.Schema) + TicketResponseSchema = new(gojsonschema.Schema) + TicketSimpleResponseSchema = new(gojsonschema.Schema) + TicketTemplateSchema = new(gojsonschema.Schema) + TicketTemplateFormSchema = new(gojsonschema.Schema) + TicketTemplateResponseSchema = new(gojsonschema.Schema) + TicketTypeSchema = new(gojsonschema.Schema) + TicketTypeFormSchema = new(gojsonschema.Schema) + TicketTypeResponseSchema = new(gojsonschema.Schema) + TicketWithTicketsSchema = new(gojsonschema.Schema) + TypeSchema = new(gojsonschema.Schema) + UserSchema = new(gojsonschema.Schema) + UserDataSchema = new(gojsonschema.Schema) + UserDataResponseSchema = new(gojsonschema.Schema) + UserFormSchema = new(gojsonschema.Schema) + UserResponseSchema = new(gojsonschema.Schema) +) + +func init() { + err := schemaLoader.AddSchemas( + gojsonschema.NewStringLoader(`{"type":"object","required":["name"],"x-embed":"","properties":{"enrichments":{"type":"object","additionalProperties":{"$ref":"#/definitions/Enrichment"}},"name":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"}},"$id":"#/definitions/Artifact"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["ticket_id","artifact"],"x-embed":"","properties":{"artifact":{"type":"string"},"ticket_id":{"format":"int64","type":"integer"}},"$id":"#/definitions/ArtifactOrigin"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["image","script","type"],"x-embed":"","properties":{"image":{"type":"string"},"schema":{"type":"string"},"script":{"type":"string"},"type":{"items":{"type":"string","enum":["artifact","playbook","global"]},"type":"array"}},"$id":"#/definitions/Automation"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["id","image","script","type"],"x-embed":"","properties":{"id":{"type":"string"},"image":{"type":"string"},"schema":{"type":"string"},"script":{"type":"string"},"type":{"items":{"type":"string","enum":["artifact","playbook","global"]},"type":"array"}},"$id":"#/definitions/AutomationForm"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["id","image","script","type"],"x-embed":"","properties":{"id":{"type":"string"},"image":{"type":"string"},"schema":{"type":"string"},"script":{"type":"string"},"type":{"items":{"type":"string","enum":["artifact","playbook","global"]},"type":"array"}},"$id":"#/definitions/AutomationResponse"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["creator","created","message"],"x-embed":"","properties":{"created":{"format":"date-time","type":"string"},"creator":{"type":"string"},"message":{"type":"string"}},"$id":"#/definitions/Comment"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["message"],"x-embed":"","properties":{"created":{"format":"date-time","type":"string"},"creator":{"type":"string"},"message":{"type":"string"}},"$id":"#/definitions/CommentForm"}`), + gojsonschema.NewStringLoader(`{"type":"object","x-embed":"","properties":{"artifact":{"$ref":"#/definitions/Artifact"},"playbook":{"$ref":"#/definitions/PlaybookResponse"},"task":{"$ref":"#/definitions/TaskResponse"},"ticket":{"$ref":"#/definitions/TicketResponse"}},"$id":"#/definitions/Context"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["name","data","created"],"x-embed":"","properties":{"created":{"format":"date-time","type":"string"},"data":{"type":"object"},"name":{"type":"string"}},"$id":"#/definitions/Enrichment"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["name","data"],"x-embed":"","properties":{"data":{"type":"object"},"name":{"type":"string"}},"$id":"#/definitions/EnrichmentForm"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["key","name"],"x-embed":"","properties":{"key":{"type":"string"},"name":{"type":"string"}},"$id":"#/definitions/File"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["automation","running","status"],"x-embed":"","properties":{"automation":{"type":"string"},"container":{"type":"string"},"log":{"type":"string"},"origin":{"$ref":"#/definitions/Origin"},"output":{"type":"object"},"payload":{},"running":{"type":"boolean"},"status":{"type":"string"}},"$id":"#/definitions/Job"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["automation"],"x-embed":"","properties":{"automation":{"type":"string"},"origin":{"$ref":"#/definitions/Origin"},"payload":{}},"$id":"#/definitions/JobForm"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["id","automation","status"],"x-embed":"","properties":{"automation":{"type":"string"},"container":{"type":"string"},"id":{"type":"string"},"log":{"type":"string"},"origin":{"$ref":"#/definitions/Origin"},"output":{"type":"object"},"payload":{},"status":{"type":"string"}},"$id":"#/definitions/JobResponse"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["reference","creator","created","message"],"x-embed":"","properties":{"created":{"format":"date-time","type":"string"},"creator":{"type":"string"},"message":{"type":"string"},"reference":{"type":"string"}},"$id":"#/definitions/LogEntry"}`), + gojsonschema.NewStringLoader(`{"type":"object","x-embed":"","properties":{"context":{"$ref":"#/definitions/Context"},"payload":{"type":"object"},"secrets":{"type":"object","additionalProperties":{"type":"string"}}},"$id":"#/definitions/Message"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["id","blocked","roles"],"x-embed":"","properties":{"blocked":{"type":"boolean"},"id":{"type":"string"},"roles":{"items":{"type":"string"},"type":"array"},"secret":{"type":"string"}},"$id":"#/definitions/NewUserResponse"}`), + gojsonschema.NewStringLoader(`{"type":"object","x-embed":"","properties":{"artifact_origin":{"$ref":"#/definitions/ArtifactOrigin"},"task_origin":{"$ref":"#/definitions/TaskOrigin"}},"$id":"#/definitions/Origin"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["name","tasks"],"x-embed":"","properties":{"name":{"type":"string"},"tasks":{"type":"object","additionalProperties":{"$ref":"#/definitions/Task"}}},"$id":"#/definitions/Playbook"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["name","tasks"],"x-embed":"","properties":{"name":{"type":"string"},"tasks":{"type":"object","additionalProperties":{"$ref":"#/definitions/TaskResponse"}}},"$id":"#/definitions/PlaybookResponse"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["name","yaml"],"x-embed":"","properties":{"name":{"type":"string"},"yaml":{"type":"string"}},"$id":"#/definitions/PlaybookTemplate"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["yaml"],"x-embed":"","properties":{"id":{"type":"string"},"yaml":{"type":"string"}},"$id":"#/definitions/PlaybookTemplateForm"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["id","name","yaml"],"x-embed":"","properties":{"id":{"type":"string"},"name":{"type":"string"},"yaml":{"type":"string"}},"$id":"#/definitions/PlaybookTemplateResponse"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["name","href"],"x-embed":"","properties":{"href":{"type":"string"},"name":{"type":"string"}},"$id":"#/definitions/Reference"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["version","tier","timeformat","ticketTypes","artifactStates"],"x-embed":"","properties":{"artifactStates":{"title":"Artifact States","items":{"$ref":"#/definitions/Type"},"type":"array"},"roles":{"title":"Roles","items":{"type":"string"},"type":"array"},"ticketTypes":{"title":"Ticket Types","items":{"$ref":"#/definitions/TicketTypeResponse"},"type":"array"},"tier":{"title":"Tier","type":"string","enum":["community","enterprise"]},"timeformat":{"title":"Time Format","type":"string"},"version":{"title":"Version","type":"string"}},"$id":"#/definitions/Settings"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["unassigned","open_tickets_per_user","tickets_per_week","tickets_per_type"],"x-embed":"","properties":{"open_tickets_per_user":{"type":"object","additionalProperties":{"type":"integer"}},"tickets_per_type":{"type":"object","additionalProperties":{"type":"integer"}},"tickets_per_week":{"type":"object","additionalProperties":{"type":"integer"}},"unassigned":{"type":"integer"}},"$id":"#/definitions/Statistics"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["name","type","done","created"],"x-embed":"","properties":{"automation":{"type":"string"},"closed":{"format":"date-time","type":"string"},"created":{"format":"date-time","type":"string"},"data":{"type":"object"},"done":{"type":"boolean"},"join":{"type":"boolean"},"name":{"type":"string"},"next":{"type":"object","additionalProperties":{"type":"string"}},"owner":{"type":"string"},"payload":{"type":"object","additionalProperties":{"type":"string"}},"schema":{"type":"object"},"type":{"type":"string","enum":["task","input","automation"]}},"$id":"#/definitions/Task"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["name","type"],"x-embed":"","properties":{"automation":{"type":"string"},"closed":{"format":"date-time","type":"string"},"created":{"format":"date-time","type":"string"},"data":{"type":"object"},"done":{"type":"boolean"},"join":{"type":"boolean"},"name":{"type":"string"},"next":{"type":"object","additionalProperties":{"type":"string"}},"owner":{"type":"string"},"payload":{"type":"object","additionalProperties":{"type":"string"}},"schema":{"type":"object"},"type":{"type":"string","enum":["task","input","automation"]}},"$id":"#/definitions/TaskForm"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["ticket_id","playbook_id","task_id"],"x-embed":"","properties":{"playbook_id":{"type":"string"},"task_id":{"type":"string"},"ticket_id":{"format":"int64","type":"integer"}},"$id":"#/definitions/TaskOrigin"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["name","type","done","created","order","active"],"x-embed":"","properties":{"active":{"type":"boolean"},"automation":{"type":"string"},"closed":{"format":"date-time","type":"string"},"created":{"format":"date-time","type":"string"},"data":{"type":"object"},"done":{"type":"boolean"},"join":{"type":"boolean"},"name":{"type":"string"},"next":{"type":"object","additionalProperties":{"type":"string"}},"order":{"format":"int64","type":"number"},"owner":{"type":"string"},"payload":{"type":"object","additionalProperties":{"type":"string"}},"schema":{"type":"object"},"type":{"type":"string","enum":["task","input","automation"]}},"$id":"#/definitions/TaskResponse"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["ticket_id","ticket_name","playbook_id","playbook_name","task_id","task"],"x-embed":"","properties":{"playbook_id":{"type":"string"},"playbook_name":{"type":"string"},"task":{"$ref":"#/definitions/TaskResponse"},"task_id":{"type":"string"},"ticket_id":{"format":"int64","type":"number"},"ticket_name":{"type":"string"}},"$id":"#/definitions/TaskWithContext"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["name","type","status","created","modified","schema"],"x-embed":"","properties":{"artifacts":{"items":{"$ref":"#/definitions/Artifact"},"type":"array"},"comments":{"items":{"$ref":"#/definitions/Comment"},"type":"array"},"created":{"format":"date-time","type":"string"},"details":{"type":"object"},"files":{"items":{"$ref":"#/definitions/File"},"type":"array"},"modified":{"format":"date-time","type":"string"},"name":{"type":"string"},"owner":{"type":"string"},"playbooks":{"type":"object","additionalProperties":{"$ref":"#/definitions/Playbook"}},"read":{"items":{"type":"string"},"type":"array"},"references":{"items":{"$ref":"#/definitions/Reference"},"type":"array"},"schema":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"write":{"items":{"type":"string"},"type":"array"}},"$id":"#/definitions/Ticket"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["name","type","status"],"x-embed":"","properties":{"artifacts":{"items":{"$ref":"#/definitions/Artifact"},"type":"array"},"comments":{"items":{"$ref":"#/definitions/Comment"},"type":"array"},"created":{"format":"date-time","type":"string"},"details":{"type":"object"},"files":{"items":{"$ref":"#/definitions/File"},"type":"array"},"id":{"format":"int64","type":"integer"},"modified":{"format":"date-time","type":"string"},"name":{"type":"string"},"owner":{"type":"string"},"playbooks":{"items":{"$ref":"#/definitions/PlaybookTemplateForm"},"type":"array"},"read":{"items":{"type":"string"},"type":"array"},"references":{"items":{"$ref":"#/definitions/Reference"},"type":"array"},"schema":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"write":{"items":{"type":"string"},"type":"array"}},"$id":"#/definitions/TicketForm"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["tickets","count"],"x-embed":"","properties":{"count":{"type":"number"},"tickets":{"items":{"$ref":"#/definitions/TicketSimpleResponse"},"type":"array"}},"$id":"#/definitions/TicketList"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["id","name","type","status","created","modified","schema"],"x-embed":"","properties":{"artifacts":{"items":{"$ref":"#/definitions/Artifact"},"type":"array"},"comments":{"items":{"$ref":"#/definitions/Comment"},"type":"array"},"created":{"format":"date-time","type":"string"},"details":{"type":"object"},"files":{"items":{"$ref":"#/definitions/File"},"type":"array"},"id":{"format":"int64","type":"integer"},"modified":{"format":"date-time","type":"string"},"name":{"type":"string"},"owner":{"type":"string"},"playbooks":{"type":"object","additionalProperties":{"$ref":"#/definitions/PlaybookResponse"}},"read":{"items":{"type":"string"},"type":"array"},"references":{"items":{"$ref":"#/definitions/Reference"},"type":"array"},"schema":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"write":{"items":{"type":"string"},"type":"array"}},"$id":"#/definitions/TicketResponse"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["id","name","type","status","created","modified","schema"],"x-embed":"","properties":{"artifacts":{"items":{"$ref":"#/definitions/Artifact"},"type":"array"},"comments":{"items":{"$ref":"#/definitions/Comment"},"type":"array"},"created":{"format":"date-time","type":"string"},"details":{"type":"object"},"files":{"items":{"$ref":"#/definitions/File"},"type":"array"},"id":{"format":"int64","type":"integer"},"modified":{"format":"date-time","type":"string"},"name":{"type":"string"},"owner":{"type":"string"},"playbooks":{"type":"object","additionalProperties":{"$ref":"#/definitions/Playbook"}},"read":{"items":{"type":"string"},"type":"array"},"references":{"items":{"$ref":"#/definitions/Reference"},"type":"array"},"schema":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"write":{"items":{"type":"string"},"type":"array"}},"$id":"#/definitions/TicketSimpleResponse"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["name","schema"],"x-embed":"","properties":{"name":{"type":"string"},"schema":{"type":"string"}},"$id":"#/definitions/TicketTemplate"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["name","schema"],"x-embed":"","properties":{"id":{"type":"string"},"name":{"type":"string"},"schema":{"type":"string"}},"$id":"#/definitions/TicketTemplateForm"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["id","name","schema"],"x-embed":"","properties":{"id":{"type":"string"},"name":{"type":"string"},"schema":{"type":"string"}},"$id":"#/definitions/TicketTemplateResponse"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["name","icon","default_template","default_playbooks"],"x-embed":"","properties":{"default_groups":{"items":{"type":"string"},"type":"array"},"default_playbooks":{"items":{"type":"string"},"type":"array"},"default_template":{"type":"string"},"icon":{"type":"string"},"name":{"type":"string"}},"$id":"#/definitions/TicketType"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["name","icon","default_template","default_playbooks"],"x-embed":"","properties":{"default_groups":{"items":{"type":"string"},"type":"array"},"default_playbooks":{"items":{"type":"string"},"type":"array"},"default_template":{"type":"string"},"icon":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"}},"$id":"#/definitions/TicketTypeForm"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["id","name","icon","default_template","default_playbooks"],"x-embed":"","properties":{"default_groups":{"items":{"type":"string"},"type":"array"},"default_playbooks":{"items":{"type":"string"},"type":"array"},"default_template":{"type":"string"},"icon":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"}},"$id":"#/definitions/TicketTypeResponse"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["id","name","type","status","created","modified","schema"],"x-embed":"","properties":{"artifacts":{"items":{"$ref":"#/definitions/Artifact"},"type":"array"},"comments":{"items":{"$ref":"#/definitions/Comment"},"type":"array"},"created":{"format":"date-time","type":"string"},"details":{"type":"object"},"files":{"items":{"$ref":"#/definitions/File"},"type":"array"},"id":{"format":"int64","type":"integer"},"modified":{"format":"date-time","type":"string"},"name":{"type":"string"},"owner":{"type":"string"},"playbooks":{"type":"object","additionalProperties":{"$ref":"#/definitions/PlaybookResponse"}},"read":{"items":{"type":"string"},"type":"array"},"references":{"items":{"$ref":"#/definitions/Reference"},"type":"array"},"schema":{"type":"string"},"status":{"type":"string"},"tickets":{"items":{"$ref":"#/definitions/TicketSimpleResponse"},"type":"array"},"type":{"type":"string"},"write":{"items":{"type":"string"},"type":"array"}},"$id":"#/definitions/TicketWithTickets"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["id","name","icon"],"x-embed":"","properties":{"color":{"title":"Color","type":"string","enum":["error","info","success","warning"]},"icon":{"title":"Icon (https://materialdesignicons.com)","type":"string"},"id":{"title":"ID","type":"string"},"name":{"title":"Name","type":"string"}},"$id":"#/definitions/Type"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["blocked","apikey","roles"],"x-embed":"","properties":{"apikey":{"type":"boolean"},"blocked":{"type":"boolean"},"roles":{"items":{"type":"string"},"type":"array"},"sha256":{"type":"string"}},"$id":"#/definitions/User"}`), + gojsonschema.NewStringLoader(`{"type":"object","x-embed":"","properties":{"email":{"type":"string"},"image":{"type":"string"},"name":{"type":"string"},"timeformat":{"title":"Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens)","type":"string"}},"$id":"#/definitions/UserData"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["id"],"x-embed":"","properties":{"email":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"name":{"type":"string"},"timeformat":{"title":"Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens)","type":"string"}},"$id":"#/definitions/UserDataResponse"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["id","blocked","roles","apikey"],"x-embed":"","properties":{"apikey":{"type":"boolean"},"blocked":{"type":"boolean"},"id":{"type":"string"},"roles":{"items":{"type":"string"},"type":"array"}},"$id":"#/definitions/UserForm"}`), + gojsonschema.NewStringLoader(`{"type":"object","required":["id","blocked","roles","apikey"],"x-embed":"","properties":{"apikey":{"type":"boolean"},"blocked":{"type":"boolean"},"id":{"type":"string"},"roles":{"items":{"type":"string"},"type":"array"}},"$id":"#/definitions/UserResponse"}`), + ) + if err != nil { + panic(err) + } + + ArtifactSchema = mustCompile(`#/definitions/Artifact`) + ArtifactOriginSchema = mustCompile(`#/definitions/ArtifactOrigin`) + AutomationSchema = mustCompile(`#/definitions/Automation`) + AutomationFormSchema = mustCompile(`#/definitions/AutomationForm`) + AutomationResponseSchema = mustCompile(`#/definitions/AutomationResponse`) + CommentSchema = mustCompile(`#/definitions/Comment`) + CommentFormSchema = mustCompile(`#/definitions/CommentForm`) + ContextSchema = mustCompile(`#/definitions/Context`) + EnrichmentSchema = mustCompile(`#/definitions/Enrichment`) + EnrichmentFormSchema = mustCompile(`#/definitions/EnrichmentForm`) + FileSchema = mustCompile(`#/definitions/File`) + JobSchema = mustCompile(`#/definitions/Job`) + JobFormSchema = mustCompile(`#/definitions/JobForm`) + JobResponseSchema = mustCompile(`#/definitions/JobResponse`) + LogEntrySchema = mustCompile(`#/definitions/LogEntry`) + MessageSchema = mustCompile(`#/definitions/Message`) + NewUserResponseSchema = mustCompile(`#/definitions/NewUserResponse`) + OriginSchema = mustCompile(`#/definitions/Origin`) + PlaybookSchema = mustCompile(`#/definitions/Playbook`) + PlaybookResponseSchema = mustCompile(`#/definitions/PlaybookResponse`) + PlaybookTemplateSchema = mustCompile(`#/definitions/PlaybookTemplate`) + PlaybookTemplateFormSchema = mustCompile(`#/definitions/PlaybookTemplateForm`) + PlaybookTemplateResponseSchema = mustCompile(`#/definitions/PlaybookTemplateResponse`) + ReferenceSchema = mustCompile(`#/definitions/Reference`) + SettingsSchema = mustCompile(`#/definitions/Settings`) + StatisticsSchema = mustCompile(`#/definitions/Statistics`) + TaskSchema = mustCompile(`#/definitions/Task`) + TaskFormSchema = mustCompile(`#/definitions/TaskForm`) + TaskOriginSchema = mustCompile(`#/definitions/TaskOrigin`) + TaskResponseSchema = mustCompile(`#/definitions/TaskResponse`) + TaskWithContextSchema = mustCompile(`#/definitions/TaskWithContext`) + TicketSchema = mustCompile(`#/definitions/Ticket`) + TicketFormSchema = mustCompile(`#/definitions/TicketForm`) + TicketListSchema = mustCompile(`#/definitions/TicketList`) + TicketResponseSchema = mustCompile(`#/definitions/TicketResponse`) + TicketSimpleResponseSchema = mustCompile(`#/definitions/TicketSimpleResponse`) + TicketTemplateSchema = mustCompile(`#/definitions/TicketTemplate`) + TicketTemplateFormSchema = mustCompile(`#/definitions/TicketTemplateForm`) + TicketTemplateResponseSchema = mustCompile(`#/definitions/TicketTemplateResponse`) + TicketTypeSchema = mustCompile(`#/definitions/TicketType`) + TicketTypeFormSchema = mustCompile(`#/definitions/TicketTypeForm`) + TicketTypeResponseSchema = mustCompile(`#/definitions/TicketTypeResponse`) + TicketWithTicketsSchema = mustCompile(`#/definitions/TicketWithTickets`) + TypeSchema = mustCompile(`#/definitions/Type`) + UserSchema = mustCompile(`#/definitions/User`) + UserDataSchema = mustCompile(`#/definitions/UserData`) + UserDataResponseSchema = mustCompile(`#/definitions/UserDataResponse`) + UserFormSchema = mustCompile(`#/definitions/UserForm`) + UserResponseSchema = mustCompile(`#/definitions/UserResponse`) +} + +type Artifact struct { + Enrichments map[string]*Enrichment `json:"enrichments,omitempty"` + Name string `json:"name"` + Status *string `json:"status,omitempty"` + Type *string `json:"type,omitempty"` +} + +type ArtifactOrigin struct { + Artifact string `json:"artifact"` + TicketId int64 `json:"ticket_id"` +} + +type Automation struct { + Image string `json:"image"` + Schema *string `json:"schema,omitempty"` + Script string `json:"script"` + Type []string `json:"type"` +} + +type AutomationForm struct { + ID string `json:"id"` + Image string `json:"image"` + Schema *string `json:"schema,omitempty"` + Script string `json:"script"` + Type []string `json:"type"` +} + +type AutomationResponse struct { + ID string `json:"id"` + Image string `json:"image"` + Schema *string `json:"schema,omitempty"` + Script string `json:"script"` + Type []string `json:"type"` +} + +type Comment struct { + Created time.Time `json:"created"` + Creator string `json:"creator"` + Message string `json:"message"` +} + +type CommentForm struct { + Created *time.Time `json:"created,omitempty"` + Creator *string `json:"creator,omitempty"` + Message string `json:"message"` +} + +type Context struct { + Artifact *Artifact `json:"artifact,omitempty"` + Playbook *PlaybookResponse `json:"playbook,omitempty"` + Task *TaskResponse `json:"task,omitempty"` + Ticket *TicketResponse `json:"ticket,omitempty"` +} + +type Enrichment struct { + Created time.Time `json:"created"` + Data interface{} `json:"data"` + Name string `json:"name"` +} + +type EnrichmentForm struct { + Data interface{} `json:"data"` + Name string `json:"name"` +} + +type File struct { + Key string `json:"key"` + Name string `json:"name"` +} + +type Job struct { + Automation string `json:"automation"` + Container *string `json:"container,omitempty"` + Log *string `json:"log,omitempty"` + Origin *Origin `json:"origin,omitempty"` + Output interface{} `json:"output,omitempty"` + Payload interface{} `json:"payload,omitempty"` + Running bool `json:"running"` + Status string `json:"status"` +} + +type JobForm struct { + Automation string `json:"automation"` + Origin *Origin `json:"origin,omitempty"` + Payload interface{} `json:"payload,omitempty"` +} + +type JobResponse struct { + Automation string `json:"automation"` + Container *string `json:"container,omitempty"` + ID string `json:"id"` + Log *string `json:"log,omitempty"` + Origin *Origin `json:"origin,omitempty"` + Output interface{} `json:"output,omitempty"` + Payload interface{} `json:"payload,omitempty"` + Status string `json:"status"` +} + +type LogEntry struct { + Created time.Time `json:"created"` + Creator string `json:"creator"` + Message string `json:"message"` + Reference string `json:"reference"` +} + +type Message struct { + Context *Context `json:"context,omitempty"` + Payload interface{} `json:"payload,omitempty"` + Secrets map[string]string `json:"secrets,omitempty"` +} + +type NewUserResponse struct { + Blocked bool `json:"blocked"` + ID string `json:"id"` + Roles []string `json:"roles"` + Secret *string `json:"secret,omitempty"` +} + +type Origin struct { + ArtifactOrigin *ArtifactOrigin `json:"artifact_origin,omitempty"` + TaskOrigin *TaskOrigin `json:"task_origin,omitempty"` +} + +type Playbook struct { + Name string `json:"name"` + Tasks map[string]*Task `json:"tasks"` +} + +type PlaybookResponse struct { + Name string `json:"name"` + Tasks map[string]*TaskResponse `json:"tasks"` +} + +type PlaybookTemplate struct { + Name string `json:"name"` + Yaml string `json:"yaml"` +} + +type PlaybookTemplateForm struct { + ID *string `json:"id,omitempty"` + Yaml string `json:"yaml"` +} + +type PlaybookTemplateResponse struct { + ID string `json:"id"` + Name string `json:"name"` + Yaml string `json:"yaml"` +} + +type Reference struct { + Href string `json:"href"` + Name string `json:"name"` +} + +type Settings struct { + ArtifactStates []*Type `json:"artifactStates"` + Roles []string `json:"roles,omitempty"` + TicketTypes []*TicketTypeResponse `json:"ticketTypes"` + Tier string `json:"tier"` + Timeformat string `json:"timeformat"` + Version string `json:"version"` +} + +type Statistics struct { + OpenTicketsPerUser map[string]int `json:"open_tickets_per_user"` + TicketsPerType map[string]int `json:"tickets_per_type"` + TicketsPerWeek map[string]int `json:"tickets_per_week"` + Unassigned int `json:"unassigned"` +} + +type Task struct { + Automation *string `json:"automation,omitempty"` + Closed *time.Time `json:"closed,omitempty"` + Created time.Time `json:"created"` + Data interface{} `json:"data,omitempty"` + Done bool `json:"done"` + Join *bool `json:"join,omitempty"` + Name string `json:"name"` + Next map[string]string `json:"next,omitempty"` + Owner *string `json:"owner,omitempty"` + Payload map[string]string `json:"payload,omitempty"` + Schema interface{} `json:"schema,omitempty"` + Type string `json:"type"` +} + +type TaskForm struct { + Automation *string `json:"automation,omitempty"` + Closed *time.Time `json:"closed,omitempty"` + Created *time.Time `json:"created,omitempty"` + Data interface{} `json:"data,omitempty"` + Done *bool `json:"done,omitempty"` + Join *bool `json:"join,omitempty"` + Name string `json:"name"` + Next map[string]string `json:"next,omitempty"` + Owner *string `json:"owner,omitempty"` + Payload map[string]string `json:"payload,omitempty"` + Schema interface{} `json:"schema,omitempty"` + Type string `json:"type"` +} + +type TaskOrigin struct { + PlaybookId string `json:"playbook_id"` + TaskId string `json:"task_id"` + TicketId int64 `json:"ticket_id"` +} + +type TaskResponse struct { + Active bool `json:"active"` + Automation *string `json:"automation,omitempty"` + Closed *time.Time `json:"closed,omitempty"` + Created time.Time `json:"created"` + Data interface{} `json:"data,omitempty"` + Done bool `json:"done"` + Join *bool `json:"join,omitempty"` + Name string `json:"name"` + Next map[string]string `json:"next,omitempty"` + Order int64 `json:"order"` + Owner *string `json:"owner,omitempty"` + Payload map[string]string `json:"payload,omitempty"` + Schema interface{} `json:"schema,omitempty"` + Type string `json:"type"` +} + +type TaskWithContext struct { + PlaybookId string `json:"playbook_id"` + PlaybookName string `json:"playbook_name"` + Task TaskResponse `json:"task"` + TaskId string `json:"task_id"` + TicketId int64 `json:"ticket_id"` + TicketName string `json:"ticket_name"` +} + +type Ticket struct { + Artifacts []*Artifact `json:"artifacts,omitempty"` + Comments []*Comment `json:"comments,omitempty"` + Created time.Time `json:"created"` + Details interface{} `json:"details,omitempty"` + Files []*File `json:"files,omitempty"` + Modified time.Time `json:"modified"` + Name string `json:"name"` + Owner *string `json:"owner,omitempty"` + Playbooks map[string]*Playbook `json:"playbooks,omitempty"` + Read []string `json:"read,omitempty"` + References []*Reference `json:"references,omitempty"` + Schema string `json:"schema"` + Status string `json:"status"` + Type string `json:"type"` + Write []string `json:"write,omitempty"` +} + +type TicketForm struct { + Artifacts []*Artifact `json:"artifacts,omitempty"` + Comments []*Comment `json:"comments,omitempty"` + Created *time.Time `json:"created,omitempty"` + Details interface{} `json:"details,omitempty"` + Files []*File `json:"files,omitempty"` + ID *int64 `json:"id,omitempty"` + Modified *time.Time `json:"modified,omitempty"` + Name string `json:"name"` + Owner *string `json:"owner,omitempty"` + Playbooks []*PlaybookTemplateForm `json:"playbooks,omitempty"` + Read []string `json:"read,omitempty"` + References []*Reference `json:"references,omitempty"` + Schema *string `json:"schema,omitempty"` + Status string `json:"status"` + Type string `json:"type"` + Write []string `json:"write,omitempty"` +} + +type TicketList struct { + Count int `json:"count"` + Tickets []*TicketSimpleResponse `json:"tickets"` +} + +type TicketResponse struct { + Artifacts []*Artifact `json:"artifacts,omitempty"` + Comments []*Comment `json:"comments,omitempty"` + Created time.Time `json:"created"` + Details interface{} `json:"details,omitempty"` + Files []*File `json:"files,omitempty"` + ID int64 `json:"id"` + Modified time.Time `json:"modified"` + Name string `json:"name"` + Owner *string `json:"owner,omitempty"` + Playbooks map[string]*PlaybookResponse `json:"playbooks,omitempty"` + Read []string `json:"read,omitempty"` + References []*Reference `json:"references,omitempty"` + Schema string `json:"schema"` + Status string `json:"status"` + Type string `json:"type"` + Write []string `json:"write,omitempty"` +} + +type TicketSimpleResponse struct { + Artifacts []*Artifact `json:"artifacts,omitempty"` + Comments []*Comment `json:"comments,omitempty"` + Created time.Time `json:"created"` + Details interface{} `json:"details,omitempty"` + Files []*File `json:"files,omitempty"` + ID int64 `json:"id"` + Modified time.Time `json:"modified"` + Name string `json:"name"` + Owner *string `json:"owner,omitempty"` + Playbooks map[string]*Playbook `json:"playbooks,omitempty"` + Read []string `json:"read,omitempty"` + References []*Reference `json:"references,omitempty"` + Schema string `json:"schema"` + Status string `json:"status"` + Type string `json:"type"` + Write []string `json:"write,omitempty"` +} + +type TicketTemplate struct { + Name string `json:"name"` + Schema string `json:"schema"` +} + +type TicketTemplateForm struct { + ID *string `json:"id,omitempty"` + Name string `json:"name"` + Schema string `json:"schema"` +} + +type TicketTemplateResponse struct { + ID string `json:"id"` + Name string `json:"name"` + Schema string `json:"schema"` +} + +type TicketType struct { + DefaultGroups []string `json:"default_groups,omitempty"` + DefaultPlaybooks []string `json:"default_playbooks"` + DefaultTemplate string `json:"default_template"` + Icon string `json:"icon"` + Name string `json:"name"` +} + +type TicketTypeForm struct { + DefaultGroups []string `json:"default_groups,omitempty"` + DefaultPlaybooks []string `json:"default_playbooks"` + DefaultTemplate string `json:"default_template"` + Icon string `json:"icon"` + ID *string `json:"id,omitempty"` + Name string `json:"name"` +} + +type TicketTypeResponse struct { + DefaultGroups []string `json:"default_groups,omitempty"` + DefaultPlaybooks []string `json:"default_playbooks"` + DefaultTemplate string `json:"default_template"` + Icon string `json:"icon"` + ID string `json:"id"` + Name string `json:"name"` +} + +type TicketWithTickets struct { + Artifacts []*Artifact `json:"artifacts,omitempty"` + Comments []*Comment `json:"comments,omitempty"` + Created time.Time `json:"created"` + Details interface{} `json:"details,omitempty"` + Files []*File `json:"files,omitempty"` + ID int64 `json:"id"` + Modified time.Time `json:"modified"` + Name string `json:"name"` + Owner *string `json:"owner,omitempty"` + Playbooks map[string]*PlaybookResponse `json:"playbooks,omitempty"` + Read []string `json:"read,omitempty"` + References []*Reference `json:"references,omitempty"` + Schema string `json:"schema"` + Status string `json:"status"` + Tickets []*TicketSimpleResponse `json:"tickets,omitempty"` + Type string `json:"type"` + Write []string `json:"write,omitempty"` +} + +type Type struct { + Color *string `json:"color,omitempty"` + Icon string `json:"icon"` + ID string `json:"id"` + Name string `json:"name"` +} + +type User struct { + Apikey bool `json:"apikey"` + Blocked bool `json:"blocked"` + Roles []string `json:"roles"` + Sha256 *string `json:"sha256,omitempty"` +} + +type UserData struct { + Email *string `json:"email,omitempty"` + Image *string `json:"image,omitempty"` + Name *string `json:"name,omitempty"` + Timeformat *string `json:"timeformat,omitempty"` +} + +type UserDataResponse struct { + Email *string `json:"email,omitempty"` + ID string `json:"id"` + Image *string `json:"image,omitempty"` + Name *string `json:"name,omitempty"` + Timeformat *string `json:"timeformat,omitempty"` +} + +type UserForm struct { + Apikey bool `json:"apikey"` + Blocked bool `json:"blocked"` + ID string `json:"id"` + Roles []string `json:"roles"` +} + +type UserResponse struct { + Apikey bool `json:"apikey"` + Blocked bool `json:"blocked"` + ID string `json:"id"` + Roles []string `json:"roles"` +} + +func mustCompile(uri string) *gojsonschema.Schema { + s, err := schemaLoader.Compile(gojsonschema.NewReferenceLoader(uri)) + if err != nil { + panic(err) + } + return s +} + +func validate(s *gojsonschema.Schema, b []byte) error { + res, err := s.Validate(gojsonschema.NewStringLoader(string(b))) + if err != nil { + return err + } + + if len(res.Errors()) > 0 { + var l []string + for _, e := range res.Errors() { + l = append(l, e.String()) + } + return fmt.Errorf("validation failed: %v", strings.Join(l, ", ")) + } + return nil +} + +const ( + SettingsTierCommunity = "community" + + SettingsTierEnterprise = "enterprise" + + TaskTypeTask = "task" + + TaskTypeInput = "input" + + TaskTypeAutomation = "automation" + + TaskFormTypeTask = "task" + + TaskFormTypeInput = "input" + + TaskFormTypeAutomation = "automation" + + TaskResponseTypeTask = "task" + + TaskResponseTypeInput = "input" + + TaskResponseTypeAutomation = "automation" + + TypeColorError = "error" + + TypeColorInfo = "info" + + TypeColorSuccess = "success" + + TypeColorWarning = "warning" +) diff --git a/generated/restapi/api.go b/generated/restapi/api.go new file mode 100644 index 0000000..b56ed31 --- /dev/null +++ b/generated/restapi/api.go @@ -0,0 +1,252 @@ +package restapi + +import ( + "context" + "log" + "net/http" + "os" + "os/signal" + "syscall" + "time" + + "github.com/gin-gonic/gin" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/automations" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/jobs" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/logs" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/playbooks" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/settings" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/statistics" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/tasks" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/templates" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/tickets" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/tickettypes" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/userdata" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/users" + "github.com/SecurityBrewery/catalyst/role" +) + +// Service is the interface that must be implemented in order to provide +// business logic for the Server service. +type Service interface { + AddArtifact(ctx context.Context, params *tickets.AddArtifactParams) *api.Response + AddComment(ctx context.Context, params *tickets.AddCommentParams) *api.Response + AddTicketPlaybook(ctx context.Context, params *tickets.AddTicketPlaybookParams) *api.Response + CompleteTask(ctx context.Context, params *tickets.CompleteTaskParams) *api.Response + CreateAutomation(ctx context.Context, params *automations.CreateAutomationParams) *api.Response + CreatePlaybook(ctx context.Context, params *playbooks.CreatePlaybookParams) *api.Response + CreateTemplate(ctx context.Context, params *templates.CreateTemplateParams) *api.Response + CreateTicket(ctx context.Context, params *tickets.CreateTicketParams) *api.Response + CreateTicketBatch(ctx context.Context, params *tickets.CreateTicketBatchParams) *api.Response + CreateTicketType(ctx context.Context, params *tickettypes.CreateTicketTypeParams) *api.Response + CreateUser(ctx context.Context, params *users.CreateUserParams) *api.Response + CurrentUser(ctx context.Context) *api.Response + CurrentUserData(ctx context.Context) *api.Response + DeleteAutomation(ctx context.Context, params *automations.DeleteAutomationParams) *api.Response + DeletePlaybook(ctx context.Context, params *playbooks.DeletePlaybookParams) *api.Response + DeleteTemplate(ctx context.Context, params *templates.DeleteTemplateParams) *api.Response + DeleteTicket(ctx context.Context, params *tickets.DeleteTicketParams) *api.Response + DeleteTicketType(ctx context.Context, params *tickettypes.DeleteTicketTypeParams) *api.Response + DeleteUser(ctx context.Context, params *users.DeleteUserParams) *api.Response + EnrichArtifact(ctx context.Context, params *tickets.EnrichArtifactParams) *api.Response + GetArtifact(ctx context.Context, params *tickets.GetArtifactParams) *api.Response + GetAutomation(ctx context.Context, params *automations.GetAutomationParams) *api.Response + GetJob(ctx context.Context, params *jobs.GetJobParams) *api.Response + GetLogs(ctx context.Context, params *logs.GetLogsParams) *api.Response + GetPlaybook(ctx context.Context, params *playbooks.GetPlaybookParams) *api.Response + GetSettings(ctx context.Context) *api.Response + GetStatistics(ctx context.Context) *api.Response + GetTemplate(ctx context.Context, params *templates.GetTemplateParams) *api.Response + GetTicket(ctx context.Context, params *tickets.GetTicketParams) *api.Response + GetTicketType(ctx context.Context, params *tickettypes.GetTicketTypeParams) *api.Response + GetUser(ctx context.Context, params *users.GetUserParams) *api.Response + GetUserData(ctx context.Context, params *userdata.GetUserDataParams) *api.Response + LinkFiles(ctx context.Context, params *tickets.LinkFilesParams) *api.Response + LinkTicket(ctx context.Context, params *tickets.LinkTicketParams) *api.Response + ListAutomations(ctx context.Context) *api.Response + ListJobs(ctx context.Context) *api.Response + ListPlaybooks(ctx context.Context) *api.Response + ListTasks(ctx context.Context) *api.Response + ListTemplates(ctx context.Context) *api.Response + ListTicketTypes(ctx context.Context) *api.Response + ListTickets(ctx context.Context, params *tickets.ListTicketsParams) *api.Response + ListUserData(ctx context.Context) *api.Response + ListUsers(ctx context.Context) *api.Response + RemoveArtifact(ctx context.Context, params *tickets.RemoveArtifactParams) *api.Response + RemoveComment(ctx context.Context, params *tickets.RemoveCommentParams) *api.Response + RemoveTicketPlaybook(ctx context.Context, params *tickets.RemoveTicketPlaybookParams) *api.Response + RunArtifact(ctx context.Context, params *tickets.RunArtifactParams) *api.Response + RunJob(ctx context.Context, params *jobs.RunJobParams) *api.Response + RunTask(ctx context.Context, params *tickets.RunTaskParams) *api.Response + SetArtifact(ctx context.Context, params *tickets.SetArtifactParams) *api.Response + SetReferences(ctx context.Context, params *tickets.SetReferencesParams) *api.Response + SetSchema(ctx context.Context, params *tickets.SetSchemaParams) *api.Response + SetTask(ctx context.Context, params *tickets.SetTaskParams) *api.Response + UnlinkTicket(ctx context.Context, params *tickets.UnlinkTicketParams) *api.Response + UpdateAutomation(ctx context.Context, params *automations.UpdateAutomationParams) *api.Response + UpdateCurrentUserData(ctx context.Context, params *userdata.UpdateCurrentUserDataParams) *api.Response + UpdateJob(ctx context.Context, params *jobs.UpdateJobParams) *api.Response + UpdatePlaybook(ctx context.Context, params *playbooks.UpdatePlaybookParams) *api.Response + UpdateTemplate(ctx context.Context, params *templates.UpdateTemplateParams) *api.Response + UpdateTicket(ctx context.Context, params *tickets.UpdateTicketParams) *api.Response + UpdateTicketType(ctx context.Context, params *tickettypes.UpdateTicketTypeParams) *api.Response + UpdateUser(ctx context.Context, params *users.UpdateUserParams) *api.Response + UpdateUserData(ctx context.Context, params *userdata.UpdateUserDataParams) *api.Response +} + +// Config defines the config options for the API server. +type Config struct { + Address string + InsecureHTTP bool + TLSCertFile string + TLSKeyFile string +} + +// Server defines the Server service. +type Server struct { + *gin.Engine + config *Config + server *http.Server + service Service + + ApiGroup *gin.RouterGroup + + RoleAuth func([]role.Role) gin.HandlerFunc +} + +// New initializes a new Server service. +func New(svc Service, config *Config) *Server { + engine := gin.New() + engine.Use(gin.Recovery()) + + return &Server{ + Engine: engine, + service: svc, + config: config, + server: &http.Server{ + Addr: config.Address, + Handler: engine, + ReadTimeout: 10 * time.Second, + WriteTimeout: 10 * time.Second, + }, + + ApiGroup: engine.Group("/api"), + + RoleAuth: func(i []role.Role) gin.HandlerFunc { return func(c *gin.Context) { c.Next() } }, + } +} + +// ConfigureRoutes configures the routes for the Server service. +// Configuring of routes includes setting up Auth if it is enabled. +func (s *Server) ConfigureRoutes() { + s.ApiGroup.POST("/tickets/:id/artifacts", s.RoleAuth([]role.Role{role.TicketWrite}), tickets.AddArtifactEndpoint(s.service.AddArtifact)) + s.ApiGroup.POST("/tickets/:id/comments", s.RoleAuth([]role.Role{role.TicketWrite}), tickets.AddCommentEndpoint(s.service.AddComment)) + s.ApiGroup.POST("/tickets/:id/playbooks", s.RoleAuth([]role.Role{}), tickets.AddTicketPlaybookEndpoint(s.service.AddTicketPlaybook)) + s.ApiGroup.PUT("/tickets/:id/playbooks/:playbookID/task/:taskID/complete", s.RoleAuth([]role.Role{role.TicketWrite}), tickets.CompleteTaskEndpoint(s.service.CompleteTask)) + s.ApiGroup.POST("/automations", s.RoleAuth([]role.Role{role.AutomationWrite}), automations.CreateAutomationEndpoint(s.service.CreateAutomation)) + s.ApiGroup.POST("/playbooks", s.RoleAuth([]role.Role{role.PlaybookWrite}), playbooks.CreatePlaybookEndpoint(s.service.CreatePlaybook)) + s.ApiGroup.POST("/templates", s.RoleAuth([]role.Role{role.TemplateWrite}), templates.CreateTemplateEndpoint(s.service.CreateTemplate)) + s.ApiGroup.POST("/tickets", s.RoleAuth([]role.Role{role.TicketWrite}), tickets.CreateTicketEndpoint(s.service.CreateTicket)) + s.ApiGroup.POST("/tickets/batch", s.RoleAuth([]role.Role{role.TicketWrite}), tickets.CreateTicketBatchEndpoint(s.service.CreateTicketBatch)) + s.ApiGroup.POST("/tickettypes", s.RoleAuth([]role.Role{role.TickettypeWrite}), tickettypes.CreateTicketTypeEndpoint(s.service.CreateTicketType)) + s.ApiGroup.POST("/users", s.RoleAuth([]role.Role{role.UserWrite}), users.CreateUserEndpoint(s.service.CreateUser)) + s.ApiGroup.GET("/currentuser", s.RoleAuth([]role.Role{role.CurrentuserRead}), users.CurrentUserEndpoint(s.service.CurrentUser)) + s.ApiGroup.GET("/currentuserdata", s.RoleAuth([]role.Role{role.CurrentuserdataRead}), userdata.CurrentUserDataEndpoint(s.service.CurrentUserData)) + s.ApiGroup.DELETE("/automations/:id", s.RoleAuth([]role.Role{role.AutomationWrite}), automations.DeleteAutomationEndpoint(s.service.DeleteAutomation)) + s.ApiGroup.DELETE("/playbooks/:id", s.RoleAuth([]role.Role{role.PlaybookWrite}), playbooks.DeletePlaybookEndpoint(s.service.DeletePlaybook)) + s.ApiGroup.DELETE("/templates/:id", s.RoleAuth([]role.Role{role.TemplateWrite}), templates.DeleteTemplateEndpoint(s.service.DeleteTemplate)) + s.ApiGroup.DELETE("/tickets/:id", s.RoleAuth([]role.Role{role.TicketDelete}), tickets.DeleteTicketEndpoint(s.service.DeleteTicket)) + s.ApiGroup.DELETE("/tickettypes/:id", s.RoleAuth([]role.Role{role.TickettypeWrite}), tickettypes.DeleteTicketTypeEndpoint(s.service.DeleteTicketType)) + s.ApiGroup.DELETE("/users/:id", s.RoleAuth([]role.Role{role.UserWrite}), users.DeleteUserEndpoint(s.service.DeleteUser)) + s.ApiGroup.POST("/tickets/:id/artifacts/:name/enrich", s.RoleAuth([]role.Role{role.TicketWrite}), tickets.EnrichArtifactEndpoint(s.service.EnrichArtifact)) + s.ApiGroup.GET("/tickets/:id/artifacts/:name", s.RoleAuth([]role.Role{role.TicketWrite}), tickets.GetArtifactEndpoint(s.service.GetArtifact)) + s.ApiGroup.GET("/automations/:id", s.RoleAuth([]role.Role{role.AutomationRead}), automations.GetAutomationEndpoint(s.service.GetAutomation)) + s.ApiGroup.GET("/jobs/:id", s.RoleAuth([]role.Role{role.JobRead}), jobs.GetJobEndpoint(s.service.GetJob)) + s.ApiGroup.GET("/logs/:reference", s.RoleAuth([]role.Role{role.LogRead}), logs.GetLogsEndpoint(s.service.GetLogs)) + s.ApiGroup.GET("/playbooks/:id", s.RoleAuth([]role.Role{role.PlaybookRead}), playbooks.GetPlaybookEndpoint(s.service.GetPlaybook)) + s.ApiGroup.GET("/settings", s.RoleAuth([]role.Role{role.SettingsRead}), settings.GetSettingsEndpoint(s.service.GetSettings)) + s.ApiGroup.GET("/statistics", s.RoleAuth([]role.Role{role.TicketRead}), statistics.GetStatisticsEndpoint(s.service.GetStatistics)) + s.ApiGroup.GET("/templates/:id", s.RoleAuth([]role.Role{role.TemplateRead}), templates.GetTemplateEndpoint(s.service.GetTemplate)) + s.ApiGroup.GET("/tickets/:id", s.RoleAuth([]role.Role{role.TicketRead}), tickets.GetTicketEndpoint(s.service.GetTicket)) + s.ApiGroup.GET("/tickettypes/:id", s.RoleAuth([]role.Role{role.TickettypeRead}), tickettypes.GetTicketTypeEndpoint(s.service.GetTicketType)) + s.ApiGroup.GET("/users/:id", s.RoleAuth([]role.Role{role.UserRead}), users.GetUserEndpoint(s.service.GetUser)) + s.ApiGroup.GET("/userdata/:id", s.RoleAuth([]role.Role{role.UserdataRead}), userdata.GetUserDataEndpoint(s.service.GetUserData)) + s.ApiGroup.PUT("/tickets/:id/files", s.RoleAuth([]role.Role{role.TicketWrite}), tickets.LinkFilesEndpoint(s.service.LinkFiles)) + s.ApiGroup.PATCH("/tickets/:id/tickets", s.RoleAuth([]role.Role{role.TicketWrite}), tickets.LinkTicketEndpoint(s.service.LinkTicket)) + s.ApiGroup.GET("/automations", s.RoleAuth([]role.Role{role.AutomationRead}), automations.ListAutomationsEndpoint(s.service.ListAutomations)) + s.ApiGroup.GET("/jobs", s.RoleAuth([]role.Role{role.JobRead}), jobs.ListJobsEndpoint(s.service.ListJobs)) + s.ApiGroup.GET("/playbooks", s.RoleAuth([]role.Role{role.PlaybookRead}), playbooks.ListPlaybooksEndpoint(s.service.ListPlaybooks)) + s.ApiGroup.GET("/tasks", s.RoleAuth([]role.Role{role.TicketRead}), tasks.ListTasksEndpoint(s.service.ListTasks)) + s.ApiGroup.GET("/templates", s.RoleAuth([]role.Role{role.TemplateRead}), templates.ListTemplatesEndpoint(s.service.ListTemplates)) + s.ApiGroup.GET("/tickettypes", s.RoleAuth([]role.Role{role.TickettypeRead}), tickettypes.ListTicketTypesEndpoint(s.service.ListTicketTypes)) + s.ApiGroup.GET("/tickets", s.RoleAuth([]role.Role{role.TicketRead}), tickets.ListTicketsEndpoint(s.service.ListTickets)) + s.ApiGroup.GET("/userdata", s.RoleAuth([]role.Role{role.UserdataRead}), userdata.ListUserDataEndpoint(s.service.ListUserData)) + s.ApiGroup.GET("/users", s.RoleAuth([]role.Role{role.UserRead}), users.ListUsersEndpoint(s.service.ListUsers)) + s.ApiGroup.DELETE("/tickets/:id/artifacts/:name", s.RoleAuth([]role.Role{role.TicketWrite}), tickets.RemoveArtifactEndpoint(s.service.RemoveArtifact)) + s.ApiGroup.DELETE("/tickets/:id/comments/:commentID", s.RoleAuth([]role.Role{role.TicketWrite}), tickets.RemoveCommentEndpoint(s.service.RemoveComment)) + s.ApiGroup.DELETE("/tickets/:id/playbooks/:playbookID", s.RoleAuth([]role.Role{role.TicketWrite}), tickets.RemoveTicketPlaybookEndpoint(s.service.RemoveTicketPlaybook)) + s.ApiGroup.POST("/tickets/:id/artifacts/:name/run/:automation", s.RoleAuth([]role.Role{role.TicketWrite}), tickets.RunArtifactEndpoint(s.service.RunArtifact)) + s.ApiGroup.POST("/jobs", s.RoleAuth([]role.Role{role.JobWrite}), jobs.RunJobEndpoint(s.service.RunJob)) + s.ApiGroup.POST("/tickets/:id/playbooks/:playbookID/task/:taskID/run", s.RoleAuth([]role.Role{role.TicketWrite}), tickets.RunTaskEndpoint(s.service.RunTask)) + s.ApiGroup.PUT("/tickets/:id/artifacts/:name", s.RoleAuth([]role.Role{role.TicketWrite}), tickets.SetArtifactEndpoint(s.service.SetArtifact)) + s.ApiGroup.PUT("/tickets/:id/references", s.RoleAuth([]role.Role{role.TicketWrite}), tickets.SetReferencesEndpoint(s.service.SetReferences)) + s.ApiGroup.PUT("/tickets/:id/schema", s.RoleAuth([]role.Role{role.TicketWrite}), tickets.SetSchemaEndpoint(s.service.SetSchema)) + s.ApiGroup.PUT("/tickets/:id/playbooks/:playbookID/task/:taskID", s.RoleAuth([]role.Role{role.TicketWrite}), tickets.SetTaskEndpoint(s.service.SetTask)) + s.ApiGroup.DELETE("/tickets/:id/tickets", s.RoleAuth([]role.Role{role.TicketWrite}), tickets.UnlinkTicketEndpoint(s.service.UnlinkTicket)) + s.ApiGroup.PUT("/automations/:id", s.RoleAuth([]role.Role{role.AutomationWrite}), automations.UpdateAutomationEndpoint(s.service.UpdateAutomation)) + s.ApiGroup.PUT("/currentuserdata", s.RoleAuth([]role.Role{role.CurrentuserdataWrite}), userdata.UpdateCurrentUserDataEndpoint(s.service.UpdateCurrentUserData)) + s.ApiGroup.PUT("/jobs/:id", s.RoleAuth([]role.Role{role.JobWrite}), jobs.UpdateJobEndpoint(s.service.UpdateJob)) + s.ApiGroup.PUT("/playbooks/:id", s.RoleAuth([]role.Role{role.PlaybookWrite}), playbooks.UpdatePlaybookEndpoint(s.service.UpdatePlaybook)) + s.ApiGroup.PUT("/templates/:id", s.RoleAuth([]role.Role{role.TemplateWrite}), templates.UpdateTemplateEndpoint(s.service.UpdateTemplate)) + s.ApiGroup.PUT("/tickets/:id", s.RoleAuth([]role.Role{role.TicketWrite}), tickets.UpdateTicketEndpoint(s.service.UpdateTicket)) + s.ApiGroup.PUT("/tickettypes/:id", s.RoleAuth([]role.Role{role.TickettypeWrite}), tickettypes.UpdateTicketTypeEndpoint(s.service.UpdateTicketType)) + s.ApiGroup.PUT("/users/:id", s.RoleAuth([]role.Role{role.UserWrite}), users.UpdateUserEndpoint(s.service.UpdateUser)) + s.ApiGroup.PUT("/userdata/:id", s.RoleAuth([]role.Role{role.UserdataWrite}), userdata.UpdateUserDataEndpoint(s.service.UpdateUserData)) +} + +// run the Server. It will listen on either HTTP or HTTPS depending on the +// config passed to NewServer. +func (s *Server) run() error { + log.Printf("Serving on address %s\n", s.server.Addr) + if s.config.InsecureHTTP { + return s.server.ListenAndServe() + } + return s.server.ListenAndServeTLS(s.config.TLSCertFile, s.config.TLSKeyFile) +} + +// Shutdown will gracefully shutdown the Server. +func (s *Server) Shutdown() error { + return s.server.Shutdown(context.Background()) +} + +// RunWithSigHandler runs the Server with SIGTERM handling automatically +// enabled. The server will listen for a SIGTERM signal and gracefully shutdown +// the web server. +// It's possible to optionally pass any number shutdown functions which will +// execute one by one after the webserver has been shutdown successfully. +func (s *Server) RunWithSigHandler(shutdown ...func() error) error { + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM) + + go func() { + <-sigCh + s.Shutdown() + }() + + err := s.run() + if err != nil { + if err != http.ErrServerClosed { + return err + } + } + + for _, fn := range shutdown { + err := fn() + if err != nil { + return err + } + } + + return nil +} diff --git a/generated/restapi/api/response.go b/generated/restapi/api/response.go new file mode 100644 index 0000000..a11347a --- /dev/null +++ b/generated/restapi/api/response.go @@ -0,0 +1,6 @@ +package api + +type Response struct { + Code int + Body interface{} +} diff --git a/generated/restapi/embedded_spec.go b/generated/restapi/embedded_spec.go new file mode 100644 index 0000000..2aba816 --- /dev/null +++ b/generated/restapi/embedded_spec.go @@ -0,0 +1,14076 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package restapi + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "encoding/json" +) + +var ( + // SwaggerJSON embedded version of the swagger document used at generation time + SwaggerJSON json.RawMessage + // FlatSwaggerJSON embedded flattened version of the swagger document used at generation time + FlatSwaggerJSON json.RawMessage +) + +func init() { + SwaggerJSON = json.RawMessage([]byte(`{ + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "http" + ], + "swagger": "2.0", + "info": { + "description": "API for the catalyst incident response platform." + }, + "host": ".", + "basePath": "/api", + "paths": { + "/automations": { + "get": { + "security": [ + { + "roles": [ + "automation:read" + ] + } + ], + "tags": [ + "automations" + ], + "summary": "List automations", + "operationId": "listAutomations", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/AutomationResponse" + } + }, + "examples": { + "test": [ + { + "id": "comment", + "image": "docker.io/python:3", + "script": "", + "type": [ + "playbook" + ] + }, + { + "id": "hash.sha1", + "image": "docker.io/python:3", + "schema": "{\"title\":\"Input\",\"type\":\"object\",\"properties\":{\"default\":{\"type\":\"string\",\"title\":\"Value\"}},\"required\":[\"default\"]}", + "script": "", + "type": [ + "global", + "artifact", + "playbook" + ] + }, + { + "id": "thehive", + "image": "docker.io/python:3", + "schema": "{\"title\":\"TheHive credentials\",\"type\":\"object\",\"properties\":{\"thehiveurl\":{\"type\":\"string\",\"title\":\"TheHive URL (e.g. 'https://thehive.example.org')\"},\"thehivekey\":{\"type\":\"string\",\"title\":\"TheHive API Key\"},\"skip_files\":{\"type\":\"boolean\", \"default\": true, \"title\":\"Skip Files (much faster)\"},\"keep_ids\":{\"type\":\"boolean\", \"default\": true, \"title\":\"Keep IDs and overwrite existing IDs\"}},\"required\":[\"thehiveurl\", \"thehivekey\", \"skip_files\", \"keep_ids\"]}", + "script": "", + "type": [ + "global" + ] + }, + { + "id": "vt.hash", + "image": "docker.io/python:3", + "schema": "{\"title\":\"Input\",\"type\":\"object\",\"properties\":{\"default\":{\"type\":\"string\",\"title\":\"Value\"}},\"required\":[\"default\"]}", + "script": "", + "type": [ + "global", + "artifact", + "playbook" + ] + } + ] + } + } + } + }, + "post": { + "security": [ + { + "roles": [ + "automation:write" + ] + } + ], + "tags": [ + "automations" + ], + "summary": "Create a new automation", + "operationId": "createAutomation", + "parameters": [ + { + "x-example": { + "id": "hash-sha-256", + "image": "docker.io/python:3", + "script": "import sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha256 = hashlib.sha256(msg['payload']['default'].encode('utf-8'))\n return {'hash': sha256.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", + "type": [ + "global" + ] + }, + "description": "New automation", + "name": "automation", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/AutomationForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/AutomationResponse" + }, + "examples": { + "test": { + "id": "hash-sha-256", + "image": "docker.io/python:3", + "script": "import sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha256 = hashlib.sha256(msg['payload']['default'].encode('utf-8'))\n return {'hash': sha256.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", + "type": [ + "global" + ] + } + } + } + } + } + }, + "/automations/{id}": { + "get": { + "security": [ + { + "roles": [ + "automation:read" + ] + } + ], + "tags": [ + "automations" + ], + "summary": "Get a single automation", + "operationId": "getAutomation", + "parameters": [ + { + "type": "string", + "x-example": "hash.sha1", + "description": "Automation ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/AutomationResponse" + }, + "examples": { + "test": { + "id": "hash.sha1", + "image": "docker.io/python:3", + "schema": "{\"title\":\"Input\",\"type\":\"object\",\"properties\":{\"default\":{\"type\":\"string\",\"title\":\"Value\"}},\"required\":[\"default\"]}", + "script": "#!/usr/bin/env python\n\nimport sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha1 = hashlib.sha1(msg['payload']['default'].encode('utf-8'))\n return {\"hash\": sha1.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", + "type": [ + "global", + "artifact", + "playbook" + ] + } + } + } + } + }, + "put": { + "security": [ + { + "roles": [ + "automation:write" + ] + } + ], + "tags": [ + "automations" + ], + "summary": "Update an existing automation", + "operationId": "updateAutomation", + "parameters": [ + { + "type": "string", + "x-example": "hash.sha1", + "description": "Automation ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "id": "hash.sha1", + "image": "docker.io/python:3", + "script": "import sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha1 = hashlib.sha1(msg['payload'].encode('utf-8'))\n return {'hash': sha1.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", + "type": [ + "global", + "artifact", + "playbook" + ] + }, + "description": "Automation object that needs to be added", + "name": "automation", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/AutomationForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/AutomationResponse" + }, + "examples": { + "test": { + "id": "hash.sha1", + "image": "docker.io/python:3", + "script": "import sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha1 = hashlib.sha1(msg['payload'].encode('utf-8'))\n return {'hash': sha1.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", + "type": [ + "global", + "artifact", + "playbook" + ] + } + } + } + } + }, + "delete": { + "security": [ + { + "roles": [ + "automation:write" + ] + } + ], + "tags": [ + "automations" + ], + "summary": "Delete a automation", + "operationId": "deleteAutomation", + "parameters": [ + { + "type": "string", + "x-example": "hash.sha1", + "description": "Automation ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "successful operation" + } + } + } + }, + "/currentuser": { + "get": { + "security": [ + { + "roles": [ + "currentuser:read" + ] + } + ], + "tags": [ + "users" + ], + "summary": "Get current user", + "operationId": "currentUser", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/UserResponse" + }, + "examples": { + "test": { + "apikey": false, + "blocked": false, + "id": "bob", + "roles": [ + "admin:backup:read", + "admin:backup:restore", + "admin:group:write", + "admin:job:read", + "admin:job:write", + "admin:log:read", + "admin:ticket:delete", + "admin:user:write", + "admin:userdata:read", + "admin:userdata:write", + "analyst:automation:read", + "analyst:currentsettings:write", + "analyst:currentuser:read", + "analyst:currentuserdata:read", + "analyst:file", + "analyst:group:read", + "analyst:playbook:read", + "analyst:rule:read", + "analyst:settings:read", + "analyst:template:read", + "analyst:ticket:read", + "analyst:ticket:write", + "analyst:tickettype:read", + "analyst:user:read", + "engineer:automation:write", + "engineer:playbook:write", + "engineer:rule:write", + "engineer:template:write", + "engineer:tickettype:write" + ] + } + } + } + } + } + }, + "/currentuserdata": { + "get": { + "security": [ + { + "roles": [ + "currentuserdata:read" + ] + } + ], + "tags": [ + "userdata" + ], + "summary": "Get current user data", + "operationId": "currentUserData", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/UserDataResponse" + }, + "examples": { + "test": { + "email": "bob@example.org", + "id": "bob", + "name": "Bob Bad" + } + } + } + } + }, + "put": { + "security": [ + { + "roles": [ + "currentuserdata:write" + ] + } + ], + "tags": [ + "userdata" + ], + "summary": "Update current user data", + "operationId": "updateCurrentUserData", + "parameters": [ + { + "x-example": { + "email": "bob@example.org", + "name": "Bob Bad" + }, + "description": "User data object that needs to be added", + "name": "userdata", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UserData" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/UserDataResponse" + }, + "examples": { + "test": { + "email": "bob@example.org", + "id": "bob", + "name": "Bob Bad" + } + } + } + } + } + }, + "/jobs": { + "get": { + "security": [ + { + "roles": [ + "job:read" + ] + } + ], + "tags": [ + "jobs" + ], + "summary": "List jobs", + "operationId": "listJobs", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/JobResponse" + } + }, + "examples": { + "test": [ + { + "automation": "hash.sha1", + "id": "99cd67131b48", + "payload": "test", + "status": "created" + } + ] + } + } + } + }, + "post": { + "security": [ + { + "roles": [ + "job:write" + ] + } + ], + "tags": [ + "jobs" + ], + "summary": "Start a new job", + "operationId": "runJob", + "parameters": [ + { + "x-example": { + "automation": "hash.sha1", + "message": { + "payload": "test" + } + }, + "description": "New job", + "name": "job", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/JobForm" + } + } + ], + "responses": { + "204": { + "description": "successful operation" + } + } + } + }, + "/jobs/{id}": { + "get": { + "security": [ + { + "roles": [ + "job:read" + ] + } + ], + "tags": [ + "jobs" + ], + "summary": "Get a single job", + "operationId": "getJob", + "parameters": [ + { + "type": "string", + "x-example": "99cd67131b48", + "description": "Job ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/JobResponse" + }, + "examples": { + "test": { + "automation": "hash.sha1", + "id": "99cd67131b48", + "payload": "test", + "status": "created" + } + } + } + } + }, + "put": { + "security": [ + { + "roles": [ + "job:write" + ] + } + ], + "tags": [ + "jobs" + ], + "summary": "Update an existing job", + "operationId": "updateJob", + "parameters": [ + { + "type": "string", + "x-example": "99cd67131b48", + "description": "Job ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "automation": "hash.sha1", + "id": "99cd67131b48", + "payload": "test", + "status": "failed" + }, + "description": "Job object that needs to be added", + "name": "job", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/Job" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/JobResponse" + }, + "examples": { + "test": { + "automation": "hash.sha1", + "id": "99cd67131b48", + "payload": "test", + "status": "failed" + } + } + } + } + } + }, + "/logs/{reference}": { + "get": { + "security": [ + { + "roles": [ + "log:read" + ] + } + ], + "tags": [ + "logs" + ], + "summary": "Get log entries", + "operationId": "getLogs", + "parameters": [ + { + "type": "string", + "x-example": "tickets%2F294511", + "description": "Reference", + "name": "reference", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/LogEntry" + } + }, + "examples": { + "test": [ + { + "created": "2021-10-02T18:05:00.333535+02:00", + "creator": "bob", + "message": "Fail run account resist lend solve incident centre priority temperature. Cause change distribution examine location technique shape partner milk customer. Rail tea plate soil report cook railway interpretation breath action. Exercise dream accept park conclusion addition shoot assistance may answer. Gold writer link stop combine hear power name commitment operation. Determine lifespan support grow degree henry exclude detail set religion. Direct library policy convention chain retain discover ride walk student. Gather proposal select march aspect play noise avoid encourage employ. Assessment preserve transport combine wish influence income guess run stand. Charge limit crime ignore statement foundation study issue stop claim.", + "reference": "tickets/294511" + } + ] + } + } + } + } + }, + "/playbooks": { + "get": { + "security": [ + { + "roles": [ + "playbook:read" + ] + } + ], + "tags": [ + "playbooks" + ], + "summary": "List playbooks", + "operationId": "listPlaybooks", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/PlaybookTemplateResponse" + } + }, + "examples": { + "test": [ + { + "id": "malware", + "name": "Malware", + "yaml": "name: Malware\ntasks:\n file-or-hash:\n name: Do you have the file or the hash?\n type: input\n schema:\n title: Malware\n type: object\n properties:\n file:\n type: string\n title: \"I have the\"\n enum: [ \"File\", \"Hash\" ]\n next:\n enter-hash: \"file == 'Hash'\"\n upload: \"file == 'File'\"\n\n enter-hash:\n name: Please enter the hash\n type: input\n schema:\n title: Malware\n type: object\n properties:\n hash:\n type: string\n title: Please enter the hash value\n minlength: 32\n next:\n virustotal: \"hash != ''\"\n\n upload:\n name: Upload the malware\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: object\n x-display: file\n title: Please upload the malware\n next:\n hash: \"malware\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['upload'].data['malware']\"\n next:\n virustotal:\n\n virustotal:\n name: Send hash to VirusTotal\n type: automation\n automation: vt.hash\n args:\n hash: \"playbook.tasks['enter-hash'].data['hash'] || playbook.tasks['hash'].data['hash']\"\n # next:\n # known-malware: \"score \u003e 5\"\n # sandbox: \"score \u003c 6\" # unknown-malware\n" + }, + { + "id": "phishing", + "name": "Phishing", + "yaml": "name: Phishing\ntasks:\n board:\n name: Board Involvement?\n description: Is a board member involved?\n type: input\n schema:\n properties:\n boardInvolved:\n default: false\n title: A board member is involved.\n type: boolean\n required:\n - boardInvolved\n title: Board Involvement?\n type: object\n next:\n escalate: \"boardInvolved == true\"\n mail-available: \"boardInvolved == false\"\n\n escalate:\n name: Escalate to CISO\n description: Please escalate the task to the CISO\n type: task\n\n mail-available:\n name: Mail available\n type: input\n schema:\n oneOf:\n - properties:\n mail:\n title: Mail\n type: string\n x-display: textarea\n schemaKey:\n const: 'yes'\n type: string\n required:\n - mail\n title: 'Yes'\n - properties:\n schemaKey:\n const: 'no'\n type: string\n title: 'No'\n title: Mail available\n type: object\n next:\n block-sender: \"schemaKey == 'yes'\"\n extract-iocs: \"schemaKey == 'yes'\"\n search-email-gateway: \"schemaKey == 'no'\"\n\n search-email-gateway:\n name: Search email gateway\n description: Please search email-gateway for the phishing mail.\n type: task\n next:\n extract-iocs:\n\n block-sender:\n name: Block sender\n type: task\n next:\n extract-iocs:\n\n extract-iocs:\n name: Extract IOCs\n description: Please insert the IOCs\n type: input\n schema:\n properties:\n iocs:\n items:\n type: string\n title: IOCs\n type: array\n title: Extract IOCs\n type: object\n next:\n block-iocs:\n\n block-iocs:\n name: Block IOCs\n type: task\n" + }, + { + "id": "simple", + "name": "Simple", + "yaml": "name: Simple\ntasks:\n input:\n name: Enter something to hash\n type: input\n schema:\n title: Something\n type: object\n properties:\n something:\n type: string\n title: Something\n default: \"\"\n next:\n hash: \"something != ''\"\n\n hash:\n name: Hash the something\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['something']\"\n next:\n comment: \"hash != ''\"\n\n comment:\n name: Comment the hash\n type: automation\n automation: comment\n payload:\n default: \"playbook.tasks['hash'].data['hash']\"\n next:\n done: \"done\"\n\n done:\n name: You can close this case now\n type: task\n" + } + ] + } + } + } + }, + "post": { + "security": [ + { + "roles": [ + "playbook:write" + ] + } + ], + "tags": [ + "playbooks" + ], + "summary": "Create a playbook", + "operationId": "createPlaybook", + "parameters": [ + { + "x-example": { + "yaml": "name: Simple2\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n" + }, + "description": "New playbook", + "name": "playbook", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/PlaybookTemplateForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/PlaybookTemplateResponse" + } + }, + "examples": { + "test": { + "id": "simple-2", + "name": "Simple2", + "yaml": "name: Simple2\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n" + } + } + } + } + } + }, + "/playbooks/{id}": { + "get": { + "security": [ + { + "roles": [ + "playbook:read" + ] + } + ], + "tags": [ + "playbooks" + ], + "summary": "Get a single playbook", + "operationId": "getPlaybook", + "parameters": [ + { + "type": "string", + "x-example": "simple", + "description": "Playbook name", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/PlaybookTemplateResponse" + }, + "examples": { + "test": { + "id": "simple", + "name": "Simple", + "yaml": "name: Simple\ntasks:\n input:\n name: Enter something to hash\n type: input\n schema:\n title: Something\n type: object\n properties:\n something:\n type: string\n title: Something\n default: \"\"\n next:\n hash: \"something != ''\"\n\n hash:\n name: Hash the something\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['something']\"\n next:\n comment: \"hash != ''\"\n\n comment:\n name: Comment the hash\n type: automation\n automation: comment\n payload:\n default: \"playbook.tasks['hash'].data['hash']\"\n next:\n done: \"done\"\n\n done:\n name: You can close this case now\n type: task\n" + } + } + } + } + }, + "put": { + "security": [ + { + "roles": [ + "playbook:write" + ] + } + ], + "tags": [ + "playbooks" + ], + "summary": "Update an existing ticket playbook", + "operationId": "updatePlaybook", + "parameters": [ + { + "type": "string", + "x-example": "simple", + "description": "Playbook ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "yaml": "name: Simple\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n" + }, + "description": "Updated playbook", + "name": "playbook", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/PlaybookTemplateForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/PlaybookTemplateResponse" + }, + "examples": { + "test": { + "id": "simple", + "name": "Simple", + "yaml": "name: Simple\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n" + } + } + } + } + }, + "delete": { + "security": [ + { + "roles": [ + "playbook:write" + ] + } + ], + "tags": [ + "playbooks" + ], + "summary": "Delete a playbook", + "operationId": "deletePlaybook", + "parameters": [ + { + "type": "string", + "x-example": "simple", + "description": "Playbook name", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "successful operation" + } + } + } + }, + "/settings": { + "get": { + "security": [ + { + "roles": [ + "settings:read" + ] + } + ], + "tags": [ + "settings" + ], + "summary": "Get settings", + "operationId": "getSettings", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/Settings" + }, + "examples": { + "test": { + "artifactStates": [ + { + "color": "info", + "icon": "mdi-help-circle-outline", + "id": "unknown", + "name": "Unknown" + }, + { + "color": "error", + "icon": "mdi-skull", + "id": "malicious", + "name": "Malicious" + }, + { + "color": "success", + "icon": "mdi-check", + "id": "clean", + "name": "Clean" + } + ], + "roles": [ + "admin:backup:read", + "admin:backup:restore", + "admin:group:write", + "admin:job:read", + "admin:job:write", + "admin:log:read", + "admin:ticket:delete", + "admin:user:write", + "admin:userdata:read", + "admin:userdata:write", + "analyst:automation:read", + "analyst:currentsettings:write", + "analyst:currentuser:read", + "analyst:currentuserdata:read", + "analyst:file", + "analyst:group:read", + "analyst:playbook:read", + "analyst:rule:read", + "analyst:settings:read", + "analyst:template:read", + "analyst:ticket:read", + "analyst:ticket:write", + "analyst:tickettype:read", + "analyst:user:read", + "engineer:automation:write", + "engineer:playbook:write", + "engineer:rule:write", + "engineer:template:write", + "engineer:tickettype:write" + ], + "ticketTypes": [ + { + "default_playbooks": null, + "default_template": "default", + "icon": "mdi-alert", + "id": "alert", + "name": "Alerts" + }, + { + "default_playbooks": null, + "default_template": "default", + "icon": "mdi-radioactive", + "id": "incident", + "name": "Incidents" + }, + { + "default_playbooks": null, + "default_template": "default", + "icon": "mdi-fingerprint", + "id": "investigation", + "name": "Forensic Investigations" + }, + { + "default_playbooks": null, + "default_template": "default", + "icon": "mdi-target", + "id": "hunt", + "name": "Threat Hunting" + } + ], + "tier": "community", + "timeformat": "YYYY-MM-DDThh:mm:ss", + "version": "0.0.0-test" + } + } + } + } + } + }, + "/statistics": { + "get": { + "security": [ + { + "roles": [ + "ticket:read" + ] + } + ], + "tags": [ + "statistics" + ], + "summary": "Get statistics", + "operationId": "getStatistics", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/Statistics" + }, + "examples": { + "test": { + "open_tickets_per_user": {}, + "tickets_per_type": { + "alert": 2, + "incident": 1 + }, + "tickets_per_week": { + "2021-39": 3 + }, + "unassigned": 0 + } + } + } + } + } + }, + "/tasks": { + "get": { + "security": [ + { + "roles": [ + "ticket:read" + ] + } + ], + "tags": [ + "tasks" + ], + "summary": "List tasks", + "operationId": "listTasks", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/TaskResponse" + } + }, + "examples": { + "test": null + } + } + } + } + }, + "/templates": { + "get": { + "security": [ + { + "roles": [ + "template:read" + ] + } + ], + "tags": [ + "templates" + ], + "summary": "List templates", + "operationId": "listTemplates", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/TicketTemplateResponse" + } + }, + "examples": { + "test": [ + { + "id": "default", + "name": "Default", + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Default\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + } + ] + } + } + } + }, + "post": { + "security": [ + { + "roles": [ + "template:write" + ] + } + ], + "tags": [ + "templates" + ], + "summary": "Create a new template", + "operationId": "createTemplate", + "parameters": [ + { + "x-example": { + "name": "My Template", + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + }, + "description": "New template", + "name": "template", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/TicketTemplateForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketTemplateResponse" + }, + "examples": { + "test": { + "id": "my-template", + "name": "My Template", + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + } + } + } + } + } + }, + "/templates/{id}": { + "get": { + "security": [ + { + "roles": [ + "template:read" + ] + } + ], + "tags": [ + "templates" + ], + "summary": "Get a single template", + "operationId": "getTemplate", + "parameters": [ + { + "type": "string", + "x-example": "default", + "description": "Template ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketTemplateResponse" + }, + "examples": { + "test": { + "id": "default", + "name": "Default", + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Default\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + } + } + } + } + }, + "put": { + "security": [ + { + "roles": [ + "template:write" + ] + } + ], + "tags": [ + "templates" + ], + "summary": "Update an existing template", + "operationId": "updateTemplate", + "parameters": [ + { + "type": "string", + "x-example": "default", + "description": "Template ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "name": "My Template", + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + }, + "description": "Template object that needs to be added", + "name": "template", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/TicketTemplateForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketTemplateResponse" + }, + "examples": { + "test": { + "id": "default", + "name": "My Template", + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + } + } + } + } + }, + "delete": { + "security": [ + { + "roles": [ + "template:write" + ] + } + ], + "tags": [ + "templates" + ], + "summary": "Delete a template", + "operationId": "deleteTemplate", + "parameters": [ + { + "type": "string", + "x-example": "default", + "description": "Template ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "successful operation" + } + } + } + }, + "/tickets": { + "get": { + "security": [ + { + "roles": [ + "ticket:read" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "List tickets", + "operationId": "listTickets", + "parameters": [ + { + "type": "string", + "description": "Ticket Type", + "name": "type", + "in": "query" + }, + { + "type": "integer", + "default": 0, + "description": "Offset of the list", + "name": "offset", + "in": "query" + }, + { + "maximum": 100, + "type": "integer", + "default": 25, + "description": "Number of tickets", + "name": "count", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "description": "Sort columns", + "name": "sort", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "boolean" + }, + "description": "Sort descending", + "name": "desc", + "in": "query" + }, + { + "type": "string", + "description": "Search query", + "name": "query", + "in": "query" + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketList" + }, + "examples": { + "test": { + "count": 3, + "tickets": [ + { + "artifacts": [ + { + "name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status": "unknown" + }, + { + "name": "http://www.customerviral.io/scalable/vertical/killer", + "status": "clean" + }, + { + "name": "leadreintermediate.io", + "status": "malicious" + } + ], + "created": "2021-10-02T18:04:59.078206+02:00", + "id": 8123, + "modified": "2021-10-02T18:04:59.078206+02:00", + "name": "live zebra", + "owner": "demo", + "playbooks": { + "phishing": { + "name": "Phishing", + "tasks": { + "block-iocs": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block IOCs", + "type": "task" + }, + "block-sender": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block sender", + "next": { + "extract-iocs": "" + }, + "type": "task" + }, + "board": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Board Involvement?", + "next": { + "escalate": "boardInvolved == true", + "mail-available": "boardInvolved == false" + }, + "schema": { + "properties": { + "boardInvolved": { + "default": false, + "title": "A board member is involved.", + "type": "boolean" + } + }, + "required": [ + "boardInvolved" + ], + "title": "Board Involvement?", + "type": "object" + }, + "type": "input" + }, + "escalate": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Escalate to CISO", + "type": "task" + }, + "extract-iocs": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Extract IOCs", + "next": { + "block-iocs": "" + }, + "schema": { + "properties": { + "iocs": { + "items": { + "type": "string" + }, + "title": "IOCs", + "type": "array" + } + }, + "title": "Extract IOCs", + "type": "object" + }, + "type": "input" + }, + "mail-available": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Mail available", + "next": { + "block-sender": "schemaKey == 'yes'", + "extract-iocs": "schemaKey == 'yes'", + "search-email-gateway": "schemaKey == 'no'" + }, + "schema": { + "oneOf": [ + { + "properties": { + "mail": { + "title": "Mail", + "type": "string", + "x-display": "textarea" + }, + "schemaKey": { + "const": "yes", + "type": "string" + } + }, + "required": [ + "mail" + ], + "title": "Yes" + }, + { + "properties": { + "schemaKey": { + "const": "no", + "type": "string" + } + }, + "title": "No" + } + ], + "title": "Mail available", + "type": "object" + }, + "type": "input" + }, + "search-email-gateway": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Search email gateway", + "next": { + "extract-iocs": "" + }, + "type": "task" + } + } + } + }, + "references": [ + { + "href": "https://www.leadmaximize.net/e-services/back-end", + "name": "performance" + }, + { + "href": "http://www.corporateinteractive.name/rich", + "name": "autumn" + }, + { + "href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name": "suggest" + } + ], + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status": "closed", + "type": "incident" + }, + { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8125, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "phishing from selenafadel@von.com detected", + "owner": "demo", + "references": [ + { + "href": "https://www.seniorleading-edge.name/users/efficient", + "name": "recovery" + }, + { + "href": "http://www.dynamicseamless.com/clicks-and-mortar", + "name": "force" + }, + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + }, + { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8126, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "Surfaceintroduce virus detected", + "owner": "demo", + "references": [ + { + "href": "http://www.centralworld-class.io/synthesize", + "name": "university" + }, + { + "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name": "goal" + }, + { + "href": "http://www.chiefsyndicate.io/action-items", + "name": "unemployment" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + } + ] + } + } + } + } + }, + "post": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Create a new ticket", + "operationId": "createTicket", + "parameters": [ + { + "x-example": { + "id": 123, + "name": "Wannacry infection", + "owner": "bob", + "status": "open", + "type": "incident" + }, + "description": "New ticket", + "name": "ticket", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/TicketForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "created": "1985-04-12T23:20:50.52Z", + "id": 123, + "modified": "1985-04-12T23:20:50.52Z", + "name": "Wannacry infection", + "owner": "bob", + "schema": "{}", + "status": "open", + "type": "incident" + } + } + } + } + } + }, + "/tickets/batch": { + "post": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Create a new tickets in batch", + "operationId": "createTicketBatch", + "parameters": [ + { + "x-example": [ + { + "id": 123, + "name": "Wannacry infection", + "owner": "bob", + "status": "open", + "type": "incident" + } + ], + "description": "New ticket", + "name": "ticket", + "in": "body", + "required": true, + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/TicketForm" + } + } + } + ], + "responses": { + "204": { + "description": "successful operation" + } + } + } + }, + "/tickets/{id}": { + "get": { + "security": [ + { + "roles": [ + "ticket:read" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Get a single ticket", + "operationId": "getTicket", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8125, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8125, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "phishing from selenafadel@von.com detected", + "owner": "demo", + "references": [ + { + "href": "https://www.seniorleading-edge.name/users/efficient", + "name": "recovery" + }, + { + "href": "http://www.dynamicseamless.com/clicks-and-mortar", + "name": "force" + }, + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "schema": "{}", + "status": "closed", + "tickets": [ + { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8126, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "Surfaceintroduce virus detected", + "owner": "demo", + "references": [ + { + "href": "http://www.centralworld-class.io/synthesize", + "name": "university" + }, + { + "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name": "goal" + }, + { + "href": "http://www.chiefsyndicate.io/action-items", + "name": "unemployment" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + } + ], + "type": "alert" + } + } + } + } + }, + "put": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Update an existing ticket", + "operationId": "updateTicket", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8125, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "created": "2021-10-02T18:04:59.078186+02:00", + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "phishing from selenafadel@von.org detected", + "owner": "demo", + "references": [ + { + "href": "https://www.seniorleading-edge.name/users/efficient", + "name": "recovery" + }, + { + "href": "http://www.dynamicseamless.com/clicks-and-mortar", + "name": "force" + }, + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + }, + "description": "Updated ticket", + "name": "ticket", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/Ticket" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8125, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "phishing from selenafadel@von.org detected", + "owner": "demo", + "references": [ + { + "href": "https://www.seniorleading-edge.name/users/efficient", + "name": "recovery" + }, + { + "href": "http://www.dynamicseamless.com/clicks-and-mortar", + "name": "force" + }, + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "schema": "{}", + "status": "closed", + "tickets": [ + { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8126, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "Surfaceintroduce virus detected", + "owner": "demo", + "references": [ + { + "href": "http://www.centralworld-class.io/synthesize", + "name": "university" + }, + { + "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name": "goal" + }, + { + "href": "http://www.chiefsyndicate.io/action-items", + "name": "unemployment" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + } + ], + "type": "alert" + } + } + } + } + }, + "delete": { + "security": [ + { + "roles": [ + "ticket:delete" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Delete an ticket", + "operationId": "deleteTicket", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8125, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "successful operation" + } + } + } + }, + "/tickets/{id}/artifacts": { + "post": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Add a single artifact", + "operationId": "addArtifact", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "name": "2.2.2.2" + }, + "description": "Artifact object that needs to be added", + "name": "artifact", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/Artifact" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "artifacts": [ + { + "name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status": "unknown" + }, + { + "name": "http://www.customerviral.io/scalable/vertical/killer", + "status": "clean" + }, + { + "name": "leadreintermediate.io", + "status": "malicious" + }, + { + "name": "2.2.2.2", + "status": "unknown", + "type": "ip" + } + ], + "created": "2021-10-02T18:04:59.078206+02:00", + "id": 8123, + "modified": "2021-10-02T18:04:59.078206+02:00", + "name": "live zebra", + "owner": "demo", + "playbooks": { + "phishing": { + "name": "Phishing", + "tasks": { + "block-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block IOCs", + "order": 6, + "type": "task" + }, + "block-sender": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block sender", + "next": { + "extract-iocs": "" + }, + "order": 3, + "type": "task" + }, + "board": { + "active": true, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Board Involvement?", + "next": { + "escalate": "boardInvolved == true", + "mail-available": "boardInvolved == false" + }, + "order": 0, + "schema": { + "properties": { + "boardInvolved": { + "default": false, + "title": "A board member is involved.", + "type": "boolean" + } + }, + "required": [ + "boardInvolved" + ], + "title": "Board Involvement?", + "type": "object" + }, + "type": "input" + }, + "escalate": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Escalate to CISO", + "order": 1, + "type": "task" + }, + "extract-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Extract IOCs", + "next": { + "block-iocs": "" + }, + "order": 5, + "schema": { + "properties": { + "iocs": { + "items": { + "type": "string" + }, + "title": "IOCs", + "type": "array" + } + }, + "title": "Extract IOCs", + "type": "object" + }, + "type": "input" + }, + "mail-available": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Mail available", + "next": { + "block-sender": "schemaKey == 'yes'", + "extract-iocs": "schemaKey == 'yes'", + "search-email-gateway": "schemaKey == 'no'" + }, + "order": 2, + "schema": { + "oneOf": [ + { + "properties": { + "mail": { + "title": "Mail", + "type": "string", + "x-display": "textarea" + }, + "schemaKey": { + "const": "yes", + "type": "string" + } + }, + "required": [ + "mail" + ], + "title": "Yes" + }, + { + "properties": { + "schemaKey": { + "const": "no", + "type": "string" + } + }, + "title": "No" + } + ], + "title": "Mail available", + "type": "object" + }, + "type": "input" + }, + "search-email-gateway": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Search email gateway", + "next": { + "extract-iocs": "" + }, + "order": 4, + "type": "task" + } + } + } + }, + "references": [ + { + "href": "https://www.leadmaximize.net/e-services/back-end", + "name": "performance" + }, + { + "href": "http://www.corporateinteractive.name/rich", + "name": "autumn" + }, + { + "href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name": "suggest" + } + ], + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status": "closed", + "type": "incident" + } + } + } + } + } + }, + "/tickets/{id}/artifacts/{name}": { + "get": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Get a single artifact", + "operationId": "getArtifact", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "leadreintermediate.io", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/Artifact" + }, + "examples": { + "test": { + "name": "leadreintermediate.io", + "status": "malicious" + } + } + } + } + }, + "put": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Set a single artifact", + "operationId": "setArtifact", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "leadreintermediate.io", + "name": "name", + "in": "path", + "required": true + }, + { + "x-example": { + "name": "leadreintermediate.io", + "status": "clean" + }, + "name": "artifact", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/Artifact" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "artifacts": [ + { + "name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status": "unknown" + }, + { + "name": "http://www.customerviral.io/scalable/vertical/killer", + "status": "clean" + }, + { + "name": "leadreintermediate.io", + "status": "clean" + } + ], + "created": "2021-10-02T18:04:59.078206+02:00", + "id": 8123, + "modified": "2021-10-02T18:04:59.078206+02:00", + "name": "live zebra", + "owner": "demo", + "playbooks": { + "phishing": { + "name": "Phishing", + "tasks": { + "block-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block IOCs", + "order": 6, + "type": "task" + }, + "block-sender": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block sender", + "next": { + "extract-iocs": "" + }, + "order": 3, + "type": "task" + }, + "board": { + "active": true, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Board Involvement?", + "next": { + "escalate": "boardInvolved == true", + "mail-available": "boardInvolved == false" + }, + "order": 0, + "schema": { + "properties": { + "boardInvolved": { + "default": false, + "title": "A board member is involved.", + "type": "boolean" + } + }, + "required": [ + "boardInvolved" + ], + "title": "Board Involvement?", + "type": "object" + }, + "type": "input" + }, + "escalate": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Escalate to CISO", + "order": 1, + "type": "task" + }, + "extract-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Extract IOCs", + "next": { + "block-iocs": "" + }, + "order": 5, + "schema": { + "properties": { + "iocs": { + "items": { + "type": "string" + }, + "title": "IOCs", + "type": "array" + } + }, + "title": "Extract IOCs", + "type": "object" + }, + "type": "input" + }, + "mail-available": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Mail available", + "next": { + "block-sender": "schemaKey == 'yes'", + "extract-iocs": "schemaKey == 'yes'", + "search-email-gateway": "schemaKey == 'no'" + }, + "order": 2, + "schema": { + "oneOf": [ + { + "properties": { + "mail": { + "title": "Mail", + "type": "string", + "x-display": "textarea" + }, + "schemaKey": { + "const": "yes", + "type": "string" + } + }, + "required": [ + "mail" + ], + "title": "Yes" + }, + { + "properties": { + "schemaKey": { + "const": "no", + "type": "string" + } + }, + "title": "No" + } + ], + "title": "Mail available", + "type": "object" + }, + "type": "input" + }, + "search-email-gateway": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Search email gateway", + "next": { + "extract-iocs": "" + }, + "order": 4, + "type": "task" + } + } + } + }, + "references": [ + { + "href": "https://www.leadmaximize.net/e-services/back-end", + "name": "performance" + }, + { + "href": "http://www.corporateinteractive.name/rich", + "name": "autumn" + }, + { + "href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name": "suggest" + } + ], + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status": "closed", + "type": "incident" + } + } + } + } + }, + "delete": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Remove an artifact", + "operationId": "removeArtifact", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "leadreintermediate.io", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "artifacts": [ + { + "name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status": "unknown" + }, + { + "name": "http://www.customerviral.io/scalable/vertical/killer", + "status": "clean" + } + ], + "created": "2021-10-02T18:04:59.078206+02:00", + "id": 8123, + "modified": "2021-10-02T18:04:59.078206+02:00", + "name": "live zebra", + "owner": "demo", + "playbooks": { + "phishing": { + "name": "Phishing", + "tasks": { + "block-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block IOCs", + "order": 6, + "type": "task" + }, + "block-sender": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block sender", + "next": { + "extract-iocs": "" + }, + "order": 3, + "type": "task" + }, + "board": { + "active": true, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Board Involvement?", + "next": { + "escalate": "boardInvolved == true", + "mail-available": "boardInvolved == false" + }, + "order": 0, + "schema": { + "properties": { + "boardInvolved": { + "default": false, + "title": "A board member is involved.", + "type": "boolean" + } + }, + "required": [ + "boardInvolved" + ], + "title": "Board Involvement?", + "type": "object" + }, + "type": "input" + }, + "escalate": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Escalate to CISO", + "order": 1, + "type": "task" + }, + "extract-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Extract IOCs", + "next": { + "block-iocs": "" + }, + "order": 5, + "schema": { + "properties": { + "iocs": { + "items": { + "type": "string" + }, + "title": "IOCs", + "type": "array" + } + }, + "title": "Extract IOCs", + "type": "object" + }, + "type": "input" + }, + "mail-available": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Mail available", + "next": { + "block-sender": "schemaKey == 'yes'", + "extract-iocs": "schemaKey == 'yes'", + "search-email-gateway": "schemaKey == 'no'" + }, + "order": 2, + "schema": { + "oneOf": [ + { + "properties": { + "mail": { + "title": "Mail", + "type": "string", + "x-display": "textarea" + }, + "schemaKey": { + "const": "yes", + "type": "string" + } + }, + "required": [ + "mail" + ], + "title": "Yes" + }, + { + "properties": { + "schemaKey": { + "const": "no", + "type": "string" + } + }, + "title": "No" + } + ], + "title": "Mail available", + "type": "object" + }, + "type": "input" + }, + "search-email-gateway": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Search email gateway", + "next": { + "extract-iocs": "" + }, + "order": 4, + "type": "task" + } + } + } + }, + "references": [ + { + "href": "https://www.leadmaximize.net/e-services/back-end", + "name": "performance" + }, + { + "href": "http://www.corporateinteractive.name/rich", + "name": "autumn" + }, + { + "href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name": "suggest" + } + ], + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status": "closed", + "type": "incident" + } + } + } + } + } + }, + "/tickets/{id}/artifacts/{name}/enrich": { + "post": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Enrich a single artifact", + "operationId": "enrichArtifact", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "leadreintermediate.io", + "name": "name", + "in": "path", + "required": true + }, + { + "x-example": { + "data": { + "hash": "b7a067a742c20d07a7456646de89bc2d408a1153" + }, + "name": "hash.sha1" + }, + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/EnrichmentForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/Artifact" + }, + "examples": { + "test": { + "artifacts": [ + { + "name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status": "unknown" + }, + { + "name": "http://www.customerviral.io/scalable/vertical/killer", + "status": "clean" + }, + { + "enrichments": { + "hash.sha1": { + "created": "2021-10-03T18:44:06.488923+02:00", + "data": { + "hash": "b7a067a742c20d07a7456646de89bc2d408a1153" + }, + "name": "hash.sha1" + } + }, + "name": "leadreintermediate.io", + "status": "malicious" + } + ], + "created": "2021-10-02T18:04:59.078206+02:00", + "id": 8123, + "modified": "2021-10-02T18:04:59.078206+02:00", + "name": "live zebra", + "owner": "demo", + "playbooks": { + "phishing": { + "name": "Phishing", + "tasks": { + "block-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block IOCs", + "order": 6, + "type": "task" + }, + "block-sender": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block sender", + "next": { + "extract-iocs": "" + }, + "order": 3, + "type": "task" + }, + "board": { + "active": true, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Board Involvement?", + "next": { + "escalate": "boardInvolved == true", + "mail-available": "boardInvolved == false" + }, + "order": 0, + "schema": { + "properties": { + "boardInvolved": { + "default": false, + "title": "A board member is involved.", + "type": "boolean" + } + }, + "required": [ + "boardInvolved" + ], + "title": "Board Involvement?", + "type": "object" + }, + "type": "input" + }, + "escalate": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Escalate to CISO", + "order": 1, + "type": "task" + }, + "extract-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Extract IOCs", + "next": { + "block-iocs": "" + }, + "order": 5, + "schema": { + "properties": { + "iocs": { + "items": { + "type": "string" + }, + "title": "IOCs", + "type": "array" + } + }, + "title": "Extract IOCs", + "type": "object" + }, + "type": "input" + }, + "mail-available": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Mail available", + "next": { + "block-sender": "schemaKey == 'yes'", + "extract-iocs": "schemaKey == 'yes'", + "search-email-gateway": "schemaKey == 'no'" + }, + "order": 2, + "schema": { + "oneOf": [ + { + "properties": { + "mail": { + "title": "Mail", + "type": "string", + "x-display": "textarea" + }, + "schemaKey": { + "const": "yes", + "type": "string" + } + }, + "required": [ + "mail" + ], + "title": "Yes" + }, + { + "properties": { + "schemaKey": { + "const": "no", + "type": "string" + } + }, + "title": "No" + } + ], + "title": "Mail available", + "type": "object" + }, + "type": "input" + }, + "search-email-gateway": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Search email gateway", + "next": { + "extract-iocs": "" + }, + "order": 4, + "type": "task" + } + } + } + }, + "references": [ + { + "href": "https://www.leadmaximize.net/e-services/back-end", + "name": "performance" + }, + { + "href": "http://www.corporateinteractive.name/rich", + "name": "autumn" + }, + { + "href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name": "suggest" + } + ], + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status": "closed", + "type": "incident" + } + } + } + } + } + }, + "/tickets/{id}/artifacts/{name}/run/{automation}": { + "post": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Run automation on a single artifact", + "operationId": "runArtifact", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "leadreintermediate.io", + "name": "name", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "hash.sha1", + "name": "automation", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "successful operation" + } + } + } + }, + "/tickets/{id}/comments": { + "post": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Add ticket comment", + "operationId": "addComment", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8125, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "message": "My first comment" + }, + "description": "Ticket comment", + "name": "comment", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CommentForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "comments": [ + { + "created": "2021-10-02T18:04:59.078186+02:00", + "creator": "bob", + "message": "My first comment" + } + ], + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8125, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "phishing from selenafadel@von.com detected", + "owner": "demo", + "references": [ + { + "href": "https://www.seniorleading-edge.name/users/efficient", + "name": "recovery" + }, + { + "href": "http://www.dynamicseamless.com/clicks-and-mortar", + "name": "force" + }, + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "schema": "{}", + "status": "closed", + "tickets": [ + { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8126, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "Surfaceintroduce virus detected", + "owner": "demo", + "references": [ + { + "href": "http://www.centralworld-class.io/synthesize", + "name": "university" + }, + { + "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name": "goal" + }, + { + "href": "http://www.chiefsyndicate.io/action-items", + "name": "unemployment" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + } + ], + "type": "alert" + } + } + } + } + } + }, + "/tickets/{id}/comments/{commentID}": { + "delete": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "description": "Comment will be removed from the ticket.", + "tags": [ + "tickets" + ], + "summary": "Remove an comment from an ticket", + "operationId": "removeComment", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "integer", + "x-example": 0, + "description": "Comment ID to remove", + "name": "commentID", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "artifacts": [ + { + "name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status": "unknown" + }, + { + "name": "http://www.customerviral.io/scalable/vertical/killer", + "status": "clean" + }, + { + "name": "leadreintermediate.io", + "status": "malicious" + } + ], + "created": "2021-10-02T18:04:59.078206+02:00", + "id": 8123, + "modified": "2021-10-02T18:04:59.078206+02:00", + "name": "live zebra", + "owner": "demo", + "playbooks": { + "phishing": { + "name": "Phishing", + "tasks": { + "block-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block IOCs", + "order": 6, + "type": "task" + }, + "block-sender": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block sender", + "next": { + "extract-iocs": "" + }, + "order": 3, + "type": "task" + }, + "board": { + "active": true, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Board Involvement?", + "next": { + "escalate": "boardInvolved == true", + "mail-available": "boardInvolved == false" + }, + "order": 0, + "schema": { + "properties": { + "boardInvolved": { + "default": false, + "title": "A board member is involved.", + "type": "boolean" + } + }, + "required": [ + "boardInvolved" + ], + "title": "Board Involvement?", + "type": "object" + }, + "type": "input" + }, + "escalate": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Escalate to CISO", + "order": 1, + "type": "task" + }, + "extract-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Extract IOCs", + "next": { + "block-iocs": "" + }, + "order": 5, + "schema": { + "properties": { + "iocs": { + "items": { + "type": "string" + }, + "title": "IOCs", + "type": "array" + } + }, + "title": "Extract IOCs", + "type": "object" + }, + "type": "input" + }, + "mail-available": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Mail available", + "next": { + "block-sender": "schemaKey == 'yes'", + "extract-iocs": "schemaKey == 'yes'", + "search-email-gateway": "schemaKey == 'no'" + }, + "order": 2, + "schema": { + "oneOf": [ + { + "properties": { + "mail": { + "title": "Mail", + "type": "string", + "x-display": "textarea" + }, + "schemaKey": { + "const": "yes", + "type": "string" + } + }, + "required": [ + "mail" + ], + "title": "Yes" + }, + { + "properties": { + "schemaKey": { + "const": "no", + "type": "string" + } + }, + "title": "No" + } + ], + "title": "Mail available", + "type": "object" + }, + "type": "input" + }, + "search-email-gateway": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Search email gateway", + "next": { + "extract-iocs": "" + }, + "order": 4, + "type": "task" + } + } + } + }, + "references": [ + { + "href": "https://www.leadmaximize.net/e-services/back-end", + "name": "performance" + }, + { + "href": "http://www.corporateinteractive.name/rich", + "name": "autumn" + }, + { + "href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name": "suggest" + } + ], + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status": "closed", + "type": "incident" + } + } + } + } + } + }, + "/tickets/{id}/files": { + "put": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "description": "Link files to an ticket. The files themself will be stored in object storage.", + "tags": [ + "tickets" + ], + "summary": "Link files to an ticket", + "operationId": "linkFiles", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8125, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": [ + { + "key": "myfile", + "name": "document.doc" + } + ], + "description": "Added files", + "name": "files", + "in": "body", + "required": true, + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/File" + } + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "created": "2021-10-02T18:04:59.078186+02:00", + "files": [ + { + "key": "myfile", + "name": "document.doc" + } + ], + "id": 8125, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "phishing from selenafadel@von.com detected", + "owner": "demo", + "references": [ + { + "href": "https://www.seniorleading-edge.name/users/efficient", + "name": "recovery" + }, + { + "href": "http://www.dynamicseamless.com/clicks-and-mortar", + "name": "force" + }, + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "schema": "{}", + "status": "closed", + "tickets": [ + { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8126, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "Surfaceintroduce virus detected", + "owner": "demo", + "references": [ + { + "href": "http://www.centralworld-class.io/synthesize", + "name": "university" + }, + { + "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name": "goal" + }, + { + "href": "http://www.chiefsyndicate.io/action-items", + "name": "unemployment" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + } + ], + "type": "alert" + } + } + } + } + } + }, + "/tickets/{id}/playbooks": { + "post": { + "tags": [ + "tickets" + ], + "summary": "Add a new ticket playbook", + "operationId": "addTicketPlaybook", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8125, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "yaml": "name: Simple\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n" + }, + "description": "Ticket playbook object that needs to be added", + "name": "playbook", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/PlaybookTemplateForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "created": "1985-04-12T23:20:50.52Z", + "id": 8125, + "modified": "1985-04-12T23:20:50.52Z", + "name": "phishing from selenafadel@von.com detected", + "owner": "demo", + "playbooks": { + "simple": { + "name": "Simple", + "tasks": { + "escalate": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Escalate to malware team", + "order": 2, + "type": "task" + }, + "hash": { + "active": false, + "automation": "hash.sha1", + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Hash the malware", + "next": { + "escalate": "" + }, + "order": 1, + "payload": { + "default": "playbook.tasks['input'].data['malware']" + }, + "type": "automation" + }, + "input": { + "active": true, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Upload malware if possible", + "next": { + "hash": "malware != ''" + }, + "order": 0, + "schema": { + "properties": { + "malware": { + "default": "", + "title": "Select malware", + "type": "string" + } + }, + "title": "Malware", + "type": "object" + }, + "type": "input" + } + } + } + }, + "references": [ + { + "href": "https://www.seniorleading-edge.name/users/efficient", + "name": "recovery" + }, + { + "href": "http://www.dynamicseamless.com/clicks-and-mortar", + "name": "force" + }, + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "schema": "{}", + "status": "closed", + "tickets": [ + { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8126, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "Surfaceintroduce virus detected", + "owner": "demo", + "references": [ + { + "href": "http://www.centralworld-class.io/synthesize", + "name": "university" + }, + { + "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name": "goal" + }, + { + "href": "http://www.chiefsyndicate.io/action-items", + "name": "unemployment" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + } + ], + "type": "alert" + } + } + } + } + } + }, + "/tickets/{id}/playbooks/{playbookID}": { + "delete": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Remove an ticket playbook", + "operationId": "removeTicketPlaybook", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "phishing", + "description": "Playbook ID", + "name": "playbookID", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "artifacts": [ + { + "name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status": "unknown" + }, + { + "name": "http://www.customerviral.io/scalable/vertical/killer", + "status": "clean" + }, + { + "name": "leadreintermediate.io", + "status": "malicious" + } + ], + "created": "1985-04-12T23:20:50.52Z", + "id": 8123, + "modified": "1985-04-12T23:20:50.52Z", + "name": "live zebra", + "owner": "demo", + "references": [ + { + "href": "https://www.leadmaximize.net/e-services/back-end", + "name": "performance" + }, + { + "href": "http://www.corporateinteractive.name/rich", + "name": "autumn" + }, + { + "href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name": "suggest" + } + ], + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status": "closed", + "type": "incident" + } + } + } + } + } + }, + "/tickets/{id}/playbooks/{playbookID}/task/{taskID}": { + "put": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Set a ticket playbook task", + "operationId": "setTask", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "phishing", + "description": "Playbook ID", + "name": "playbookID", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "board", + "description": "Task ID", + "name": "taskID", + "in": "path", + "required": true + }, + { + "x-example": { + "active": true, + "data": { + "boardInvolved": true + }, + "done": false, + "name": "Board Involvement?", + "next": { + "escalate": "boardInvolved == true", + "mail-available": "boardInvolved == false" + }, + "order": 0, + "schema": { + "properties": { + "boardInvolved": { + "default": false, + "title": "A board member is involved.", + "type": "boolean" + } + }, + "required": [ + "boardInvolved" + ], + "title": "Board Involvement?", + "type": "object" + }, + "type": "input" + }, + "description": "Task", + "name": "task", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/Task" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "artifacts": [ + { + "name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status": "unknown" + }, + { + "name": "http://www.customerviral.io/scalable/vertical/killer", + "status": "clean" + }, + { + "name": "leadreintermediate.io", + "status": "malicious" + } + ], + "created": "2021-10-02T18:04:59.078206+02:00", + "id": 8123, + "modified": "2021-10-02T18:04:59.078206+02:00", + "name": "live zebra", + "owner": "demo", + "playbooks": { + "phishing": { + "name": "Phishing", + "tasks": { + "block-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block IOCs", + "order": 6, + "type": "task" + }, + "block-sender": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block sender", + "next": { + "extract-iocs": "" + }, + "order": 3, + "type": "task" + }, + "board": { + "active": true, + "created": "2021-10-02T18:04:59.078186+02:00", + "data": { + "boardInvolved": true + }, + "done": false, + "name": "Board Involvement?", + "next": { + "escalate": "boardInvolved == true", + "mail-available": "boardInvolved == false" + }, + "order": 0, + "schema": { + "properties": { + "boardInvolved": { + "default": false, + "title": "A board member is involved.", + "type": "boolean" + } + }, + "required": [ + "boardInvolved" + ], + "title": "Board Involvement?", + "type": "object" + }, + "type": "input" + }, + "escalate": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Escalate to CISO", + "order": 1, + "type": "task" + }, + "extract-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Extract IOCs", + "next": { + "block-iocs": "" + }, + "order": 5, + "schema": { + "properties": { + "iocs": { + "items": { + "type": "string" + }, + "title": "IOCs", + "type": "array" + } + }, + "title": "Extract IOCs", + "type": "object" + }, + "type": "input" + }, + "mail-available": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Mail available", + "next": { + "block-sender": "schemaKey == 'yes'", + "extract-iocs": "schemaKey == 'yes'", + "search-email-gateway": "schemaKey == 'no'" + }, + "order": 2, + "schema": { + "oneOf": [ + { + "properties": { + "mail": { + "title": "Mail", + "type": "string", + "x-display": "textarea" + }, + "schemaKey": { + "const": "yes", + "type": "string" + } + }, + "required": [ + "mail" + ], + "title": "Yes" + }, + { + "properties": { + "schemaKey": { + "const": "no", + "type": "string" + } + }, + "title": "No" + } + ], + "title": "Mail available", + "type": "object" + }, + "type": "input" + }, + "search-email-gateway": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Search email gateway", + "next": { + "extract-iocs": "" + }, + "order": 4, + "type": "task" + } + } + } + }, + "references": [ + { + "href": "https://www.leadmaximize.net/e-services/back-end", + "name": "performance" + }, + { + "href": "http://www.corporateinteractive.name/rich", + "name": "autumn" + }, + { + "href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name": "suggest" + } + ], + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status": "closed", + "type": "incident" + } + } + } + } + } + }, + "/tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete": { + "put": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Complete ticket playbook task", + "operationId": "completeTask", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "phishing", + "description": "Playbook ID", + "name": "playbookID", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "board", + "description": "Task ID", + "name": "taskID", + "in": "path", + "required": true + }, + { + "x-example": { + "boardInvolved": true + }, + "description": "Ticket playbook object that needs to be added", + "name": "data", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "artifacts": [ + { + "name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status": "unknown" + }, + { + "name": "http://www.customerviral.io/scalable/vertical/killer", + "status": "clean" + }, + { + "name": "leadreintermediate.io", + "status": "malicious" + } + ], + "created": "2021-10-02T18:04:59.078206+02:00", + "id": 8123, + "modified": "2021-10-02T18:04:59.078206+02:00", + "name": "live zebra", + "owner": "demo", + "playbooks": { + "phishing": { + "name": "Phishing", + "tasks": { + "block-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block IOCs", + "order": 6, + "type": "task" + }, + "block-sender": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block sender", + "next": { + "extract-iocs": "" + }, + "order": 3, + "type": "task" + }, + "board": { + "active": false, + "closed": "2021-10-02T18:04:59.078186+02:00", + "created": "2021-10-02T18:04:59.078186+02:00", + "data": { + "boardInvolved": true + }, + "done": true, + "name": "Board Involvement?", + "next": { + "escalate": "boardInvolved == true", + "mail-available": "boardInvolved == false" + }, + "order": 0, + "schema": { + "properties": { + "boardInvolved": { + "default": false, + "title": "A board member is involved.", + "type": "boolean" + } + }, + "required": [ + "boardInvolved" + ], + "title": "Board Involvement?", + "type": "object" + }, + "type": "input" + }, + "escalate": { + "active": true, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Escalate to CISO", + "order": 1, + "type": "task" + }, + "extract-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Extract IOCs", + "next": { + "block-iocs": "" + }, + "order": 5, + "schema": { + "properties": { + "iocs": { + "items": { + "type": "string" + }, + "title": "IOCs", + "type": "array" + } + }, + "title": "Extract IOCs", + "type": "object" + }, + "type": "input" + }, + "mail-available": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Mail available", + "next": { + "block-sender": "schemaKey == 'yes'", + "extract-iocs": "schemaKey == 'yes'", + "search-email-gateway": "schemaKey == 'no'" + }, + "order": 2, + "schema": { + "oneOf": [ + { + "properties": { + "mail": { + "title": "Mail", + "type": "string", + "x-display": "textarea" + }, + "schemaKey": { + "const": "yes", + "type": "string" + } + }, + "required": [ + "mail" + ], + "title": "Yes" + }, + { + "properties": { + "schemaKey": { + "const": "no", + "type": "string" + } + }, + "title": "No" + } + ], + "title": "Mail available", + "type": "object" + }, + "type": "input" + }, + "search-email-gateway": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Search email gateway", + "next": { + "extract-iocs": "" + }, + "order": 4, + "type": "task" + } + } + } + }, + "references": [ + { + "href": "https://www.leadmaximize.net/e-services/back-end", + "name": "performance" + }, + { + "href": "http://www.corporateinteractive.name/rich", + "name": "autumn" + }, + { + "href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name": "suggest" + } + ], + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status": "closed", + "type": "incident" + } + } + } + } + } + }, + "/tickets/{id}/playbooks/{playbookID}/task/{taskID}/run": { + "post": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Run ticket playbook task", + "operationId": "runTask", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "phishing", + "description": "Playbook ID", + "name": "playbookID", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "board", + "description": "Task ID", + "name": "taskID", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "successful operation" + } + } + } + }, + "/tickets/{id}/references": { + "put": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Set ticket references", + "operationId": "setReferences", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8125, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": [ + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "description": "All ticket references", + "name": "references", + "in": "body", + "required": true, + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Reference" + } + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8125, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "phishing from selenafadel@von.com detected", + "owner": "demo", + "references": [ + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "schema": "{}", + "status": "closed", + "tickets": [ + { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8126, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "Surfaceintroduce virus detected", + "owner": "demo", + "references": [ + { + "href": "http://www.centralworld-class.io/synthesize", + "name": "university" + }, + { + "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name": "goal" + }, + { + "href": "http://www.chiefsyndicate.io/action-items", + "name": "unemployment" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + } + ], + "type": "alert" + } + } + } + } + } + }, + "/tickets/{id}/schema": { + "put": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Set ticket schema", + "operationId": "setSchema", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8125, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": "{}", + "description": "New ticket schema", + "name": "schema", + "in": "body", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8125, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "phishing from selenafadel@von.com detected", + "owner": "demo", + "references": [ + { + "href": "https://www.seniorleading-edge.name/users/efficient", + "name": "recovery" + }, + { + "href": "http://www.dynamicseamless.com/clicks-and-mortar", + "name": "force" + }, + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "schema": "{}", + "status": "closed", + "tickets": [ + { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8126, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "Surfaceintroduce virus detected", + "owner": "demo", + "references": [ + { + "href": "http://www.centralworld-class.io/synthesize", + "name": "university" + }, + { + "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name": "goal" + }, + { + "href": "http://www.chiefsyndicate.io/action-items", + "name": "unemployment" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + } + ], + "type": "alert" + } + } + } + } + } + }, + "/tickets/{id}/tickets": { + "delete": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Unlink an ticket to an ticket", + "operationId": "unlinkTicket", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8126, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": 8125, + "description": "Added ticket ID", + "name": "linkedID", + "in": "body", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8126, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "Surfaceintroduce virus detected", + "owner": "demo", + "references": [ + { + "href": "http://www.centralworld-class.io/synthesize", + "name": "university" + }, + { + "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name": "goal" + }, + { + "href": "http://www.chiefsyndicate.io/action-items", + "name": "unemployment" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + } + } + } + } + }, + "patch": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Link an ticket to an ticket", + "operationId": "linkTicket", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8126, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": 8123, + "description": "Added ticket ID", + "name": "linkedID", + "in": "body", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8126, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "Surfaceintroduce virus detected", + "owner": "demo", + "references": [ + { + "href": "http://www.centralworld-class.io/synthesize", + "name": "university" + }, + { + "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name": "goal" + }, + { + "href": "http://www.chiefsyndicate.io/action-items", + "name": "unemployment" + } + ], + "schema": "{}", + "status": "closed", + "tickets": [ + { + "artifacts": [ + { + "name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status": "unknown" + }, + { + "name": "http://www.customerviral.io/scalable/vertical/killer", + "status": "clean" + }, + { + "name": "leadreintermediate.io", + "status": "malicious" + } + ], + "created": "2021-10-02T18:04:59.078206+02:00", + "id": 8123, + "modified": "2021-10-02T18:04:59.078206+02:00", + "name": "live zebra", + "owner": "demo", + "playbooks": { + "phishing": { + "name": "Phishing", + "tasks": { + "block-iocs": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block IOCs", + "type": "task" + }, + "block-sender": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block sender", + "next": { + "extract-iocs": "" + }, + "type": "task" + }, + "board": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Board Involvement?", + "next": { + "escalate": "boardInvolved == true", + "mail-available": "boardInvolved == false" + }, + "schema": { + "properties": { + "boardInvolved": { + "default": false, + "title": "A board member is involved.", + "type": "boolean" + } + }, + "required": [ + "boardInvolved" + ], + "title": "Board Involvement?", + "type": "object" + }, + "type": "input" + }, + "escalate": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Escalate to CISO", + "type": "task" + }, + "extract-iocs": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Extract IOCs", + "next": { + "block-iocs": "" + }, + "schema": { + "properties": { + "iocs": { + "items": { + "type": "string" + }, + "title": "IOCs", + "type": "array" + } + }, + "title": "Extract IOCs", + "type": "object" + }, + "type": "input" + }, + "mail-available": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Mail available", + "next": { + "block-sender": "schemaKey == 'yes'", + "extract-iocs": "schemaKey == 'yes'", + "search-email-gateway": "schemaKey == 'no'" + }, + "schema": { + "oneOf": [ + { + "properties": { + "mail": { + "title": "Mail", + "type": "string", + "x-display": "textarea" + }, + "schemaKey": { + "const": "yes", + "type": "string" + } + }, + "required": [ + "mail" + ], + "title": "Yes" + }, + { + "properties": { + "schemaKey": { + "const": "no", + "type": "string" + } + }, + "title": "No" + } + ], + "title": "Mail available", + "type": "object" + }, + "type": "input" + }, + "search-email-gateway": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Search email gateway", + "next": { + "extract-iocs": "" + }, + "type": "task" + } + } + } + }, + "references": [ + { + "href": "https://www.leadmaximize.net/e-services/back-end", + "name": "performance" + }, + { + "href": "http://www.corporateinteractive.name/rich", + "name": "autumn" + }, + { + "href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name": "suggest" + } + ], + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status": "closed", + "type": "incident" + }, + { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8125, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "phishing from selenafadel@von.com detected", + "owner": "demo", + "references": [ + { + "href": "https://www.seniorleading-edge.name/users/efficient", + "name": "recovery" + }, + { + "href": "http://www.dynamicseamless.com/clicks-and-mortar", + "name": "force" + }, + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + } + ], + "type": "alert" + } + } + } + } + } + }, + "/tickettypes": { + "get": { + "security": [ + { + "roles": [ + "tickettype:read" + ] + } + ], + "tags": [ + "tickettypes" + ], + "summary": "List tickettypes", + "operationId": "listTicketTypes", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/TicketTypeResponse" + } + }, + "examples": { + "test": [ + { + "default_playbooks": null, + "default_template": "default", + "icon": "mdi-alert", + "id": "alert", + "name": "Alerts" + }, + { + "default_playbooks": null, + "default_template": "default", + "icon": "mdi-radioactive", + "id": "incident", + "name": "Incidents" + }, + { + "default_playbooks": null, + "default_template": "default", + "icon": "mdi-fingerprint", + "id": "investigation", + "name": "Forensic Investigations" + }, + { + "default_playbooks": null, + "default_template": "default", + "icon": "mdi-target", + "id": "hunt", + "name": "Threat Hunting" + } + ] + } + } + } + }, + "post": { + "security": [ + { + "roles": [ + "tickettype:write" + ] + } + ], + "tags": [ + "tickettypes" + ], + "summary": "Create a new tickettype", + "operationId": "createTicketType", + "parameters": [ + { + "x-example": { + "default_playbooks": null, + "default_template": "default", + "icon": "mdi-newspaper-variant-outline", + "name": "TI Tickets" + }, + "description": "New tickettype", + "name": "tickettype", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/TicketTypeForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketTypeResponse" + }, + "examples": { + "test": { + "default_playbooks": null, + "default_template": "default", + "icon": "mdi-newspaper-variant-outline", + "id": "ti-tickets", + "name": "TI Tickets" + } + } + } + } + } + }, + "/tickettypes/{id}": { + "get": { + "security": [ + { + "roles": [ + "tickettype:read" + ] + } + ], + "tags": [ + "tickettypes" + ], + "summary": "Get a single tickettype", + "operationId": "getTicketType", + "parameters": [ + { + "type": "string", + "x-example": "alert", + "description": "TicketType ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketTypeResponse" + }, + "examples": { + "test": { + "default_playbooks": null, + "default_template": "default", + "icon": "mdi-alert", + "id": "alert", + "name": "Alerts" + } + } + } + } + }, + "put": { + "security": [ + { + "roles": [ + "tickettype:write" + ] + } + ], + "tags": [ + "tickettypes" + ], + "summary": "Update an existing tickettype", + "operationId": "updateTicketType", + "parameters": [ + { + "type": "string", + "x-example": "alert", + "description": "TicketType ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "default_playbooks": null, + "default_template": "default", + "icon": "mdi-bell", + "id": "alert", + "name": "Alerts" + }, + "description": "TicketType object that needs to be added", + "name": "tickettype", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/TicketTypeForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketTypeResponse" + }, + "examples": { + "test": { + "default_playbooks": null, + "default_template": "default", + "icon": "mdi-bell", + "id": "alert", + "name": "Alerts" + } + } + } + } + }, + "delete": { + "security": [ + { + "roles": [ + "tickettype:write" + ] + } + ], + "tags": [ + "tickettypes" + ], + "summary": "Delete a tickettype", + "operationId": "deleteTicketType", + "parameters": [ + { + "type": "string", + "x-example": "alert", + "description": "TicketType ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "successful operation" + } + } + } + }, + "/userdata": { + "get": { + "security": [ + { + "roles": [ + "userdata:read" + ] + } + ], + "tags": [ + "userdata" + ], + "summary": "List userdata", + "operationId": "listUserData", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/UserDataResponse" + } + }, + "examples": { + "test": [ + { + "email": "bob@example.org", + "id": "bob", + "name": "Bob Bad" + } + ] + } + } + } + } + }, + "/userdata/{id}": { + "get": { + "security": [ + { + "roles": [ + "userdata:read" + ] + } + ], + "tags": [ + "userdata" + ], + "summary": "Get a single user data", + "operationId": "getUserData", + "parameters": [ + { + "type": "string", + "x-example": "bob", + "description": "User Data ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/UserDataResponse" + }, + "examples": { + "test": { + "email": "bob@example.org", + "id": "bob", + "name": "Bob Bad" + } + } + } + } + }, + "put": { + "security": [ + { + "roles": [ + "userdata:write" + ] + } + ], + "tags": [ + "userdata" + ], + "summary": "Update an existing user data", + "operationId": "updateUserData", + "parameters": [ + { + "type": "string", + "x-example": "bob", + "description": "User Data ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "blocked": false, + "email": "bob@example.org", + "name": "Bob Bad" + }, + "description": "User data object that needs to be added", + "name": "userdata", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UserData" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/UserDataResponse" + }, + "examples": { + "test": { + "email": "bob@example.org", + "id": "bob", + "name": "Bob Bad" + } + } + } + } + } + }, + "/users": { + "get": { + "security": [ + { + "roles": [ + "user:read" + ] + } + ], + "tags": [ + "users" + ], + "summary": "List users", + "operationId": "listUsers", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/UserResponse" + } + }, + "examples": { + "test": [ + { + "apikey": false, + "blocked": false, + "id": "bob", + "roles": [ + "admin:backup:read", + "admin:backup:restore", + "admin:group:write", + "admin:job:read", + "admin:job:write", + "admin:log:read", + "admin:ticket:delete", + "admin:user:write", + "admin:userdata:read", + "admin:userdata:write", + "analyst:automation:read", + "analyst:currentsettings:write", + "analyst:currentuser:read", + "analyst:currentuserdata:read", + "analyst:file", + "analyst:group:read", + "analyst:playbook:read", + "analyst:rule:read", + "analyst:settings:read", + "analyst:template:read", + "analyst:ticket:read", + "analyst:ticket:write", + "analyst:tickettype:read", + "analyst:user:read", + "engineer:automation:write", + "engineer:playbook:write", + "engineer:rule:write", + "engineer:template:write", + "engineer:tickettype:write" + ] + }, + { + "apikey": true, + "blocked": false, + "id": "script", + "roles": [ + "analyst:automation:read", + "analyst:currentsettings:write", + "analyst:currentuser:read", + "analyst:currentuserdata:read", + "analyst:file", + "analyst:group:read", + "analyst:playbook:read", + "analyst:rule:read", + "analyst:settings:read", + "analyst:template:read", + "analyst:ticket:read", + "analyst:ticket:write", + "analyst:tickettype:read", + "analyst:user:read", + "engineer:automation:write", + "engineer:playbook:write", + "engineer:rule:write", + "engineer:template:write", + "engineer:tickettype:write" + ] + } + ] + } + } + } + }, + "post": { + "security": [ + { + "roles": [ + "user:write" + ] + } + ], + "tags": [ + "users" + ], + "summary": "Create user", + "operationId": "createUser", + "parameters": [ + { + "x-example": { + "id": "syncscript", + "roles": [ + "analyst" + ] + }, + "description": "user object that needs to be added", + "name": "user", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UserForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/NewUserResponse" + }, + "examples": { + "test": { + "blocked": false, + "id": "syncscript", + "roles": [ + "analyst:automation:read", + "analyst:currentsettings:write", + "analyst:currentuser:read", + "analyst:currentuserdata:read", + "analyst:file", + "analyst:group:read", + "analyst:playbook:read", + "analyst:rule:read", + "analyst:settings:read", + "analyst:template:read", + "analyst:ticket:read", + "analyst:ticket:write", + "analyst:tickettype:read", + "analyst:user:read" + ], + "secret": "v39bOuobnlEljfWzjAgoKzhmnh1xSMxH" + } + } + } + } + } + }, + "/users/{id}": { + "get": { + "security": [ + { + "roles": [ + "user:read" + ] + } + ], + "tags": [ + "users" + ], + "summary": "Get a single user", + "operationId": "getUser", + "parameters": [ + { + "type": "string", + "x-example": "script", + "description": "user ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/UserResponse" + }, + "examples": { + "test": { + "apikey": true, + "blocked": false, + "id": "script", + "roles": [ + "analyst:automation:read", + "analyst:currentsettings:write", + "analyst:currentuser:read", + "analyst:currentuserdata:read", + "analyst:file", + "analyst:group:read", + "analyst:playbook:read", + "analyst:rule:read", + "analyst:settings:read", + "analyst:template:read", + "analyst:ticket:read", + "analyst:ticket:write", + "analyst:tickettype:read", + "analyst:user:read", + "engineer:automation:write", + "engineer:playbook:write", + "engineer:rule:write", + "engineer:template:write", + "engineer:tickettype:write" + ] + } + } + } + } + }, + "put": { + "security": [ + { + "roles": [ + "user:write" + ] + } + ], + "tags": [ + "users" + ], + "summary": "Update user", + "operationId": "updateUser", + "parameters": [ + { + "type": "string", + "x-example": "bob", + "description": "Template ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "roles": [ + "analyst", + "admin" + ] + }, + "description": "user object that needs to be added", + "name": "user", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UserForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/UserResponse" + }, + "examples": { + "test": { + "apikey": false, + "blocked": false, + "id": "bob", + "roles": [ + "admin:backup:read", + "admin:backup:restore", + "admin:group:write", + "admin:job:read", + "admin:job:write", + "admin:log:read", + "admin:ticket:delete", + "admin:user:write", + "admin:userdata:read", + "admin:userdata:write", + "analyst:automation:read", + "analyst:currentsettings:write", + "analyst:currentuser:read", + "analyst:currentuserdata:read", + "analyst:file", + "analyst:group:read", + "analyst:playbook:read", + "analyst:rule:read", + "analyst:settings:read", + "analyst:template:read", + "analyst:ticket:read", + "analyst:ticket:write", + "analyst:tickettype:read", + "analyst:user:read", + "engineer:automation:write", + "engineer:playbook:write", + "engineer:rule:write", + "engineer:template:write", + "engineer:tickettype:write" + ] + } + } + } + } + }, + "delete": { + "security": [ + { + "roles": [ + "user:write" + ] + } + ], + "tags": [ + "users" + ], + "summary": "Delete user", + "operationId": "deleteUser", + "parameters": [ + { + "type": "string", + "x-example": "script", + "description": "user ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "successful operation" + } + } + } + } + }, + "definitions": { + "Artifact": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "enrichments": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/Enrichment" + } + }, + "name": { + "type": "string", + "example": "2.2.2.2" + }, + "status": { + "type": "string", + "example": "Unknown" + }, + "type": { + "type": "string" + } + } + }, + "ArtifactOrigin": { + "type": "object", + "required": [ + "ticket_id", + "artifact" + ], + "properties": { + "artifact": { + "type": "string" + }, + "ticket_id": { + "type": "integer", + "format": "int64" + } + } + }, + "Automation": { + "type": "object", + "required": [ + "image", + "script", + "type" + ], + "properties": { + "image": { + "type": "string" + }, + "schema": { + "type": "string", + "example": "{}" + }, + "script": { + "type": "string" + }, + "type": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "artifact", + "playbook", + "global" + ] + } + } + } + }, + "AutomationForm": { + "type": "object", + "required": [ + "id", + "image", + "script", + "type" + ], + "properties": { + "id": { + "type": "string" + }, + "image": { + "type": "string" + }, + "schema": { + "type": "string", + "example": "{}" + }, + "script": { + "type": "string" + }, + "type": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "artifact", + "playbook", + "global" + ] + } + } + } + }, + "AutomationResponse": { + "type": "object", + "required": [ + "id", + "image", + "script", + "type" + ], + "properties": { + "id": { + "type": "string" + }, + "image": { + "type": "string" + }, + "schema": { + "type": "string", + "example": "{}" + }, + "script": { + "type": "string" + }, + "type": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "artifact", + "playbook", + "global" + ] + } + } + } + }, + "Comment": { + "type": "object", + "required": [ + "creator", + "created", + "message" + ], + "properties": { + "created": { + "type": "string", + "format": "date-time" + }, + "creator": { + "type": "string" + }, + "message": { + "type": "string" + } + } + }, + "CommentForm": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "created": { + "type": "string", + "format": "date-time" + }, + "creator": { + "type": "string" + }, + "message": { + "type": "string" + } + } + }, + "Context": { + "type": "object", + "properties": { + "artifact": { + "$ref": "#/definitions/Artifact" + }, + "playbook": { + "$ref": "#/definitions/PlaybookResponse" + }, + "task": { + "$ref": "#/definitions/TaskResponse" + }, + "ticket": { + "$ref": "#/definitions/TicketResponse" + } + } + }, + "Enrichment": { + "type": "object", + "required": [ + "name", + "data", + "created" + ], + "properties": { + "created": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "data": { + "type": "object", + "example": { + "hash": "b7a067a742c20d07a7456646de89bc2d408a1153" + } + }, + "name": { + "type": "string", + "example": "hash.sha1" + } + } + }, + "EnrichmentForm": { + "type": "object", + "required": [ + "name", + "data" + ], + "properties": { + "data": { + "type": "object", + "example": { + "hash": "b7a067a742c20d07a7456646de89bc2d408a1153" + } + }, + "name": { + "type": "string", + "example": "hash.sha1" + } + } + }, + "File": { + "type": "object", + "required": [ + "key", + "name" + ], + "properties": { + "key": { + "type": "string", + "example": "myfile" + }, + "name": { + "type": "string", + "example": "notes.docx" + } + } + }, + "Job": { + "type": "object", + "required": [ + "automation", + "running", + "status" + ], + "properties": { + "automation": { + "type": "string" + }, + "container": { + "type": "string" + }, + "log": { + "type": "string" + }, + "origin": { + "$ref": "#/definitions/Origin" + }, + "output": { + "type": "object" + }, + "payload": {}, + "running": { + "type": "boolean" + }, + "status": { + "type": "string" + } + } + }, + "JobForm": { + "type": "object", + "required": [ + "automation" + ], + "properties": { + "automation": { + "type": "string" + }, + "origin": { + "$ref": "#/definitions/Origin" + }, + "payload": {} + } + }, + "JobResponse": { + "type": "object", + "required": [ + "id", + "automation", + "status" + ], + "properties": { + "automation": { + "type": "string" + }, + "container": { + "type": "string" + }, + "id": { + "type": "string" + }, + "log": { + "type": "string" + }, + "origin": { + "$ref": "#/definitions/Origin" + }, + "output": { + "type": "object" + }, + "payload": {}, + "status": { + "type": "string" + } + } + }, + "LogEntry": { + "type": "object", + "required": [ + "reference", + "creator", + "created", + "message" + ], + "properties": { + "created": { + "type": "string", + "format": "date-time" + }, + "creator": { + "type": "string" + }, + "message": { + "type": "string" + }, + "reference": { + "type": "string" + } + } + }, + "Message": { + "type": "object", + "properties": { + "context": { + "$ref": "#/definitions/Context" + }, + "payload": { + "type": "object" + }, + "secrets": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "NewUserResponse": { + "type": "object", + "required": [ + "id", + "blocked", + "roles" + ], + "properties": { + "blocked": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + }, + "secret": { + "type": "string" + } + } + }, + "Origin": { + "type": "object", + "properties": { + "artifact_origin": { + "$ref": "#/definitions/ArtifactOrigin" + }, + "task_origin": { + "$ref": "#/definitions/TaskOrigin" + } + } + }, + "Playbook": { + "type": "object", + "required": [ + "name", + "tasks" + ], + "properties": { + "name": { + "type": "string", + "example": "Phishing" + }, + "tasks": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/Task" + } + } + } + }, + "PlaybookResponse": { + "type": "object", + "required": [ + "name", + "tasks" + ], + "properties": { + "name": { + "type": "string", + "example": "Phishing" + }, + "tasks": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/TaskResponse" + } + } + } + }, + "PlaybookTemplate": { + "type": "object", + "required": [ + "name", + "yaml" + ], + "properties": { + "name": { + "type": "string" + }, + "yaml": { + "type": "string" + } + } + }, + "PlaybookTemplateForm": { + "type": "object", + "required": [ + "yaml" + ], + "properties": { + "id": { + "type": "string" + }, + "yaml": { + "type": "string" + } + } + }, + "PlaybookTemplateResponse": { + "type": "object", + "required": [ + "id", + "name", + "yaml" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "yaml": { + "type": "string" + } + } + }, + "Reference": { + "type": "object", + "required": [ + "name", + "href" + ], + "properties": { + "href": { + "type": "string", + "example": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2017-0144" + }, + "name": { + "type": "string", + "example": "CVE-2017-0144" + } + } + }, + "Settings": { + "type": "object", + "required": [ + "version", + "tier", + "timeformat", + "ticketTypes", + "artifactStates" + ], + "properties": { + "artifactStates": { + "type": "array", + "title": "Artifact States", + "items": { + "$ref": "#/definitions/Type" + } + }, + "roles": { + "type": "array", + "title": "Roles", + "items": { + "type": "string" + } + }, + "ticketTypes": { + "type": "array", + "title": "Ticket Types", + "items": { + "$ref": "#/definitions/TicketTypeResponse" + } + }, + "tier": { + "type": "string", + "title": "Tier", + "enum": [ + "community", + "enterprise" + ] + }, + "timeformat": { + "type": "string", + "title": "Time Format" + }, + "version": { + "type": "string", + "title": "Version" + } + } + }, + "Statistics": { + "type": "object", + "required": [ + "unassigned", + "open_tickets_per_user", + "tickets_per_week", + "tickets_per_type" + ], + "properties": { + "open_tickets_per_user": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "tickets_per_type": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "tickets_per_week": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "unassigned": { + "type": "integer" + } + } + }, + "Task": { + "type": "object", + "required": [ + "name", + "type", + "done", + "created" + ], + "properties": { + "automation": { + "type": "string" + }, + "closed": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "created": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "data": { + "type": "object" + }, + "done": { + "type": "boolean" + }, + "join": { + "type": "boolean", + "example": false + }, + "name": { + "type": "string", + "example": "Inform user" + }, + "next": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "owner": { + "type": "string" + }, + "payload": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "schema": { + "type": "object" + }, + "type": { + "type": "string", + "enum": [ + "task", + "input", + "automation" + ], + "example": "task" + } + } + }, + "TaskForm": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "automation": { + "type": "string" + }, + "closed": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "created": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "data": { + "type": "object" + }, + "done": { + "type": "boolean" + }, + "join": { + "type": "boolean", + "example": false + }, + "name": { + "type": "string", + "example": "Inform user" + }, + "next": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "owner": { + "type": "string" + }, + "payload": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "schema": { + "type": "object" + }, + "type": { + "type": "string", + "enum": [ + "task", + "input", + "automation" + ], + "example": "task" + } + } + }, + "TaskOrigin": { + "type": "object", + "required": [ + "ticket_id", + "playbook_id", + "task_id" + ], + "properties": { + "playbook_id": { + "type": "string" + }, + "task_id": { + "type": "string" + }, + "ticket_id": { + "type": "integer", + "format": "int64" + } + } + }, + "TaskResponse": { + "type": "object", + "required": [ + "name", + "type", + "done", + "created", + "order", + "active" + ], + "properties": { + "active": { + "type": "boolean", + "example": false + }, + "automation": { + "type": "string" + }, + "closed": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "created": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "data": { + "type": "object" + }, + "done": { + "type": "boolean" + }, + "join": { + "type": "boolean", + "example": false + }, + "name": { + "type": "string", + "example": "Inform user" + }, + "next": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "order": { + "type": "number", + "format": "int64", + "example": 2 + }, + "owner": { + "type": "string" + }, + "payload": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "schema": { + "type": "object" + }, + "type": { + "type": "string", + "enum": [ + "task", + "input", + "automation" + ], + "example": "task" + } + } + }, + "TaskWithContext": { + "type": "object", + "required": [ + "ticket_id", + "ticket_name", + "playbook_id", + "playbook_name", + "task_id", + "task" + ], + "properties": { + "playbook_id": { + "type": "string" + }, + "playbook_name": { + "type": "string" + }, + "task": { + "$ref": "#/definitions/TaskResponse" + }, + "task_id": { + "type": "string" + }, + "ticket_id": { + "type": "number", + "format": "int64" + }, + "ticket_name": { + "type": "string" + } + } + }, + "Ticket": { + "type": "object", + "required": [ + "name", + "type", + "status", + "created", + "modified", + "schema" + ], + "properties": { + "artifacts": { + "type": "array", + "items": { + "$ref": "#/definitions/Artifact" + } + }, + "comments": { + "type": "array", + "items": { + "$ref": "#/definitions/Comment" + } + }, + "created": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "details": { + "type": "object", + "example": { + "description": "my little incident" + } + }, + "files": { + "type": "array", + "items": { + "$ref": "#/definitions/File" + } + }, + "modified": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "name": { + "type": "string", + "example": "WannyCry" + }, + "owner": { + "type": "string", + "example": "bob" + }, + "playbooks": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/Playbook" + } + }, + "read": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "bob" + ] + }, + "references": { + "type": "array", + "items": { + "$ref": "#/definitions/Reference" + } + }, + "schema": { + "type": "string", + "example": "{}" + }, + "status": { + "type": "string", + "example": "open" + }, + "type": { + "type": "string", + "example": "incident" + }, + "write": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "alice" + ] + } + } + }, + "TicketForm": { + "type": "object", + "required": [ + "name", + "type", + "status" + ], + "properties": { + "artifacts": { + "type": "array", + "items": { + "$ref": "#/definitions/Artifact" + } + }, + "comments": { + "type": "array", + "items": { + "$ref": "#/definitions/Comment" + } + }, + "created": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "details": { + "type": "object", + "example": { + "description": "my little incident" + } + }, + "files": { + "type": "array", + "items": { + "$ref": "#/definitions/File" + } + }, + "id": { + "type": "integer", + "format": "int64", + "example": 123 + }, + "modified": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "name": { + "type": "string", + "example": "WannyCry" + }, + "owner": { + "type": "string", + "example": "bob" + }, + "playbooks": { + "type": "array", + "items": { + "$ref": "#/definitions/PlaybookTemplateForm" + } + }, + "read": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "bob" + ] + }, + "references": { + "type": "array", + "items": { + "$ref": "#/definitions/Reference" + } + }, + "schema": { + "type": "string", + "example": "{}" + }, + "status": { + "type": "string", + "example": "open" + }, + "type": { + "type": "string", + "example": "incident" + }, + "write": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "alice" + ] + } + } + }, + "TicketList": { + "type": "object", + "required": [ + "tickets", + "count" + ], + "properties": { + "count": { + "type": "number", + "example": 3 + }, + "tickets": { + "type": "array", + "items": { + "$ref": "#/definitions/TicketSimpleResponse" + } + } + } + }, + "TicketResponse": { + "type": "object", + "required": [ + "id", + "name", + "type", + "status", + "created", + "modified", + "schema" + ], + "properties": { + "artifacts": { + "type": "array", + "items": { + "$ref": "#/definitions/Artifact" + } + }, + "comments": { + "type": "array", + "items": { + "$ref": "#/definitions/Comment" + } + }, + "created": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "details": { + "type": "object", + "example": { + "description": "my little incident" + } + }, + "files": { + "type": "array", + "items": { + "$ref": "#/definitions/File" + } + }, + "id": { + "type": "integer", + "format": "int64", + "example": 123 + }, + "modified": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "name": { + "type": "string", + "example": "WannyCry" + }, + "owner": { + "type": "string", + "example": "bob" + }, + "playbooks": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/PlaybookResponse" + } + }, + "read": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "bob" + ] + }, + "references": { + "type": "array", + "items": { + "$ref": "#/definitions/Reference" + } + }, + "schema": { + "type": "string", + "example": "{}" + }, + "status": { + "type": "string", + "example": "open" + }, + "type": { + "type": "string", + "example": "incident" + }, + "write": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "alice" + ] + } + } + }, + "TicketSimpleResponse": { + "type": "object", + "required": [ + "id", + "name", + "type", + "status", + "created", + "modified", + "schema" + ], + "properties": { + "artifacts": { + "type": "array", + "items": { + "$ref": "#/definitions/Artifact" + } + }, + "comments": { + "type": "array", + "items": { + "$ref": "#/definitions/Comment" + } + }, + "created": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "details": { + "type": "object", + "example": { + "description": "my little incident" + } + }, + "files": { + "type": "array", + "items": { + "$ref": "#/definitions/File" + } + }, + "id": { + "type": "integer", + "format": "int64", + "example": 123 + }, + "modified": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "name": { + "type": "string", + "example": "WannyCry" + }, + "owner": { + "type": "string", + "example": "bob" + }, + "playbooks": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/Playbook" + } + }, + "read": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "bob" + ] + }, + "references": { + "type": "array", + "items": { + "$ref": "#/definitions/Reference" + } + }, + "schema": { + "type": "string", + "example": "{}" + }, + "status": { + "type": "string", + "example": "open" + }, + "type": { + "type": "string", + "example": "incident" + }, + "write": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "alice" + ] + } + } + }, + "TicketTemplate": { + "type": "object", + "required": [ + "name", + "schema" + ], + "properties": { + "name": { + "type": "string" + }, + "schema": { + "type": "string" + } + } + }, + "TicketTemplateForm": { + "type": "object", + "required": [ + "name", + "schema" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "schema": { + "type": "string" + } + } + }, + "TicketTemplateResponse": { + "type": "object", + "required": [ + "id", + "name", + "schema" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "schema": { + "type": "string" + } + } + }, + "TicketType": { + "type": "object", + "required": [ + "name", + "icon", + "default_template", + "default_playbooks" + ], + "properties": { + "default_groups": { + "type": "array", + "items": { + "type": "string" + } + }, + "default_playbooks": { + "type": "array", + "items": { + "type": "string" + } + }, + "default_template": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "TicketTypeForm": { + "type": "object", + "required": [ + "name", + "icon", + "default_template", + "default_playbooks" + ], + "properties": { + "default_groups": { + "type": "array", + "items": { + "type": "string" + } + }, + "default_playbooks": { + "type": "array", + "items": { + "type": "string" + } + }, + "default_template": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "TicketTypeResponse": { + "type": "object", + "required": [ + "id", + "name", + "icon", + "default_template", + "default_playbooks" + ], + "properties": { + "default_groups": { + "type": "array", + "items": { + "type": "string" + } + }, + "default_playbooks": { + "type": "array", + "items": { + "type": "string" + } + }, + "default_template": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "TicketWithTickets": { + "type": "object", + "required": [ + "id", + "name", + "type", + "status", + "created", + "modified", + "schema" + ], + "properties": { + "artifacts": { + "type": "array", + "items": { + "$ref": "#/definitions/Artifact" + } + }, + "comments": { + "type": "array", + "items": { + "$ref": "#/definitions/Comment" + } + }, + "created": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "details": { + "type": "object", + "example": { + "description": "my little incident" + } + }, + "files": { + "type": "array", + "items": { + "$ref": "#/definitions/File" + } + }, + "id": { + "type": "integer", + "format": "int64", + "example": 123 + }, + "modified": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "name": { + "type": "string", + "example": "WannyCry" + }, + "owner": { + "type": "string", + "example": "bob" + }, + "playbooks": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/PlaybookResponse" + } + }, + "read": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "bob" + ] + }, + "references": { + "type": "array", + "items": { + "$ref": "#/definitions/Reference" + } + }, + "schema": { + "type": "string", + "example": "{}" + }, + "status": { + "type": "string", + "example": "open" + }, + "tickets": { + "type": "array", + "items": { + "$ref": "#/definitions/TicketSimpleResponse" + } + }, + "type": { + "type": "string", + "example": "incident" + }, + "write": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "alice" + ] + } + } + }, + "Type": { + "type": "object", + "required": [ + "id", + "name", + "icon" + ], + "properties": { + "color": { + "type": "string", + "title": "Color", + "enum": [ + "error", + "info", + "success", + "warning" + ], + "x-cols": 3 + }, + "icon": { + "type": "string", + "title": "Icon (https://materialdesignicons.com)", + "x-class": "pr-2", + "x-cols": 3 + }, + "id": { + "type": "string", + "title": "ID", + "x-class": "pr-2", + "x-cols": 3 + }, + "name": { + "type": "string", + "title": "Name", + "x-class": "pr-2", + "x-cols": 3 + } + } + }, + "User": { + "type": "object", + "required": [ + "blocked", + "apikey", + "roles" + ], + "properties": { + "apikey": { + "type": "boolean" + }, + "blocked": { + "type": "boolean" + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + }, + "sha256": { + "type": "string" + } + } + }, + "UserData": { + "type": "object", + "properties": { + "email": { + "type": "string", + "x-example": "bob@example.org" + }, + "image": { + "type": "string", + "x-display": "custom-avatar" + }, + "name": { + "type": "string", + "x-example": "Robert Smith" + }, + "timeformat": { + "type": "string", + "title": "Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens)" + } + } + }, + "UserDataResponse": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "email": { + "type": "string", + "x-example": "bob@example.org" + }, + "id": { + "type": "string" + }, + "image": { + "type": "string", + "x-display": "custom-avatar" + }, + "name": { + "type": "string", + "x-example": "Robert Smith" + }, + "timeformat": { + "type": "string", + "title": "Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens)" + } + } + }, + "UserForm": { + "type": "object", + "required": [ + "id", + "blocked", + "roles", + "apikey" + ], + "properties": { + "apikey": { + "type": "boolean" + }, + "blocked": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "UserResponse": { + "type": "object", + "required": [ + "id", + "blocked", + "roles", + "apikey" + ], + "properties": { + "apikey": { + "type": "boolean" + }, + "blocked": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } +}`)) + FlatSwaggerJSON = json.RawMessage([]byte(`{ + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "http" + ], + "swagger": "2.0", + "info": { + "description": "API for the catalyst incident response platform." + }, + "host": ".", + "basePath": "/api", + "paths": { + "/automations": { + "get": { + "security": [ + { + "roles": [ + "automation:read" + ] + } + ], + "tags": [ + "automations" + ], + "summary": "List automations", + "operationId": "listAutomations", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/AutomationResponse" + } + }, + "examples": { + "test": [ + { + "id": "comment", + "image": "docker.io/python:3", + "script": "", + "type": [ + "playbook" + ] + }, + { + "id": "hash.sha1", + "image": "docker.io/python:3", + "schema": "{\"title\":\"Input\",\"type\":\"object\",\"properties\":{\"default\":{\"type\":\"string\",\"title\":\"Value\"}},\"required\":[\"default\"]}", + "script": "", + "type": [ + "global", + "artifact", + "playbook" + ] + }, + { + "id": "thehive", + "image": "docker.io/python:3", + "schema": "{\"title\":\"TheHive credentials\",\"type\":\"object\",\"properties\":{\"thehiveurl\":{\"type\":\"string\",\"title\":\"TheHive URL (e.g. 'https://thehive.example.org')\"},\"thehivekey\":{\"type\":\"string\",\"title\":\"TheHive API Key\"},\"skip_files\":{\"type\":\"boolean\", \"default\": true, \"title\":\"Skip Files (much faster)\"},\"keep_ids\":{\"type\":\"boolean\", \"default\": true, \"title\":\"Keep IDs and overwrite existing IDs\"}},\"required\":[\"thehiveurl\", \"thehivekey\", \"skip_files\", \"keep_ids\"]}", + "script": "", + "type": [ + "global" + ] + }, + { + "id": "vt.hash", + "image": "docker.io/python:3", + "schema": "{\"title\":\"Input\",\"type\":\"object\",\"properties\":{\"default\":{\"type\":\"string\",\"title\":\"Value\"}},\"required\":[\"default\"]}", + "script": "", + "type": [ + "global", + "artifact", + "playbook" + ] + } + ] + } + } + } + }, + "post": { + "security": [ + { + "roles": [ + "automation:write" + ] + } + ], + "tags": [ + "automations" + ], + "summary": "Create a new automation", + "operationId": "createAutomation", + "parameters": [ + { + "x-example": { + "id": "hash-sha-256", + "image": "docker.io/python:3", + "script": "import sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha256 = hashlib.sha256(msg['payload']['default'].encode('utf-8'))\n return {'hash': sha256.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", + "type": [ + "global" + ] + }, + "description": "New automation", + "name": "automation", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/AutomationForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/AutomationResponse" + }, + "examples": { + "test": { + "id": "hash-sha-256", + "image": "docker.io/python:3", + "script": "import sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha256 = hashlib.sha256(msg['payload']['default'].encode('utf-8'))\n return {'hash': sha256.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", + "type": [ + "global" + ] + } + } + } + } + } + }, + "/automations/{id}": { + "get": { + "security": [ + { + "roles": [ + "automation:read" + ] + } + ], + "tags": [ + "automations" + ], + "summary": "Get a single automation", + "operationId": "getAutomation", + "parameters": [ + { + "type": "string", + "x-example": "hash.sha1", + "description": "Automation ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/AutomationResponse" + }, + "examples": { + "test": { + "id": "hash.sha1", + "image": "docker.io/python:3", + "schema": "{\"title\":\"Input\",\"type\":\"object\",\"properties\":{\"default\":{\"type\":\"string\",\"title\":\"Value\"}},\"required\":[\"default\"]}", + "script": "#!/usr/bin/env python\n\nimport sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha1 = hashlib.sha1(msg['payload']['default'].encode('utf-8'))\n return {\"hash\": sha1.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", + "type": [ + "global", + "artifact", + "playbook" + ] + } + } + } + } + }, + "put": { + "security": [ + { + "roles": [ + "automation:write" + ] + } + ], + "tags": [ + "automations" + ], + "summary": "Update an existing automation", + "operationId": "updateAutomation", + "parameters": [ + { + "type": "string", + "x-example": "hash.sha1", + "description": "Automation ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "id": "hash.sha1", + "image": "docker.io/python:3", + "script": "import sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha1 = hashlib.sha1(msg['payload'].encode('utf-8'))\n return {'hash': sha1.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", + "type": [ + "global", + "artifact", + "playbook" + ] + }, + "description": "Automation object that needs to be added", + "name": "automation", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/AutomationForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/AutomationResponse" + }, + "examples": { + "test": { + "id": "hash.sha1", + "image": "docker.io/python:3", + "script": "import sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha1 = hashlib.sha1(msg['payload'].encode('utf-8'))\n return {'hash': sha1.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", + "type": [ + "global", + "artifact", + "playbook" + ] + } + } + } + } + }, + "delete": { + "security": [ + { + "roles": [ + "automation:write" + ] + } + ], + "tags": [ + "automations" + ], + "summary": "Delete a automation", + "operationId": "deleteAutomation", + "parameters": [ + { + "type": "string", + "x-example": "hash.sha1", + "description": "Automation ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "successful operation" + } + } + } + }, + "/currentuser": { + "get": { + "security": [ + { + "roles": [ + "currentuser:read" + ] + } + ], + "tags": [ + "users" + ], + "summary": "Get current user", + "operationId": "currentUser", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/UserResponse" + }, + "examples": { + "test": { + "apikey": false, + "blocked": false, + "id": "bob", + "roles": [ + "admin:backup:read", + "admin:backup:restore", + "admin:group:write", + "admin:job:read", + "admin:job:write", + "admin:log:read", + "admin:ticket:delete", + "admin:user:write", + "admin:userdata:read", + "admin:userdata:write", + "analyst:automation:read", + "analyst:currentsettings:write", + "analyst:currentuser:read", + "analyst:currentuserdata:read", + "analyst:file", + "analyst:group:read", + "analyst:playbook:read", + "analyst:rule:read", + "analyst:settings:read", + "analyst:template:read", + "analyst:ticket:read", + "analyst:ticket:write", + "analyst:tickettype:read", + "analyst:user:read", + "engineer:automation:write", + "engineer:playbook:write", + "engineer:rule:write", + "engineer:template:write", + "engineer:tickettype:write" + ] + } + } + } + } + } + }, + "/currentuserdata": { + "get": { + "security": [ + { + "roles": [ + "currentuserdata:read" + ] + } + ], + "tags": [ + "userdata" + ], + "summary": "Get current user data", + "operationId": "currentUserData", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/UserDataResponse" + }, + "examples": { + "test": { + "email": "bob@example.org", + "id": "bob", + "name": "Bob Bad" + } + } + } + } + }, + "put": { + "security": [ + { + "roles": [ + "currentuserdata:write" + ] + } + ], + "tags": [ + "userdata" + ], + "summary": "Update current user data", + "operationId": "updateCurrentUserData", + "parameters": [ + { + "x-example": { + "email": "bob@example.org", + "name": "Bob Bad" + }, + "description": "User data object that needs to be added", + "name": "userdata", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UserData" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/UserDataResponse" + }, + "examples": { + "test": { + "email": "bob@example.org", + "id": "bob", + "name": "Bob Bad" + } + } + } + } + } + }, + "/jobs": { + "get": { + "security": [ + { + "roles": [ + "job:read" + ] + } + ], + "tags": [ + "jobs" + ], + "summary": "List jobs", + "operationId": "listJobs", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/JobResponse" + } + }, + "examples": { + "test": [ + { + "automation": "hash.sha1", + "id": "99cd67131b48", + "payload": "test", + "status": "created" + } + ] + } + } + } + }, + "post": { + "security": [ + { + "roles": [ + "job:write" + ] + } + ], + "tags": [ + "jobs" + ], + "summary": "Start a new job", + "operationId": "runJob", + "parameters": [ + { + "x-example": { + "automation": "hash.sha1", + "message": { + "payload": "test" + } + }, + "description": "New job", + "name": "job", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/JobForm" + } + } + ], + "responses": { + "204": { + "description": "successful operation" + } + } + } + }, + "/jobs/{id}": { + "get": { + "security": [ + { + "roles": [ + "job:read" + ] + } + ], + "tags": [ + "jobs" + ], + "summary": "Get a single job", + "operationId": "getJob", + "parameters": [ + { + "type": "string", + "x-example": "99cd67131b48", + "description": "Job ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/JobResponse" + }, + "examples": { + "test": { + "automation": "hash.sha1", + "id": "99cd67131b48", + "payload": "test", + "status": "created" + } + } + } + } + }, + "put": { + "security": [ + { + "roles": [ + "job:write" + ] + } + ], + "tags": [ + "jobs" + ], + "summary": "Update an existing job", + "operationId": "updateJob", + "parameters": [ + { + "type": "string", + "x-example": "99cd67131b48", + "description": "Job ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "automation": "hash.sha1", + "id": "99cd67131b48", + "payload": "test", + "status": "failed" + }, + "description": "Job object that needs to be added", + "name": "job", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/Job" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/JobResponse" + }, + "examples": { + "test": { + "automation": "hash.sha1", + "id": "99cd67131b48", + "payload": "test", + "status": "failed" + } + } + } + } + } + }, + "/logs/{reference}": { + "get": { + "security": [ + { + "roles": [ + "log:read" + ] + } + ], + "tags": [ + "logs" + ], + "summary": "Get log entries", + "operationId": "getLogs", + "parameters": [ + { + "type": "string", + "x-example": "tickets%2F294511", + "description": "Reference", + "name": "reference", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/LogEntry" + } + }, + "examples": { + "test": [ + { + "created": "2021-10-02T18:05:00.333535+02:00", + "creator": "bob", + "message": "Fail run account resist lend solve incident centre priority temperature. Cause change distribution examine location technique shape partner milk customer. Rail tea plate soil report cook railway interpretation breath action. Exercise dream accept park conclusion addition shoot assistance may answer. Gold writer link stop combine hear power name commitment operation. Determine lifespan support grow degree henry exclude detail set religion. Direct library policy convention chain retain discover ride walk student. Gather proposal select march aspect play noise avoid encourage employ. Assessment preserve transport combine wish influence income guess run stand. Charge limit crime ignore statement foundation study issue stop claim.", + "reference": "tickets/294511" + } + ] + } + } + } + } + }, + "/playbooks": { + "get": { + "security": [ + { + "roles": [ + "playbook:read" + ] + } + ], + "tags": [ + "playbooks" + ], + "summary": "List playbooks", + "operationId": "listPlaybooks", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/PlaybookTemplateResponse" + } + }, + "examples": { + "test": [ + { + "id": "malware", + "name": "Malware", + "yaml": "name: Malware\ntasks:\n file-or-hash:\n name: Do you have the file or the hash?\n type: input\n schema:\n title: Malware\n type: object\n properties:\n file:\n type: string\n title: \"I have the\"\n enum: [ \"File\", \"Hash\" ]\n next:\n enter-hash: \"file == 'Hash'\"\n upload: \"file == 'File'\"\n\n enter-hash:\n name: Please enter the hash\n type: input\n schema:\n title: Malware\n type: object\n properties:\n hash:\n type: string\n title: Please enter the hash value\n minlength: 32\n next:\n virustotal: \"hash != ''\"\n\n upload:\n name: Upload the malware\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: object\n x-display: file\n title: Please upload the malware\n next:\n hash: \"malware\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['upload'].data['malware']\"\n next:\n virustotal:\n\n virustotal:\n name: Send hash to VirusTotal\n type: automation\n automation: vt.hash\n args:\n hash: \"playbook.tasks['enter-hash'].data['hash'] || playbook.tasks['hash'].data['hash']\"\n # next:\n # known-malware: \"score \u003e 5\"\n # sandbox: \"score \u003c 6\" # unknown-malware\n" + }, + { + "id": "phishing", + "name": "Phishing", + "yaml": "name: Phishing\ntasks:\n board:\n name: Board Involvement?\n description: Is a board member involved?\n type: input\n schema:\n properties:\n boardInvolved:\n default: false\n title: A board member is involved.\n type: boolean\n required:\n - boardInvolved\n title: Board Involvement?\n type: object\n next:\n escalate: \"boardInvolved == true\"\n mail-available: \"boardInvolved == false\"\n\n escalate:\n name: Escalate to CISO\n description: Please escalate the task to the CISO\n type: task\n\n mail-available:\n name: Mail available\n type: input\n schema:\n oneOf:\n - properties:\n mail:\n title: Mail\n type: string\n x-display: textarea\n schemaKey:\n const: 'yes'\n type: string\n required:\n - mail\n title: 'Yes'\n - properties:\n schemaKey:\n const: 'no'\n type: string\n title: 'No'\n title: Mail available\n type: object\n next:\n block-sender: \"schemaKey == 'yes'\"\n extract-iocs: \"schemaKey == 'yes'\"\n search-email-gateway: \"schemaKey == 'no'\"\n\n search-email-gateway:\n name: Search email gateway\n description: Please search email-gateway for the phishing mail.\n type: task\n next:\n extract-iocs:\n\n block-sender:\n name: Block sender\n type: task\n next:\n extract-iocs:\n\n extract-iocs:\n name: Extract IOCs\n description: Please insert the IOCs\n type: input\n schema:\n properties:\n iocs:\n items:\n type: string\n title: IOCs\n type: array\n title: Extract IOCs\n type: object\n next:\n block-iocs:\n\n block-iocs:\n name: Block IOCs\n type: task\n" + }, + { + "id": "simple", + "name": "Simple", + "yaml": "name: Simple\ntasks:\n input:\n name: Enter something to hash\n type: input\n schema:\n title: Something\n type: object\n properties:\n something:\n type: string\n title: Something\n default: \"\"\n next:\n hash: \"something != ''\"\n\n hash:\n name: Hash the something\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['something']\"\n next:\n comment: \"hash != ''\"\n\n comment:\n name: Comment the hash\n type: automation\n automation: comment\n payload:\n default: \"playbook.tasks['hash'].data['hash']\"\n next:\n done: \"done\"\n\n done:\n name: You can close this case now\n type: task\n" + } + ] + } + } + } + }, + "post": { + "security": [ + { + "roles": [ + "playbook:write" + ] + } + ], + "tags": [ + "playbooks" + ], + "summary": "Create a playbook", + "operationId": "createPlaybook", + "parameters": [ + { + "x-example": { + "yaml": "name: Simple2\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n" + }, + "description": "New playbook", + "name": "playbook", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/PlaybookTemplateForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/PlaybookTemplateResponse" + } + }, + "examples": { + "test": { + "id": "simple-2", + "name": "Simple2", + "yaml": "name: Simple2\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n" + } + } + } + } + } + }, + "/playbooks/{id}": { + "get": { + "security": [ + { + "roles": [ + "playbook:read" + ] + } + ], + "tags": [ + "playbooks" + ], + "summary": "Get a single playbook", + "operationId": "getPlaybook", + "parameters": [ + { + "type": "string", + "x-example": "simple", + "description": "Playbook name", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/PlaybookTemplateResponse" + }, + "examples": { + "test": { + "id": "simple", + "name": "Simple", + "yaml": "name: Simple\ntasks:\n input:\n name: Enter something to hash\n type: input\n schema:\n title: Something\n type: object\n properties:\n something:\n type: string\n title: Something\n default: \"\"\n next:\n hash: \"something != ''\"\n\n hash:\n name: Hash the something\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['something']\"\n next:\n comment: \"hash != ''\"\n\n comment:\n name: Comment the hash\n type: automation\n automation: comment\n payload:\n default: \"playbook.tasks['hash'].data['hash']\"\n next:\n done: \"done\"\n\n done:\n name: You can close this case now\n type: task\n" + } + } + } + } + }, + "put": { + "security": [ + { + "roles": [ + "playbook:write" + ] + } + ], + "tags": [ + "playbooks" + ], + "summary": "Update an existing ticket playbook", + "operationId": "updatePlaybook", + "parameters": [ + { + "type": "string", + "x-example": "simple", + "description": "Playbook ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "yaml": "name: Simple\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n" + }, + "description": "Updated playbook", + "name": "playbook", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/PlaybookTemplateForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/PlaybookTemplateResponse" + }, + "examples": { + "test": { + "id": "simple", + "name": "Simple", + "yaml": "name: Simple\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n" + } + } + } + } + }, + "delete": { + "security": [ + { + "roles": [ + "playbook:write" + ] + } + ], + "tags": [ + "playbooks" + ], + "summary": "Delete a playbook", + "operationId": "deletePlaybook", + "parameters": [ + { + "type": "string", + "x-example": "simple", + "description": "Playbook name", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "successful operation" + } + } + } + }, + "/settings": { + "get": { + "security": [ + { + "roles": [ + "settings:read" + ] + } + ], + "tags": [ + "settings" + ], + "summary": "Get settings", + "operationId": "getSettings", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/Settings" + }, + "examples": { + "test": { + "artifactStates": [ + { + "color": "info", + "icon": "mdi-help-circle-outline", + "id": "unknown", + "name": "Unknown" + }, + { + "color": "error", + "icon": "mdi-skull", + "id": "malicious", + "name": "Malicious" + }, + { + "color": "success", + "icon": "mdi-check", + "id": "clean", + "name": "Clean" + } + ], + "roles": [ + "admin:backup:read", + "admin:backup:restore", + "admin:group:write", + "admin:job:read", + "admin:job:write", + "admin:log:read", + "admin:ticket:delete", + "admin:user:write", + "admin:userdata:read", + "admin:userdata:write", + "analyst:automation:read", + "analyst:currentsettings:write", + "analyst:currentuser:read", + "analyst:currentuserdata:read", + "analyst:file", + "analyst:group:read", + "analyst:playbook:read", + "analyst:rule:read", + "analyst:settings:read", + "analyst:template:read", + "analyst:ticket:read", + "analyst:ticket:write", + "analyst:tickettype:read", + "analyst:user:read", + "engineer:automation:write", + "engineer:playbook:write", + "engineer:rule:write", + "engineer:template:write", + "engineer:tickettype:write" + ], + "ticketTypes": [ + { + "default_playbooks": [], + "default_template": "default", + "icon": "mdi-alert", + "id": "alert", + "name": "Alerts" + }, + { + "default_playbooks": [], + "default_template": "default", + "icon": "mdi-radioactive", + "id": "incident", + "name": "Incidents" + }, + { + "default_playbooks": [], + "default_template": "default", + "icon": "mdi-fingerprint", + "id": "investigation", + "name": "Forensic Investigations" + }, + { + "default_playbooks": [], + "default_template": "default", + "icon": "mdi-target", + "id": "hunt", + "name": "Threat Hunting" + } + ], + "tier": "community", + "timeformat": "YYYY-MM-DDThh:mm:ss", + "version": "0.0.0-test" + } + } + } + } + } + }, + "/statistics": { + "get": { + "security": [ + { + "roles": [ + "ticket:read" + ] + } + ], + "tags": [ + "statistics" + ], + "summary": "Get statistics", + "operationId": "getStatistics", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/Statistics" + }, + "examples": { + "test": { + "open_tickets_per_user": {}, + "tickets_per_type": { + "alert": 2, + "incident": 1 + }, + "tickets_per_week": { + "2021-39": 3 + }, + "unassigned": 0 + } + } + } + } + } + }, + "/tasks": { + "get": { + "security": [ + { + "roles": [ + "ticket:read" + ] + } + ], + "tags": [ + "tasks" + ], + "summary": "List tasks", + "operationId": "listTasks", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/TaskResponse" + } + }, + "examples": { + "test": [] + } + } + } + } + }, + "/templates": { + "get": { + "security": [ + { + "roles": [ + "template:read" + ] + } + ], + "tags": [ + "templates" + ], + "summary": "List templates", + "operationId": "listTemplates", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/TicketTemplateResponse" + } + }, + "examples": { + "test": [ + { + "id": "default", + "name": "Default", + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Default\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + } + ] + } + } + } + }, + "post": { + "security": [ + { + "roles": [ + "template:write" + ] + } + ], + "tags": [ + "templates" + ], + "summary": "Create a new template", + "operationId": "createTemplate", + "parameters": [ + { + "x-example": { + "name": "My Template", + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + }, + "description": "New template", + "name": "template", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/TicketTemplateForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketTemplateResponse" + }, + "examples": { + "test": { + "id": "my-template", + "name": "My Template", + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + } + } + } + } + } + }, + "/templates/{id}": { + "get": { + "security": [ + { + "roles": [ + "template:read" + ] + } + ], + "tags": [ + "templates" + ], + "summary": "Get a single template", + "operationId": "getTemplate", + "parameters": [ + { + "type": "string", + "x-example": "default", + "description": "Template ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketTemplateResponse" + }, + "examples": { + "test": { + "id": "default", + "name": "Default", + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Default\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + } + } + } + } + }, + "put": { + "security": [ + { + "roles": [ + "template:write" + ] + } + ], + "tags": [ + "templates" + ], + "summary": "Update an existing template", + "operationId": "updateTemplate", + "parameters": [ + { + "type": "string", + "x-example": "default", + "description": "Template ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "name": "My Template", + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + }, + "description": "Template object that needs to be added", + "name": "template", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/TicketTemplateForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketTemplateResponse" + }, + "examples": { + "test": { + "id": "default", + "name": "My Template", + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" + } + } + } + } + }, + "delete": { + "security": [ + { + "roles": [ + "template:write" + ] + } + ], + "tags": [ + "templates" + ], + "summary": "Delete a template", + "operationId": "deleteTemplate", + "parameters": [ + { + "type": "string", + "x-example": "default", + "description": "Template ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "successful operation" + } + } + } + }, + "/tickets": { + "get": { + "security": [ + { + "roles": [ + "ticket:read" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "List tickets", + "operationId": "listTickets", + "parameters": [ + { + "type": "string", + "description": "Ticket Type", + "name": "type", + "in": "query" + }, + { + "type": "integer", + "default": 0, + "description": "Offset of the list", + "name": "offset", + "in": "query" + }, + { + "maximum": 100, + "type": "integer", + "default": 25, + "description": "Number of tickets", + "name": "count", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "description": "Sort columns", + "name": "sort", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "boolean" + }, + "description": "Sort descending", + "name": "desc", + "in": "query" + }, + { + "type": "string", + "description": "Search query", + "name": "query", + "in": "query" + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketList" + }, + "examples": { + "test": { + "count": 3, + "tickets": [ + { + "artifacts": [ + { + "name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status": "unknown" + }, + { + "name": "http://www.customerviral.io/scalable/vertical/killer", + "status": "clean" + }, + { + "name": "leadreintermediate.io", + "status": "malicious" + } + ], + "created": "2021-10-02T18:04:59.078206+02:00", + "id": 8123, + "modified": "2021-10-02T18:04:59.078206+02:00", + "name": "live zebra", + "owner": "demo", + "playbooks": { + "phishing": { + "name": "Phishing", + "tasks": { + "block-iocs": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block IOCs", + "type": "task" + }, + "block-sender": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block sender", + "next": { + "extract-iocs": "" + }, + "type": "task" + }, + "board": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Board Involvement?", + "next": { + "escalate": "boardInvolved == true", + "mail-available": "boardInvolved == false" + }, + "schema": { + "properties": { + "boardInvolved": { + "default": false, + "title": "A board member is involved.", + "type": "boolean" + } + }, + "required": [ + "boardInvolved" + ], + "title": "Board Involvement?", + "type": "object" + }, + "type": "input" + }, + "escalate": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Escalate to CISO", + "type": "task" + }, + "extract-iocs": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Extract IOCs", + "next": { + "block-iocs": "" + }, + "schema": { + "properties": { + "iocs": { + "items": { + "type": "string" + }, + "title": "IOCs", + "type": "array" + } + }, + "title": "Extract IOCs", + "type": "object" + }, + "type": "input" + }, + "mail-available": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Mail available", + "next": { + "block-sender": "schemaKey == 'yes'", + "extract-iocs": "schemaKey == 'yes'", + "search-email-gateway": "schemaKey == 'no'" + }, + "schema": { + "oneOf": [ + { + "properties": { + "mail": { + "title": "Mail", + "type": "string", + "x-display": "textarea" + }, + "schemaKey": { + "const": "yes", + "type": "string" + } + }, + "required": [ + "mail" + ], + "title": "Yes" + }, + { + "properties": { + "schemaKey": { + "const": "no", + "type": "string" + } + }, + "title": "No" + } + ], + "title": "Mail available", + "type": "object" + }, + "type": "input" + }, + "search-email-gateway": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Search email gateway", + "next": { + "extract-iocs": "" + }, + "type": "task" + } + } + } + }, + "references": [ + { + "href": "https://www.leadmaximize.net/e-services/back-end", + "name": "performance" + }, + { + "href": "http://www.corporateinteractive.name/rich", + "name": "autumn" + }, + { + "href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name": "suggest" + } + ], + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status": "closed", + "type": "incident" + }, + { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8125, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "phishing from selenafadel@von.com detected", + "owner": "demo", + "references": [ + { + "href": "https://www.seniorleading-edge.name/users/efficient", + "name": "recovery" + }, + { + "href": "http://www.dynamicseamless.com/clicks-and-mortar", + "name": "force" + }, + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + }, + { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8126, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "Surfaceintroduce virus detected", + "owner": "demo", + "references": [ + { + "href": "http://www.centralworld-class.io/synthesize", + "name": "university" + }, + { + "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name": "goal" + }, + { + "href": "http://www.chiefsyndicate.io/action-items", + "name": "unemployment" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + } + ] + } + } + } + } + }, + "post": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Create a new ticket", + "operationId": "createTicket", + "parameters": [ + { + "x-example": { + "id": 123, + "name": "Wannacry infection", + "owner": "bob", + "status": "open", + "type": "incident" + }, + "description": "New ticket", + "name": "ticket", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/TicketForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "created": "1985-04-12T23:20:50.52Z", + "id": 123, + "modified": "1985-04-12T23:20:50.52Z", + "name": "Wannacry infection", + "owner": "bob", + "schema": "{}", + "status": "open", + "type": "incident" + } + } + } + } + } + }, + "/tickets/batch": { + "post": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Create a new tickets in batch", + "operationId": "createTicketBatch", + "parameters": [ + { + "x-example": [ + { + "id": 123, + "name": "Wannacry infection", + "owner": "bob", + "status": "open", + "type": "incident" + } + ], + "description": "New ticket", + "name": "ticket", + "in": "body", + "required": true, + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/TicketForm" + } + } + } + ], + "responses": { + "204": { + "description": "successful operation" + } + } + } + }, + "/tickets/{id}": { + "get": { + "security": [ + { + "roles": [ + "ticket:read" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Get a single ticket", + "operationId": "getTicket", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8125, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8125, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "phishing from selenafadel@von.com detected", + "owner": "demo", + "references": [ + { + "href": "https://www.seniorleading-edge.name/users/efficient", + "name": "recovery" + }, + { + "href": "http://www.dynamicseamless.com/clicks-and-mortar", + "name": "force" + }, + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "schema": "{}", + "status": "closed", + "tickets": [ + { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8126, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "Surfaceintroduce virus detected", + "owner": "demo", + "references": [ + { + "href": "http://www.centralworld-class.io/synthesize", + "name": "university" + }, + { + "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name": "goal" + }, + { + "href": "http://www.chiefsyndicate.io/action-items", + "name": "unemployment" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + } + ], + "type": "alert" + } + } + } + } + }, + "put": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Update an existing ticket", + "operationId": "updateTicket", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8125, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "created": "2021-10-02T18:04:59.078186+02:00", + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "phishing from selenafadel@von.org detected", + "owner": "demo", + "references": [ + { + "href": "https://www.seniorleading-edge.name/users/efficient", + "name": "recovery" + }, + { + "href": "http://www.dynamicseamless.com/clicks-and-mortar", + "name": "force" + }, + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + }, + "description": "Updated ticket", + "name": "ticket", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/Ticket" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8125, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "phishing from selenafadel@von.org detected", + "owner": "demo", + "references": [ + { + "href": "https://www.seniorleading-edge.name/users/efficient", + "name": "recovery" + }, + { + "href": "http://www.dynamicseamless.com/clicks-and-mortar", + "name": "force" + }, + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "schema": "{}", + "status": "closed", + "tickets": [ + { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8126, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "Surfaceintroduce virus detected", + "owner": "demo", + "references": [ + { + "href": "http://www.centralworld-class.io/synthesize", + "name": "university" + }, + { + "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name": "goal" + }, + { + "href": "http://www.chiefsyndicate.io/action-items", + "name": "unemployment" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + } + ], + "type": "alert" + } + } + } + } + }, + "delete": { + "security": [ + { + "roles": [ + "ticket:delete" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Delete an ticket", + "operationId": "deleteTicket", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8125, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "successful operation" + } + } + } + }, + "/tickets/{id}/artifacts": { + "post": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Add a single artifact", + "operationId": "addArtifact", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "name": "2.2.2.2" + }, + "description": "Artifact object that needs to be added", + "name": "artifact", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/Artifact" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "artifacts": [ + { + "name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status": "unknown" + }, + { + "name": "http://www.customerviral.io/scalable/vertical/killer", + "status": "clean" + }, + { + "name": "leadreintermediate.io", + "status": "malicious" + }, + { + "name": "2.2.2.2", + "status": "unknown", + "type": "ip" + } + ], + "created": "2021-10-02T18:04:59.078206+02:00", + "id": 8123, + "modified": "2021-10-02T18:04:59.078206+02:00", + "name": "live zebra", + "owner": "demo", + "playbooks": { + "phishing": { + "name": "Phishing", + "tasks": { + "block-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block IOCs", + "order": 6, + "type": "task" + }, + "block-sender": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block sender", + "next": { + "extract-iocs": "" + }, + "order": 3, + "type": "task" + }, + "board": { + "active": true, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Board Involvement?", + "next": { + "escalate": "boardInvolved == true", + "mail-available": "boardInvolved == false" + }, + "order": 0, + "schema": { + "properties": { + "boardInvolved": { + "default": false, + "title": "A board member is involved.", + "type": "boolean" + } + }, + "required": [ + "boardInvolved" + ], + "title": "Board Involvement?", + "type": "object" + }, + "type": "input" + }, + "escalate": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Escalate to CISO", + "order": 1, + "type": "task" + }, + "extract-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Extract IOCs", + "next": { + "block-iocs": "" + }, + "order": 5, + "schema": { + "properties": { + "iocs": { + "items": { + "type": "string" + }, + "title": "IOCs", + "type": "array" + } + }, + "title": "Extract IOCs", + "type": "object" + }, + "type": "input" + }, + "mail-available": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Mail available", + "next": { + "block-sender": "schemaKey == 'yes'", + "extract-iocs": "schemaKey == 'yes'", + "search-email-gateway": "schemaKey == 'no'" + }, + "order": 2, + "schema": { + "oneOf": [ + { + "properties": { + "mail": { + "title": "Mail", + "type": "string", + "x-display": "textarea" + }, + "schemaKey": { + "const": "yes", + "type": "string" + } + }, + "required": [ + "mail" + ], + "title": "Yes" + }, + { + "properties": { + "schemaKey": { + "const": "no", + "type": "string" + } + }, + "title": "No" + } + ], + "title": "Mail available", + "type": "object" + }, + "type": "input" + }, + "search-email-gateway": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Search email gateway", + "next": { + "extract-iocs": "" + }, + "order": 4, + "type": "task" + } + } + } + }, + "references": [ + { + "href": "https://www.leadmaximize.net/e-services/back-end", + "name": "performance" + }, + { + "href": "http://www.corporateinteractive.name/rich", + "name": "autumn" + }, + { + "href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name": "suggest" + } + ], + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status": "closed", + "type": "incident" + } + } + } + } + } + }, + "/tickets/{id}/artifacts/{name}": { + "get": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Get a single artifact", + "operationId": "getArtifact", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "leadreintermediate.io", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/Artifact" + }, + "examples": { + "test": { + "name": "leadreintermediate.io", + "status": "malicious" + } + } + } + } + }, + "put": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Set a single artifact", + "operationId": "setArtifact", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "leadreintermediate.io", + "name": "name", + "in": "path", + "required": true + }, + { + "x-example": { + "name": "leadreintermediate.io", + "status": "clean" + }, + "name": "artifact", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/Artifact" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "artifacts": [ + { + "name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status": "unknown" + }, + { + "name": "http://www.customerviral.io/scalable/vertical/killer", + "status": "clean" + }, + { + "name": "leadreintermediate.io", + "status": "clean" + } + ], + "created": "2021-10-02T18:04:59.078206+02:00", + "id": 8123, + "modified": "2021-10-02T18:04:59.078206+02:00", + "name": "live zebra", + "owner": "demo", + "playbooks": { + "phishing": { + "name": "Phishing", + "tasks": { + "block-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block IOCs", + "order": 6, + "type": "task" + }, + "block-sender": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block sender", + "next": { + "extract-iocs": "" + }, + "order": 3, + "type": "task" + }, + "board": { + "active": true, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Board Involvement?", + "next": { + "escalate": "boardInvolved == true", + "mail-available": "boardInvolved == false" + }, + "order": 0, + "schema": { + "properties": { + "boardInvolved": { + "default": false, + "title": "A board member is involved.", + "type": "boolean" + } + }, + "required": [ + "boardInvolved" + ], + "title": "Board Involvement?", + "type": "object" + }, + "type": "input" + }, + "escalate": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Escalate to CISO", + "order": 1, + "type": "task" + }, + "extract-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Extract IOCs", + "next": { + "block-iocs": "" + }, + "order": 5, + "schema": { + "properties": { + "iocs": { + "items": { + "type": "string" + }, + "title": "IOCs", + "type": "array" + } + }, + "title": "Extract IOCs", + "type": "object" + }, + "type": "input" + }, + "mail-available": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Mail available", + "next": { + "block-sender": "schemaKey == 'yes'", + "extract-iocs": "schemaKey == 'yes'", + "search-email-gateway": "schemaKey == 'no'" + }, + "order": 2, + "schema": { + "oneOf": [ + { + "properties": { + "mail": { + "title": "Mail", + "type": "string", + "x-display": "textarea" + }, + "schemaKey": { + "const": "yes", + "type": "string" + } + }, + "required": [ + "mail" + ], + "title": "Yes" + }, + { + "properties": { + "schemaKey": { + "const": "no", + "type": "string" + } + }, + "title": "No" + } + ], + "title": "Mail available", + "type": "object" + }, + "type": "input" + }, + "search-email-gateway": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Search email gateway", + "next": { + "extract-iocs": "" + }, + "order": 4, + "type": "task" + } + } + } + }, + "references": [ + { + "href": "https://www.leadmaximize.net/e-services/back-end", + "name": "performance" + }, + { + "href": "http://www.corporateinteractive.name/rich", + "name": "autumn" + }, + { + "href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name": "suggest" + } + ], + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status": "closed", + "type": "incident" + } + } + } + } + }, + "delete": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Remove an artifact", + "operationId": "removeArtifact", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "leadreintermediate.io", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "artifacts": [ + { + "name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status": "unknown" + }, + { + "name": "http://www.customerviral.io/scalable/vertical/killer", + "status": "clean" + } + ], + "created": "2021-10-02T18:04:59.078206+02:00", + "id": 8123, + "modified": "2021-10-02T18:04:59.078206+02:00", + "name": "live zebra", + "owner": "demo", + "playbooks": { + "phishing": { + "name": "Phishing", + "tasks": { + "block-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block IOCs", + "order": 6, + "type": "task" + }, + "block-sender": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block sender", + "next": { + "extract-iocs": "" + }, + "order": 3, + "type": "task" + }, + "board": { + "active": true, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Board Involvement?", + "next": { + "escalate": "boardInvolved == true", + "mail-available": "boardInvolved == false" + }, + "order": 0, + "schema": { + "properties": { + "boardInvolved": { + "default": false, + "title": "A board member is involved.", + "type": "boolean" + } + }, + "required": [ + "boardInvolved" + ], + "title": "Board Involvement?", + "type": "object" + }, + "type": "input" + }, + "escalate": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Escalate to CISO", + "order": 1, + "type": "task" + }, + "extract-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Extract IOCs", + "next": { + "block-iocs": "" + }, + "order": 5, + "schema": { + "properties": { + "iocs": { + "items": { + "type": "string" + }, + "title": "IOCs", + "type": "array" + } + }, + "title": "Extract IOCs", + "type": "object" + }, + "type": "input" + }, + "mail-available": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Mail available", + "next": { + "block-sender": "schemaKey == 'yes'", + "extract-iocs": "schemaKey == 'yes'", + "search-email-gateway": "schemaKey == 'no'" + }, + "order": 2, + "schema": { + "oneOf": [ + { + "properties": { + "mail": { + "title": "Mail", + "type": "string", + "x-display": "textarea" + }, + "schemaKey": { + "const": "yes", + "type": "string" + } + }, + "required": [ + "mail" + ], + "title": "Yes" + }, + { + "properties": { + "schemaKey": { + "const": "no", + "type": "string" + } + }, + "title": "No" + } + ], + "title": "Mail available", + "type": "object" + }, + "type": "input" + }, + "search-email-gateway": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Search email gateway", + "next": { + "extract-iocs": "" + }, + "order": 4, + "type": "task" + } + } + } + }, + "references": [ + { + "href": "https://www.leadmaximize.net/e-services/back-end", + "name": "performance" + }, + { + "href": "http://www.corporateinteractive.name/rich", + "name": "autumn" + }, + { + "href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name": "suggest" + } + ], + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status": "closed", + "type": "incident" + } + } + } + } + } + }, + "/tickets/{id}/artifacts/{name}/enrich": { + "post": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Enrich a single artifact", + "operationId": "enrichArtifact", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "leadreintermediate.io", + "name": "name", + "in": "path", + "required": true + }, + { + "x-example": { + "data": { + "hash": "b7a067a742c20d07a7456646de89bc2d408a1153" + }, + "name": "hash.sha1" + }, + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/EnrichmentForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/Artifact" + }, + "examples": { + "test": { + "artifacts": [ + { + "name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status": "unknown" + }, + { + "name": "http://www.customerviral.io/scalable/vertical/killer", + "status": "clean" + }, + { + "enrichments": { + "hash.sha1": { + "created": "2021-10-03T18:44:06.488923+02:00", + "data": { + "hash": "b7a067a742c20d07a7456646de89bc2d408a1153" + }, + "name": "hash.sha1" + } + }, + "name": "leadreintermediate.io", + "status": "malicious" + } + ], + "created": "2021-10-02T18:04:59.078206+02:00", + "id": 8123, + "modified": "2021-10-02T18:04:59.078206+02:00", + "name": "live zebra", + "owner": "demo", + "playbooks": { + "phishing": { + "name": "Phishing", + "tasks": { + "block-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block IOCs", + "order": 6, + "type": "task" + }, + "block-sender": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block sender", + "next": { + "extract-iocs": "" + }, + "order": 3, + "type": "task" + }, + "board": { + "active": true, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Board Involvement?", + "next": { + "escalate": "boardInvolved == true", + "mail-available": "boardInvolved == false" + }, + "order": 0, + "schema": { + "properties": { + "boardInvolved": { + "default": false, + "title": "A board member is involved.", + "type": "boolean" + } + }, + "required": [ + "boardInvolved" + ], + "title": "Board Involvement?", + "type": "object" + }, + "type": "input" + }, + "escalate": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Escalate to CISO", + "order": 1, + "type": "task" + }, + "extract-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Extract IOCs", + "next": { + "block-iocs": "" + }, + "order": 5, + "schema": { + "properties": { + "iocs": { + "items": { + "type": "string" + }, + "title": "IOCs", + "type": "array" + } + }, + "title": "Extract IOCs", + "type": "object" + }, + "type": "input" + }, + "mail-available": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Mail available", + "next": { + "block-sender": "schemaKey == 'yes'", + "extract-iocs": "schemaKey == 'yes'", + "search-email-gateway": "schemaKey == 'no'" + }, + "order": 2, + "schema": { + "oneOf": [ + { + "properties": { + "mail": { + "title": "Mail", + "type": "string", + "x-display": "textarea" + }, + "schemaKey": { + "const": "yes", + "type": "string" + } + }, + "required": [ + "mail" + ], + "title": "Yes" + }, + { + "properties": { + "schemaKey": { + "const": "no", + "type": "string" + } + }, + "title": "No" + } + ], + "title": "Mail available", + "type": "object" + }, + "type": "input" + }, + "search-email-gateway": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Search email gateway", + "next": { + "extract-iocs": "" + }, + "order": 4, + "type": "task" + } + } + } + }, + "references": [ + { + "href": "https://www.leadmaximize.net/e-services/back-end", + "name": "performance" + }, + { + "href": "http://www.corporateinteractive.name/rich", + "name": "autumn" + }, + { + "href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name": "suggest" + } + ], + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status": "closed", + "type": "incident" + } + } + } + } + } + }, + "/tickets/{id}/artifacts/{name}/run/{automation}": { + "post": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Run automation on a single artifact", + "operationId": "runArtifact", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "leadreintermediate.io", + "name": "name", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "hash.sha1", + "name": "automation", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "successful operation" + } + } + } + }, + "/tickets/{id}/comments": { + "post": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Add ticket comment", + "operationId": "addComment", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8125, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "message": "My first comment" + }, + "description": "Ticket comment", + "name": "comment", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CommentForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "comments": [ + { + "created": "2021-10-02T18:04:59.078186+02:00", + "creator": "bob", + "message": "My first comment" + } + ], + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8125, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "phishing from selenafadel@von.com detected", + "owner": "demo", + "references": [ + { + "href": "https://www.seniorleading-edge.name/users/efficient", + "name": "recovery" + }, + { + "href": "http://www.dynamicseamless.com/clicks-and-mortar", + "name": "force" + }, + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "schema": "{}", + "status": "closed", + "tickets": [ + { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8126, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "Surfaceintroduce virus detected", + "owner": "demo", + "references": [ + { + "href": "http://www.centralworld-class.io/synthesize", + "name": "university" + }, + { + "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name": "goal" + }, + { + "href": "http://www.chiefsyndicate.io/action-items", + "name": "unemployment" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + } + ], + "type": "alert" + } + } + } + } + } + }, + "/tickets/{id}/comments/{commentID}": { + "delete": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "description": "Comment will be removed from the ticket.", + "tags": [ + "tickets" + ], + "summary": "Remove an comment from an ticket", + "operationId": "removeComment", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "integer", + "x-example": 0, + "description": "Comment ID to remove", + "name": "commentID", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "artifacts": [ + { + "name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status": "unknown" + }, + { + "name": "http://www.customerviral.io/scalable/vertical/killer", + "status": "clean" + }, + { + "name": "leadreintermediate.io", + "status": "malicious" + } + ], + "created": "2021-10-02T18:04:59.078206+02:00", + "id": 8123, + "modified": "2021-10-02T18:04:59.078206+02:00", + "name": "live zebra", + "owner": "demo", + "playbooks": { + "phishing": { + "name": "Phishing", + "tasks": { + "block-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block IOCs", + "order": 6, + "type": "task" + }, + "block-sender": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block sender", + "next": { + "extract-iocs": "" + }, + "order": 3, + "type": "task" + }, + "board": { + "active": true, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Board Involvement?", + "next": { + "escalate": "boardInvolved == true", + "mail-available": "boardInvolved == false" + }, + "order": 0, + "schema": { + "properties": { + "boardInvolved": { + "default": false, + "title": "A board member is involved.", + "type": "boolean" + } + }, + "required": [ + "boardInvolved" + ], + "title": "Board Involvement?", + "type": "object" + }, + "type": "input" + }, + "escalate": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Escalate to CISO", + "order": 1, + "type": "task" + }, + "extract-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Extract IOCs", + "next": { + "block-iocs": "" + }, + "order": 5, + "schema": { + "properties": { + "iocs": { + "items": { + "type": "string" + }, + "title": "IOCs", + "type": "array" + } + }, + "title": "Extract IOCs", + "type": "object" + }, + "type": "input" + }, + "mail-available": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Mail available", + "next": { + "block-sender": "schemaKey == 'yes'", + "extract-iocs": "schemaKey == 'yes'", + "search-email-gateway": "schemaKey == 'no'" + }, + "order": 2, + "schema": { + "oneOf": [ + { + "properties": { + "mail": { + "title": "Mail", + "type": "string", + "x-display": "textarea" + }, + "schemaKey": { + "const": "yes", + "type": "string" + } + }, + "required": [ + "mail" + ], + "title": "Yes" + }, + { + "properties": { + "schemaKey": { + "const": "no", + "type": "string" + } + }, + "title": "No" + } + ], + "title": "Mail available", + "type": "object" + }, + "type": "input" + }, + "search-email-gateway": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Search email gateway", + "next": { + "extract-iocs": "" + }, + "order": 4, + "type": "task" + } + } + } + }, + "references": [ + { + "href": "https://www.leadmaximize.net/e-services/back-end", + "name": "performance" + }, + { + "href": "http://www.corporateinteractive.name/rich", + "name": "autumn" + }, + { + "href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name": "suggest" + } + ], + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status": "closed", + "type": "incident" + } + } + } + } + } + }, + "/tickets/{id}/files": { + "put": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "description": "Link files to an ticket. The files themself will be stored in object storage.", + "tags": [ + "tickets" + ], + "summary": "Link files to an ticket", + "operationId": "linkFiles", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8125, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": [ + { + "key": "myfile", + "name": "document.doc" + } + ], + "description": "Added files", + "name": "files", + "in": "body", + "required": true, + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/File" + } + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "created": "2021-10-02T18:04:59.078186+02:00", + "files": [ + { + "key": "myfile", + "name": "document.doc" + } + ], + "id": 8125, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "phishing from selenafadel@von.com detected", + "owner": "demo", + "references": [ + { + "href": "https://www.seniorleading-edge.name/users/efficient", + "name": "recovery" + }, + { + "href": "http://www.dynamicseamless.com/clicks-and-mortar", + "name": "force" + }, + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "schema": "{}", + "status": "closed", + "tickets": [ + { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8126, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "Surfaceintroduce virus detected", + "owner": "demo", + "references": [ + { + "href": "http://www.centralworld-class.io/synthesize", + "name": "university" + }, + { + "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name": "goal" + }, + { + "href": "http://www.chiefsyndicate.io/action-items", + "name": "unemployment" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + } + ], + "type": "alert" + } + } + } + } + } + }, + "/tickets/{id}/playbooks": { + "post": { + "tags": [ + "tickets" + ], + "summary": "Add a new ticket playbook", + "operationId": "addTicketPlaybook", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8125, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "yaml": "name: Simple\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n" + }, + "description": "Ticket playbook object that needs to be added", + "name": "playbook", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/PlaybookTemplateForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "created": "1985-04-12T23:20:50.52Z", + "id": 8125, + "modified": "1985-04-12T23:20:50.52Z", + "name": "phishing from selenafadel@von.com detected", + "owner": "demo", + "playbooks": { + "simple": { + "name": "Simple", + "tasks": { + "escalate": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Escalate to malware team", + "order": 2, + "type": "task" + }, + "hash": { + "active": false, + "automation": "hash.sha1", + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Hash the malware", + "next": { + "escalate": "" + }, + "order": 1, + "payload": { + "default": "playbook.tasks['input'].data['malware']" + }, + "type": "automation" + }, + "input": { + "active": true, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Upload malware if possible", + "next": { + "hash": "malware != ''" + }, + "order": 0, + "schema": { + "properties": { + "malware": { + "default": "", + "title": "Select malware", + "type": "string" + } + }, + "title": "Malware", + "type": "object" + }, + "type": "input" + } + } + } + }, + "references": [ + { + "href": "https://www.seniorleading-edge.name/users/efficient", + "name": "recovery" + }, + { + "href": "http://www.dynamicseamless.com/clicks-and-mortar", + "name": "force" + }, + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "schema": "{}", + "status": "closed", + "tickets": [ + { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8126, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "Surfaceintroduce virus detected", + "owner": "demo", + "references": [ + { + "href": "http://www.centralworld-class.io/synthesize", + "name": "university" + }, + { + "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name": "goal" + }, + { + "href": "http://www.chiefsyndicate.io/action-items", + "name": "unemployment" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + } + ], + "type": "alert" + } + } + } + } + } + }, + "/tickets/{id}/playbooks/{playbookID}": { + "delete": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Remove an ticket playbook", + "operationId": "removeTicketPlaybook", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "phishing", + "description": "Playbook ID", + "name": "playbookID", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "artifacts": [ + { + "name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status": "unknown" + }, + { + "name": "http://www.customerviral.io/scalable/vertical/killer", + "status": "clean" + }, + { + "name": "leadreintermediate.io", + "status": "malicious" + } + ], + "created": "1985-04-12T23:20:50.52Z", + "id": 8123, + "modified": "1985-04-12T23:20:50.52Z", + "name": "live zebra", + "owner": "demo", + "references": [ + { + "href": "https://www.leadmaximize.net/e-services/back-end", + "name": "performance" + }, + { + "href": "http://www.corporateinteractive.name/rich", + "name": "autumn" + }, + { + "href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name": "suggest" + } + ], + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status": "closed", + "type": "incident" + } + } + } + } + } + }, + "/tickets/{id}/playbooks/{playbookID}/task/{taskID}": { + "put": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Set a ticket playbook task", + "operationId": "setTask", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "phishing", + "description": "Playbook ID", + "name": "playbookID", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "board", + "description": "Task ID", + "name": "taskID", + "in": "path", + "required": true + }, + { + "x-example": { + "active": true, + "data": { + "boardInvolved": true + }, + "done": false, + "name": "Board Involvement?", + "next": { + "escalate": "boardInvolved == true", + "mail-available": "boardInvolved == false" + }, + "order": 0, + "schema": { + "properties": { + "boardInvolved": { + "default": false, + "title": "A board member is involved.", + "type": "boolean" + } + }, + "required": [ + "boardInvolved" + ], + "title": "Board Involvement?", + "type": "object" + }, + "type": "input" + }, + "description": "Task", + "name": "task", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/Task" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "artifacts": [ + { + "name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status": "unknown" + }, + { + "name": "http://www.customerviral.io/scalable/vertical/killer", + "status": "clean" + }, + { + "name": "leadreintermediate.io", + "status": "malicious" + } + ], + "created": "2021-10-02T18:04:59.078206+02:00", + "id": 8123, + "modified": "2021-10-02T18:04:59.078206+02:00", + "name": "live zebra", + "owner": "demo", + "playbooks": { + "phishing": { + "name": "Phishing", + "tasks": { + "block-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block IOCs", + "order": 6, + "type": "task" + }, + "block-sender": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block sender", + "next": { + "extract-iocs": "" + }, + "order": 3, + "type": "task" + }, + "board": { + "active": true, + "created": "2021-10-02T18:04:59.078186+02:00", + "data": { + "boardInvolved": true + }, + "done": false, + "name": "Board Involvement?", + "next": { + "escalate": "boardInvolved == true", + "mail-available": "boardInvolved == false" + }, + "order": 0, + "schema": { + "properties": { + "boardInvolved": { + "default": false, + "title": "A board member is involved.", + "type": "boolean" + } + }, + "required": [ + "boardInvolved" + ], + "title": "Board Involvement?", + "type": "object" + }, + "type": "input" + }, + "escalate": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Escalate to CISO", + "order": 1, + "type": "task" + }, + "extract-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Extract IOCs", + "next": { + "block-iocs": "" + }, + "order": 5, + "schema": { + "properties": { + "iocs": { + "items": { + "type": "string" + }, + "title": "IOCs", + "type": "array" + } + }, + "title": "Extract IOCs", + "type": "object" + }, + "type": "input" + }, + "mail-available": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Mail available", + "next": { + "block-sender": "schemaKey == 'yes'", + "extract-iocs": "schemaKey == 'yes'", + "search-email-gateway": "schemaKey == 'no'" + }, + "order": 2, + "schema": { + "oneOf": [ + { + "properties": { + "mail": { + "title": "Mail", + "type": "string", + "x-display": "textarea" + }, + "schemaKey": { + "const": "yes", + "type": "string" + } + }, + "required": [ + "mail" + ], + "title": "Yes" + }, + { + "properties": { + "schemaKey": { + "const": "no", + "type": "string" + } + }, + "title": "No" + } + ], + "title": "Mail available", + "type": "object" + }, + "type": "input" + }, + "search-email-gateway": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Search email gateway", + "next": { + "extract-iocs": "" + }, + "order": 4, + "type": "task" + } + } + } + }, + "references": [ + { + "href": "https://www.leadmaximize.net/e-services/back-end", + "name": "performance" + }, + { + "href": "http://www.corporateinteractive.name/rich", + "name": "autumn" + }, + { + "href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name": "suggest" + } + ], + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status": "closed", + "type": "incident" + } + } + } + } + } + }, + "/tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete": { + "put": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Complete ticket playbook task", + "operationId": "completeTask", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "phishing", + "description": "Playbook ID", + "name": "playbookID", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "board", + "description": "Task ID", + "name": "taskID", + "in": "path", + "required": true + }, + { + "x-example": { + "boardInvolved": true + }, + "description": "Ticket playbook object that needs to be added", + "name": "data", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "artifacts": [ + { + "name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status": "unknown" + }, + { + "name": "http://www.customerviral.io/scalable/vertical/killer", + "status": "clean" + }, + { + "name": "leadreintermediate.io", + "status": "malicious" + } + ], + "created": "2021-10-02T18:04:59.078206+02:00", + "id": 8123, + "modified": "2021-10-02T18:04:59.078206+02:00", + "name": "live zebra", + "owner": "demo", + "playbooks": { + "phishing": { + "name": "Phishing", + "tasks": { + "block-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block IOCs", + "order": 6, + "type": "task" + }, + "block-sender": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block sender", + "next": { + "extract-iocs": "" + }, + "order": 3, + "type": "task" + }, + "board": { + "active": false, + "closed": "2021-10-02T18:04:59.078186+02:00", + "created": "2021-10-02T18:04:59.078186+02:00", + "data": { + "boardInvolved": true + }, + "done": true, + "name": "Board Involvement?", + "next": { + "escalate": "boardInvolved == true", + "mail-available": "boardInvolved == false" + }, + "order": 0, + "schema": { + "properties": { + "boardInvolved": { + "default": false, + "title": "A board member is involved.", + "type": "boolean" + } + }, + "required": [ + "boardInvolved" + ], + "title": "Board Involvement?", + "type": "object" + }, + "type": "input" + }, + "escalate": { + "active": true, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Escalate to CISO", + "order": 1, + "type": "task" + }, + "extract-iocs": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Extract IOCs", + "next": { + "block-iocs": "" + }, + "order": 5, + "schema": { + "properties": { + "iocs": { + "items": { + "type": "string" + }, + "title": "IOCs", + "type": "array" + } + }, + "title": "Extract IOCs", + "type": "object" + }, + "type": "input" + }, + "mail-available": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Mail available", + "next": { + "block-sender": "schemaKey == 'yes'", + "extract-iocs": "schemaKey == 'yes'", + "search-email-gateway": "schemaKey == 'no'" + }, + "order": 2, + "schema": { + "oneOf": [ + { + "properties": { + "mail": { + "title": "Mail", + "type": "string", + "x-display": "textarea" + }, + "schemaKey": { + "const": "yes", + "type": "string" + } + }, + "required": [ + "mail" + ], + "title": "Yes" + }, + { + "properties": { + "schemaKey": { + "const": "no", + "type": "string" + } + }, + "title": "No" + } + ], + "title": "Mail available", + "type": "object" + }, + "type": "input" + }, + "search-email-gateway": { + "active": false, + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Search email gateway", + "next": { + "extract-iocs": "" + }, + "order": 4, + "type": "task" + } + } + } + }, + "references": [ + { + "href": "https://www.leadmaximize.net/e-services/back-end", + "name": "performance" + }, + { + "href": "http://www.corporateinteractive.name/rich", + "name": "autumn" + }, + { + "href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name": "suggest" + } + ], + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status": "closed", + "type": "incident" + } + } + } + } + } + }, + "/tickets/{id}/playbooks/{playbookID}/task/{taskID}/run": { + "post": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Run ticket playbook task", + "operationId": "runTask", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8123, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "phishing", + "description": "Playbook ID", + "name": "playbookID", + "in": "path", + "required": true + }, + { + "type": "string", + "x-example": "board", + "description": "Task ID", + "name": "taskID", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "successful operation" + } + } + } + }, + "/tickets/{id}/references": { + "put": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Set ticket references", + "operationId": "setReferences", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8125, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": [ + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "description": "All ticket references", + "name": "references", + "in": "body", + "required": true, + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Reference" + } + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8125, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "phishing from selenafadel@von.com detected", + "owner": "demo", + "references": [ + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "schema": "{}", + "status": "closed", + "tickets": [ + { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8126, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "Surfaceintroduce virus detected", + "owner": "demo", + "references": [ + { + "href": "http://www.centralworld-class.io/synthesize", + "name": "university" + }, + { + "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name": "goal" + }, + { + "href": "http://www.chiefsyndicate.io/action-items", + "name": "unemployment" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + } + ], + "type": "alert" + } + } + } + } + } + }, + "/tickets/{id}/schema": { + "put": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Set ticket schema", + "operationId": "setSchema", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8125, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": "{}", + "description": "New ticket schema", + "name": "schema", + "in": "body", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8125, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "phishing from selenafadel@von.com detected", + "owner": "demo", + "references": [ + { + "href": "https://www.seniorleading-edge.name/users/efficient", + "name": "recovery" + }, + { + "href": "http://www.dynamicseamless.com/clicks-and-mortar", + "name": "force" + }, + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "schema": "{}", + "status": "closed", + "tickets": [ + { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8126, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "Surfaceintroduce virus detected", + "owner": "demo", + "references": [ + { + "href": "http://www.centralworld-class.io/synthesize", + "name": "university" + }, + { + "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name": "goal" + }, + { + "href": "http://www.chiefsyndicate.io/action-items", + "name": "unemployment" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + } + ], + "type": "alert" + } + } + } + } + } + }, + "/tickets/{id}/tickets": { + "delete": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Unlink an ticket to an ticket", + "operationId": "unlinkTicket", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8126, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": 8125, + "description": "Added ticket ID", + "name": "linkedID", + "in": "body", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8126, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "Surfaceintroduce virus detected", + "owner": "demo", + "references": [ + { + "href": "http://www.centralworld-class.io/synthesize", + "name": "university" + }, + { + "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name": "goal" + }, + { + "href": "http://www.chiefsyndicate.io/action-items", + "name": "unemployment" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + } + } + } + } + }, + "patch": { + "security": [ + { + "roles": [ + "ticket:write" + ] + } + ], + "tags": [ + "tickets" + ], + "summary": "Link an ticket to an ticket", + "operationId": "linkTicket", + "parameters": [ + { + "type": "integer", + "format": "int64", + "x-example": 8126, + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": 8123, + "description": "Added ticket ID", + "name": "linkedID", + "in": "body", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketResponse" + }, + "examples": { + "test": { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8126, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "Surfaceintroduce virus detected", + "owner": "demo", + "references": [ + { + "href": "http://www.centralworld-class.io/synthesize", + "name": "university" + }, + { + "href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", + "name": "goal" + }, + { + "href": "http://www.chiefsyndicate.io/action-items", + "name": "unemployment" + } + ], + "schema": "{}", + "status": "closed", + "tickets": [ + { + "artifacts": [ + { + "name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", + "status": "unknown" + }, + { + "name": "http://www.customerviral.io/scalable/vertical/killer", + "status": "clean" + }, + { + "name": "leadreintermediate.io", + "status": "malicious" + } + ], + "created": "2021-10-02T18:04:59.078206+02:00", + "id": 8123, + "modified": "2021-10-02T18:04:59.078206+02:00", + "name": "live zebra", + "owner": "demo", + "playbooks": { + "phishing": { + "name": "Phishing", + "tasks": { + "block-iocs": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block IOCs", + "type": "task" + }, + "block-sender": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Block sender", + "next": { + "extract-iocs": "" + }, + "type": "task" + }, + "board": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Board Involvement?", + "next": { + "escalate": "boardInvolved == true", + "mail-available": "boardInvolved == false" + }, + "schema": { + "properties": { + "boardInvolved": { + "default": false, + "title": "A board member is involved.", + "type": "boolean" + } + }, + "required": [ + "boardInvolved" + ], + "title": "Board Involvement?", + "type": "object" + }, + "type": "input" + }, + "escalate": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Escalate to CISO", + "type": "task" + }, + "extract-iocs": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Extract IOCs", + "next": { + "block-iocs": "" + }, + "schema": { + "properties": { + "iocs": { + "items": { + "type": "string" + }, + "title": "IOCs", + "type": "array" + } + }, + "title": "Extract IOCs", + "type": "object" + }, + "type": "input" + }, + "mail-available": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Mail available", + "next": { + "block-sender": "schemaKey == 'yes'", + "extract-iocs": "schemaKey == 'yes'", + "search-email-gateway": "schemaKey == 'no'" + }, + "schema": { + "oneOf": [ + { + "properties": { + "mail": { + "title": "Mail", + "type": "string", + "x-display": "textarea" + }, + "schemaKey": { + "const": "yes", + "type": "string" + } + }, + "required": [ + "mail" + ], + "title": "Yes" + }, + { + "properties": { + "schemaKey": { + "const": "no", + "type": "string" + } + }, + "title": "No" + } + ], + "title": "Mail available", + "type": "object" + }, + "type": "input" + }, + "search-email-gateway": { + "created": "2021-10-02T18:04:59.078186+02:00", + "done": false, + "name": "Search email gateway", + "next": { + "extract-iocs": "" + }, + "type": "task" + } + } + } + }, + "references": [ + { + "href": "https://www.leadmaximize.net/e-services/back-end", + "name": "performance" + }, + { + "href": "http://www.corporateinteractive.name/rich", + "name": "autumn" + }, + { + "href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", + "name": "suggest" + } + ], + "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", + "status": "closed", + "type": "incident" + }, + { + "created": "2021-10-02T18:04:59.078186+02:00", + "id": 8125, + "modified": "2021-10-02T18:04:59.078186+02:00", + "name": "phishing from selenafadel@von.com detected", + "owner": "demo", + "references": [ + { + "href": "https://www.seniorleading-edge.name/users/efficient", + "name": "recovery" + }, + { + "href": "http://www.dynamicseamless.com/clicks-and-mortar", + "name": "force" + }, + { + "href": "http://www.leadscalable.biz/envisioneer", + "name": "fund" + } + ], + "schema": "{}", + "status": "closed", + "type": "alert" + } + ], + "type": "alert" + } + } + } + } + } + }, + "/tickettypes": { + "get": { + "security": [ + { + "roles": [ + "tickettype:read" + ] + } + ], + "tags": [ + "tickettypes" + ], + "summary": "List tickettypes", + "operationId": "listTicketTypes", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/TicketTypeResponse" + } + }, + "examples": { + "test": [ + { + "default_playbooks": [], + "default_template": "default", + "icon": "mdi-alert", + "id": "alert", + "name": "Alerts" + }, + { + "default_playbooks": [], + "default_template": "default", + "icon": "mdi-radioactive", + "id": "incident", + "name": "Incidents" + }, + { + "default_playbooks": [], + "default_template": "default", + "icon": "mdi-fingerprint", + "id": "investigation", + "name": "Forensic Investigations" + }, + { + "default_playbooks": [], + "default_template": "default", + "icon": "mdi-target", + "id": "hunt", + "name": "Threat Hunting" + } + ] + } + } + } + }, + "post": { + "security": [ + { + "roles": [ + "tickettype:write" + ] + } + ], + "tags": [ + "tickettypes" + ], + "summary": "Create a new tickettype", + "operationId": "createTicketType", + "parameters": [ + { + "x-example": { + "default_playbooks": [], + "default_template": "default", + "icon": "mdi-newspaper-variant-outline", + "name": "TI Tickets" + }, + "description": "New tickettype", + "name": "tickettype", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/TicketTypeForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketTypeResponse" + }, + "examples": { + "test": { + "default_playbooks": [], + "default_template": "default", + "icon": "mdi-newspaper-variant-outline", + "id": "ti-tickets", + "name": "TI Tickets" + } + } + } + } + } + }, + "/tickettypes/{id}": { + "get": { + "security": [ + { + "roles": [ + "tickettype:read" + ] + } + ], + "tags": [ + "tickettypes" + ], + "summary": "Get a single tickettype", + "operationId": "getTicketType", + "parameters": [ + { + "type": "string", + "x-example": "alert", + "description": "TicketType ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketTypeResponse" + }, + "examples": { + "test": { + "default_playbooks": [], + "default_template": "default", + "icon": "mdi-alert", + "id": "alert", + "name": "Alerts" + } + } + } + } + }, + "put": { + "security": [ + { + "roles": [ + "tickettype:write" + ] + } + ], + "tags": [ + "tickettypes" + ], + "summary": "Update an existing tickettype", + "operationId": "updateTicketType", + "parameters": [ + { + "type": "string", + "x-example": "alert", + "description": "TicketType ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "default_playbooks": [], + "default_template": "default", + "icon": "mdi-bell", + "id": "alert", + "name": "Alerts" + }, + "description": "TicketType object that needs to be added", + "name": "tickettype", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/TicketTypeForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/TicketTypeResponse" + }, + "examples": { + "test": { + "default_playbooks": [], + "default_template": "default", + "icon": "mdi-bell", + "id": "alert", + "name": "Alerts" + } + } + } + } + }, + "delete": { + "security": [ + { + "roles": [ + "tickettype:write" + ] + } + ], + "tags": [ + "tickettypes" + ], + "summary": "Delete a tickettype", + "operationId": "deleteTicketType", + "parameters": [ + { + "type": "string", + "x-example": "alert", + "description": "TicketType ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "successful operation" + } + } + } + }, + "/userdata": { + "get": { + "security": [ + { + "roles": [ + "userdata:read" + ] + } + ], + "tags": [ + "userdata" + ], + "summary": "List userdata", + "operationId": "listUserData", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/UserDataResponse" + } + }, + "examples": { + "test": [ + { + "email": "bob@example.org", + "id": "bob", + "name": "Bob Bad" + } + ] + } + } + } + } + }, + "/userdata/{id}": { + "get": { + "security": [ + { + "roles": [ + "userdata:read" + ] + } + ], + "tags": [ + "userdata" + ], + "summary": "Get a single user data", + "operationId": "getUserData", + "parameters": [ + { + "type": "string", + "x-example": "bob", + "description": "User Data ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/UserDataResponse" + }, + "examples": { + "test": { + "email": "bob@example.org", + "id": "bob", + "name": "Bob Bad" + } + } + } + } + }, + "put": { + "security": [ + { + "roles": [ + "userdata:write" + ] + } + ], + "tags": [ + "userdata" + ], + "summary": "Update an existing user data", + "operationId": "updateUserData", + "parameters": [ + { + "type": "string", + "x-example": "bob", + "description": "User Data ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "blocked": false, + "email": "bob@example.org", + "name": "Bob Bad" + }, + "description": "User data object that needs to be added", + "name": "userdata", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UserData" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/UserDataResponse" + }, + "examples": { + "test": { + "email": "bob@example.org", + "id": "bob", + "name": "Bob Bad" + } + } + } + } + } + }, + "/users": { + "get": { + "security": [ + { + "roles": [ + "user:read" + ] + } + ], + "tags": [ + "users" + ], + "summary": "List users", + "operationId": "listUsers", + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/UserResponse" + } + }, + "examples": { + "test": [ + { + "apikey": false, + "blocked": false, + "id": "bob", + "roles": [ + "admin:backup:read", + "admin:backup:restore", + "admin:group:write", + "admin:job:read", + "admin:job:write", + "admin:log:read", + "admin:ticket:delete", + "admin:user:write", + "admin:userdata:read", + "admin:userdata:write", + "analyst:automation:read", + "analyst:currentsettings:write", + "analyst:currentuser:read", + "analyst:currentuserdata:read", + "analyst:file", + "analyst:group:read", + "analyst:playbook:read", + "analyst:rule:read", + "analyst:settings:read", + "analyst:template:read", + "analyst:ticket:read", + "analyst:ticket:write", + "analyst:tickettype:read", + "analyst:user:read", + "engineer:automation:write", + "engineer:playbook:write", + "engineer:rule:write", + "engineer:template:write", + "engineer:tickettype:write" + ] + }, + { + "apikey": true, + "blocked": false, + "id": "script", + "roles": [ + "analyst:automation:read", + "analyst:currentsettings:write", + "analyst:currentuser:read", + "analyst:currentuserdata:read", + "analyst:file", + "analyst:group:read", + "analyst:playbook:read", + "analyst:rule:read", + "analyst:settings:read", + "analyst:template:read", + "analyst:ticket:read", + "analyst:ticket:write", + "analyst:tickettype:read", + "analyst:user:read", + "engineer:automation:write", + "engineer:playbook:write", + "engineer:rule:write", + "engineer:template:write", + "engineer:tickettype:write" + ] + } + ] + } + } + } + }, + "post": { + "security": [ + { + "roles": [ + "user:write" + ] + } + ], + "tags": [ + "users" + ], + "summary": "Create user", + "operationId": "createUser", + "parameters": [ + { + "x-example": { + "id": "syncscript", + "roles": [ + "analyst" + ] + }, + "description": "user object that needs to be added", + "name": "user", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UserForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/NewUserResponse" + }, + "examples": { + "test": { + "blocked": false, + "id": "syncscript", + "roles": [ + "analyst:automation:read", + "analyst:currentsettings:write", + "analyst:currentuser:read", + "analyst:currentuserdata:read", + "analyst:file", + "analyst:group:read", + "analyst:playbook:read", + "analyst:rule:read", + "analyst:settings:read", + "analyst:template:read", + "analyst:ticket:read", + "analyst:ticket:write", + "analyst:tickettype:read", + "analyst:user:read" + ], + "secret": "v39bOuobnlEljfWzjAgoKzhmnh1xSMxH" + } + } + } + } + } + }, + "/users/{id}": { + "get": { + "security": [ + { + "roles": [ + "user:read" + ] + } + ], + "tags": [ + "users" + ], + "summary": "Get a single user", + "operationId": "getUser", + "parameters": [ + { + "type": "string", + "x-example": "script", + "description": "user ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/UserResponse" + }, + "examples": { + "test": { + "apikey": true, + "blocked": false, + "id": "script", + "roles": [ + "analyst:automation:read", + "analyst:currentsettings:write", + "analyst:currentuser:read", + "analyst:currentuserdata:read", + "analyst:file", + "analyst:group:read", + "analyst:playbook:read", + "analyst:rule:read", + "analyst:settings:read", + "analyst:template:read", + "analyst:ticket:read", + "analyst:ticket:write", + "analyst:tickettype:read", + "analyst:user:read", + "engineer:automation:write", + "engineer:playbook:write", + "engineer:rule:write", + "engineer:template:write", + "engineer:tickettype:write" + ] + } + } + } + } + }, + "put": { + "security": [ + { + "roles": [ + "user:write" + ] + } + ], + "tags": [ + "users" + ], + "summary": "Update user", + "operationId": "updateUser", + "parameters": [ + { + "type": "string", + "x-example": "bob", + "description": "Template ID", + "name": "id", + "in": "path", + "required": true + }, + { + "x-example": { + "roles": [ + "analyst", + "admin" + ] + }, + "description": "user object that needs to be added", + "name": "user", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UserForm" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/UserResponse" + }, + "examples": { + "test": { + "apikey": false, + "blocked": false, + "id": "bob", + "roles": [ + "admin:backup:read", + "admin:backup:restore", + "admin:group:write", + "admin:job:read", + "admin:job:write", + "admin:log:read", + "admin:ticket:delete", + "admin:user:write", + "admin:userdata:read", + "admin:userdata:write", + "analyst:automation:read", + "analyst:currentsettings:write", + "analyst:currentuser:read", + "analyst:currentuserdata:read", + "analyst:file", + "analyst:group:read", + "analyst:playbook:read", + "analyst:rule:read", + "analyst:settings:read", + "analyst:template:read", + "analyst:ticket:read", + "analyst:ticket:write", + "analyst:tickettype:read", + "analyst:user:read", + "engineer:automation:write", + "engineer:playbook:write", + "engineer:rule:write", + "engineer:template:write", + "engineer:tickettype:write" + ] + } + } + } + } + }, + "delete": { + "security": [ + { + "roles": [ + "user:write" + ] + } + ], + "tags": [ + "users" + ], + "summary": "Delete user", + "operationId": "deleteUser", + "parameters": [ + { + "type": "string", + "x-example": "script", + "description": "user ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "successful operation" + } + } + } + } + }, + "definitions": { + "Artifact": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "enrichments": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/Enrichment" + } + }, + "name": { + "type": "string", + "example": "2.2.2.2" + }, + "status": { + "type": "string", + "example": "Unknown" + }, + "type": { + "type": "string" + } + } + }, + "ArtifactOrigin": { + "type": "object", + "required": [ + "ticket_id", + "artifact" + ], + "properties": { + "artifact": { + "type": "string" + }, + "ticket_id": { + "type": "integer", + "format": "int64" + } + } + }, + "Automation": { + "type": "object", + "required": [ + "image", + "script", + "type" + ], + "properties": { + "image": { + "type": "string" + }, + "schema": { + "type": "string", + "example": "{}" + }, + "script": { + "type": "string" + }, + "type": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "artifact", + "playbook", + "global" + ] + } + } + } + }, + "AutomationForm": { + "type": "object", + "required": [ + "id", + "image", + "script", + "type" + ], + "properties": { + "id": { + "type": "string" + }, + "image": { + "type": "string" + }, + "schema": { + "type": "string", + "example": "{}" + }, + "script": { + "type": "string" + }, + "type": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "artifact", + "playbook", + "global" + ] + } + } + } + }, + "AutomationResponse": { + "type": "object", + "required": [ + "id", + "image", + "script", + "type" + ], + "properties": { + "id": { + "type": "string" + }, + "image": { + "type": "string" + }, + "schema": { + "type": "string", + "example": "{}" + }, + "script": { + "type": "string" + }, + "type": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "artifact", + "playbook", + "global" + ] + } + } + } + }, + "Comment": { + "type": "object", + "required": [ + "creator", + "created", + "message" + ], + "properties": { + "created": { + "type": "string", + "format": "date-time" + }, + "creator": { + "type": "string" + }, + "message": { + "type": "string" + } + } + }, + "CommentForm": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "created": { + "type": "string", + "format": "date-time" + }, + "creator": { + "type": "string" + }, + "message": { + "type": "string" + } + } + }, + "Context": { + "type": "object", + "properties": { + "artifact": { + "$ref": "#/definitions/Artifact" + }, + "playbook": { + "$ref": "#/definitions/PlaybookResponse" + }, + "task": { + "$ref": "#/definitions/TaskResponse" + }, + "ticket": { + "$ref": "#/definitions/TicketResponse" + } + } + }, + "Enrichment": { + "type": "object", + "required": [ + "name", + "data", + "created" + ], + "properties": { + "created": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "data": { + "type": "object", + "example": { + "hash": "b7a067a742c20d07a7456646de89bc2d408a1153" + } + }, + "name": { + "type": "string", + "example": "hash.sha1" + } + } + }, + "EnrichmentForm": { + "type": "object", + "required": [ + "name", + "data" + ], + "properties": { + "data": { + "type": "object", + "example": { + "hash": "b7a067a742c20d07a7456646de89bc2d408a1153" + } + }, + "name": { + "type": "string", + "example": "hash.sha1" + } + } + }, + "File": { + "type": "object", + "required": [ + "key", + "name" + ], + "properties": { + "key": { + "type": "string", + "example": "myfile" + }, + "name": { + "type": "string", + "example": "notes.docx" + } + } + }, + "Job": { + "type": "object", + "required": [ + "automation", + "running", + "status" + ], + "properties": { + "automation": { + "type": "string" + }, + "container": { + "type": "string" + }, + "log": { + "type": "string" + }, + "origin": { + "$ref": "#/definitions/Origin" + }, + "output": { + "type": "object" + }, + "payload": {}, + "running": { + "type": "boolean" + }, + "status": { + "type": "string" + } + } + }, + "JobForm": { + "type": "object", + "required": [ + "automation" + ], + "properties": { + "automation": { + "type": "string" + }, + "origin": { + "$ref": "#/definitions/Origin" + }, + "payload": {} + } + }, + "JobResponse": { + "type": "object", + "required": [ + "id", + "automation", + "status" + ], + "properties": { + "automation": { + "type": "string" + }, + "container": { + "type": "string" + }, + "id": { + "type": "string" + }, + "log": { + "type": "string" + }, + "origin": { + "$ref": "#/definitions/Origin" + }, + "output": { + "type": "object" + }, + "payload": {}, + "status": { + "type": "string" + } + } + }, + "LogEntry": { + "type": "object", + "required": [ + "reference", + "creator", + "created", + "message" + ], + "properties": { + "created": { + "type": "string", + "format": "date-time" + }, + "creator": { + "type": "string" + }, + "message": { + "type": "string" + }, + "reference": { + "type": "string" + } + } + }, + "Message": { + "type": "object", + "properties": { + "context": { + "$ref": "#/definitions/Context" + }, + "payload": { + "type": "object" + }, + "secrets": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "NewUserResponse": { + "type": "object", + "required": [ + "id", + "blocked", + "roles" + ], + "properties": { + "blocked": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + }, + "secret": { + "type": "string" + } + } + }, + "Origin": { + "type": "object", + "properties": { + "artifact_origin": { + "$ref": "#/definitions/ArtifactOrigin" + }, + "task_origin": { + "$ref": "#/definitions/TaskOrigin" + } + } + }, + "Playbook": { + "type": "object", + "required": [ + "name", + "tasks" + ], + "properties": { + "name": { + "type": "string", + "example": "Phishing" + }, + "tasks": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/Task" + } + } + } + }, + "PlaybookResponse": { + "type": "object", + "required": [ + "name", + "tasks" + ], + "properties": { + "name": { + "type": "string", + "example": "Phishing" + }, + "tasks": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/TaskResponse" + } + } + } + }, + "PlaybookTemplate": { + "type": "object", + "required": [ + "name", + "yaml" + ], + "properties": { + "name": { + "type": "string" + }, + "yaml": { + "type": "string" + } + } + }, + "PlaybookTemplateForm": { + "type": "object", + "required": [ + "yaml" + ], + "properties": { + "id": { + "type": "string" + }, + "yaml": { + "type": "string" + } + } + }, + "PlaybookTemplateResponse": { + "type": "object", + "required": [ + "id", + "name", + "yaml" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "yaml": { + "type": "string" + } + } + }, + "Reference": { + "type": "object", + "required": [ + "name", + "href" + ], + "properties": { + "href": { + "type": "string", + "example": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2017-0144" + }, + "name": { + "type": "string", + "example": "CVE-2017-0144" + } + } + }, + "Settings": { + "type": "object", + "required": [ + "version", + "tier", + "timeformat", + "ticketTypes", + "artifactStates" + ], + "properties": { + "artifactStates": { + "type": "array", + "title": "Artifact States", + "items": { + "$ref": "#/definitions/Type" + } + }, + "roles": { + "type": "array", + "title": "Roles", + "items": { + "type": "string" + } + }, + "ticketTypes": { + "type": "array", + "title": "Ticket Types", + "items": { + "$ref": "#/definitions/TicketTypeResponse" + } + }, + "tier": { + "type": "string", + "title": "Tier", + "enum": [ + "community", + "enterprise" + ] + }, + "timeformat": { + "type": "string", + "title": "Time Format" + }, + "version": { + "type": "string", + "title": "Version" + } + } + }, + "Statistics": { + "type": "object", + "required": [ + "unassigned", + "open_tickets_per_user", + "tickets_per_week", + "tickets_per_type" + ], + "properties": { + "open_tickets_per_user": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "tickets_per_type": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "tickets_per_week": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "unassigned": { + "type": "integer" + } + } + }, + "Task": { + "type": "object", + "required": [ + "name", + "type", + "done", + "created" + ], + "properties": { + "automation": { + "type": "string" + }, + "closed": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "created": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "data": { + "type": "object" + }, + "done": { + "type": "boolean" + }, + "join": { + "type": "boolean", + "example": false + }, + "name": { + "type": "string", + "example": "Inform user" + }, + "next": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "owner": { + "type": "string" + }, + "payload": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "schema": { + "type": "object" + }, + "type": { + "type": "string", + "enum": [ + "task", + "input", + "automation" + ], + "example": "task" + } + } + }, + "TaskForm": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "automation": { + "type": "string" + }, + "closed": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "created": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "data": { + "type": "object" + }, + "done": { + "type": "boolean" + }, + "join": { + "type": "boolean", + "example": false + }, + "name": { + "type": "string", + "example": "Inform user" + }, + "next": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "owner": { + "type": "string" + }, + "payload": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "schema": { + "type": "object" + }, + "type": { + "type": "string", + "enum": [ + "task", + "input", + "automation" + ], + "example": "task" + } + } + }, + "TaskOrigin": { + "type": "object", + "required": [ + "ticket_id", + "playbook_id", + "task_id" + ], + "properties": { + "playbook_id": { + "type": "string" + }, + "task_id": { + "type": "string" + }, + "ticket_id": { + "type": "integer", + "format": "int64" + } + } + }, + "TaskResponse": { + "type": "object", + "required": [ + "name", + "type", + "done", + "created", + "order", + "active" + ], + "properties": { + "active": { + "type": "boolean", + "example": false + }, + "automation": { + "type": "string" + }, + "closed": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "created": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "data": { + "type": "object" + }, + "done": { + "type": "boolean" + }, + "join": { + "type": "boolean", + "example": false + }, + "name": { + "type": "string", + "example": "Inform user" + }, + "next": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "order": { + "type": "number", + "format": "int64", + "example": 2 + }, + "owner": { + "type": "string" + }, + "payload": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "schema": { + "type": "object" + }, + "type": { + "type": "string", + "enum": [ + "task", + "input", + "automation" + ], + "example": "task" + } + } + }, + "TaskWithContext": { + "type": "object", + "required": [ + "ticket_id", + "ticket_name", + "playbook_id", + "playbook_name", + "task_id", + "task" + ], + "properties": { + "playbook_id": { + "type": "string" + }, + "playbook_name": { + "type": "string" + }, + "task": { + "$ref": "#/definitions/TaskResponse" + }, + "task_id": { + "type": "string" + }, + "ticket_id": { + "type": "number", + "format": "int64" + }, + "ticket_name": { + "type": "string" + } + } + }, + "Ticket": { + "type": "object", + "required": [ + "name", + "type", + "status", + "created", + "modified", + "schema" + ], + "properties": { + "artifacts": { + "type": "array", + "items": { + "$ref": "#/definitions/Artifact" + } + }, + "comments": { + "type": "array", + "items": { + "$ref": "#/definitions/Comment" + } + }, + "created": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "details": { + "type": "object", + "example": { + "description": "my little incident" + } + }, + "files": { + "type": "array", + "items": { + "$ref": "#/definitions/File" + } + }, + "modified": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "name": { + "type": "string", + "example": "WannyCry" + }, + "owner": { + "type": "string", + "example": "bob" + }, + "playbooks": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/Playbook" + } + }, + "read": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "bob" + ] + }, + "references": { + "type": "array", + "items": { + "$ref": "#/definitions/Reference" + } + }, + "schema": { + "type": "string", + "example": "{}" + }, + "status": { + "type": "string", + "example": "open" + }, + "type": { + "type": "string", + "example": "incident" + }, + "write": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "alice" + ] + } + } + }, + "TicketForm": { + "type": "object", + "required": [ + "name", + "type", + "status" + ], + "properties": { + "artifacts": { + "type": "array", + "items": { + "$ref": "#/definitions/Artifact" + } + }, + "comments": { + "type": "array", + "items": { + "$ref": "#/definitions/Comment" + } + }, + "created": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "details": { + "type": "object", + "example": { + "description": "my little incident" + } + }, + "files": { + "type": "array", + "items": { + "$ref": "#/definitions/File" + } + }, + "id": { + "type": "integer", + "format": "int64", + "example": 123 + }, + "modified": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "name": { + "type": "string", + "example": "WannyCry" + }, + "owner": { + "type": "string", + "example": "bob" + }, + "playbooks": { + "type": "array", + "items": { + "$ref": "#/definitions/PlaybookTemplateForm" + } + }, + "read": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "bob" + ] + }, + "references": { + "type": "array", + "items": { + "$ref": "#/definitions/Reference" + } + }, + "schema": { + "type": "string", + "example": "{}" + }, + "status": { + "type": "string", + "example": "open" + }, + "type": { + "type": "string", + "example": "incident" + }, + "write": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "alice" + ] + } + } + }, + "TicketList": { + "type": "object", + "required": [ + "tickets", + "count" + ], + "properties": { + "count": { + "type": "number", + "example": 3 + }, + "tickets": { + "type": "array", + "items": { + "$ref": "#/definitions/TicketSimpleResponse" + } + } + } + }, + "TicketResponse": { + "type": "object", + "required": [ + "id", + "name", + "type", + "status", + "created", + "modified", + "schema" + ], + "properties": { + "artifacts": { + "type": "array", + "items": { + "$ref": "#/definitions/Artifact" + } + }, + "comments": { + "type": "array", + "items": { + "$ref": "#/definitions/Comment" + } + }, + "created": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "details": { + "type": "object", + "example": { + "description": "my little incident" + } + }, + "files": { + "type": "array", + "items": { + "$ref": "#/definitions/File" + } + }, + "id": { + "type": "integer", + "format": "int64", + "example": 123 + }, + "modified": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "name": { + "type": "string", + "example": "WannyCry" + }, + "owner": { + "type": "string", + "example": "bob" + }, + "playbooks": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/PlaybookResponse" + } + }, + "read": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "bob" + ] + }, + "references": { + "type": "array", + "items": { + "$ref": "#/definitions/Reference" + } + }, + "schema": { + "type": "string", + "example": "{}" + }, + "status": { + "type": "string", + "example": "open" + }, + "type": { + "type": "string", + "example": "incident" + }, + "write": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "alice" + ] + } + } + }, + "TicketSimpleResponse": { + "type": "object", + "required": [ + "id", + "name", + "type", + "status", + "created", + "modified", + "schema" + ], + "properties": { + "artifacts": { + "type": "array", + "items": { + "$ref": "#/definitions/Artifact" + } + }, + "comments": { + "type": "array", + "items": { + "$ref": "#/definitions/Comment" + } + }, + "created": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "details": { + "type": "object", + "example": { + "description": "my little incident" + } + }, + "files": { + "type": "array", + "items": { + "$ref": "#/definitions/File" + } + }, + "id": { + "type": "integer", + "format": "int64", + "example": 123 + }, + "modified": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "name": { + "type": "string", + "example": "WannyCry" + }, + "owner": { + "type": "string", + "example": "bob" + }, + "playbooks": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/Playbook" + } + }, + "read": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "bob" + ] + }, + "references": { + "type": "array", + "items": { + "$ref": "#/definitions/Reference" + } + }, + "schema": { + "type": "string", + "example": "{}" + }, + "status": { + "type": "string", + "example": "open" + }, + "type": { + "type": "string", + "example": "incident" + }, + "write": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "alice" + ] + } + } + }, + "TicketTemplate": { + "type": "object", + "required": [ + "name", + "schema" + ], + "properties": { + "name": { + "type": "string" + }, + "schema": { + "type": "string" + } + } + }, + "TicketTemplateForm": { + "type": "object", + "required": [ + "name", + "schema" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "schema": { + "type": "string" + } + } + }, + "TicketTemplateResponse": { + "type": "object", + "required": [ + "id", + "name", + "schema" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "schema": { + "type": "string" + } + } + }, + "TicketType": { + "type": "object", + "required": [ + "name", + "icon", + "default_template", + "default_playbooks" + ], + "properties": { + "default_groups": { + "type": "array", + "items": { + "type": "string" + } + }, + "default_playbooks": { + "type": "array", + "items": { + "type": "string" + } + }, + "default_template": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "TicketTypeForm": { + "type": "object", + "required": [ + "name", + "icon", + "default_template", + "default_playbooks" + ], + "properties": { + "default_groups": { + "type": "array", + "items": { + "type": "string" + } + }, + "default_playbooks": { + "type": "array", + "items": { + "type": "string" + } + }, + "default_template": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "TicketTypeResponse": { + "type": "object", + "required": [ + "id", + "name", + "icon", + "default_template", + "default_playbooks" + ], + "properties": { + "default_groups": { + "type": "array", + "items": { + "type": "string" + } + }, + "default_playbooks": { + "type": "array", + "items": { + "type": "string" + } + }, + "default_template": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "TicketWithTickets": { + "type": "object", + "required": [ + "id", + "name", + "type", + "status", + "created", + "modified", + "schema" + ], + "properties": { + "artifacts": { + "type": "array", + "items": { + "$ref": "#/definitions/Artifact" + } + }, + "comments": { + "type": "array", + "items": { + "$ref": "#/definitions/Comment" + } + }, + "created": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "details": { + "type": "object", + "example": { + "description": "my little incident" + } + }, + "files": { + "type": "array", + "items": { + "$ref": "#/definitions/File" + } + }, + "id": { + "type": "integer", + "format": "int64", + "example": 123 + }, + "modified": { + "type": "string", + "format": "date-time", + "example": "1985-04-12T23:20:50.52Z" + }, + "name": { + "type": "string", + "example": "WannyCry" + }, + "owner": { + "type": "string", + "example": "bob" + }, + "playbooks": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/PlaybookResponse" + } + }, + "read": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "bob" + ] + }, + "references": { + "type": "array", + "items": { + "$ref": "#/definitions/Reference" + } + }, + "schema": { + "type": "string", + "example": "{}" + }, + "status": { + "type": "string", + "example": "open" + }, + "tickets": { + "type": "array", + "items": { + "$ref": "#/definitions/TicketSimpleResponse" + } + }, + "type": { + "type": "string", + "example": "incident" + }, + "write": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "alice" + ] + } + } + }, + "Type": { + "type": "object", + "required": [ + "id", + "name", + "icon" + ], + "properties": { + "color": { + "type": "string", + "title": "Color", + "enum": [ + "error", + "info", + "success", + "warning" + ], + "x-cols": 3 + }, + "icon": { + "type": "string", + "title": "Icon (https://materialdesignicons.com)", + "x-class": "pr-2", + "x-cols": 3 + }, + "id": { + "type": "string", + "title": "ID", + "x-class": "pr-2", + "x-cols": 3 + }, + "name": { + "type": "string", + "title": "Name", + "x-class": "pr-2", + "x-cols": 3 + } + } + }, + "User": { + "type": "object", + "required": [ + "blocked", + "apikey", + "roles" + ], + "properties": { + "apikey": { + "type": "boolean" + }, + "blocked": { + "type": "boolean" + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + }, + "sha256": { + "type": "string" + } + } + }, + "UserData": { + "type": "object", + "properties": { + "email": { + "type": "string", + "x-example": "bob@example.org" + }, + "image": { + "type": "string", + "x-display": "custom-avatar" + }, + "name": { + "type": "string", + "x-example": "Robert Smith" + }, + "timeformat": { + "type": "string", + "title": "Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens)" + } + } + }, + "UserDataResponse": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "email": { + "type": "string", + "x-example": "bob@example.org" + }, + "id": { + "type": "string" + }, + "image": { + "type": "string", + "x-display": "custom-avatar" + }, + "name": { + "type": "string", + "x-example": "Robert Smith" + }, + "timeformat": { + "type": "string", + "title": "Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens)" + } + } + }, + "UserForm": { + "type": "object", + "required": [ + "id", + "blocked", + "roles", + "apikey" + ], + "properties": { + "apikey": { + "type": "boolean" + }, + "blocked": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "UserResponse": { + "type": "object", + "required": [ + "id", + "blocked", + "roles", + "apikey" + ], + "properties": { + "apikey": { + "type": "boolean" + }, + "blocked": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } +}`)) +} diff --git a/generated/restapi/operations/automations/create_automation_parameters.go b/generated/restapi/operations/automations/create_automation_parameters.go new file mode 100644 index 0000000..2fb2634 --- /dev/null +++ b/generated/restapi/operations/automations/create_automation_parameters.go @@ -0,0 +1,90 @@ +package automations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// CreateAutomationEndpoint executes the core logic of the related +// route endpoint. +func CreateAutomationEndpoint(handler func(ctx context.Context, params *CreateAutomationParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewCreateAutomationParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewCreateAutomationParams creates a new CreateAutomationParams object +// with the default values initialized. +func NewCreateAutomationParams() *CreateAutomationParams { + var () + return &CreateAutomationParams{} +} + +// CreateAutomationParams contains all the bound params for the create automation operation +// typically these are obtained from a http.Request +// +// swagger:parameters createAutomation +type CreateAutomationParams struct { + + /*New automation + Required: true + In: body + */ + Automation *models.AutomationForm +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *CreateAutomationParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if runtime.HasBody(ctx.Request) { + var body models.AutomationForm + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("automation", "body", "")) + } else { + res = append(res, errors.NewParseError("automation", "body", "", err)) + } + + } else { + o.Automation = &body + } + } else { + res = append(res, errors.Required("automation", "body", "")) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/automations/delete_automation_parameters.go b/generated/restapi/operations/automations/delete_automation_parameters.go new file mode 100644 index 0000000..8aef194 --- /dev/null +++ b/generated/restapi/operations/automations/delete_automation_parameters.go @@ -0,0 +1,87 @@ +package automations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// DeleteAutomationEndpoint executes the core logic of the related +// route endpoint. +func DeleteAutomationEndpoint(handler func(ctx context.Context, params *DeleteAutomationParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewDeleteAutomationParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewDeleteAutomationParams creates a new DeleteAutomationParams object +// with the default values initialized. +func NewDeleteAutomationParams() *DeleteAutomationParams { + var () + return &DeleteAutomationParams{} +} + +// DeleteAutomationParams contains all the bound params for the delete automation operation +// typically these are obtained from a http.Request +// +// swagger:parameters deleteAutomation +type DeleteAutomationParams struct { + + /*Automation ID + Required: true + In: path + */ + ID string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *DeleteAutomationParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *DeleteAutomationParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.ID = raw + + return nil +} diff --git a/generated/restapi/operations/automations/get_automation_parameters.go b/generated/restapi/operations/automations/get_automation_parameters.go new file mode 100644 index 0000000..ff5907c --- /dev/null +++ b/generated/restapi/operations/automations/get_automation_parameters.go @@ -0,0 +1,87 @@ +package automations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// GetAutomationEndpoint executes the core logic of the related +// route endpoint. +func GetAutomationEndpoint(handler func(ctx context.Context, params *GetAutomationParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewGetAutomationParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewGetAutomationParams creates a new GetAutomationParams object +// with the default values initialized. +func NewGetAutomationParams() *GetAutomationParams { + var () + return &GetAutomationParams{} +} + +// GetAutomationParams contains all the bound params for the get automation operation +// typically these are obtained from a http.Request +// +// swagger:parameters getAutomation +type GetAutomationParams struct { + + /*Automation ID + Required: true + In: path + */ + ID string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *GetAutomationParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *GetAutomationParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.ID = raw + + return nil +} diff --git a/generated/restapi/operations/automations/list_automations_parameters.go b/generated/restapi/operations/automations/list_automations_parameters.go new file mode 100644 index 0000000..68673db --- /dev/null +++ b/generated/restapi/operations/automations/list_automations_parameters.go @@ -0,0 +1,55 @@ +package automations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// ListAutomationsEndpoint executes the core logic of the related +// route endpoint. +func ListAutomationsEndpoint(handler func(ctx context.Context) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + resp := handler(ctx) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewListAutomationsParams creates a new ListAutomationsParams object +// with the default values initialized. +func NewListAutomationsParams() *ListAutomationsParams { + var () + return &ListAutomationsParams{} +} + +// ListAutomationsParams contains all the bound params for the list automations operation +// typically these are obtained from a http.Request +// +// swagger:parameters listAutomations +type ListAutomationsParams struct { +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *ListAutomationsParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/automations/update_automation_parameters.go b/generated/restapi/operations/automations/update_automation_parameters.go new file mode 100644 index 0000000..785fe06 --- /dev/null +++ b/generated/restapi/operations/automations/update_automation_parameters.go @@ -0,0 +1,111 @@ +package automations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// UpdateAutomationEndpoint executes the core logic of the related +// route endpoint. +func UpdateAutomationEndpoint(handler func(ctx context.Context, params *UpdateAutomationParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewUpdateAutomationParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewUpdateAutomationParams creates a new UpdateAutomationParams object +// with the default values initialized. +func NewUpdateAutomationParams() *UpdateAutomationParams { + var () + return &UpdateAutomationParams{} +} + +// UpdateAutomationParams contains all the bound params for the update automation operation +// typically these are obtained from a http.Request +// +// swagger:parameters updateAutomation +type UpdateAutomationParams struct { + + /*Automation object that needs to be added + Required: true + In: body + */ + Automation *models.AutomationForm + /*Automation ID + Required: true + In: path + */ + ID string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *UpdateAutomationParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if runtime.HasBody(ctx.Request) { + var body models.AutomationForm + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("automation", "body", "")) + } else { + res = append(res, errors.NewParseError("automation", "body", "", err)) + } + + } else { + o.Automation = &body + } + } else { + res = append(res, errors.Required("automation", "body", "")) + } + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *UpdateAutomationParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.ID = raw + + return nil +} diff --git a/generated/restapi/operations/jobs/get_job_parameters.go b/generated/restapi/operations/jobs/get_job_parameters.go new file mode 100644 index 0000000..d51044c --- /dev/null +++ b/generated/restapi/operations/jobs/get_job_parameters.go @@ -0,0 +1,87 @@ +package jobs + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// GetJobEndpoint executes the core logic of the related +// route endpoint. +func GetJobEndpoint(handler func(ctx context.Context, params *GetJobParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewGetJobParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewGetJobParams creates a new GetJobParams object +// with the default values initialized. +func NewGetJobParams() *GetJobParams { + var () + return &GetJobParams{} +} + +// GetJobParams contains all the bound params for the get job operation +// typically these are obtained from a http.Request +// +// swagger:parameters getJob +type GetJobParams struct { + + /*Job ID + Required: true + In: path + */ + ID string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *GetJobParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *GetJobParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.ID = raw + + return nil +} diff --git a/generated/restapi/operations/jobs/list_jobs_parameters.go b/generated/restapi/operations/jobs/list_jobs_parameters.go new file mode 100644 index 0000000..ab90ddb --- /dev/null +++ b/generated/restapi/operations/jobs/list_jobs_parameters.go @@ -0,0 +1,55 @@ +package jobs + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// ListJobsEndpoint executes the core logic of the related +// route endpoint. +func ListJobsEndpoint(handler func(ctx context.Context) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + resp := handler(ctx) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewListJobsParams creates a new ListJobsParams object +// with the default values initialized. +func NewListJobsParams() *ListJobsParams { + var () + return &ListJobsParams{} +} + +// ListJobsParams contains all the bound params for the list jobs operation +// typically these are obtained from a http.Request +// +// swagger:parameters listJobs +type ListJobsParams struct { +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *ListJobsParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/jobs/run_job_parameters.go b/generated/restapi/operations/jobs/run_job_parameters.go new file mode 100644 index 0000000..5480d1d --- /dev/null +++ b/generated/restapi/operations/jobs/run_job_parameters.go @@ -0,0 +1,90 @@ +package jobs + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// RunJobEndpoint executes the core logic of the related +// route endpoint. +func RunJobEndpoint(handler func(ctx context.Context, params *RunJobParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewRunJobParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewRunJobParams creates a new RunJobParams object +// with the default values initialized. +func NewRunJobParams() *RunJobParams { + var () + return &RunJobParams{} +} + +// RunJobParams contains all the bound params for the run job operation +// typically these are obtained from a http.Request +// +// swagger:parameters runJob +type RunJobParams struct { + + /*New job + Required: true + In: body + */ + Job *models.JobForm +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *RunJobParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if runtime.HasBody(ctx.Request) { + var body models.JobForm + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("job", "body", "")) + } else { + res = append(res, errors.NewParseError("job", "body", "", err)) + } + + } else { + o.Job = &body + } + } else { + res = append(res, errors.Required("job", "body", "")) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/jobs/update_job_parameters.go b/generated/restapi/operations/jobs/update_job_parameters.go new file mode 100644 index 0000000..caeab53 --- /dev/null +++ b/generated/restapi/operations/jobs/update_job_parameters.go @@ -0,0 +1,111 @@ +package jobs + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// UpdateJobEndpoint executes the core logic of the related +// route endpoint. +func UpdateJobEndpoint(handler func(ctx context.Context, params *UpdateJobParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewUpdateJobParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewUpdateJobParams creates a new UpdateJobParams object +// with the default values initialized. +func NewUpdateJobParams() *UpdateJobParams { + var () + return &UpdateJobParams{} +} + +// UpdateJobParams contains all the bound params for the update job operation +// typically these are obtained from a http.Request +// +// swagger:parameters updateJob +type UpdateJobParams struct { + + /*Job ID + Required: true + In: path + */ + ID string + /*Job object that needs to be added + Required: true + In: body + */ + Job *models.Job +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *UpdateJobParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if runtime.HasBody(ctx.Request) { + var body models.Job + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("job", "body", "")) + } else { + res = append(res, errors.NewParseError("job", "body", "", err)) + } + + } else { + o.Job = &body + } + } else { + res = append(res, errors.Required("job", "body", "")) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *UpdateJobParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.ID = raw + + return nil +} diff --git a/generated/restapi/operations/logs/get_logs_parameters.go b/generated/restapi/operations/logs/get_logs_parameters.go new file mode 100644 index 0000000..29236d5 --- /dev/null +++ b/generated/restapi/operations/logs/get_logs_parameters.go @@ -0,0 +1,87 @@ +package logs + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// GetLogsEndpoint executes the core logic of the related +// route endpoint. +func GetLogsEndpoint(handler func(ctx context.Context, params *GetLogsParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewGetLogsParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewGetLogsParams creates a new GetLogsParams object +// with the default values initialized. +func NewGetLogsParams() *GetLogsParams { + var () + return &GetLogsParams{} +} + +// GetLogsParams contains all the bound params for the get logs operation +// typically these are obtained from a http.Request +// +// swagger:parameters getLogs +type GetLogsParams struct { + + /*Reference + Required: true + In: path + */ + Reference string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *GetLogsParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rReference := []string{ctx.Param("reference")} + if err := o.bindReference(rReference, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *GetLogsParams) bindReference(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.Reference = raw + + return nil +} diff --git a/generated/restapi/operations/playbooks/create_playbook_parameters.go b/generated/restapi/operations/playbooks/create_playbook_parameters.go new file mode 100644 index 0000000..1f80305 --- /dev/null +++ b/generated/restapi/operations/playbooks/create_playbook_parameters.go @@ -0,0 +1,90 @@ +package playbooks + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// CreatePlaybookEndpoint executes the core logic of the related +// route endpoint. +func CreatePlaybookEndpoint(handler func(ctx context.Context, params *CreatePlaybookParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewCreatePlaybookParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewCreatePlaybookParams creates a new CreatePlaybookParams object +// with the default values initialized. +func NewCreatePlaybookParams() *CreatePlaybookParams { + var () + return &CreatePlaybookParams{} +} + +// CreatePlaybookParams contains all the bound params for the create playbook operation +// typically these are obtained from a http.Request +// +// swagger:parameters createPlaybook +type CreatePlaybookParams struct { + + /*New playbook + Required: true + In: body + */ + Playbook *models.PlaybookTemplateForm +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *CreatePlaybookParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if runtime.HasBody(ctx.Request) { + var body models.PlaybookTemplateForm + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("playbook", "body", "")) + } else { + res = append(res, errors.NewParseError("playbook", "body", "", err)) + } + + } else { + o.Playbook = &body + } + } else { + res = append(res, errors.Required("playbook", "body", "")) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/playbooks/delete_playbook_parameters.go b/generated/restapi/operations/playbooks/delete_playbook_parameters.go new file mode 100644 index 0000000..ba16dd7 --- /dev/null +++ b/generated/restapi/operations/playbooks/delete_playbook_parameters.go @@ -0,0 +1,87 @@ +package playbooks + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// DeletePlaybookEndpoint executes the core logic of the related +// route endpoint. +func DeletePlaybookEndpoint(handler func(ctx context.Context, params *DeletePlaybookParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewDeletePlaybookParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewDeletePlaybookParams creates a new DeletePlaybookParams object +// with the default values initialized. +func NewDeletePlaybookParams() *DeletePlaybookParams { + var () + return &DeletePlaybookParams{} +} + +// DeletePlaybookParams contains all the bound params for the delete playbook operation +// typically these are obtained from a http.Request +// +// swagger:parameters deletePlaybook +type DeletePlaybookParams struct { + + /*Playbook name + Required: true + In: path + */ + ID string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *DeletePlaybookParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *DeletePlaybookParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.ID = raw + + return nil +} diff --git a/generated/restapi/operations/playbooks/get_playbook_parameters.go b/generated/restapi/operations/playbooks/get_playbook_parameters.go new file mode 100644 index 0000000..8aed8d2 --- /dev/null +++ b/generated/restapi/operations/playbooks/get_playbook_parameters.go @@ -0,0 +1,87 @@ +package playbooks + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// GetPlaybookEndpoint executes the core logic of the related +// route endpoint. +func GetPlaybookEndpoint(handler func(ctx context.Context, params *GetPlaybookParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewGetPlaybookParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewGetPlaybookParams creates a new GetPlaybookParams object +// with the default values initialized. +func NewGetPlaybookParams() *GetPlaybookParams { + var () + return &GetPlaybookParams{} +} + +// GetPlaybookParams contains all the bound params for the get playbook operation +// typically these are obtained from a http.Request +// +// swagger:parameters getPlaybook +type GetPlaybookParams struct { + + /*Playbook name + Required: true + In: path + */ + ID string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *GetPlaybookParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *GetPlaybookParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.ID = raw + + return nil +} diff --git a/generated/restapi/operations/playbooks/list_playbooks_parameters.go b/generated/restapi/operations/playbooks/list_playbooks_parameters.go new file mode 100644 index 0000000..d63dc77 --- /dev/null +++ b/generated/restapi/operations/playbooks/list_playbooks_parameters.go @@ -0,0 +1,55 @@ +package playbooks + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// ListPlaybooksEndpoint executes the core logic of the related +// route endpoint. +func ListPlaybooksEndpoint(handler func(ctx context.Context) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + resp := handler(ctx) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewListPlaybooksParams creates a new ListPlaybooksParams object +// with the default values initialized. +func NewListPlaybooksParams() *ListPlaybooksParams { + var () + return &ListPlaybooksParams{} +} + +// ListPlaybooksParams contains all the bound params for the list playbooks operation +// typically these are obtained from a http.Request +// +// swagger:parameters listPlaybooks +type ListPlaybooksParams struct { +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *ListPlaybooksParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/playbooks/update_playbook_parameters.go b/generated/restapi/operations/playbooks/update_playbook_parameters.go new file mode 100644 index 0000000..ae3d524 --- /dev/null +++ b/generated/restapi/operations/playbooks/update_playbook_parameters.go @@ -0,0 +1,111 @@ +package playbooks + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// UpdatePlaybookEndpoint executes the core logic of the related +// route endpoint. +func UpdatePlaybookEndpoint(handler func(ctx context.Context, params *UpdatePlaybookParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewUpdatePlaybookParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewUpdatePlaybookParams creates a new UpdatePlaybookParams object +// with the default values initialized. +func NewUpdatePlaybookParams() *UpdatePlaybookParams { + var () + return &UpdatePlaybookParams{} +} + +// UpdatePlaybookParams contains all the bound params for the update playbook operation +// typically these are obtained from a http.Request +// +// swagger:parameters updatePlaybook +type UpdatePlaybookParams struct { + + /*Playbook ID + Required: true + In: path + */ + ID string + /*Updated playbook + Required: true + In: body + */ + Playbook *models.PlaybookTemplateForm +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *UpdatePlaybookParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if runtime.HasBody(ctx.Request) { + var body models.PlaybookTemplateForm + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("playbook", "body", "")) + } else { + res = append(res, errors.NewParseError("playbook", "body", "", err)) + } + + } else { + o.Playbook = &body + } + } else { + res = append(res, errors.Required("playbook", "body", "")) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *UpdatePlaybookParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.ID = raw + + return nil +} diff --git a/generated/restapi/operations/settings/get_settings_parameters.go b/generated/restapi/operations/settings/get_settings_parameters.go new file mode 100644 index 0000000..a6f9a19 --- /dev/null +++ b/generated/restapi/operations/settings/get_settings_parameters.go @@ -0,0 +1,55 @@ +package settings + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// GetSettingsEndpoint executes the core logic of the related +// route endpoint. +func GetSettingsEndpoint(handler func(ctx context.Context) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + resp := handler(ctx) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewGetSettingsParams creates a new GetSettingsParams object +// with the default values initialized. +func NewGetSettingsParams() *GetSettingsParams { + var () + return &GetSettingsParams{} +} + +// GetSettingsParams contains all the bound params for the get settings operation +// typically these are obtained from a http.Request +// +// swagger:parameters getSettings +type GetSettingsParams struct { +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *GetSettingsParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/statistics/get_statistics_parameters.go b/generated/restapi/operations/statistics/get_statistics_parameters.go new file mode 100644 index 0000000..ae3626e --- /dev/null +++ b/generated/restapi/operations/statistics/get_statistics_parameters.go @@ -0,0 +1,55 @@ +package statistics + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// GetStatisticsEndpoint executes the core logic of the related +// route endpoint. +func GetStatisticsEndpoint(handler func(ctx context.Context) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + resp := handler(ctx) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewGetStatisticsParams creates a new GetStatisticsParams object +// with the default values initialized. +func NewGetStatisticsParams() *GetStatisticsParams { + var () + return &GetStatisticsParams{} +} + +// GetStatisticsParams contains all the bound params for the get statistics operation +// typically these are obtained from a http.Request +// +// swagger:parameters getStatistics +type GetStatisticsParams struct { +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *GetStatisticsParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/tasks/list_tasks_parameters.go b/generated/restapi/operations/tasks/list_tasks_parameters.go new file mode 100644 index 0000000..4fd738b --- /dev/null +++ b/generated/restapi/operations/tasks/list_tasks_parameters.go @@ -0,0 +1,55 @@ +package tasks + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// ListTasksEndpoint executes the core logic of the related +// route endpoint. +func ListTasksEndpoint(handler func(ctx context.Context) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + resp := handler(ctx) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewListTasksParams creates a new ListTasksParams object +// with the default values initialized. +func NewListTasksParams() *ListTasksParams { + var () + return &ListTasksParams{} +} + +// ListTasksParams contains all the bound params for the list tasks operation +// typically these are obtained from a http.Request +// +// swagger:parameters listTasks +type ListTasksParams struct { +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *ListTasksParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/templates/create_template_parameters.go b/generated/restapi/operations/templates/create_template_parameters.go new file mode 100644 index 0000000..4ba64e0 --- /dev/null +++ b/generated/restapi/operations/templates/create_template_parameters.go @@ -0,0 +1,90 @@ +package templates + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// CreateTemplateEndpoint executes the core logic of the related +// route endpoint. +func CreateTemplateEndpoint(handler func(ctx context.Context, params *CreateTemplateParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewCreateTemplateParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewCreateTemplateParams creates a new CreateTemplateParams object +// with the default values initialized. +func NewCreateTemplateParams() *CreateTemplateParams { + var () + return &CreateTemplateParams{} +} + +// CreateTemplateParams contains all the bound params for the create template operation +// typically these are obtained from a http.Request +// +// swagger:parameters createTemplate +type CreateTemplateParams struct { + + /*New template + Required: true + In: body + */ + Template *models.TicketTemplateForm +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *CreateTemplateParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if runtime.HasBody(ctx.Request) { + var body models.TicketTemplateForm + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("template", "body", "")) + } else { + res = append(res, errors.NewParseError("template", "body", "", err)) + } + + } else { + o.Template = &body + } + } else { + res = append(res, errors.Required("template", "body", "")) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/templates/delete_template_parameters.go b/generated/restapi/operations/templates/delete_template_parameters.go new file mode 100644 index 0000000..951de04 --- /dev/null +++ b/generated/restapi/operations/templates/delete_template_parameters.go @@ -0,0 +1,87 @@ +package templates + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// DeleteTemplateEndpoint executes the core logic of the related +// route endpoint. +func DeleteTemplateEndpoint(handler func(ctx context.Context, params *DeleteTemplateParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewDeleteTemplateParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewDeleteTemplateParams creates a new DeleteTemplateParams object +// with the default values initialized. +func NewDeleteTemplateParams() *DeleteTemplateParams { + var () + return &DeleteTemplateParams{} +} + +// DeleteTemplateParams contains all the bound params for the delete template operation +// typically these are obtained from a http.Request +// +// swagger:parameters deleteTemplate +type DeleteTemplateParams struct { + + /*Template ID + Required: true + In: path + */ + ID string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *DeleteTemplateParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *DeleteTemplateParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.ID = raw + + return nil +} diff --git a/generated/restapi/operations/templates/get_template_parameters.go b/generated/restapi/operations/templates/get_template_parameters.go new file mode 100644 index 0000000..44e7020 --- /dev/null +++ b/generated/restapi/operations/templates/get_template_parameters.go @@ -0,0 +1,87 @@ +package templates + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// GetTemplateEndpoint executes the core logic of the related +// route endpoint. +func GetTemplateEndpoint(handler func(ctx context.Context, params *GetTemplateParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewGetTemplateParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewGetTemplateParams creates a new GetTemplateParams object +// with the default values initialized. +func NewGetTemplateParams() *GetTemplateParams { + var () + return &GetTemplateParams{} +} + +// GetTemplateParams contains all the bound params for the get template operation +// typically these are obtained from a http.Request +// +// swagger:parameters getTemplate +type GetTemplateParams struct { + + /*Template ID + Required: true + In: path + */ + ID string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *GetTemplateParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *GetTemplateParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.ID = raw + + return nil +} diff --git a/generated/restapi/operations/templates/list_templates_parameters.go b/generated/restapi/operations/templates/list_templates_parameters.go new file mode 100644 index 0000000..2f2e255 --- /dev/null +++ b/generated/restapi/operations/templates/list_templates_parameters.go @@ -0,0 +1,55 @@ +package templates + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// ListTemplatesEndpoint executes the core logic of the related +// route endpoint. +func ListTemplatesEndpoint(handler func(ctx context.Context) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + resp := handler(ctx) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewListTemplatesParams creates a new ListTemplatesParams object +// with the default values initialized. +func NewListTemplatesParams() *ListTemplatesParams { + var () + return &ListTemplatesParams{} +} + +// ListTemplatesParams contains all the bound params for the list templates operation +// typically these are obtained from a http.Request +// +// swagger:parameters listTemplates +type ListTemplatesParams struct { +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *ListTemplatesParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/templates/update_template_parameters.go b/generated/restapi/operations/templates/update_template_parameters.go new file mode 100644 index 0000000..66fd60e --- /dev/null +++ b/generated/restapi/operations/templates/update_template_parameters.go @@ -0,0 +1,111 @@ +package templates + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// UpdateTemplateEndpoint executes the core logic of the related +// route endpoint. +func UpdateTemplateEndpoint(handler func(ctx context.Context, params *UpdateTemplateParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewUpdateTemplateParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewUpdateTemplateParams creates a new UpdateTemplateParams object +// with the default values initialized. +func NewUpdateTemplateParams() *UpdateTemplateParams { + var () + return &UpdateTemplateParams{} +} + +// UpdateTemplateParams contains all the bound params for the update template operation +// typically these are obtained from a http.Request +// +// swagger:parameters updateTemplate +type UpdateTemplateParams struct { + + /*Template ID + Required: true + In: path + */ + ID string + /*Template object that needs to be added + Required: true + In: body + */ + Template *models.TicketTemplateForm +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *UpdateTemplateParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if runtime.HasBody(ctx.Request) { + var body models.TicketTemplateForm + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("template", "body", "")) + } else { + res = append(res, errors.NewParseError("template", "body", "", err)) + } + + } else { + o.Template = &body + } + } else { + res = append(res, errors.Required("template", "body", "")) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *UpdateTemplateParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.ID = raw + + return nil +} diff --git a/generated/restapi/operations/tickets/add_artifact_parameters.go b/generated/restapi/operations/tickets/add_artifact_parameters.go new file mode 100644 index 0000000..60cbf17 --- /dev/null +++ b/generated/restapi/operations/tickets/add_artifact_parameters.go @@ -0,0 +1,116 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// AddArtifactEndpoint executes the core logic of the related +// route endpoint. +func AddArtifactEndpoint(handler func(ctx context.Context, params *AddArtifactParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewAddArtifactParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewAddArtifactParams creates a new AddArtifactParams object +// with the default values initialized. +func NewAddArtifactParams() *AddArtifactParams { + var () + return &AddArtifactParams{} +} + +// AddArtifactParams contains all the bound params for the add artifact operation +// typically these are obtained from a http.Request +// +// swagger:parameters addArtifact +type AddArtifactParams struct { + + /*Artifact object that needs to be added + Required: true + In: body + */ + Artifact *models.Artifact + /*Ticket ID + Required: true + In: path + */ + ID int64 +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *AddArtifactParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if runtime.HasBody(ctx.Request) { + var body models.Artifact + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("artifact", "body", "")) + } else { + res = append(res, errors.NewParseError("artifact", "body", "", err)) + } + + } else { + o.Artifact = &body + } + } else { + res = append(res, errors.Required("artifact", "body", "")) + } + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *AddArtifactParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} diff --git a/generated/restapi/operations/tickets/add_comment_parameters.go b/generated/restapi/operations/tickets/add_comment_parameters.go new file mode 100644 index 0000000..52608e2 --- /dev/null +++ b/generated/restapi/operations/tickets/add_comment_parameters.go @@ -0,0 +1,116 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// AddCommentEndpoint executes the core logic of the related +// route endpoint. +func AddCommentEndpoint(handler func(ctx context.Context, params *AddCommentParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewAddCommentParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewAddCommentParams creates a new AddCommentParams object +// with the default values initialized. +func NewAddCommentParams() *AddCommentParams { + var () + return &AddCommentParams{} +} + +// AddCommentParams contains all the bound params for the add comment operation +// typically these are obtained from a http.Request +// +// swagger:parameters addComment +type AddCommentParams struct { + + /*Ticket comment + Required: true + In: body + */ + Comment *models.CommentForm + /*Ticket ID + Required: true + In: path + */ + ID int64 +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *AddCommentParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if runtime.HasBody(ctx.Request) { + var body models.CommentForm + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("comment", "body", "")) + } else { + res = append(res, errors.NewParseError("comment", "body", "", err)) + } + + } else { + o.Comment = &body + } + } else { + res = append(res, errors.Required("comment", "body", "")) + } + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *AddCommentParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} diff --git a/generated/restapi/operations/tickets/add_ticket_playbook_parameters.go b/generated/restapi/operations/tickets/add_ticket_playbook_parameters.go new file mode 100644 index 0000000..261ea32 --- /dev/null +++ b/generated/restapi/operations/tickets/add_ticket_playbook_parameters.go @@ -0,0 +1,116 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// AddTicketPlaybookEndpoint executes the core logic of the related +// route endpoint. +func AddTicketPlaybookEndpoint(handler func(ctx context.Context, params *AddTicketPlaybookParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewAddTicketPlaybookParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewAddTicketPlaybookParams creates a new AddTicketPlaybookParams object +// with the default values initialized. +func NewAddTicketPlaybookParams() *AddTicketPlaybookParams { + var () + return &AddTicketPlaybookParams{} +} + +// AddTicketPlaybookParams contains all the bound params for the add ticket playbook operation +// typically these are obtained from a http.Request +// +// swagger:parameters addTicketPlaybook +type AddTicketPlaybookParams struct { + + /*Ticket ID + Required: true + In: path + */ + ID int64 + /*Ticket playbook object that needs to be added + Required: true + In: body + */ + Playbook *models.PlaybookTemplateForm +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *AddTicketPlaybookParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if runtime.HasBody(ctx.Request) { + var body models.PlaybookTemplateForm + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("playbook", "body", "")) + } else { + res = append(res, errors.NewParseError("playbook", "body", "", err)) + } + + } else { + o.Playbook = &body + } + } else { + res = append(res, errors.Required("playbook", "body", "")) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *AddTicketPlaybookParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} diff --git a/generated/restapi/operations/tickets/complete_task_parameters.go b/generated/restapi/operations/tickets/complete_task_parameters.go new file mode 100644 index 0000000..f53bb27 --- /dev/null +++ b/generated/restapi/operations/tickets/complete_task_parameters.go @@ -0,0 +1,157 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// CompleteTaskEndpoint executes the core logic of the related +// route endpoint. +func CompleteTaskEndpoint(handler func(ctx context.Context, params *CompleteTaskParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewCompleteTaskParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewCompleteTaskParams creates a new CompleteTaskParams object +// with the default values initialized. +func NewCompleteTaskParams() *CompleteTaskParams { + var () + return &CompleteTaskParams{} +} + +// CompleteTaskParams contains all the bound params for the complete task operation +// typically these are obtained from a http.Request +// +// swagger:parameters completeTask +type CompleteTaskParams struct { + + /*Ticket playbook object that needs to be added + Required: true + In: body + */ + Data interface{} + /*Ticket ID + Required: true + In: path + */ + ID int64 + /*Playbook ID + Required: true + In: path + */ + PlaybookID string + /*Task ID + Required: true + In: path + */ + TaskID string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *CompleteTaskParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if runtime.HasBody(ctx.Request) { + var body interface{} + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("data", "body", "")) + } else { + res = append(res, errors.NewParseError("data", "body", "", err)) + } + + } else { + o.Data = body + } + } else { + res = append(res, errors.Required("data", "body", "")) + } + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + rPlaybookID := []string{ctx.Param("playbookID")} + if err := o.bindPlaybookID(rPlaybookID, true); err != nil { + res = append(res, err) + } + + rTaskID := []string{ctx.Param("taskID")} + if err := o.bindTaskID(rTaskID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *CompleteTaskParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} + +func (o *CompleteTaskParams) bindPlaybookID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.PlaybookID = raw + + return nil +} + +func (o *CompleteTaskParams) bindTaskID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.TaskID = raw + + return nil +} diff --git a/generated/restapi/operations/tickets/create_ticket_batch_parameters.go b/generated/restapi/operations/tickets/create_ticket_batch_parameters.go new file mode 100644 index 0000000..56abf52 --- /dev/null +++ b/generated/restapi/operations/tickets/create_ticket_batch_parameters.go @@ -0,0 +1,90 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// CreateTicketBatchEndpoint executes the core logic of the related +// route endpoint. +func CreateTicketBatchEndpoint(handler func(ctx context.Context, params *CreateTicketBatchParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewCreateTicketBatchParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewCreateTicketBatchParams creates a new CreateTicketBatchParams object +// with the default values initialized. +func NewCreateTicketBatchParams() *CreateTicketBatchParams { + var () + return &CreateTicketBatchParams{} +} + +// CreateTicketBatchParams contains all the bound params for the create ticket batch operation +// typically these are obtained from a http.Request +// +// swagger:parameters createTicketBatch +type CreateTicketBatchParams struct { + + /*New ticket + Required: true + In: body + */ + Ticket []*models.TicketForm +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *CreateTicketBatchParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if runtime.HasBody(ctx.Request) { + var body []*models.TicketForm + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("ticket", "body", "")) + } else { + res = append(res, errors.NewParseError("ticket", "body", "", err)) + } + + } else { + o.Ticket = body + } + } else { + res = append(res, errors.Required("ticket", "body", "")) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/tickets/create_ticket_parameters.go b/generated/restapi/operations/tickets/create_ticket_parameters.go new file mode 100644 index 0000000..e5ec2fc --- /dev/null +++ b/generated/restapi/operations/tickets/create_ticket_parameters.go @@ -0,0 +1,90 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// CreateTicketEndpoint executes the core logic of the related +// route endpoint. +func CreateTicketEndpoint(handler func(ctx context.Context, params *CreateTicketParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewCreateTicketParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewCreateTicketParams creates a new CreateTicketParams object +// with the default values initialized. +func NewCreateTicketParams() *CreateTicketParams { + var () + return &CreateTicketParams{} +} + +// CreateTicketParams contains all the bound params for the create ticket operation +// typically these are obtained from a http.Request +// +// swagger:parameters createTicket +type CreateTicketParams struct { + + /*New ticket + Required: true + In: body + */ + Ticket *models.TicketForm +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *CreateTicketParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if runtime.HasBody(ctx.Request) { + var body models.TicketForm + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("ticket", "body", "")) + } else { + res = append(res, errors.NewParseError("ticket", "body", "", err)) + } + + } else { + o.Ticket = &body + } + } else { + res = append(res, errors.Required("ticket", "body", "")) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/tickets/delete_ticket_parameters.go b/generated/restapi/operations/tickets/delete_ticket_parameters.go new file mode 100644 index 0000000..77352e0 --- /dev/null +++ b/generated/restapi/operations/tickets/delete_ticket_parameters.go @@ -0,0 +1,92 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// DeleteTicketEndpoint executes the core logic of the related +// route endpoint. +func DeleteTicketEndpoint(handler func(ctx context.Context, params *DeleteTicketParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewDeleteTicketParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewDeleteTicketParams creates a new DeleteTicketParams object +// with the default values initialized. +func NewDeleteTicketParams() *DeleteTicketParams { + var () + return &DeleteTicketParams{} +} + +// DeleteTicketParams contains all the bound params for the delete ticket operation +// typically these are obtained from a http.Request +// +// swagger:parameters deleteTicket +type DeleteTicketParams struct { + + /*Ticket ID + Required: true + In: path + */ + ID int64 +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *DeleteTicketParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *DeleteTicketParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} diff --git a/generated/restapi/operations/tickets/enrich_artifact_parameters.go b/generated/restapi/operations/tickets/enrich_artifact_parameters.go new file mode 100644 index 0000000..e94aaef --- /dev/null +++ b/generated/restapi/operations/tickets/enrich_artifact_parameters.go @@ -0,0 +1,137 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// EnrichArtifactEndpoint executes the core logic of the related +// route endpoint. +func EnrichArtifactEndpoint(handler func(ctx context.Context, params *EnrichArtifactParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewEnrichArtifactParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewEnrichArtifactParams creates a new EnrichArtifactParams object +// with the default values initialized. +func NewEnrichArtifactParams() *EnrichArtifactParams { + var () + return &EnrichArtifactParams{} +} + +// EnrichArtifactParams contains all the bound params for the enrich artifact operation +// typically these are obtained from a http.Request +// +// swagger:parameters enrichArtifact +type EnrichArtifactParams struct { + + /* + Required: true + In: body + */ + Data *models.EnrichmentForm + /*Ticket ID + Required: true + In: path + */ + ID int64 + /* + Required: true + In: path + */ + Name string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *EnrichArtifactParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if runtime.HasBody(ctx.Request) { + var body models.EnrichmentForm + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("data", "body", "")) + } else { + res = append(res, errors.NewParseError("data", "body", "", err)) + } + + } else { + o.Data = &body + } + } else { + res = append(res, errors.Required("data", "body", "")) + } + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + rName := []string{ctx.Param("name")} + if err := o.bindName(rName, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *EnrichArtifactParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} + +func (o *EnrichArtifactParams) bindName(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.Name = raw + + return nil +} diff --git a/generated/restapi/operations/tickets/get_artifact_parameters.go b/generated/restapi/operations/tickets/get_artifact_parameters.go new file mode 100644 index 0000000..3329a11 --- /dev/null +++ b/generated/restapi/operations/tickets/get_artifact_parameters.go @@ -0,0 +1,113 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// GetArtifactEndpoint executes the core logic of the related +// route endpoint. +func GetArtifactEndpoint(handler func(ctx context.Context, params *GetArtifactParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewGetArtifactParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewGetArtifactParams creates a new GetArtifactParams object +// with the default values initialized. +func NewGetArtifactParams() *GetArtifactParams { + var () + return &GetArtifactParams{} +} + +// GetArtifactParams contains all the bound params for the get artifact operation +// typically these are obtained from a http.Request +// +// swagger:parameters getArtifact +type GetArtifactParams struct { + + /*Ticket ID + Required: true + In: path + */ + ID int64 + /* + Required: true + In: path + */ + Name string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *GetArtifactParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + rName := []string{ctx.Param("name")} + if err := o.bindName(rName, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *GetArtifactParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} + +func (o *GetArtifactParams) bindName(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.Name = raw + + return nil +} diff --git a/generated/restapi/operations/tickets/get_ticket_parameters.go b/generated/restapi/operations/tickets/get_ticket_parameters.go new file mode 100644 index 0000000..1616efc --- /dev/null +++ b/generated/restapi/operations/tickets/get_ticket_parameters.go @@ -0,0 +1,92 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// GetTicketEndpoint executes the core logic of the related +// route endpoint. +func GetTicketEndpoint(handler func(ctx context.Context, params *GetTicketParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewGetTicketParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewGetTicketParams creates a new GetTicketParams object +// with the default values initialized. +func NewGetTicketParams() *GetTicketParams { + var () + return &GetTicketParams{} +} + +// GetTicketParams contains all the bound params for the get ticket operation +// typically these are obtained from a http.Request +// +// swagger:parameters getTicket +type GetTicketParams struct { + + /*Ticket ID + Required: true + In: path + */ + ID int64 +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *GetTicketParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *GetTicketParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} diff --git a/generated/restapi/operations/tickets/link_files_parameters.go b/generated/restapi/operations/tickets/link_files_parameters.go new file mode 100644 index 0000000..23eab37 --- /dev/null +++ b/generated/restapi/operations/tickets/link_files_parameters.go @@ -0,0 +1,116 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// LinkFilesEndpoint executes the core logic of the related +// route endpoint. +func LinkFilesEndpoint(handler func(ctx context.Context, params *LinkFilesParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewLinkFilesParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewLinkFilesParams creates a new LinkFilesParams object +// with the default values initialized. +func NewLinkFilesParams() *LinkFilesParams { + var () + return &LinkFilesParams{} +} + +// LinkFilesParams contains all the bound params for the link files operation +// typically these are obtained from a http.Request +// +// swagger:parameters linkFiles +type LinkFilesParams struct { + + /*Added files + Required: true + In: body + */ + Files []*models.File + /*Ticket ID + Required: true + In: path + */ + ID int64 +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *LinkFilesParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if runtime.HasBody(ctx.Request) { + var body []*models.File + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("files", "body", "")) + } else { + res = append(res, errors.NewParseError("files", "body", "", err)) + } + + } else { + o.Files = body + } + } else { + res = append(res, errors.Required("files", "body", "")) + } + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *LinkFilesParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} diff --git a/generated/restapi/operations/tickets/link_ticket_parameters.go b/generated/restapi/operations/tickets/link_ticket_parameters.go new file mode 100644 index 0000000..c86d899 --- /dev/null +++ b/generated/restapi/operations/tickets/link_ticket_parameters.go @@ -0,0 +1,115 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// LinkTicketEndpoint executes the core logic of the related +// route endpoint. +func LinkTicketEndpoint(handler func(ctx context.Context, params *LinkTicketParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewLinkTicketParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewLinkTicketParams creates a new LinkTicketParams object +// with the default values initialized. +func NewLinkTicketParams() *LinkTicketParams { + var () + return &LinkTicketParams{} +} + +// LinkTicketParams contains all the bound params for the link ticket operation +// typically these are obtained from a http.Request +// +// swagger:parameters linkTicket +type LinkTicketParams struct { + + /*Ticket ID + Required: true + In: path + */ + ID int64 + /*Added ticket ID + Required: true + In: body + */ + LinkedID int64 +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *LinkTicketParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if runtime.HasBody(ctx.Request) { + var body int64 + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("linkedId", "body", "")) + } else { + res = append(res, errors.NewParseError("linkedId", "body", "", err)) + } + + } else { + o.LinkedID = body + } + } else { + res = append(res, errors.Required("linkedId", "body", "")) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *LinkTicketParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} diff --git a/generated/restapi/operations/tickets/list_tickets_parameters.go b/generated/restapi/operations/tickets/list_tickets_parameters.go new file mode 100644 index 0000000..4c230f7 --- /dev/null +++ b/generated/restapi/operations/tickets/list_tickets_parameters.go @@ -0,0 +1,269 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "fmt" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// ListTicketsEndpoint executes the core logic of the related +// route endpoint. +func ListTicketsEndpoint(handler func(ctx context.Context, params *ListTicketsParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewListTicketsParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewListTicketsParams creates a new ListTicketsParams object +// with the default values initialized. +func NewListTicketsParams() *ListTicketsParams { + var ( + countDefault = int64(25) + offsetDefault = int64(0) + ) + return &ListTicketsParams{ + Count: &countDefault, + + Offset: &offsetDefault, + } +} + +// ListTicketsParams contains all the bound params for the list tickets operation +// typically these are obtained from a http.Request +// +// swagger:parameters listTickets +type ListTicketsParams struct { + + /*Number of tickets + Maximum: 100 + In: query + Default: 25 + */ + Count *int64 + /*Sort descending + In: query + */ + Desc []bool + /*Offset of the list + In: query + Default: 0 + */ + Offset *int64 + /*Search query + In: query + */ + Query *string + /*Sort columns + In: query + */ + Sort []string + /*Ticket Type + In: query + */ + Type *string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *ListTicketsParams) ReadRequest(ctx *gin.Context) error { + var res []error + qs := runtime.Values(ctx.Request.URL.Query()) + + qCount, qhkCount, _ := qs.GetOK("count") + if err := o.bindCount(qCount, qhkCount); err != nil { + res = append(res, err) + } + + qDesc, qhkDesc, _ := qs.GetOK("desc") + if err := o.bindDesc(qDesc, qhkDesc); err != nil { + res = append(res, err) + } + + qOffset, qhkOffset, _ := qs.GetOK("offset") + if err := o.bindOffset(qOffset, qhkOffset); err != nil { + res = append(res, err) + } + + qQuery, qhkQuery, _ := qs.GetOK("query") + if err := o.bindQuery(qQuery, qhkQuery); err != nil { + res = append(res, err) + } + + qSort, qhkSort, _ := qs.GetOK("sort") + if err := o.bindSort(qSort, qhkSort); err != nil { + res = append(res, err) + } + + qType, qhkType, _ := qs.GetOK("type") + if err := o.bindType(qType, qhkType); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *ListTicketsParams) bindCount(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + if raw == "" { // empty values pass all other validations + var countDefault int64 = int64(25) + o.Count = &countDefault + return nil + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("count", "query", "int64", raw) + } + o.Count = &value + + if err := o.validateCount(); err != nil { + return err + } + + return nil +} + +func (o *ListTicketsParams) validateCount() error { + + if err := validate.MaximumInt("count", "query", int64(*o.Count), 100, false); err != nil { + return err + } + + return nil +} + +func (o *ListTicketsParams) bindDesc(rawData []string, hasKey bool) error { + + var qvDesc string + if len(rawData) > 0 { + qvDesc = rawData[len(rawData)-1] + } + + descIC := swag.SplitByFormat(qvDesc, "") + + if len(descIC) == 0 { + return nil + } + + var descIR []bool + for i, descIV := range descIC { + descI, err := swag.ConvertBool(descIV) + if err != nil { + return errors.InvalidType(fmt.Sprintf("%s.%v", "desc", i), "query", "bool", descI) + } + + descIR = append(descIR, descI) + } + + o.Desc = descIR + + return nil +} + +func (o *ListTicketsParams) bindOffset(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + if raw == "" { // empty values pass all other validations + var offsetDefault int64 = int64(0) + o.Offset = &offsetDefault + return nil + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("offset", "query", "int64", raw) + } + o.Offset = &value + + return nil +} + +func (o *ListTicketsParams) bindQuery(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + if raw == "" { // empty values pass all other validations + return nil + } + + o.Query = &raw + + return nil +} + +func (o *ListTicketsParams) bindSort(rawData []string, hasKey bool) error { + + var qvSort string + if len(rawData) > 0 { + qvSort = rawData[len(rawData)-1] + } + + sortIC := swag.SplitByFormat(qvSort, "") + + if len(sortIC) == 0 { + return nil + } + + var sortIR []string + for _, sortIV := range sortIC { + sortI := sortIV + + sortIR = append(sortIR, sortI) + } + + o.Sort = sortIR + + return nil +} + +func (o *ListTicketsParams) bindType(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + if raw == "" { // empty values pass all other validations + return nil + } + + o.Type = &raw + + return nil +} diff --git a/generated/restapi/operations/tickets/remove_artifact_parameters.go b/generated/restapi/operations/tickets/remove_artifact_parameters.go new file mode 100644 index 0000000..4003d41 --- /dev/null +++ b/generated/restapi/operations/tickets/remove_artifact_parameters.go @@ -0,0 +1,113 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// RemoveArtifactEndpoint executes the core logic of the related +// route endpoint. +func RemoveArtifactEndpoint(handler func(ctx context.Context, params *RemoveArtifactParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewRemoveArtifactParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewRemoveArtifactParams creates a new RemoveArtifactParams object +// with the default values initialized. +func NewRemoveArtifactParams() *RemoveArtifactParams { + var () + return &RemoveArtifactParams{} +} + +// RemoveArtifactParams contains all the bound params for the remove artifact operation +// typically these are obtained from a http.Request +// +// swagger:parameters removeArtifact +type RemoveArtifactParams struct { + + /*Ticket ID + Required: true + In: path + */ + ID int64 + /* + Required: true + In: path + */ + Name string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *RemoveArtifactParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + rName := []string{ctx.Param("name")} + if err := o.bindName(rName, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *RemoveArtifactParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} + +func (o *RemoveArtifactParams) bindName(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.Name = raw + + return nil +} diff --git a/generated/restapi/operations/tickets/remove_comment_parameters.go b/generated/restapi/operations/tickets/remove_comment_parameters.go new file mode 100644 index 0000000..4ff85d2 --- /dev/null +++ b/generated/restapi/operations/tickets/remove_comment_parameters.go @@ -0,0 +1,117 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// RemoveCommentEndpoint executes the core logic of the related +// route endpoint. +func RemoveCommentEndpoint(handler func(ctx context.Context, params *RemoveCommentParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewRemoveCommentParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewRemoveCommentParams creates a new RemoveCommentParams object +// with the default values initialized. +func NewRemoveCommentParams() *RemoveCommentParams { + var () + return &RemoveCommentParams{} +} + +// RemoveCommentParams contains all the bound params for the remove comment operation +// typically these are obtained from a http.Request +// +// swagger:parameters removeComment +type RemoveCommentParams struct { + + /*Comment ID to remove + Required: true + In: path + */ + CommentID int64 + /*Ticket ID + Required: true + In: path + */ + ID int64 +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *RemoveCommentParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rCommentID := []string{ctx.Param("commentID")} + if err := o.bindCommentID(rCommentID, true); err != nil { + res = append(res, err) + } + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *RemoveCommentParams) bindCommentID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("commentID", "path", "int64", raw) + } + o.CommentID = value + + return nil +} + +func (o *RemoveCommentParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} diff --git a/generated/restapi/operations/tickets/remove_ticket_playbook_parameters.go b/generated/restapi/operations/tickets/remove_ticket_playbook_parameters.go new file mode 100644 index 0000000..a7fe504 --- /dev/null +++ b/generated/restapi/operations/tickets/remove_ticket_playbook_parameters.go @@ -0,0 +1,113 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// RemoveTicketPlaybookEndpoint executes the core logic of the related +// route endpoint. +func RemoveTicketPlaybookEndpoint(handler func(ctx context.Context, params *RemoveTicketPlaybookParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewRemoveTicketPlaybookParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewRemoveTicketPlaybookParams creates a new RemoveTicketPlaybookParams object +// with the default values initialized. +func NewRemoveTicketPlaybookParams() *RemoveTicketPlaybookParams { + var () + return &RemoveTicketPlaybookParams{} +} + +// RemoveTicketPlaybookParams contains all the bound params for the remove ticket playbook operation +// typically these are obtained from a http.Request +// +// swagger:parameters removeTicketPlaybook +type RemoveTicketPlaybookParams struct { + + /*Ticket ID + Required: true + In: path + */ + ID int64 + /*Playbook ID + Required: true + In: path + */ + PlaybookID string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *RemoveTicketPlaybookParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + rPlaybookID := []string{ctx.Param("playbookID")} + if err := o.bindPlaybookID(rPlaybookID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *RemoveTicketPlaybookParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} + +func (o *RemoveTicketPlaybookParams) bindPlaybookID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.PlaybookID = raw + + return nil +} diff --git a/generated/restapi/operations/tickets/run_artifact_parameters.go b/generated/restapi/operations/tickets/run_artifact_parameters.go new file mode 100644 index 0000000..6a4cee4 --- /dev/null +++ b/generated/restapi/operations/tickets/run_artifact_parameters.go @@ -0,0 +1,134 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// RunArtifactEndpoint executes the core logic of the related +// route endpoint. +func RunArtifactEndpoint(handler func(ctx context.Context, params *RunArtifactParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewRunArtifactParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewRunArtifactParams creates a new RunArtifactParams object +// with the default values initialized. +func NewRunArtifactParams() *RunArtifactParams { + var () + return &RunArtifactParams{} +} + +// RunArtifactParams contains all the bound params for the run artifact operation +// typically these are obtained from a http.Request +// +// swagger:parameters runArtifact +type RunArtifactParams struct { + + /* + Required: true + In: path + */ + Automation string + /*Ticket ID + Required: true + In: path + */ + ID int64 + /* + Required: true + In: path + */ + Name string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *RunArtifactParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rAutomation := []string{ctx.Param("automation")} + if err := o.bindAutomation(rAutomation, true); err != nil { + res = append(res, err) + } + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + rName := []string{ctx.Param("name")} + if err := o.bindName(rName, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *RunArtifactParams) bindAutomation(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.Automation = raw + + return nil +} + +func (o *RunArtifactParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} + +func (o *RunArtifactParams) bindName(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.Name = raw + + return nil +} diff --git a/generated/restapi/operations/tickets/run_task_parameters.go b/generated/restapi/operations/tickets/run_task_parameters.go new file mode 100644 index 0000000..f16a10b --- /dev/null +++ b/generated/restapi/operations/tickets/run_task_parameters.go @@ -0,0 +1,134 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// RunTaskEndpoint executes the core logic of the related +// route endpoint. +func RunTaskEndpoint(handler func(ctx context.Context, params *RunTaskParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewRunTaskParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewRunTaskParams creates a new RunTaskParams object +// with the default values initialized. +func NewRunTaskParams() *RunTaskParams { + var () + return &RunTaskParams{} +} + +// RunTaskParams contains all the bound params for the run task operation +// typically these are obtained from a http.Request +// +// swagger:parameters runTask +type RunTaskParams struct { + + /*Ticket ID + Required: true + In: path + */ + ID int64 + /*Playbook ID + Required: true + In: path + */ + PlaybookID string + /*Task ID + Required: true + In: path + */ + TaskID string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *RunTaskParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + rPlaybookID := []string{ctx.Param("playbookID")} + if err := o.bindPlaybookID(rPlaybookID, true); err != nil { + res = append(res, err) + } + + rTaskID := []string{ctx.Param("taskID")} + if err := o.bindTaskID(rTaskID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *RunTaskParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} + +func (o *RunTaskParams) bindPlaybookID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.PlaybookID = raw + + return nil +} + +func (o *RunTaskParams) bindTaskID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.TaskID = raw + + return nil +} diff --git a/generated/restapi/operations/tickets/set_artifact_parameters.go b/generated/restapi/operations/tickets/set_artifact_parameters.go new file mode 100644 index 0000000..50c573f --- /dev/null +++ b/generated/restapi/operations/tickets/set_artifact_parameters.go @@ -0,0 +1,137 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// SetArtifactEndpoint executes the core logic of the related +// route endpoint. +func SetArtifactEndpoint(handler func(ctx context.Context, params *SetArtifactParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewSetArtifactParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewSetArtifactParams creates a new SetArtifactParams object +// with the default values initialized. +func NewSetArtifactParams() *SetArtifactParams { + var () + return &SetArtifactParams{} +} + +// SetArtifactParams contains all the bound params for the set artifact operation +// typically these are obtained from a http.Request +// +// swagger:parameters setArtifact +type SetArtifactParams struct { + + /* + Required: true + In: body + */ + Artifact *models.Artifact + /*Ticket ID + Required: true + In: path + */ + ID int64 + /* + Required: true + In: path + */ + Name string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *SetArtifactParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if runtime.HasBody(ctx.Request) { + var body models.Artifact + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("artifact", "body", "")) + } else { + res = append(res, errors.NewParseError("artifact", "body", "", err)) + } + + } else { + o.Artifact = &body + } + } else { + res = append(res, errors.Required("artifact", "body", "")) + } + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + rName := []string{ctx.Param("name")} + if err := o.bindName(rName, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *SetArtifactParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} + +func (o *SetArtifactParams) bindName(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.Name = raw + + return nil +} diff --git a/generated/restapi/operations/tickets/set_references_parameters.go b/generated/restapi/operations/tickets/set_references_parameters.go new file mode 100644 index 0000000..99d1206 --- /dev/null +++ b/generated/restapi/operations/tickets/set_references_parameters.go @@ -0,0 +1,116 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// SetReferencesEndpoint executes the core logic of the related +// route endpoint. +func SetReferencesEndpoint(handler func(ctx context.Context, params *SetReferencesParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewSetReferencesParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewSetReferencesParams creates a new SetReferencesParams object +// with the default values initialized. +func NewSetReferencesParams() *SetReferencesParams { + var () + return &SetReferencesParams{} +} + +// SetReferencesParams contains all the bound params for the set references operation +// typically these are obtained from a http.Request +// +// swagger:parameters setReferences +type SetReferencesParams struct { + + /*Ticket ID + Required: true + In: path + */ + ID int64 + /*All ticket references + Required: true + In: body + */ + References []*models.Reference +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *SetReferencesParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if runtime.HasBody(ctx.Request) { + var body []*models.Reference + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("references", "body", "")) + } else { + res = append(res, errors.NewParseError("references", "body", "", err)) + } + + } else { + o.References = body + } + } else { + res = append(res, errors.Required("references", "body", "")) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *SetReferencesParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} diff --git a/generated/restapi/operations/tickets/set_schema_parameters.go b/generated/restapi/operations/tickets/set_schema_parameters.go new file mode 100644 index 0000000..f93406d --- /dev/null +++ b/generated/restapi/operations/tickets/set_schema_parameters.go @@ -0,0 +1,106 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// SetSchemaEndpoint executes the core logic of the related +// route endpoint. +func SetSchemaEndpoint(handler func(ctx context.Context, params *SetSchemaParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewSetSchemaParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewSetSchemaParams creates a new SetSchemaParams object +// with the default values initialized. +func NewSetSchemaParams() *SetSchemaParams { + var () + return &SetSchemaParams{} +} + +// SetSchemaParams contains all the bound params for the set schema operation +// typically these are obtained from a http.Request +// +// swagger:parameters setSchema +type SetSchemaParams struct { + + /*Ticket ID + Required: true + In: path + */ + ID int64 + /*New ticket schema + In: body + */ + Schema string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *SetSchemaParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if runtime.HasBody(ctx.Request) { + var body string + if err := ctx.BindJSON(&body); err != nil { + res = append(res, errors.NewParseError("schema", "body", "", err)) + } else { + o.Schema = body + } + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *SetSchemaParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} diff --git a/generated/restapi/operations/tickets/set_task_parameters.go b/generated/restapi/operations/tickets/set_task_parameters.go new file mode 100644 index 0000000..3fd05ca --- /dev/null +++ b/generated/restapi/operations/tickets/set_task_parameters.go @@ -0,0 +1,158 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// SetTaskEndpoint executes the core logic of the related +// route endpoint. +func SetTaskEndpoint(handler func(ctx context.Context, params *SetTaskParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewSetTaskParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewSetTaskParams creates a new SetTaskParams object +// with the default values initialized. +func NewSetTaskParams() *SetTaskParams { + var () + return &SetTaskParams{} +} + +// SetTaskParams contains all the bound params for the set task operation +// typically these are obtained from a http.Request +// +// swagger:parameters setTask +type SetTaskParams struct { + + /*Ticket ID + Required: true + In: path + */ + ID int64 + /*Playbook ID + Required: true + In: path + */ + PlaybookID string + /*Task + Required: true + In: body + */ + Task *models.Task + /*Task ID + Required: true + In: path + */ + TaskID string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *SetTaskParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + rPlaybookID := []string{ctx.Param("playbookID")} + if err := o.bindPlaybookID(rPlaybookID, true); err != nil { + res = append(res, err) + } + + if runtime.HasBody(ctx.Request) { + var body models.Task + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("task", "body", "")) + } else { + res = append(res, errors.NewParseError("task", "body", "", err)) + } + + } else { + o.Task = &body + } + } else { + res = append(res, errors.Required("task", "body", "")) + } + + rTaskID := []string{ctx.Param("taskID")} + if err := o.bindTaskID(rTaskID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *SetTaskParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} + +func (o *SetTaskParams) bindPlaybookID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.PlaybookID = raw + + return nil +} + +func (o *SetTaskParams) bindTaskID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.TaskID = raw + + return nil +} diff --git a/generated/restapi/operations/tickets/unlink_ticket_parameters.go b/generated/restapi/operations/tickets/unlink_ticket_parameters.go new file mode 100644 index 0000000..fc3ff3a --- /dev/null +++ b/generated/restapi/operations/tickets/unlink_ticket_parameters.go @@ -0,0 +1,115 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// UnlinkTicketEndpoint executes the core logic of the related +// route endpoint. +func UnlinkTicketEndpoint(handler func(ctx context.Context, params *UnlinkTicketParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewUnlinkTicketParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewUnlinkTicketParams creates a new UnlinkTicketParams object +// with the default values initialized. +func NewUnlinkTicketParams() *UnlinkTicketParams { + var () + return &UnlinkTicketParams{} +} + +// UnlinkTicketParams contains all the bound params for the unlink ticket operation +// typically these are obtained from a http.Request +// +// swagger:parameters unlinkTicket +type UnlinkTicketParams struct { + + /*Ticket ID + Required: true + In: path + */ + ID int64 + /*Added ticket ID + Required: true + In: body + */ + LinkedID int64 +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *UnlinkTicketParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if runtime.HasBody(ctx.Request) { + var body int64 + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("linkedId", "body", "")) + } else { + res = append(res, errors.NewParseError("linkedId", "body", "", err)) + } + + } else { + o.LinkedID = body + } + } else { + res = append(res, errors.Required("linkedId", "body", "")) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *UnlinkTicketParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} diff --git a/generated/restapi/operations/tickets/update_ticket_parameters.go b/generated/restapi/operations/tickets/update_ticket_parameters.go new file mode 100644 index 0000000..ebd673f --- /dev/null +++ b/generated/restapi/operations/tickets/update_ticket_parameters.go @@ -0,0 +1,116 @@ +package tickets + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/swag" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// UpdateTicketEndpoint executes the core logic of the related +// route endpoint. +func UpdateTicketEndpoint(handler func(ctx context.Context, params *UpdateTicketParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewUpdateTicketParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewUpdateTicketParams creates a new UpdateTicketParams object +// with the default values initialized. +func NewUpdateTicketParams() *UpdateTicketParams { + var () + return &UpdateTicketParams{} +} + +// UpdateTicketParams contains all the bound params for the update ticket operation +// typically these are obtained from a http.Request +// +// swagger:parameters updateTicket +type UpdateTicketParams struct { + + /*Ticket ID + Required: true + In: path + */ + ID int64 + /*Updated ticket + Required: true + In: body + */ + Ticket *models.Ticket +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *UpdateTicketParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if runtime.HasBody(ctx.Request) { + var body models.Ticket + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("ticket", "body", "")) + } else { + res = append(res, errors.NewParseError("ticket", "body", "", err)) + } + + } else { + o.Ticket = &body + } + } else { + res = append(res, errors.Required("ticket", "body", "")) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *UpdateTicketParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("id", "path", "int64", raw) + } + o.ID = value + + return nil +} diff --git a/generated/restapi/operations/tickettypes/create_ticket_type_parameters.go b/generated/restapi/operations/tickettypes/create_ticket_type_parameters.go new file mode 100644 index 0000000..034d5ed --- /dev/null +++ b/generated/restapi/operations/tickettypes/create_ticket_type_parameters.go @@ -0,0 +1,90 @@ +package tickettypes + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// CreateTicketTypeEndpoint executes the core logic of the related +// route endpoint. +func CreateTicketTypeEndpoint(handler func(ctx context.Context, params *CreateTicketTypeParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewCreateTicketTypeParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewCreateTicketTypeParams creates a new CreateTicketTypeParams object +// with the default values initialized. +func NewCreateTicketTypeParams() *CreateTicketTypeParams { + var () + return &CreateTicketTypeParams{} +} + +// CreateTicketTypeParams contains all the bound params for the create ticket type operation +// typically these are obtained from a http.Request +// +// swagger:parameters createTicketType +type CreateTicketTypeParams struct { + + /*New tickettype + Required: true + In: body + */ + Tickettype *models.TicketTypeForm +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *CreateTicketTypeParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if runtime.HasBody(ctx.Request) { + var body models.TicketTypeForm + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("tickettype", "body", "")) + } else { + res = append(res, errors.NewParseError("tickettype", "body", "", err)) + } + + } else { + o.Tickettype = &body + } + } else { + res = append(res, errors.Required("tickettype", "body", "")) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/tickettypes/delete_ticket_type_parameters.go b/generated/restapi/operations/tickettypes/delete_ticket_type_parameters.go new file mode 100644 index 0000000..98e677d --- /dev/null +++ b/generated/restapi/operations/tickettypes/delete_ticket_type_parameters.go @@ -0,0 +1,87 @@ +package tickettypes + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// DeleteTicketTypeEndpoint executes the core logic of the related +// route endpoint. +func DeleteTicketTypeEndpoint(handler func(ctx context.Context, params *DeleteTicketTypeParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewDeleteTicketTypeParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewDeleteTicketTypeParams creates a new DeleteTicketTypeParams object +// with the default values initialized. +func NewDeleteTicketTypeParams() *DeleteTicketTypeParams { + var () + return &DeleteTicketTypeParams{} +} + +// DeleteTicketTypeParams contains all the bound params for the delete ticket type operation +// typically these are obtained from a http.Request +// +// swagger:parameters deleteTicketType +type DeleteTicketTypeParams struct { + + /*TicketType ID + Required: true + In: path + */ + ID string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *DeleteTicketTypeParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *DeleteTicketTypeParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.ID = raw + + return nil +} diff --git a/generated/restapi/operations/tickettypes/get_ticket_type_parameters.go b/generated/restapi/operations/tickettypes/get_ticket_type_parameters.go new file mode 100644 index 0000000..70ad526 --- /dev/null +++ b/generated/restapi/operations/tickettypes/get_ticket_type_parameters.go @@ -0,0 +1,87 @@ +package tickettypes + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// GetTicketTypeEndpoint executes the core logic of the related +// route endpoint. +func GetTicketTypeEndpoint(handler func(ctx context.Context, params *GetTicketTypeParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewGetTicketTypeParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewGetTicketTypeParams creates a new GetTicketTypeParams object +// with the default values initialized. +func NewGetTicketTypeParams() *GetTicketTypeParams { + var () + return &GetTicketTypeParams{} +} + +// GetTicketTypeParams contains all the bound params for the get ticket type operation +// typically these are obtained from a http.Request +// +// swagger:parameters getTicketType +type GetTicketTypeParams struct { + + /*TicketType ID + Required: true + In: path + */ + ID string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *GetTicketTypeParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *GetTicketTypeParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.ID = raw + + return nil +} diff --git a/generated/restapi/operations/tickettypes/list_ticket_types_parameters.go b/generated/restapi/operations/tickettypes/list_ticket_types_parameters.go new file mode 100644 index 0000000..607dcc3 --- /dev/null +++ b/generated/restapi/operations/tickettypes/list_ticket_types_parameters.go @@ -0,0 +1,55 @@ +package tickettypes + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// ListTicketTypesEndpoint executes the core logic of the related +// route endpoint. +func ListTicketTypesEndpoint(handler func(ctx context.Context) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + resp := handler(ctx) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewListTicketTypesParams creates a new ListTicketTypesParams object +// with the default values initialized. +func NewListTicketTypesParams() *ListTicketTypesParams { + var () + return &ListTicketTypesParams{} +} + +// ListTicketTypesParams contains all the bound params for the list ticket types operation +// typically these are obtained from a http.Request +// +// swagger:parameters listTicketTypes +type ListTicketTypesParams struct { +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *ListTicketTypesParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/tickettypes/update_ticket_type_parameters.go b/generated/restapi/operations/tickettypes/update_ticket_type_parameters.go new file mode 100644 index 0000000..9c7b323 --- /dev/null +++ b/generated/restapi/operations/tickettypes/update_ticket_type_parameters.go @@ -0,0 +1,111 @@ +package tickettypes + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// UpdateTicketTypeEndpoint executes the core logic of the related +// route endpoint. +func UpdateTicketTypeEndpoint(handler func(ctx context.Context, params *UpdateTicketTypeParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewUpdateTicketTypeParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewUpdateTicketTypeParams creates a new UpdateTicketTypeParams object +// with the default values initialized. +func NewUpdateTicketTypeParams() *UpdateTicketTypeParams { + var () + return &UpdateTicketTypeParams{} +} + +// UpdateTicketTypeParams contains all the bound params for the update ticket type operation +// typically these are obtained from a http.Request +// +// swagger:parameters updateTicketType +type UpdateTicketTypeParams struct { + + /*TicketType ID + Required: true + In: path + */ + ID string + /*TicketType object that needs to be added + Required: true + In: body + */ + Tickettype *models.TicketTypeForm +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *UpdateTicketTypeParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if runtime.HasBody(ctx.Request) { + var body models.TicketTypeForm + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("tickettype", "body", "")) + } else { + res = append(res, errors.NewParseError("tickettype", "body", "", err)) + } + + } else { + o.Tickettype = &body + } + } else { + res = append(res, errors.Required("tickettype", "body", "")) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *UpdateTicketTypeParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.ID = raw + + return nil +} diff --git a/generated/restapi/operations/userdata/current_user_data_parameters.go b/generated/restapi/operations/userdata/current_user_data_parameters.go new file mode 100644 index 0000000..800485a --- /dev/null +++ b/generated/restapi/operations/userdata/current_user_data_parameters.go @@ -0,0 +1,55 @@ +package userdata + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// CurrentUserDataEndpoint executes the core logic of the related +// route endpoint. +func CurrentUserDataEndpoint(handler func(ctx context.Context) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + resp := handler(ctx) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewCurrentUserDataParams creates a new CurrentUserDataParams object +// with the default values initialized. +func NewCurrentUserDataParams() *CurrentUserDataParams { + var () + return &CurrentUserDataParams{} +} + +// CurrentUserDataParams contains all the bound params for the current user data operation +// typically these are obtained from a http.Request +// +// swagger:parameters currentUserData +type CurrentUserDataParams struct { +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *CurrentUserDataParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/userdata/get_user_data_parameters.go b/generated/restapi/operations/userdata/get_user_data_parameters.go new file mode 100644 index 0000000..c255598 --- /dev/null +++ b/generated/restapi/operations/userdata/get_user_data_parameters.go @@ -0,0 +1,87 @@ +package userdata + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// GetUserDataEndpoint executes the core logic of the related +// route endpoint. +func GetUserDataEndpoint(handler func(ctx context.Context, params *GetUserDataParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewGetUserDataParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewGetUserDataParams creates a new GetUserDataParams object +// with the default values initialized. +func NewGetUserDataParams() *GetUserDataParams { + var () + return &GetUserDataParams{} +} + +// GetUserDataParams contains all the bound params for the get user data operation +// typically these are obtained from a http.Request +// +// swagger:parameters getUserData +type GetUserDataParams struct { + + /*User Data ID + Required: true + In: path + */ + ID string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *GetUserDataParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *GetUserDataParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.ID = raw + + return nil +} diff --git a/generated/restapi/operations/userdata/list_user_data_parameters.go b/generated/restapi/operations/userdata/list_user_data_parameters.go new file mode 100644 index 0000000..fff2a0d --- /dev/null +++ b/generated/restapi/operations/userdata/list_user_data_parameters.go @@ -0,0 +1,55 @@ +package userdata + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// ListUserDataEndpoint executes the core logic of the related +// route endpoint. +func ListUserDataEndpoint(handler func(ctx context.Context) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + resp := handler(ctx) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewListUserDataParams creates a new ListUserDataParams object +// with the default values initialized. +func NewListUserDataParams() *ListUserDataParams { + var () + return &ListUserDataParams{} +} + +// ListUserDataParams contains all the bound params for the list user data operation +// typically these are obtained from a http.Request +// +// swagger:parameters listUserData +type ListUserDataParams struct { +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *ListUserDataParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/userdata/update_current_user_data_parameters.go b/generated/restapi/operations/userdata/update_current_user_data_parameters.go new file mode 100644 index 0000000..2b926ba --- /dev/null +++ b/generated/restapi/operations/userdata/update_current_user_data_parameters.go @@ -0,0 +1,90 @@ +package userdata + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// UpdateCurrentUserDataEndpoint executes the core logic of the related +// route endpoint. +func UpdateCurrentUserDataEndpoint(handler func(ctx context.Context, params *UpdateCurrentUserDataParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewUpdateCurrentUserDataParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewUpdateCurrentUserDataParams creates a new UpdateCurrentUserDataParams object +// with the default values initialized. +func NewUpdateCurrentUserDataParams() *UpdateCurrentUserDataParams { + var () + return &UpdateCurrentUserDataParams{} +} + +// UpdateCurrentUserDataParams contains all the bound params for the update current user data operation +// typically these are obtained from a http.Request +// +// swagger:parameters updateCurrentUserData +type UpdateCurrentUserDataParams struct { + + /*User data object that needs to be added + Required: true + In: body + */ + Userdata *models.UserData +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *UpdateCurrentUserDataParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if runtime.HasBody(ctx.Request) { + var body models.UserData + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("userdata", "body", "")) + } else { + res = append(res, errors.NewParseError("userdata", "body", "", err)) + } + + } else { + o.Userdata = &body + } + } else { + res = append(res, errors.Required("userdata", "body", "")) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/userdata/update_user_data_parameters.go b/generated/restapi/operations/userdata/update_user_data_parameters.go new file mode 100644 index 0000000..4212316 --- /dev/null +++ b/generated/restapi/operations/userdata/update_user_data_parameters.go @@ -0,0 +1,111 @@ +package userdata + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// UpdateUserDataEndpoint executes the core logic of the related +// route endpoint. +func UpdateUserDataEndpoint(handler func(ctx context.Context, params *UpdateUserDataParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewUpdateUserDataParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewUpdateUserDataParams creates a new UpdateUserDataParams object +// with the default values initialized. +func NewUpdateUserDataParams() *UpdateUserDataParams { + var () + return &UpdateUserDataParams{} +} + +// UpdateUserDataParams contains all the bound params for the update user data operation +// typically these are obtained from a http.Request +// +// swagger:parameters updateUserData +type UpdateUserDataParams struct { + + /*User Data ID + Required: true + In: path + */ + ID string + /*User data object that needs to be added + Required: true + In: body + */ + Userdata *models.UserData +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *UpdateUserDataParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if runtime.HasBody(ctx.Request) { + var body models.UserData + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("userdata", "body", "")) + } else { + res = append(res, errors.NewParseError("userdata", "body", "", err)) + } + + } else { + o.Userdata = &body + } + } else { + res = append(res, errors.Required("userdata", "body", "")) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *UpdateUserDataParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.ID = raw + + return nil +} diff --git a/generated/restapi/operations/users/create_user_parameters.go b/generated/restapi/operations/users/create_user_parameters.go new file mode 100644 index 0000000..d345bae --- /dev/null +++ b/generated/restapi/operations/users/create_user_parameters.go @@ -0,0 +1,90 @@ +package users + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// CreateUserEndpoint executes the core logic of the related +// route endpoint. +func CreateUserEndpoint(handler func(ctx context.Context, params *CreateUserParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewCreateUserParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewCreateUserParams creates a new CreateUserParams object +// with the default values initialized. +func NewCreateUserParams() *CreateUserParams { + var () + return &CreateUserParams{} +} + +// CreateUserParams contains all the bound params for the create user operation +// typically these are obtained from a http.Request +// +// swagger:parameters createUser +type CreateUserParams struct { + + /*user object that needs to be added + Required: true + In: body + */ + User *models.UserForm +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *CreateUserParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if runtime.HasBody(ctx.Request) { + var body models.UserForm + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("user", "body", "")) + } else { + res = append(res, errors.NewParseError("user", "body", "", err)) + } + + } else { + o.User = &body + } + } else { + res = append(res, errors.Required("user", "body", "")) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/users/current_user_parameters.go b/generated/restapi/operations/users/current_user_parameters.go new file mode 100644 index 0000000..28420e0 --- /dev/null +++ b/generated/restapi/operations/users/current_user_parameters.go @@ -0,0 +1,55 @@ +package users + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// CurrentUserEndpoint executes the core logic of the related +// route endpoint. +func CurrentUserEndpoint(handler func(ctx context.Context) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + resp := handler(ctx) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewCurrentUserParams creates a new CurrentUserParams object +// with the default values initialized. +func NewCurrentUserParams() *CurrentUserParams { + var () + return &CurrentUserParams{} +} + +// CurrentUserParams contains all the bound params for the current user operation +// typically these are obtained from a http.Request +// +// swagger:parameters currentUser +type CurrentUserParams struct { +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *CurrentUserParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/users/delete_user_parameters.go b/generated/restapi/operations/users/delete_user_parameters.go new file mode 100644 index 0000000..3c7ccea --- /dev/null +++ b/generated/restapi/operations/users/delete_user_parameters.go @@ -0,0 +1,87 @@ +package users + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// DeleteUserEndpoint executes the core logic of the related +// route endpoint. +func DeleteUserEndpoint(handler func(ctx context.Context, params *DeleteUserParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewDeleteUserParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewDeleteUserParams creates a new DeleteUserParams object +// with the default values initialized. +func NewDeleteUserParams() *DeleteUserParams { + var () + return &DeleteUserParams{} +} + +// DeleteUserParams contains all the bound params for the delete user operation +// typically these are obtained from a http.Request +// +// swagger:parameters deleteUser +type DeleteUserParams struct { + + /*user ID + Required: true + In: path + */ + ID string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *DeleteUserParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *DeleteUserParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.ID = raw + + return nil +} diff --git a/generated/restapi/operations/users/get_user_parameters.go b/generated/restapi/operations/users/get_user_parameters.go new file mode 100644 index 0000000..2f3230e --- /dev/null +++ b/generated/restapi/operations/users/get_user_parameters.go @@ -0,0 +1,87 @@ +package users + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// GetUserEndpoint executes the core logic of the related +// route endpoint. +func GetUserEndpoint(handler func(ctx context.Context, params *GetUserParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewGetUserParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewGetUserParams creates a new GetUserParams object +// with the default values initialized. +func NewGetUserParams() *GetUserParams { + var () + return &GetUserParams{} +} + +// GetUserParams contains all the bound params for the get user operation +// typically these are obtained from a http.Request +// +// swagger:parameters getUser +type GetUserParams struct { + + /*user ID + Required: true + In: path + */ + ID string +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *GetUserParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *GetUserParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.ID = raw + + return nil +} diff --git a/generated/restapi/operations/users/list_users_parameters.go b/generated/restapi/operations/users/list_users_parameters.go new file mode 100644 index 0000000..b6c664b --- /dev/null +++ b/generated/restapi/operations/users/list_users_parameters.go @@ -0,0 +1,55 @@ +package users + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// ListUsersEndpoint executes the core logic of the related +// route endpoint. +func ListUsersEndpoint(handler func(ctx context.Context) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + resp := handler(ctx) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewListUsersParams creates a new ListUsersParams object +// with the default values initialized. +func NewListUsersParams() *ListUsersParams { + var () + return &ListUsersParams{} +} + +// ListUsersParams contains all the bound params for the list users operation +// typically these are obtained from a http.Request +// +// swagger:parameters listUsers +type ListUsersParams struct { +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *ListUsersParams) ReadRequest(ctx *gin.Context) error { + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/generated/restapi/operations/users/update_user_parameters.go b/generated/restapi/operations/users/update_user_parameters.go new file mode 100644 index 0000000..9ad2352 --- /dev/null +++ b/generated/restapi/operations/users/update_user_parameters.go @@ -0,0 +1,111 @@ +package users + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "io" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// UpdateUserEndpoint executes the core logic of the related +// route endpoint. +func UpdateUserEndpoint(handler func(ctx context.Context, params *UpdateUserParams) *api.Response) gin.HandlerFunc { + return func(ctx *gin.Context) { + + // generate params from request + params := NewUpdateUserParams() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + + resp := handler(ctx, params) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// NewUpdateUserParams creates a new UpdateUserParams object +// with the default values initialized. +func NewUpdateUserParams() *UpdateUserParams { + var () + return &UpdateUserParams{} +} + +// UpdateUserParams contains all the bound params for the update user operation +// typically these are obtained from a http.Request +// +// swagger:parameters updateUser +type UpdateUserParams struct { + + /*Template ID + Required: true + In: path + */ + ID string + /*user object that needs to be added + Required: true + In: body + */ + User *models.UserForm +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func (o *UpdateUserParams) ReadRequest(ctx *gin.Context) error { + var res []error + + rID := []string{ctx.Param("id")} + if err := o.bindID(rID, true); err != nil { + res = append(res, err) + } + + if runtime.HasBody(ctx.Request) { + var body models.UserForm + if err := ctx.BindJSON(&body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("user", "body", "")) + } else { + res = append(res, errors.NewParseError("user", "body", "", err)) + } + + } else { + o.User = &body + } + } else { + res = append(res, errors.Required("user", "body", "")) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *UpdateUserParams) bindID(rawData []string, hasKey bool) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + o.ID = raw + + return nil +} diff --git a/generated/test/api_server_test.go b/generated/test/api_server_test.go new file mode 100644 index 0000000..62dad9c --- /dev/null +++ b/generated/test/api_server_test.go @@ -0,0 +1,675 @@ +package test + +import ( + "bytes" + "encoding/json" + "io" + "net/http" + "net/http/httptest" + "testing" + + "github.com/gin-gonic/gin" + "github.com/stretchr/testify/assert" + "github.com/tidwall/gjson" + "github.com/tidwall/sjson" + + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/test" +) + +func TestService(t *testing.T) { + gin.SetMode(gin.TestMode) + + type args struct { + method string + url string + data interface{} + } + type want struct { + status int + body interface{} + } + tests := []struct { + name string + args args + want want + }{ + + { + name: "AddArtifact", + args: args{method: "POST", url: "/api/tickets/8123/artifacts", data: map[string]interface{}{"name": "2.2.2.2"}}, + want: want{ + status: 200, + body: map[string]interface{}{"artifacts": []interface{}{map[string]interface{}{"name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", "status": "unknown"}, map[string]interface{}{"name": "http://www.customerviral.io/scalable/vertical/killer", "status": "clean"}, map[string]interface{}{"name": "leadreintermediate.io", "status": "malicious"}, map[string]interface{}{"name": "2.2.2.2", "status": "unknown", "type": "ip"}}, "created": "2021-10-02T18:04:59.078206+02:00", "id": 8123, "modified": "2021-10-02T18:04:59.078206+02:00", "name": "live zebra", "owner": "demo", "playbooks": map[string]interface{}{"phishing": map[string]interface{}{"name": "Phishing", "tasks": map[string]interface{}{"block-iocs": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Block IOCs", "order": 6, "type": "task"}, "block-sender": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Block sender", "next": map[string]interface{}{"extract-iocs": ""}, "order": 3, "type": "task"}, "board": map[string]interface{}{"active": true, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Board Involvement?", "next": map[string]interface{}{"escalate": "boardInvolved == true", "mail-available": "boardInvolved == false"}, "order": 0, "schema": map[string]interface{}{"properties": map[string]interface{}{"boardInvolved": map[string]interface{}{"default": false, "title": "A board member is involved.", "type": "boolean"}}, "required": []interface{}{"boardInvolved"}, "title": "Board Involvement?", "type": "object"}, "type": "input"}, "escalate": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Escalate to CISO", "order": 1, "type": "task"}, "extract-iocs": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Extract IOCs", "next": map[string]interface{}{"block-iocs": ""}, "order": 5, "schema": map[string]interface{}{"properties": map[string]interface{}{"iocs": map[string]interface{}{"items": map[string]interface{}{"type": "string"}, "title": "IOCs", "type": "array"}}, "title": "Extract IOCs", "type": "object"}, "type": "input"}, "mail-available": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Mail available", "next": map[string]interface{}{"block-sender": "schemaKey == 'yes'", "extract-iocs": "schemaKey == 'yes'", "search-email-gateway": "schemaKey == 'no'"}, "order": 2, "schema": map[string]interface{}{"oneOf": []interface{}{map[string]interface{}{"properties": map[string]interface{}{"mail": map[string]interface{}{"title": "Mail", "type": "string", "x-display": "textarea"}, "schemaKey": map[string]interface{}{"const": "yes", "type": "string"}}, "required": []interface{}{"mail"}, "title": "Yes"}, map[string]interface{}{"properties": map[string]interface{}{"schemaKey": map[string]interface{}{"const": "no", "type": "string"}}, "title": "No"}}, "title": "Mail available", "type": "object"}, "type": "input"}, "search-email-gateway": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Search email gateway", "next": map[string]interface{}{"extract-iocs": ""}, "order": 4, "type": "task"}}}}, "references": []interface{}{map[string]interface{}{"href": "https://www.leadmaximize.net/e-services/back-end", "name": "performance"}, map[string]interface{}{"href": "http://www.corporateinteractive.name/rich", "name": "autumn"}, map[string]interface{}{"href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", "name": "suggest"}}, "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", "status": "closed", "type": "incident"}, + }, + }, + { + name: "AddComment", + args: args{method: "POST", url: "/api/tickets/8125/comments", data: map[string]interface{}{"message": "My first comment"}}, + want: want{ + status: 200, + body: map[string]interface{}{"comments": []interface{}{map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "creator": "bob", "message": "My first comment"}}, "created": "2021-10-02T18:04:59.078186+02:00", "id": 8125, "modified": "2021-10-02T18:04:59.078186+02:00", "name": "phishing from selenafadel@von.com detected", "owner": "demo", "references": []interface{}{map[string]interface{}{"href": "https://www.seniorleading-edge.name/users/efficient", "name": "recovery"}, map[string]interface{}{"href": "http://www.dynamicseamless.com/clicks-and-mortar", "name": "force"}, map[string]interface{}{"href": "http://www.leadscalable.biz/envisioneer", "name": "fund"}}, "schema": "{}", "status": "closed", "tickets": []interface{}{map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "id": 8126, "modified": "2021-10-02T18:04:59.078186+02:00", "name": "Surfaceintroduce virus detected", "owner": "demo", "references": []interface{}{map[string]interface{}{"href": "http://www.centralworld-class.io/synthesize", "name": "university"}, map[string]interface{}{"href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", "name": "goal"}, map[string]interface{}{"href": "http://www.chiefsyndicate.io/action-items", "name": "unemployment"}}, "schema": "{}", "status": "closed", "type": "alert"}}, "type": "alert"}, + }, + }, + { + name: "AddTicketPlaybook", + args: args{method: "POST", url: "/api/tickets/8125/playbooks", data: map[string]interface{}{"yaml": "name: Simple\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n"}}, + want: want{ + status: 200, + body: map[string]interface{}{"created": "1985-04-12T23:20:50.52Z", "id": 8125, "modified": "1985-04-12T23:20:50.52Z", "name": "phishing from selenafadel@von.com detected", "owner": "demo", "playbooks": map[string]interface{}{"simple": map[string]interface{}{"name": "Simple", "tasks": map[string]interface{}{"escalate": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Escalate to malware team", "order": 2, "type": "task"}, "hash": map[string]interface{}{"active": false, "automation": "hash.sha1", "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Hash the malware", "next": map[string]interface{}{"escalate": ""}, "order": 1, "payload": map[string]interface{}{"default": "playbook.tasks['input'].data['malware']"}, "type": "automation"}, "input": map[string]interface{}{"active": true, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Upload malware if possible", "next": map[string]interface{}{"hash": "malware != ''"}, "order": 0, "schema": map[string]interface{}{"properties": map[string]interface{}{"malware": map[string]interface{}{"default": "", "title": "Select malware", "type": "string"}}, "title": "Malware", "type": "object"}, "type": "input"}}}}, "references": []interface{}{map[string]interface{}{"href": "https://www.seniorleading-edge.name/users/efficient", "name": "recovery"}, map[string]interface{}{"href": "http://www.dynamicseamless.com/clicks-and-mortar", "name": "force"}, map[string]interface{}{"href": "http://www.leadscalable.biz/envisioneer", "name": "fund"}}, "schema": "{}", "status": "closed", "tickets": []interface{}{map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "id": 8126, "modified": "2021-10-02T18:04:59.078186+02:00", "name": "Surfaceintroduce virus detected", "owner": "demo", "references": []interface{}{map[string]interface{}{"href": "http://www.centralworld-class.io/synthesize", "name": "university"}, map[string]interface{}{"href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", "name": "goal"}, map[string]interface{}{"href": "http://www.chiefsyndicate.io/action-items", "name": "unemployment"}}, "schema": "{}", "status": "closed", "type": "alert"}}, "type": "alert"}, + }, + }, + { + name: "CompleteTask", + args: args{method: "PUT", url: "/api/tickets/8123/playbooks/phishing/task/board/complete", data: map[string]interface{}{"boardInvolved": true}}, + want: want{ + status: 200, + body: map[string]interface{}{"artifacts": []interface{}{map[string]interface{}{"name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", "status": "unknown"}, map[string]interface{}{"name": "http://www.customerviral.io/scalable/vertical/killer", "status": "clean"}, map[string]interface{}{"name": "leadreintermediate.io", "status": "malicious"}}, "created": "2021-10-02T18:04:59.078206+02:00", "id": 8123, "modified": "2021-10-02T18:04:59.078206+02:00", "name": "live zebra", "owner": "demo", "playbooks": map[string]interface{}{"phishing": map[string]interface{}{"name": "Phishing", "tasks": map[string]interface{}{"block-iocs": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Block IOCs", "order": 6, "type": "task"}, "block-sender": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Block sender", "next": map[string]interface{}{"extract-iocs": ""}, "order": 3, "type": "task"}, "board": map[string]interface{}{"active": false, "closed": "2021-10-02T18:04:59.078186+02:00", "created": "2021-10-02T18:04:59.078186+02:00", "data": map[string]interface{}{"boardInvolved": true}, "done": true, "name": "Board Involvement?", "next": map[string]interface{}{"escalate": "boardInvolved == true", "mail-available": "boardInvolved == false"}, "order": 0, "schema": map[string]interface{}{"properties": map[string]interface{}{"boardInvolved": map[string]interface{}{"default": false, "title": "A board member is involved.", "type": "boolean"}}, "required": []interface{}{"boardInvolved"}, "title": "Board Involvement?", "type": "object"}, "type": "input"}, "escalate": map[string]interface{}{"active": true, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Escalate to CISO", "order": 1, "type": "task"}, "extract-iocs": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Extract IOCs", "next": map[string]interface{}{"block-iocs": ""}, "order": 5, "schema": map[string]interface{}{"properties": map[string]interface{}{"iocs": map[string]interface{}{"items": map[string]interface{}{"type": "string"}, "title": "IOCs", "type": "array"}}, "title": "Extract IOCs", "type": "object"}, "type": "input"}, "mail-available": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Mail available", "next": map[string]interface{}{"block-sender": "schemaKey == 'yes'", "extract-iocs": "schemaKey == 'yes'", "search-email-gateway": "schemaKey == 'no'"}, "order": 2, "schema": map[string]interface{}{"oneOf": []interface{}{map[string]interface{}{"properties": map[string]interface{}{"mail": map[string]interface{}{"title": "Mail", "type": "string", "x-display": "textarea"}, "schemaKey": map[string]interface{}{"const": "yes", "type": "string"}}, "required": []interface{}{"mail"}, "title": "Yes"}, map[string]interface{}{"properties": map[string]interface{}{"schemaKey": map[string]interface{}{"const": "no", "type": "string"}}, "title": "No"}}, "title": "Mail available", "type": "object"}, "type": "input"}, "search-email-gateway": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Search email gateway", "next": map[string]interface{}{"extract-iocs": ""}, "order": 4, "type": "task"}}}}, "references": []interface{}{map[string]interface{}{"href": "https://www.leadmaximize.net/e-services/back-end", "name": "performance"}, map[string]interface{}{"href": "http://www.corporateinteractive.name/rich", "name": "autumn"}, map[string]interface{}{"href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", "name": "suggest"}}, "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", "status": "closed", "type": "incident"}, + }, + }, + { + name: "CreateAutomation", + args: args{method: "POST", url: "/api/automations", data: map[string]interface{}{"id": "hash-sha-256", "image": "docker.io/python:3", "script": "import sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha256 = hashlib.sha256(msg['payload']['default'].encode('utf-8'))\n return {'hash': sha256.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", "type": []interface{}{"global"}}}, + want: want{ + status: 200, + body: map[string]interface{}{"id": "hash-sha-256", "image": "docker.io/python:3", "script": "import sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha256 = hashlib.sha256(msg['payload']['default'].encode('utf-8'))\n return {'hash': sha256.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", "type": []interface{}{"global"}}, + }, + }, + { + name: "CreatePlaybook", + args: args{method: "POST", url: "/api/playbooks", data: map[string]interface{}{"yaml": "name: Simple2\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n"}}, + want: want{ + status: 200, + body: map[string]interface{}{"id": "simple-2", "name": "Simple2", "yaml": "name: Simple2\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n"}, + }, + }, + { + name: "CreateTemplate", + args: args{method: "POST", url: "/api/templates", data: map[string]interface{}{"name": "My Template", "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n"}}, + want: want{ + status: 200, + body: map[string]interface{}{"id": "my-template", "name": "My Template", "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n"}, + }, + }, + { + name: "CreateTicket", + args: args{method: "POST", url: "/api/tickets", data: map[string]interface{}{"id": 123, "name": "Wannacry infection", "owner": "bob", "status": "open", "type": "incident"}}, + want: want{ + status: 200, + body: map[string]interface{}{"created": "1985-04-12T23:20:50.52Z", "id": 123, "modified": "1985-04-12T23:20:50.52Z", "name": "Wannacry infection", "owner": "bob", "schema": "{}", "status": "open", "type": "incident"}, + }, + }, + { + name: "CreateTicketBatch", + args: args{method: "POST", url: "/api/tickets/batch", data: []interface{}{map[string]interface{}{"id": 123, "name": "Wannacry infection", "owner": "bob", "status": "open", "type": "incident"}}}, + want: want{ + status: 204, + body: nil, + }, + }, + { + name: "CreateTicketType", + args: args{method: "POST", url: "/api/tickettypes", data: map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-newspaper-variant-outline", "name": "TI Tickets"}}, + want: want{ + status: 200, + body: map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-newspaper-variant-outline", "id": "ti-tickets", "name": "TI Tickets"}, + }, + }, + { + name: "CreateUser", + args: args{method: "POST", url: "/api/users", data: map[string]interface{}{"id": "syncscript", "roles": []interface{}{"analyst"}}}, + want: want{ + status: 200, + body: map[string]interface{}{"blocked": false, "id": "syncscript", "roles": []interface{}{"analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read"}, "secret": "v39bOuobnlEljfWzjAgoKzhmnh1xSMxH"}, + }, + }, + { + name: "CurrentUser", + args: args{method: "GET", url: "/api/currentuser"}, + want: want{ + status: 200, + body: map[string]interface{}{"apikey": false, "blocked": false, "id": "bob", "roles": []interface{}{"admin:backup:read", "admin:backup:restore", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write"}}, + }, + }, + { + name: "CurrentUserData", + args: args{method: "GET", url: "/api/currentuserdata"}, + want: want{ + status: 200, + body: map[string]interface{}{"email": "bob@example.org", "id": "bob", "name": "Bob Bad"}, + }, + }, + { + name: "DeleteAutomation", + args: args{method: "DELETE", url: "/api/automations/hash.sha1"}, + want: want{ + status: 204, + body: nil, + }, + }, + { + name: "DeletePlaybook", + args: args{method: "DELETE", url: "/api/playbooks/simple"}, + want: want{ + status: 204, + body: nil, + }, + }, + { + name: "DeleteTemplate", + args: args{method: "DELETE", url: "/api/templates/default"}, + want: want{ + status: 204, + body: nil, + }, + }, + { + name: "DeleteTicket", + args: args{method: "DELETE", url: "/api/tickets/8125"}, + want: want{ + status: 204, + body: nil, + }, + }, + { + name: "DeleteTicketType", + args: args{method: "DELETE", url: "/api/tickettypes/alert"}, + want: want{ + status: 204, + body: nil, + }, + }, + { + name: "DeleteUser", + args: args{method: "DELETE", url: "/api/users/script"}, + want: want{ + status: 204, + body: nil, + }, + }, + { + name: "EnrichArtifact", + args: args{method: "POST", url: "/api/tickets/8123/artifacts/leadreintermediate.io/enrich", data: map[string]interface{}{"data": map[string]interface{}{"hash": "b7a067a742c20d07a7456646de89bc2d408a1153"}, "name": "hash.sha1"}}, + want: want{ + status: 200, + body: map[string]interface{}{"artifacts": []interface{}{map[string]interface{}{"name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", "status": "unknown"}, map[string]interface{}{"name": "http://www.customerviral.io/scalable/vertical/killer", "status": "clean"}, map[string]interface{}{"enrichments": map[string]interface{}{"hash.sha1": map[string]interface{}{"created": "2021-10-03T18:44:06.488923+02:00", "data": map[string]interface{}{"hash": "b7a067a742c20d07a7456646de89bc2d408a1153"}, "name": "hash.sha1"}}, "name": "leadreintermediate.io", "status": "malicious"}}, "created": "2021-10-02T18:04:59.078206+02:00", "id": 8123, "modified": "2021-10-02T18:04:59.078206+02:00", "name": "live zebra", "owner": "demo", "playbooks": map[string]interface{}{"phishing": map[string]interface{}{"name": "Phishing", "tasks": map[string]interface{}{"block-iocs": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Block IOCs", "order": 6, "type": "task"}, "block-sender": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Block sender", "next": map[string]interface{}{"extract-iocs": ""}, "order": 3, "type": "task"}, "board": map[string]interface{}{"active": true, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Board Involvement?", "next": map[string]interface{}{"escalate": "boardInvolved == true", "mail-available": "boardInvolved == false"}, "order": 0, "schema": map[string]interface{}{"properties": map[string]interface{}{"boardInvolved": map[string]interface{}{"default": false, "title": "A board member is involved.", "type": "boolean"}}, "required": []interface{}{"boardInvolved"}, "title": "Board Involvement?", "type": "object"}, "type": "input"}, "escalate": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Escalate to CISO", "order": 1, "type": "task"}, "extract-iocs": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Extract IOCs", "next": map[string]interface{}{"block-iocs": ""}, "order": 5, "schema": map[string]interface{}{"properties": map[string]interface{}{"iocs": map[string]interface{}{"items": map[string]interface{}{"type": "string"}, "title": "IOCs", "type": "array"}}, "title": "Extract IOCs", "type": "object"}, "type": "input"}, "mail-available": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Mail available", "next": map[string]interface{}{"block-sender": "schemaKey == 'yes'", "extract-iocs": "schemaKey == 'yes'", "search-email-gateway": "schemaKey == 'no'"}, "order": 2, "schema": map[string]interface{}{"oneOf": []interface{}{map[string]interface{}{"properties": map[string]interface{}{"mail": map[string]interface{}{"title": "Mail", "type": "string", "x-display": "textarea"}, "schemaKey": map[string]interface{}{"const": "yes", "type": "string"}}, "required": []interface{}{"mail"}, "title": "Yes"}, map[string]interface{}{"properties": map[string]interface{}{"schemaKey": map[string]interface{}{"const": "no", "type": "string"}}, "title": "No"}}, "title": "Mail available", "type": "object"}, "type": "input"}, "search-email-gateway": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Search email gateway", "next": map[string]interface{}{"extract-iocs": ""}, "order": 4, "type": "task"}}}}, "references": []interface{}{map[string]interface{}{"href": "https://www.leadmaximize.net/e-services/back-end", "name": "performance"}, map[string]interface{}{"href": "http://www.corporateinteractive.name/rich", "name": "autumn"}, map[string]interface{}{"href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", "name": "suggest"}}, "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", "status": "closed", "type": "incident"}, + }, + }, + { + name: "GetArtifact", + args: args{method: "GET", url: "/api/tickets/8123/artifacts/leadreintermediate.io"}, + want: want{ + status: 200, + body: map[string]interface{}{"name": "leadreintermediate.io", "status": "malicious"}, + }, + }, + { + name: "GetAutomation", + args: args{method: "GET", url: "/api/automations/hash.sha1"}, + want: want{ + status: 200, + body: map[string]interface{}{"id": "hash.sha1", "image": "docker.io/python:3", "schema": "{\"title\":\"Input\",\"type\":\"object\",\"properties\":{\"default\":{\"type\":\"string\",\"title\":\"Value\"}},\"required\":[\"default\"]}", "script": "#!/usr/bin/env python\n\nimport sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha1 = hashlib.sha1(msg['payload']['default'].encode('utf-8'))\n return {\"hash\": sha1.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", "type": []interface{}{"global", "artifact", "playbook"}}, + }, + }, + { + name: "GetJob", + args: args{method: "GET", url: "/api/jobs/99cd67131b48"}, + want: want{ + status: 200, + body: map[string]interface{}{"automation": "hash.sha1", "id": "99cd67131b48", "payload": "test", "status": "created"}, + }, + }, + { + name: "GetLogs", + args: args{method: "GET", url: "/api/logs/tickets%252F294511"}, + want: want{ + status: 200, + body: []interface{}{map[string]interface{}{"created": "2021-10-02T18:05:00.333535+02:00", "creator": "bob", "message": "Fail run account resist lend solve incident centre priority temperature. Cause change distribution examine location technique shape partner milk customer. Rail tea plate soil report cook railway interpretation breath action. Exercise dream accept park conclusion addition shoot assistance may answer. Gold writer link stop combine hear power name commitment operation. Determine lifespan support grow degree henry exclude detail set religion. Direct library policy convention chain retain discover ride walk student. Gather proposal select march aspect play noise avoid encourage employ. Assessment preserve transport combine wish influence income guess run stand. Charge limit crime ignore statement foundation study issue stop claim.", "reference": "tickets/294511"}}, + }, + }, + { + name: "GetPlaybook", + args: args{method: "GET", url: "/api/playbooks/simple"}, + want: want{ + status: 200, + body: map[string]interface{}{"id": "simple", "name": "Simple", "yaml": "name: Simple\ntasks:\n input:\n name: Enter something to hash\n type: input\n schema:\n title: Something\n type: object\n properties:\n something:\n type: string\n title: Something\n default: \"\"\n next:\n hash: \"something != ''\"\n\n hash:\n name: Hash the something\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['something']\"\n next:\n comment: \"hash != ''\"\n\n comment:\n name: Comment the hash\n type: automation\n automation: comment\n payload:\n default: \"playbook.tasks['hash'].data['hash']\"\n next:\n done: \"done\"\n\n done:\n name: You can close this case now\n type: task\n"}, + }, + }, + { + name: "GetSettings", + args: args{method: "GET", url: "/api/settings"}, + want: want{ + status: 200, + body: map[string]interface{}{"artifactStates": []interface{}{map[string]interface{}{"color": "info", "icon": "mdi-help-circle-outline", "id": "unknown", "name": "Unknown"}, map[string]interface{}{"color": "error", "icon": "mdi-skull", "id": "malicious", "name": "Malicious"}, map[string]interface{}{"color": "success", "icon": "mdi-check", "id": "clean", "name": "Clean"}}, "roles": []interface{}{"admin:backup:read", "admin:backup:restore", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write"}, "ticketTypes": []interface{}{map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-alert", "id": "alert", "name": "Alerts"}, map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-radioactive", "id": "incident", "name": "Incidents"}, map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-fingerprint", "id": "investigation", "name": "Forensic Investigations"}, map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-target", "id": "hunt", "name": "Threat Hunting"}}, "tier": "community", "timeformat": "YYYY-MM-DDThh:mm:ss", "version": "0.0.0-test"}, + }, + }, + { + name: "GetStatistics", + args: args{method: "GET", url: "/api/statistics"}, + want: want{ + status: 200, + body: map[string]interface{}{"open_tickets_per_user": map[string]interface{}{}, "tickets_per_type": map[string]interface{}{"alert": 2, "incident": 1}, "tickets_per_week": map[string]interface{}{"2021-39": 3}, "unassigned": 0}, + }, + }, + { + name: "GetTemplate", + args: args{method: "GET", url: "/api/templates/default"}, + want: want{ + status: 200, + body: map[string]interface{}{"id": "default", "name": "Default", "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Default\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n"}, + }, + }, + { + name: "GetTicket", + args: args{method: "GET", url: "/api/tickets/8125"}, + want: want{ + status: 200, + body: map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "id": 8125, "modified": "2021-10-02T18:04:59.078186+02:00", "name": "phishing from selenafadel@von.com detected", "owner": "demo", "references": []interface{}{map[string]interface{}{"href": "https://www.seniorleading-edge.name/users/efficient", "name": "recovery"}, map[string]interface{}{"href": "http://www.dynamicseamless.com/clicks-and-mortar", "name": "force"}, map[string]interface{}{"href": "http://www.leadscalable.biz/envisioneer", "name": "fund"}}, "schema": "{}", "status": "closed", "tickets": []interface{}{map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "id": 8126, "modified": "2021-10-02T18:04:59.078186+02:00", "name": "Surfaceintroduce virus detected", "owner": "demo", "references": []interface{}{map[string]interface{}{"href": "http://www.centralworld-class.io/synthesize", "name": "university"}, map[string]interface{}{"href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", "name": "goal"}, map[string]interface{}{"href": "http://www.chiefsyndicate.io/action-items", "name": "unemployment"}}, "schema": "{}", "status": "closed", "type": "alert"}}, "type": "alert"}, + }, + }, + { + name: "GetTicketType", + args: args{method: "GET", url: "/api/tickettypes/alert"}, + want: want{ + status: 200, + body: map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-alert", "id": "alert", "name": "Alerts"}, + }, + }, + { + name: "GetUser", + args: args{method: "GET", url: "/api/users/script"}, + want: want{ + status: 200, + body: map[string]interface{}{"apikey": true, "blocked": false, "id": "script", "roles": []interface{}{"analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write"}}, + }, + }, + { + name: "GetUserData", + args: args{method: "GET", url: "/api/userdata/bob"}, + want: want{ + status: 200, + body: map[string]interface{}{"email": "bob@example.org", "id": "bob", "name": "Bob Bad"}, + }, + }, + { + name: "LinkFiles", + args: args{method: "PUT", url: "/api/tickets/8125/files", data: []interface{}{map[string]interface{}{"key": "myfile", "name": "document.doc"}}}, + want: want{ + status: 200, + body: map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "files": []interface{}{map[string]interface{}{"key": "myfile", "name": "document.doc"}}, "id": 8125, "modified": "2021-10-02T18:04:59.078186+02:00", "name": "phishing from selenafadel@von.com detected", "owner": "demo", "references": []interface{}{map[string]interface{}{"href": "https://www.seniorleading-edge.name/users/efficient", "name": "recovery"}, map[string]interface{}{"href": "http://www.dynamicseamless.com/clicks-and-mortar", "name": "force"}, map[string]interface{}{"href": "http://www.leadscalable.biz/envisioneer", "name": "fund"}}, "schema": "{}", "status": "closed", "tickets": []interface{}{map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "id": 8126, "modified": "2021-10-02T18:04:59.078186+02:00", "name": "Surfaceintroduce virus detected", "owner": "demo", "references": []interface{}{map[string]interface{}{"href": "http://www.centralworld-class.io/synthesize", "name": "university"}, map[string]interface{}{"href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", "name": "goal"}, map[string]interface{}{"href": "http://www.chiefsyndicate.io/action-items", "name": "unemployment"}}, "schema": "{}", "status": "closed", "type": "alert"}}, "type": "alert"}, + }, + }, + { + name: "LinkTicket", + args: args{method: "PATCH", url: "/api/tickets/8126/tickets", data: 8123}, + want: want{ + status: 200, + body: map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "id": 8126, "modified": "2021-10-02T18:04:59.078186+02:00", "name": "Surfaceintroduce virus detected", "owner": "demo", "references": []interface{}{map[string]interface{}{"href": "http://www.centralworld-class.io/synthesize", "name": "university"}, map[string]interface{}{"href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", "name": "goal"}, map[string]interface{}{"href": "http://www.chiefsyndicate.io/action-items", "name": "unemployment"}}, "schema": "{}", "status": "closed", "tickets": []interface{}{map[string]interface{}{"artifacts": []interface{}{map[string]interface{}{"name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", "status": "unknown"}, map[string]interface{}{"name": "http://www.customerviral.io/scalable/vertical/killer", "status": "clean"}, map[string]interface{}{"name": "leadreintermediate.io", "status": "malicious"}}, "created": "2021-10-02T18:04:59.078206+02:00", "id": 8123, "modified": "2021-10-02T18:04:59.078206+02:00", "name": "live zebra", "owner": "demo", "playbooks": map[string]interface{}{"phishing": map[string]interface{}{"name": "Phishing", "tasks": map[string]interface{}{"block-iocs": map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Block IOCs", "type": "task"}, "block-sender": map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Block sender", "next": map[string]interface{}{"extract-iocs": ""}, "type": "task"}, "board": map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Board Involvement?", "next": map[string]interface{}{"escalate": "boardInvolved == true", "mail-available": "boardInvolved == false"}, "schema": map[string]interface{}{"properties": map[string]interface{}{"boardInvolved": map[string]interface{}{"default": false, "title": "A board member is involved.", "type": "boolean"}}, "required": []interface{}{"boardInvolved"}, "title": "Board Involvement?", "type": "object"}, "type": "input"}, "escalate": map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Escalate to CISO", "type": "task"}, "extract-iocs": map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Extract IOCs", "next": map[string]interface{}{"block-iocs": ""}, "schema": map[string]interface{}{"properties": map[string]interface{}{"iocs": map[string]interface{}{"items": map[string]interface{}{"type": "string"}, "title": "IOCs", "type": "array"}}, "title": "Extract IOCs", "type": "object"}, "type": "input"}, "mail-available": map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Mail available", "next": map[string]interface{}{"block-sender": "schemaKey == 'yes'", "extract-iocs": "schemaKey == 'yes'", "search-email-gateway": "schemaKey == 'no'"}, "schema": map[string]interface{}{"oneOf": []interface{}{map[string]interface{}{"properties": map[string]interface{}{"mail": map[string]interface{}{"title": "Mail", "type": "string", "x-display": "textarea"}, "schemaKey": map[string]interface{}{"const": "yes", "type": "string"}}, "required": []interface{}{"mail"}, "title": "Yes"}, map[string]interface{}{"properties": map[string]interface{}{"schemaKey": map[string]interface{}{"const": "no", "type": "string"}}, "title": "No"}}, "title": "Mail available", "type": "object"}, "type": "input"}, "search-email-gateway": map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Search email gateway", "next": map[string]interface{}{"extract-iocs": ""}, "type": "task"}}}}, "references": []interface{}{map[string]interface{}{"href": "https://www.leadmaximize.net/e-services/back-end", "name": "performance"}, map[string]interface{}{"href": "http://www.corporateinteractive.name/rich", "name": "autumn"}, map[string]interface{}{"href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", "name": "suggest"}}, "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", "status": "closed", "type": "incident"}, map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "id": 8125, "modified": "2021-10-02T18:04:59.078186+02:00", "name": "phishing from selenafadel@von.com detected", "owner": "demo", "references": []interface{}{map[string]interface{}{"href": "https://www.seniorleading-edge.name/users/efficient", "name": "recovery"}, map[string]interface{}{"href": "http://www.dynamicseamless.com/clicks-and-mortar", "name": "force"}, map[string]interface{}{"href": "http://www.leadscalable.biz/envisioneer", "name": "fund"}}, "schema": "{}", "status": "closed", "type": "alert"}}, "type": "alert"}, + }, + }, + { + name: "ListAutomations", + args: args{method: "GET", url: "/api/automations"}, + want: want{ + status: 200, + body: []interface{}{map[string]interface{}{"id": "comment", "image": "docker.io/python:3", "script": "", "type": []interface{}{"playbook"}}, map[string]interface{}{"id": "hash.sha1", "image": "docker.io/python:3", "schema": "{\"title\":\"Input\",\"type\":\"object\",\"properties\":{\"default\":{\"type\":\"string\",\"title\":\"Value\"}},\"required\":[\"default\"]}", "script": "", "type": []interface{}{"global", "artifact", "playbook"}}, map[string]interface{}{"id": "thehive", "image": "docker.io/python:3", "schema": "{\"title\":\"TheHive credentials\",\"type\":\"object\",\"properties\":{\"thehiveurl\":{\"type\":\"string\",\"title\":\"TheHive URL (e.g. 'https://thehive.example.org')\"},\"thehivekey\":{\"type\":\"string\",\"title\":\"TheHive API Key\"},\"skip_files\":{\"type\":\"boolean\", \"default\": true, \"title\":\"Skip Files (much faster)\"},\"keep_ids\":{\"type\":\"boolean\", \"default\": true, \"title\":\"Keep IDs and overwrite existing IDs\"}},\"required\":[\"thehiveurl\", \"thehivekey\", \"skip_files\", \"keep_ids\"]}", "script": "", "type": []interface{}{"global"}}, map[string]interface{}{"id": "vt.hash", "image": "docker.io/python:3", "schema": "{\"title\":\"Input\",\"type\":\"object\",\"properties\":{\"default\":{\"type\":\"string\",\"title\":\"Value\"}},\"required\":[\"default\"]}", "script": "", "type": []interface{}{"global", "artifact", "playbook"}}}, + }, + }, + { + name: "ListJobs", + args: args{method: "GET", url: "/api/jobs"}, + want: want{ + status: 200, + body: []interface{}{map[string]interface{}{"automation": "hash.sha1", "id": "99cd67131b48", "payload": "test", "status": "created"}}, + }, + }, + { + name: "ListPlaybooks", + args: args{method: "GET", url: "/api/playbooks"}, + want: want{ + status: 200, + body: []interface{}{map[string]interface{}{"id": "malware", "name": "Malware", "yaml": "name: Malware\ntasks:\n file-or-hash:\n name: Do you have the file or the hash?\n type: input\n schema:\n title: Malware\n type: object\n properties:\n file:\n type: string\n title: \"I have the\"\n enum: [ \"File\", \"Hash\" ]\n next:\n enter-hash: \"file == 'Hash'\"\n upload: \"file == 'File'\"\n\n enter-hash:\n name: Please enter the hash\n type: input\n schema:\n title: Malware\n type: object\n properties:\n hash:\n type: string\n title: Please enter the hash value\n minlength: 32\n next:\n virustotal: \"hash != ''\"\n\n upload:\n name: Upload the malware\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: object\n x-display: file\n title: Please upload the malware\n next:\n hash: \"malware\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['upload'].data['malware']\"\n next:\n virustotal:\n\n virustotal:\n name: Send hash to VirusTotal\n type: automation\n automation: vt.hash\n args:\n hash: \"playbook.tasks['enter-hash'].data['hash'] || playbook.tasks['hash'].data['hash']\"\n # next:\n # known-malware: \"score > 5\"\n # sandbox: \"score < 6\" # unknown-malware\n"}, map[string]interface{}{"id": "phishing", "name": "Phishing", "yaml": "name: Phishing\ntasks:\n board:\n name: Board Involvement?\n description: Is a board member involved?\n type: input\n schema:\n properties:\n boardInvolved:\n default: false\n title: A board member is involved.\n type: boolean\n required:\n - boardInvolved\n title: Board Involvement?\n type: object\n next:\n escalate: \"boardInvolved == true\"\n mail-available: \"boardInvolved == false\"\n\n escalate:\n name: Escalate to CISO\n description: Please escalate the task to the CISO\n type: task\n\n mail-available:\n name: Mail available\n type: input\n schema:\n oneOf:\n - properties:\n mail:\n title: Mail\n type: string\n x-display: textarea\n schemaKey:\n const: 'yes'\n type: string\n required:\n - mail\n title: 'Yes'\n - properties:\n schemaKey:\n const: 'no'\n type: string\n title: 'No'\n title: Mail available\n type: object\n next:\n block-sender: \"schemaKey == 'yes'\"\n extract-iocs: \"schemaKey == 'yes'\"\n search-email-gateway: \"schemaKey == 'no'\"\n\n search-email-gateway:\n name: Search email gateway\n description: Please search email-gateway for the phishing mail.\n type: task\n next:\n extract-iocs:\n\n block-sender:\n name: Block sender\n type: task\n next:\n extract-iocs:\n\n extract-iocs:\n name: Extract IOCs\n description: Please insert the IOCs\n type: input\n schema:\n properties:\n iocs:\n items:\n type: string\n title: IOCs\n type: array\n title: Extract IOCs\n type: object\n next:\n block-iocs:\n\n block-iocs:\n name: Block IOCs\n type: task\n"}, map[string]interface{}{"id": "simple", "name": "Simple", "yaml": "name: Simple\ntasks:\n input:\n name: Enter something to hash\n type: input\n schema:\n title: Something\n type: object\n properties:\n something:\n type: string\n title: Something\n default: \"\"\n next:\n hash: \"something != ''\"\n\n hash:\n name: Hash the something\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['something']\"\n next:\n comment: \"hash != ''\"\n\n comment:\n name: Comment the hash\n type: automation\n automation: comment\n payload:\n default: \"playbook.tasks['hash'].data['hash']\"\n next:\n done: \"done\"\n\n done:\n name: You can close this case now\n type: task\n"}}, + }, + }, + { + name: "ListTasks", + args: args{method: "GET", url: "/api/tasks"}, + want: want{ + status: 200, + body: []interface{}{}, + }, + }, + { + name: "ListTemplates", + args: args{method: "GET", url: "/api/templates"}, + want: want{ + status: 200, + body: []interface{}{map[string]interface{}{"id": "default", "name": "Default", "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Default\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n"}}, + }, + }, + { + name: "ListTicketTypes", + args: args{method: "GET", url: "/api/tickettypes"}, + want: want{ + status: 200, + body: []interface{}{map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-alert", "id": "alert", "name": "Alerts"}, map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-radioactive", "id": "incident", "name": "Incidents"}, map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-fingerprint", "id": "investigation", "name": "Forensic Investigations"}, map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-target", "id": "hunt", "name": "Threat Hunting"}}, + }, + }, + { + name: "ListTickets", + args: args{method: "GET", url: "/api/tickets"}, + want: want{ + status: 200, + body: map[string]interface{}{"count": 3, "tickets": []interface{}{map[string]interface{}{"artifacts": []interface{}{map[string]interface{}{"name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", "status": "unknown"}, map[string]interface{}{"name": "http://www.customerviral.io/scalable/vertical/killer", "status": "clean"}, map[string]interface{}{"name": "leadreintermediate.io", "status": "malicious"}}, "created": "2021-10-02T18:04:59.078206+02:00", "id": 8123, "modified": "2021-10-02T18:04:59.078206+02:00", "name": "live zebra", "owner": "demo", "playbooks": map[string]interface{}{"phishing": map[string]interface{}{"name": "Phishing", "tasks": map[string]interface{}{"block-iocs": map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Block IOCs", "type": "task"}, "block-sender": map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Block sender", "next": map[string]interface{}{"extract-iocs": ""}, "type": "task"}, "board": map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Board Involvement?", "next": map[string]interface{}{"escalate": "boardInvolved == true", "mail-available": "boardInvolved == false"}, "schema": map[string]interface{}{"properties": map[string]interface{}{"boardInvolved": map[string]interface{}{"default": false, "title": "A board member is involved.", "type": "boolean"}}, "required": []interface{}{"boardInvolved"}, "title": "Board Involvement?", "type": "object"}, "type": "input"}, "escalate": map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Escalate to CISO", "type": "task"}, "extract-iocs": map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Extract IOCs", "next": map[string]interface{}{"block-iocs": ""}, "schema": map[string]interface{}{"properties": map[string]interface{}{"iocs": map[string]interface{}{"items": map[string]interface{}{"type": "string"}, "title": "IOCs", "type": "array"}}, "title": "Extract IOCs", "type": "object"}, "type": "input"}, "mail-available": map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Mail available", "next": map[string]interface{}{"block-sender": "schemaKey == 'yes'", "extract-iocs": "schemaKey == 'yes'", "search-email-gateway": "schemaKey == 'no'"}, "schema": map[string]interface{}{"oneOf": []interface{}{map[string]interface{}{"properties": map[string]interface{}{"mail": map[string]interface{}{"title": "Mail", "type": "string", "x-display": "textarea"}, "schemaKey": map[string]interface{}{"const": "yes", "type": "string"}}, "required": []interface{}{"mail"}, "title": "Yes"}, map[string]interface{}{"properties": map[string]interface{}{"schemaKey": map[string]interface{}{"const": "no", "type": "string"}}, "title": "No"}}, "title": "Mail available", "type": "object"}, "type": "input"}, "search-email-gateway": map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Search email gateway", "next": map[string]interface{}{"extract-iocs": ""}, "type": "task"}}}}, "references": []interface{}{map[string]interface{}{"href": "https://www.leadmaximize.net/e-services/back-end", "name": "performance"}, map[string]interface{}{"href": "http://www.corporateinteractive.name/rich", "name": "autumn"}, map[string]interface{}{"href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", "name": "suggest"}}, "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", "status": "closed", "type": "incident"}, map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "id": 8125, "modified": "2021-10-02T18:04:59.078186+02:00", "name": "phishing from selenafadel@von.com detected", "owner": "demo", "references": []interface{}{map[string]interface{}{"href": "https://www.seniorleading-edge.name/users/efficient", "name": "recovery"}, map[string]interface{}{"href": "http://www.dynamicseamless.com/clicks-and-mortar", "name": "force"}, map[string]interface{}{"href": "http://www.leadscalable.biz/envisioneer", "name": "fund"}}, "schema": "{}", "status": "closed", "type": "alert"}, map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "id": 8126, "modified": "2021-10-02T18:04:59.078186+02:00", "name": "Surfaceintroduce virus detected", "owner": "demo", "references": []interface{}{map[string]interface{}{"href": "http://www.centralworld-class.io/synthesize", "name": "university"}, map[string]interface{}{"href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", "name": "goal"}, map[string]interface{}{"href": "http://www.chiefsyndicate.io/action-items", "name": "unemployment"}}, "schema": "{}", "status": "closed", "type": "alert"}}}, + }, + }, + { + name: "ListUserData", + args: args{method: "GET", url: "/api/userdata"}, + want: want{ + status: 200, + body: []interface{}{map[string]interface{}{"email": "bob@example.org", "id": "bob", "name": "Bob Bad"}}, + }, + }, + { + name: "ListUsers", + args: args{method: "GET", url: "/api/users"}, + want: want{ + status: 200, + body: []interface{}{map[string]interface{}{"apikey": false, "blocked": false, "id": "bob", "roles": []interface{}{"admin:backup:read", "admin:backup:restore", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write"}}, map[string]interface{}{"apikey": true, "blocked": false, "id": "script", "roles": []interface{}{"analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write"}}}, + }, + }, + { + name: "RemoveArtifact", + args: args{method: "DELETE", url: "/api/tickets/8123/artifacts/leadreintermediate.io"}, + want: want{ + status: 200, + body: map[string]interface{}{"artifacts": []interface{}{map[string]interface{}{"name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", "status": "unknown"}, map[string]interface{}{"name": "http://www.customerviral.io/scalable/vertical/killer", "status": "clean"}}, "created": "2021-10-02T18:04:59.078206+02:00", "id": 8123, "modified": "2021-10-02T18:04:59.078206+02:00", "name": "live zebra", "owner": "demo", "playbooks": map[string]interface{}{"phishing": map[string]interface{}{"name": "Phishing", "tasks": map[string]interface{}{"block-iocs": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Block IOCs", "order": 6, "type": "task"}, "block-sender": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Block sender", "next": map[string]interface{}{"extract-iocs": ""}, "order": 3, "type": "task"}, "board": map[string]interface{}{"active": true, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Board Involvement?", "next": map[string]interface{}{"escalate": "boardInvolved == true", "mail-available": "boardInvolved == false"}, "order": 0, "schema": map[string]interface{}{"properties": map[string]interface{}{"boardInvolved": map[string]interface{}{"default": false, "title": "A board member is involved.", "type": "boolean"}}, "required": []interface{}{"boardInvolved"}, "title": "Board Involvement?", "type": "object"}, "type": "input"}, "escalate": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Escalate to CISO", "order": 1, "type": "task"}, "extract-iocs": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Extract IOCs", "next": map[string]interface{}{"block-iocs": ""}, "order": 5, "schema": map[string]interface{}{"properties": map[string]interface{}{"iocs": map[string]interface{}{"items": map[string]interface{}{"type": "string"}, "title": "IOCs", "type": "array"}}, "title": "Extract IOCs", "type": "object"}, "type": "input"}, "mail-available": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Mail available", "next": map[string]interface{}{"block-sender": "schemaKey == 'yes'", "extract-iocs": "schemaKey == 'yes'", "search-email-gateway": "schemaKey == 'no'"}, "order": 2, "schema": map[string]interface{}{"oneOf": []interface{}{map[string]interface{}{"properties": map[string]interface{}{"mail": map[string]interface{}{"title": "Mail", "type": "string", "x-display": "textarea"}, "schemaKey": map[string]interface{}{"const": "yes", "type": "string"}}, "required": []interface{}{"mail"}, "title": "Yes"}, map[string]interface{}{"properties": map[string]interface{}{"schemaKey": map[string]interface{}{"const": "no", "type": "string"}}, "title": "No"}}, "title": "Mail available", "type": "object"}, "type": "input"}, "search-email-gateway": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Search email gateway", "next": map[string]interface{}{"extract-iocs": ""}, "order": 4, "type": "task"}}}}, "references": []interface{}{map[string]interface{}{"href": "https://www.leadmaximize.net/e-services/back-end", "name": "performance"}, map[string]interface{}{"href": "http://www.corporateinteractive.name/rich", "name": "autumn"}, map[string]interface{}{"href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", "name": "suggest"}}, "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", "status": "closed", "type": "incident"}, + }, + }, + { + name: "RemoveComment", + args: args{method: "DELETE", url: "/api/tickets/8123/comments/0"}, + want: want{ + status: 200, + body: map[string]interface{}{"artifacts": []interface{}{map[string]interface{}{"name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", "status": "unknown"}, map[string]interface{}{"name": "http://www.customerviral.io/scalable/vertical/killer", "status": "clean"}, map[string]interface{}{"name": "leadreintermediate.io", "status": "malicious"}}, "created": "2021-10-02T18:04:59.078206+02:00", "id": 8123, "modified": "2021-10-02T18:04:59.078206+02:00", "name": "live zebra", "owner": "demo", "playbooks": map[string]interface{}{"phishing": map[string]interface{}{"name": "Phishing", "tasks": map[string]interface{}{"block-iocs": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Block IOCs", "order": 6, "type": "task"}, "block-sender": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Block sender", "next": map[string]interface{}{"extract-iocs": ""}, "order": 3, "type": "task"}, "board": map[string]interface{}{"active": true, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Board Involvement?", "next": map[string]interface{}{"escalate": "boardInvolved == true", "mail-available": "boardInvolved == false"}, "order": 0, "schema": map[string]interface{}{"properties": map[string]interface{}{"boardInvolved": map[string]interface{}{"default": false, "title": "A board member is involved.", "type": "boolean"}}, "required": []interface{}{"boardInvolved"}, "title": "Board Involvement?", "type": "object"}, "type": "input"}, "escalate": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Escalate to CISO", "order": 1, "type": "task"}, "extract-iocs": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Extract IOCs", "next": map[string]interface{}{"block-iocs": ""}, "order": 5, "schema": map[string]interface{}{"properties": map[string]interface{}{"iocs": map[string]interface{}{"items": map[string]interface{}{"type": "string"}, "title": "IOCs", "type": "array"}}, "title": "Extract IOCs", "type": "object"}, "type": "input"}, "mail-available": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Mail available", "next": map[string]interface{}{"block-sender": "schemaKey == 'yes'", "extract-iocs": "schemaKey == 'yes'", "search-email-gateway": "schemaKey == 'no'"}, "order": 2, "schema": map[string]interface{}{"oneOf": []interface{}{map[string]interface{}{"properties": map[string]interface{}{"mail": map[string]interface{}{"title": "Mail", "type": "string", "x-display": "textarea"}, "schemaKey": map[string]interface{}{"const": "yes", "type": "string"}}, "required": []interface{}{"mail"}, "title": "Yes"}, map[string]interface{}{"properties": map[string]interface{}{"schemaKey": map[string]interface{}{"const": "no", "type": "string"}}, "title": "No"}}, "title": "Mail available", "type": "object"}, "type": "input"}, "search-email-gateway": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Search email gateway", "next": map[string]interface{}{"extract-iocs": ""}, "order": 4, "type": "task"}}}}, "references": []interface{}{map[string]interface{}{"href": "https://www.leadmaximize.net/e-services/back-end", "name": "performance"}, map[string]interface{}{"href": "http://www.corporateinteractive.name/rich", "name": "autumn"}, map[string]interface{}{"href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", "name": "suggest"}}, "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", "status": "closed", "type": "incident"}, + }, + }, + { + name: "RemoveTicketPlaybook", + args: args{method: "DELETE", url: "/api/tickets/8123/playbooks/phishing"}, + want: want{ + status: 200, + body: map[string]interface{}{"artifacts": []interface{}{map[string]interface{}{"name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", "status": "unknown"}, map[string]interface{}{"name": "http://www.customerviral.io/scalable/vertical/killer", "status": "clean"}, map[string]interface{}{"name": "leadreintermediate.io", "status": "malicious"}}, "created": "1985-04-12T23:20:50.52Z", "id": 8123, "modified": "1985-04-12T23:20:50.52Z", "name": "live zebra", "owner": "demo", "references": []interface{}{map[string]interface{}{"href": "https://www.leadmaximize.net/e-services/back-end", "name": "performance"}, map[string]interface{}{"href": "http://www.corporateinteractive.name/rich", "name": "autumn"}, map[string]interface{}{"href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", "name": "suggest"}}, "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", "status": "closed", "type": "incident"}, + }, + }, + { + name: "RunArtifact", + args: args{method: "POST", url: "/api/tickets/8123/artifacts/leadreintermediate.io/run/hash.sha1"}, + want: want{ + status: 204, + body: nil, + }, + }, + { + name: "RunJob", + args: args{method: "POST", url: "/api/jobs", data: map[string]interface{}{"automation": "hash.sha1", "message": map[string]interface{}{"payload": "test"}}}, + want: want{ + status: 204, + body: nil, + }, + }, + { + name: "RunTask", + args: args{method: "POST", url: "/api/tickets/8123/playbooks/phishing/task/board/run"}, + want: want{ + status: 204, + body: nil, + }, + }, + { + name: "SetArtifact", + args: args{method: "PUT", url: "/api/tickets/8123/artifacts/leadreintermediate.io", data: map[string]interface{}{"name": "leadreintermediate.io", "status": "clean"}}, + want: want{ + status: 200, + body: map[string]interface{}{"artifacts": []interface{}{map[string]interface{}{"name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", "status": "unknown"}, map[string]interface{}{"name": "http://www.customerviral.io/scalable/vertical/killer", "status": "clean"}, map[string]interface{}{"name": "leadreintermediate.io", "status": "clean"}}, "created": "2021-10-02T18:04:59.078206+02:00", "id": 8123, "modified": "2021-10-02T18:04:59.078206+02:00", "name": "live zebra", "owner": "demo", "playbooks": map[string]interface{}{"phishing": map[string]interface{}{"name": "Phishing", "tasks": map[string]interface{}{"block-iocs": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Block IOCs", "order": 6, "type": "task"}, "block-sender": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Block sender", "next": map[string]interface{}{"extract-iocs": ""}, "order": 3, "type": "task"}, "board": map[string]interface{}{"active": true, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Board Involvement?", "next": map[string]interface{}{"escalate": "boardInvolved == true", "mail-available": "boardInvolved == false"}, "order": 0, "schema": map[string]interface{}{"properties": map[string]interface{}{"boardInvolved": map[string]interface{}{"default": false, "title": "A board member is involved.", "type": "boolean"}}, "required": []interface{}{"boardInvolved"}, "title": "Board Involvement?", "type": "object"}, "type": "input"}, "escalate": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Escalate to CISO", "order": 1, "type": "task"}, "extract-iocs": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Extract IOCs", "next": map[string]interface{}{"block-iocs": ""}, "order": 5, "schema": map[string]interface{}{"properties": map[string]interface{}{"iocs": map[string]interface{}{"items": map[string]interface{}{"type": "string"}, "title": "IOCs", "type": "array"}}, "title": "Extract IOCs", "type": "object"}, "type": "input"}, "mail-available": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Mail available", "next": map[string]interface{}{"block-sender": "schemaKey == 'yes'", "extract-iocs": "schemaKey == 'yes'", "search-email-gateway": "schemaKey == 'no'"}, "order": 2, "schema": map[string]interface{}{"oneOf": []interface{}{map[string]interface{}{"properties": map[string]interface{}{"mail": map[string]interface{}{"title": "Mail", "type": "string", "x-display": "textarea"}, "schemaKey": map[string]interface{}{"const": "yes", "type": "string"}}, "required": []interface{}{"mail"}, "title": "Yes"}, map[string]interface{}{"properties": map[string]interface{}{"schemaKey": map[string]interface{}{"const": "no", "type": "string"}}, "title": "No"}}, "title": "Mail available", "type": "object"}, "type": "input"}, "search-email-gateway": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Search email gateway", "next": map[string]interface{}{"extract-iocs": ""}, "order": 4, "type": "task"}}}}, "references": []interface{}{map[string]interface{}{"href": "https://www.leadmaximize.net/e-services/back-end", "name": "performance"}, map[string]interface{}{"href": "http://www.corporateinteractive.name/rich", "name": "autumn"}, map[string]interface{}{"href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", "name": "suggest"}}, "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", "status": "closed", "type": "incident"}, + }, + }, + { + name: "SetReferences", + args: args{method: "PUT", url: "/api/tickets/8125/references", data: []interface{}{map[string]interface{}{"href": "http://www.leadscalable.biz/envisioneer", "name": "fund"}}}, + want: want{ + status: 200, + body: map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "id": 8125, "modified": "2021-10-02T18:04:59.078186+02:00", "name": "phishing from selenafadel@von.com detected", "owner": "demo", "references": []interface{}{map[string]interface{}{"href": "http://www.leadscalable.biz/envisioneer", "name": "fund"}}, "schema": "{}", "status": "closed", "tickets": []interface{}{map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "id": 8126, "modified": "2021-10-02T18:04:59.078186+02:00", "name": "Surfaceintroduce virus detected", "owner": "demo", "references": []interface{}{map[string]interface{}{"href": "http://www.centralworld-class.io/synthesize", "name": "university"}, map[string]interface{}{"href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", "name": "goal"}, map[string]interface{}{"href": "http://www.chiefsyndicate.io/action-items", "name": "unemployment"}}, "schema": "{}", "status": "closed", "type": "alert"}}, "type": "alert"}, + }, + }, + { + name: "SetSchema", + args: args{method: "PUT", url: "/api/tickets/8125/schema", data: "{}"}, + want: want{ + status: 200, + body: map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "id": 8125, "modified": "2021-10-02T18:04:59.078186+02:00", "name": "phishing from selenafadel@von.com detected", "owner": "demo", "references": []interface{}{map[string]interface{}{"href": "https://www.seniorleading-edge.name/users/efficient", "name": "recovery"}, map[string]interface{}{"href": "http://www.dynamicseamless.com/clicks-and-mortar", "name": "force"}, map[string]interface{}{"href": "http://www.leadscalable.biz/envisioneer", "name": "fund"}}, "schema": "{}", "status": "closed", "tickets": []interface{}{map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "id": 8126, "modified": "2021-10-02T18:04:59.078186+02:00", "name": "Surfaceintroduce virus detected", "owner": "demo", "references": []interface{}{map[string]interface{}{"href": "http://www.centralworld-class.io/synthesize", "name": "university"}, map[string]interface{}{"href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", "name": "goal"}, map[string]interface{}{"href": "http://www.chiefsyndicate.io/action-items", "name": "unemployment"}}, "schema": "{}", "status": "closed", "type": "alert"}}, "type": "alert"}, + }, + }, + { + name: "SetTask", + args: args{method: "PUT", url: "/api/tickets/8123/playbooks/phishing/task/board", data: map[string]interface{}{"active": true, "data": map[string]interface{}{"boardInvolved": true}, "done": false, "name": "Board Involvement?", "next": map[string]interface{}{"escalate": "boardInvolved == true", "mail-available": "boardInvolved == false"}, "order": 0, "schema": map[string]interface{}{"properties": map[string]interface{}{"boardInvolved": map[string]interface{}{"default": false, "title": "A board member is involved.", "type": "boolean"}}, "required": []interface{}{"boardInvolved"}, "title": "Board Involvement?", "type": "object"}, "type": "input"}}, + want: want{ + status: 200, + body: map[string]interface{}{"artifacts": []interface{}{map[string]interface{}{"name": "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", "status": "unknown"}, map[string]interface{}{"name": "http://www.customerviral.io/scalable/vertical/killer", "status": "clean"}, map[string]interface{}{"name": "leadreintermediate.io", "status": "malicious"}}, "created": "2021-10-02T18:04:59.078206+02:00", "id": 8123, "modified": "2021-10-02T18:04:59.078206+02:00", "name": "live zebra", "owner": "demo", "playbooks": map[string]interface{}{"phishing": map[string]interface{}{"name": "Phishing", "tasks": map[string]interface{}{"block-iocs": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Block IOCs", "order": 6, "type": "task"}, "block-sender": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Block sender", "next": map[string]interface{}{"extract-iocs": ""}, "order": 3, "type": "task"}, "board": map[string]interface{}{"active": true, "created": "2021-10-02T18:04:59.078186+02:00", "data": map[string]interface{}{"boardInvolved": true}, "done": false, "name": "Board Involvement?", "next": map[string]interface{}{"escalate": "boardInvolved == true", "mail-available": "boardInvolved == false"}, "order": 0, "schema": map[string]interface{}{"properties": map[string]interface{}{"boardInvolved": map[string]interface{}{"default": false, "title": "A board member is involved.", "type": "boolean"}}, "required": []interface{}{"boardInvolved"}, "title": "Board Involvement?", "type": "object"}, "type": "input"}, "escalate": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Escalate to CISO", "order": 1, "type": "task"}, "extract-iocs": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Extract IOCs", "next": map[string]interface{}{"block-iocs": ""}, "order": 5, "schema": map[string]interface{}{"properties": map[string]interface{}{"iocs": map[string]interface{}{"items": map[string]interface{}{"type": "string"}, "title": "IOCs", "type": "array"}}, "title": "Extract IOCs", "type": "object"}, "type": "input"}, "mail-available": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Mail available", "next": map[string]interface{}{"block-sender": "schemaKey == 'yes'", "extract-iocs": "schemaKey == 'yes'", "search-email-gateway": "schemaKey == 'no'"}, "order": 2, "schema": map[string]interface{}{"oneOf": []interface{}{map[string]interface{}{"properties": map[string]interface{}{"mail": map[string]interface{}{"title": "Mail", "type": "string", "x-display": "textarea"}, "schemaKey": map[string]interface{}{"const": "yes", "type": "string"}}, "required": []interface{}{"mail"}, "title": "Yes"}, map[string]interface{}{"properties": map[string]interface{}{"schemaKey": map[string]interface{}{"const": "no", "type": "string"}}, "title": "No"}}, "title": "Mail available", "type": "object"}, "type": "input"}, "search-email-gateway": map[string]interface{}{"active": false, "created": "2021-10-02T18:04:59.078186+02:00", "done": false, "name": "Search email gateway", "next": map[string]interface{}{"extract-iocs": ""}, "order": 4, "type": "task"}}}}, "references": []interface{}{map[string]interface{}{"href": "https://www.leadmaximize.net/e-services/back-end", "name": "performance"}, map[string]interface{}{"href": "http://www.corporateinteractive.name/rich", "name": "autumn"}, map[string]interface{}{"href": "https://www.corporateintuitive.org/intuitive/platforms/integrate", "name": "suggest"}}, "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n", "status": "closed", "type": "incident"}, + }, + }, + { + name: "UnlinkTicket", + args: args{method: "DELETE", url: "/api/tickets/8126/tickets", data: 8125}, + want: want{ + status: 200, + body: map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "id": 8126, "modified": "2021-10-02T18:04:59.078186+02:00", "name": "Surfaceintroduce virus detected", "owner": "demo", "references": []interface{}{map[string]interface{}{"href": "http://www.centralworld-class.io/synthesize", "name": "university"}, map[string]interface{}{"href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", "name": "goal"}, map[string]interface{}{"href": "http://www.chiefsyndicate.io/action-items", "name": "unemployment"}}, "schema": "{}", "status": "closed", "type": "alert"}, + }, + }, + { + name: "UpdateAutomation", + args: args{method: "PUT", url: "/api/automations/hash.sha1", data: map[string]interface{}{"id": "hash.sha1", "image": "docker.io/python:3", "script": "import sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha1 = hashlib.sha1(msg['payload'].encode('utf-8'))\n return {'hash': sha1.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", "type": []interface{}{"global", "artifact", "playbook"}}}, + want: want{ + status: 200, + body: map[string]interface{}{"id": "hash.sha1", "image": "docker.io/python:3", "script": "import sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha1 = hashlib.sha1(msg['payload'].encode('utf-8'))\n return {'hash': sha1.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", "type": []interface{}{"global", "artifact", "playbook"}}, + }, + }, + { + name: "UpdateCurrentUserData", + args: args{method: "PUT", url: "/api/currentuserdata", data: map[string]interface{}{"email": "bob@example.org", "name": "Bob Bad"}}, + want: want{ + status: 200, + body: map[string]interface{}{"email": "bob@example.org", "id": "bob", "name": "Bob Bad"}, + }, + }, + { + name: "UpdateJob", + args: args{method: "PUT", url: "/api/jobs/99cd67131b48", data: map[string]interface{}{"automation": "hash.sha1", "id": "99cd67131b48", "payload": "test", "status": "failed"}}, + want: want{ + status: 200, + body: map[string]interface{}{"automation": "hash.sha1", "id": "99cd67131b48", "payload": "test", "status": "failed"}, + }, + }, + { + name: "UpdatePlaybook", + args: args{method: "PUT", url: "/api/playbooks/simple", data: map[string]interface{}{"yaml": "name: Simple\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n"}}, + want: want{ + status: 200, + body: map[string]interface{}{"id": "simple", "name": "Simple", "yaml": "name: Simple\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n"}, + }, + }, + { + name: "UpdateTemplate", + args: args{method: "PUT", url: "/api/templates/default", data: map[string]interface{}{"name": "My Template", "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n"}}, + want: want{ + status: 200, + body: map[string]interface{}{"id": "default", "name": "My Template", "schema": "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n"}, + }, + }, + { + name: "UpdateTicket", + args: args{method: "PUT", url: "/api/tickets/8125", data: map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "modified": "2021-10-02T18:04:59.078186+02:00", "name": "phishing from selenafadel@von.org detected", "owner": "demo", "references": []interface{}{map[string]interface{}{"href": "https://www.seniorleading-edge.name/users/efficient", "name": "recovery"}, map[string]interface{}{"href": "http://www.dynamicseamless.com/clicks-and-mortar", "name": "force"}, map[string]interface{}{"href": "http://www.leadscalable.biz/envisioneer", "name": "fund"}}, "schema": "{}", "status": "closed", "type": "alert"}}, + want: want{ + status: 200, + body: map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "id": 8125, "modified": "2021-10-02T18:04:59.078186+02:00", "name": "phishing from selenafadel@von.org detected", "owner": "demo", "references": []interface{}{map[string]interface{}{"href": "https://www.seniorleading-edge.name/users/efficient", "name": "recovery"}, map[string]interface{}{"href": "http://www.dynamicseamless.com/clicks-and-mortar", "name": "force"}, map[string]interface{}{"href": "http://www.leadscalable.biz/envisioneer", "name": "fund"}}, "schema": "{}", "status": "closed", "tickets": []interface{}{map[string]interface{}{"created": "2021-10-02T18:04:59.078186+02:00", "id": 8126, "modified": "2021-10-02T18:04:59.078186+02:00", "name": "Surfaceintroduce virus detected", "owner": "demo", "references": []interface{}{map[string]interface{}{"href": "http://www.centralworld-class.io/synthesize", "name": "university"}, map[string]interface{}{"href": "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", "name": "goal"}, map[string]interface{}{"href": "http://www.chiefsyndicate.io/action-items", "name": "unemployment"}}, "schema": "{}", "status": "closed", "type": "alert"}}, "type": "alert"}, + }, + }, + { + name: "UpdateTicketType", + args: args{method: "PUT", url: "/api/tickettypes/alert", data: map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-bell", "id": "alert", "name": "Alerts"}}, + want: want{ + status: 200, + body: map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-bell", "id": "alert", "name": "Alerts"}, + }, + }, + { + name: "UpdateUser", + args: args{method: "PUT", url: "/api/users/bob", data: map[string]interface{}{"roles": []interface{}{"analyst", "admin"}}}, + want: want{ + status: 200, + body: map[string]interface{}{"apikey": false, "blocked": false, "id": "bob", "roles": []interface{}{"admin:backup:read", "admin:backup:restore", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write"}}, + }, + }, + { + name: "UpdateUserData", + args: args{method: "PUT", url: "/api/userdata/bob", data: map[string]interface{}{"blocked": false, "email": "bob@example.org", "name": "Bob Bad"}}, + want: want{ + status: 200, + body: map[string]interface{}{"email": "bob@example.org", "id": "bob", "name": "Bob Bad"}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx, _, _, _, _, db, _, server, cleanup, err := test.Server(t) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + if err := test.SetupTestData(ctx, db); err != nil { + t.Fatal(err) + } + + setUser := func(context *gin.Context) { + busdb.SetContext(context, test.Bob) + } + server.ApiGroup.Use(setUser) + + server.ConfigureRoutes() + w := httptest.NewRecorder() + + // setup request + var req *http.Request + if tt.args.data != nil { + b, err := json.Marshal(tt.args.data) + if err != nil { + t.Fatal(err) + } + + req = httptest.NewRequest(tt.args.method, tt.args.url, bytes.NewBuffer(b)) + req.Header.Set("Content-Type", "application/json") + } else { + req = httptest.NewRequest(tt.args.method, tt.args.url, nil) + } + + // run request + server.ServeHTTP(w, req) + + result := w.Result() + + // assert results + if result.StatusCode != tt.want.status { + msg, _ := io.ReadAll(result.Body) + + t.Fatalf("Status got = %v, want %v: %s", result.Status, tt.want.status, msg) + } + if tt.want.status != http.StatusNoContent { + jsonEqual(t, result.Body, tt.want.body) + } + }) + } +} + +func jsonEqual(t *testing.T, got io.Reader, want interface{}) { + var gotObject, wantObject interface{} + + // load bytes + wantBytes, err := json.Marshal(want) + if err != nil { + t.Fatal(err) + } + gotBytes, err := io.ReadAll(got) + if err != nil { + t.Fatal(err) + } + + fields := []string{ + "created", "modified", "logs.0.created", + "artifacts.0.enrichments.hash\\.sha1.created", + "artifacts.1.enrichments.hash\\.sha1.created", + "artifacts.2.enrichments.hash\\.sha1.created", + + "playbooks.simple.tasks.input.created", + "playbooks.simple.tasks.hash.created", + "playbooks.simple.tasks.escalate.created", + + "playbooks.phishing.tasks.input.created", + "playbooks.phishing.tasks.hash.created", + "playbooks.phishing.tasks.escalate.created", + + "playbooks.phishing.tasks.block-ioc.created", + "playbooks.phishing.tasks.block-iocs.created", + "playbooks.phishing.tasks.block-sender.created", + "playbooks.phishing.tasks.board.created", + "playbooks.phishing.tasks.board.closed", + "playbooks.phishing.tasks.escalate.created", + "playbooks.phishing.tasks.extract-iocs.created", + "playbooks.phishing.tasks.fetch-iocs.created", + "playbooks.phishing.tasks.mail-available.created", + "playbooks.phishing.tasks.search-email-gateway.created", + + "0.playbooks.phishing.tasks.block-ioc.created", + "0.playbooks.phishing.tasks.block-iocs.created", + "0.playbooks.phishing.tasks.block-sender.created", + "0.playbooks.phishing.tasks.board.created", + "0.playbooks.phishing.tasks.escalate.created", + "0.playbooks.phishing.tasks.extract-iocs.created", + "0.playbooks.phishing.tasks.fetch-iocs.created", + "0.playbooks.phishing.tasks.mail-available.created", + "0.playbooks.phishing.tasks.search-email-gateway.created", + + "tickets.0.playbooks.phishing.tasks.block-ioc.created", + "tickets.0.playbooks.phishing.tasks.block-iocs.created", + "tickets.0.playbooks.phishing.tasks.block-sender.created", + "tickets.0.playbooks.phishing.tasks.board.created", + "tickets.0.playbooks.phishing.tasks.escalate.created", + "tickets.0.playbooks.phishing.tasks.extract-iocs.created", + "tickets.0.playbooks.phishing.tasks.fetch-iocs.created", + "tickets.0.playbooks.phishing.tasks.mail-available.created", + "tickets.0.playbooks.phishing.tasks.search-email-gateway.created", + + "secret", "0.created", "comments.0.created", + } + for _, field := range fields { + gField := gjson.GetBytes(wantBytes, field) + if gField.Exists() && gjson.GetBytes(gotBytes, field).Exists() { + gotBytes, err = sjson.SetBytes(gotBytes, field, gField.Value()) + if err != nil { + t.Fatal(err) + } + } + } + + // normalize bytes + if err = json.Unmarshal(wantBytes, &wantObject); err != nil { + t.Fatal(err) + } + if err := json.Unmarshal(gotBytes, &gotObject); err != nil { + t.Fatal(string(gotBytes), err) + } + + // compare + assert.Equal(t, wantObject, gotObject) +} diff --git a/generator/generator.go b/generator/generator.go new file mode 100644 index 0000000..35e5604 --- /dev/null +++ b/generator/generator.go @@ -0,0 +1,342 @@ +package main + +import ( + "bytes" + "embed" + "encoding/json" + "flag" + "fmt" + "go/format" + "log" + "net/url" + "os" + "path" + "strings" + "text/template" + + "github.com/go-openapi/analysis" + "github.com/go-swagger/go-swagger/generator" + "github.com/iancoleman/strcase" + "github.com/tidwall/sjson" + "gopkg.in/yaml.v3" +) + +//go:embed templates/simplemodel.gotmpl +var model embed.FS + +func gotype(name string, s Schema, required []string) string { + _, x := sgotype(name, s, required, false) + return x +} + +func sgotype(name string, s Schema, required []string, nopointer bool) (bool, string) { + req := "" + if !nopointer && !contains(required, name) { + req = "*" + } + + if s.Ref != "" { + return false, req + path.Base(s.Ref) + } + + primitive := false + t := "" + + switch s.Type { + case "string": + if s.Format == "date-time" { + t = req + "time.Time" + } else { + t = req + "string" + primitive = true + } + case "boolean": + t = req + "bool" + primitive = true + case "object": + if s.AdditionalProperties != nil { + subPrimitive, subType := sgotype(name, *s.AdditionalProperties, required, true) + if subPrimitive { + t = "map[string]" + subType + } else { + t = "map[string]*" + subType + } + } else { + t = "interface{}" + } + case "number", "integer": + if s.Format != "" { + t = req + s.Format + } else { + t = req + "int" + } + primitive = true + case "array": + subPrimitive, subType := sgotype(name, *s.Items, required, true) + if subPrimitive { + t = "[]" + subType + } else { + t = "[]*" + subType + } + case "": + t = "interface{}" + default: + panic(fmt.Sprintf("%#v", s)) + } + + return primitive, t +} + +func omitempty(name string, required []string) bool { + return !contains(required, name) +} + +func contains(required []string, name string) bool { + for _, r := range required { + if r == name { + return true + } + } + return false +} + +func tojson(name string, i Definition) string { + b, _ := json.Marshal(i) + b, _ = sjson.SetBytes(b, "$id", "#/definitions/"+name) + return string(b) +} + +func camel(s string) string { + if s == "id" { + return "ID" + } + return strcase.ToCamel(s) +} + +func main() { + flag.Parse() + p := flag.Arg(0) + + log.SetFlags(log.LstdFlags | log.Lshortfile) + f, err := os.Open("generated/community.yml") + if err != nil { + log.Fatalln(err) + } + defer f.Close() + + s := Swagger{} + dec := yaml.NewDecoder(f) + err = dec.Decode(&s) + if err != nil { + log.Fatalln(err) + } + + t := template.New("simplemodel.gotmpl") + t.Funcs(map[string]interface{}{ + "camel": camel, + "gotype": gotype, + "omitempty": omitempty, + "tojson": tojson, + }) + templ := template.Must(t.ParseFS(model, "templates/simplemodel.gotmpl")) + + err = os.MkdirAll("generated/models", os.ModePerm) + if err != nil { + log.Fatalln(err) + } + + buf := bytes.NewBufferString("") + + props := map[string][]string{} + for defName, definition := range s.Definitions { + for propName := range definition.Properties { + props[defName] = append(props[defName], propName) + } + } + + // for _, definition := range s.Definitions { + // if definition.Embed != "" { + // if parentProps, ok := props[definition.Embed]; ok { + // for _, parentProp := range parentProps { + // delete(definition.Properties, parentProp) + // } + // } + // } + // } + + err = templ.Execute(buf, &s) + if err != nil { + log.Fatalln(err) + } + + fmtCode, err := format.Source(buf.Bytes()) + if err != nil { + log.Println(err) + fmtCode = buf.Bytes() + } + + err = os.WriteFile("generated/models/models.go", fmtCode, os.ModePerm) + if err != nil { + log.Fatalln(err) + } + + generator.FuncMapFunc = func(opts *generator.LanguageOpts) template.FuncMap { + df := generator.DefaultFuncMap(opts) + + df["path"] = func(basePath, lpath string, parameters generator.GenParameters) string { + u := url.URL{Path: path.Join(basePath, lpath)} + q := u.Query() + for _, p := range parameters { + if p.Location == "path" { + if example, ok := p.Extensions["x-example"]; ok { + u.Path = strings.ReplaceAll(u.Path, "{"+p.Name+"}", fmt.Sprint(example)) + } + } + if p.Location == "query" { + if example, ok := p.Extensions["x-example"]; ok { + q.Set(p.Name, fmt.Sprint(example)) + } + } + } + u.RawQuery = q.Encode() + return u.String() + } + df["body"] = func(parameters generator.GenParameters) interface{} { + for _, p := range parameters { + if p.Location == "body" { + if example, ok := p.Extensions["x-example"]; ok { + return example + } + } + } + return nil + } + df["ginizePath"] = func(path string) string { + return strings.Replace(strings.Replace(path, "{", ":", -1), "}", "", -1) + } + df["export"] = func(name string) string { + return strings.ToUpper(name[0:1]) + name[1:] + } + df["basePaths"] = func(operations []generator.GenOperation) []string { + var l []string + var seen = map[string]bool{} + for _, operation := range operations { + if _, ok := seen[operation.BasePath]; !ok { + l = append(l, strings.TrimPrefix(operation.BasePath, "/")) + seen[operation.BasePath] = true + } + } + return l + } + df["roles"] = func(reqs []analysis.SecurityRequirement) string { + for _, req := range reqs { + if req.Name == "roles" { + var roles []string + for _, scope := range req.Scopes { + roles = append(roles, "role."+strcase.ToCamel(strings.ReplaceAll(scope, ":", "_"))) + // roles = append(roles, permission.FromString(scope)) + } + return strings.Join(roles, ", ") + } + } + return "" + } + return df + } + + opts := &generator.GenOpts{ + Spec: "generated/community.yml", + Target: "generated", + APIPackage: "operations", + ModelPackage: "models", + ServerPackage: "restapi", + ClientPackage: "client", + DefaultScheme: "http", + IncludeModel: true, + IncludeValidator: true, + IncludeHandler: true, + IncludeParameters: true, + IncludeResponses: true, + IncludeURLBuilder: true, + IncludeMain: true, + IncludeSupport: true, + ValidateSpec: true, + FlattenOpts: &analysis.FlattenOpts{ + Minimal: true, + Verbose: true, + }, + Name: "catalyst-test", + FlagStrategy: "go-flags", + CompatibilityMode: "modern", + Sections: generator.SectionOpts{ + Application: []generator.TemplateOpts{ + { + Name: "api-server-test", + Source: path.Join(p, "templates/api_server_test.gotmpl"), + Target: "{{ .Target }}/test", + FileName: "api_server_test.go", + }, + // { + // Name: "configure", + // Source: "generator/config.gotmpl", + // Target: "{{ joinFilePath .Target .ServerPackage }}", + // FileName: "config.go", + // SkipExists: false, + // SkipFormat: false, + // }, + { + Name: "embedded_spec", + Source: "asset:swaggerJsonEmbed", + Target: "{{ joinFilePath .Target .ServerPackage }}", + FileName: "embedded_spec.go", + }, + { + Name: "server", + Source: path.Join(p, "templates/api.gotmpl"), + Target: "{{ joinFilePath .Target .ServerPackage }}", + FileName: "api.go", + }, + { + Name: "response.go", + Source: path.Join(p, "templates/response.gotmpl"), + Target: "{{ .Target }}/restapi/api", + FileName: "response.go", + }, + }, + Operations: []generator.TemplateOpts{ + { + Name: "parameters", + Source: path.Join(p, "templates/parameter.gotmpl"), + Target: "{{ if gt (len .Tags) 0 }}{{ joinFilePath .Target .ServerPackage .APIPackage .Package }}{{ else }}{{ joinFilePath .Target .ServerPackage .Package }}{{ end }}", + FileName: "{{ (snakize (pascalize .Name)) }}_parameters.go", + }, + }, + Models: []generator.TemplateOpts{ + { + Name: "definition", + Source: "asset:model", + Target: "{{ joinFilePath .Target .ModelPackage }}/old", + FileName: "{{ (snakize (pascalize .Name)) }}.go", + }, + // { + // Name: "model", + // Source: "generator/model.gotmpl", + // Target: "{{ joinFilePath .Target .ModelPackage }}/old2", + // FileName: "{{ (snakize (pascalize .Name)) }}.go", + // }, + }, + }, + } + + err = opts.EnsureDefaults() + if err != nil { + log.Fatalln(err) + } + + err = generator.GenerateServer("catalyst", nil, nil, opts) + if err != nil { + log.Fatalln(err) + } + // loads.Spec() + // swagger. +} diff --git a/generator/swagger.go b/generator/swagger.go new file mode 100644 index 0000000..b27d7cd --- /dev/null +++ b/generator/swagger.go @@ -0,0 +1,61 @@ +package main + +type Swagger struct { + Swagger string `yaml:"swagger" json:"swagger"` + Info Info `yaml:"info" json:"info"` + Paths map[string]PathItem `yaml:"paths" json:"paths"` + Definitions map[string]Definition `yaml:"definitions" json:"definitions"` +} + +type Info struct { + Version string `yaml:"version" json:"version"` + Title string `yaml:"title" json:"title"` +} + +type PathItem struct { + Get Operation `yaml:"get" json:"get"` + Post Operation `yaml:"post" json:"post"` +} + +type Operation struct { + Tags []string `yaml:"tags" json:"tags"` + Summary string `yaml:"summary" json:"summary"` + Description string `yaml:"description" json:"description"` + OperationID string `yaml:"operationId" json:"operationId"` + Parameters []Parameter `yaml:"parameters" json:"parameters"` + Responses map[string]Response `yaml:"responses" json:"responses"` +} + +type Parameter struct { + // Description string `yaml:"description" json:"description"` + Name string `yaml:"name" json:"name"` + In string `yaml:"in" json:"in"` + Required bool `yaml:"required" json:"required"` + Schema Schema `yaml:"schema" json:"schema"` + Direct Schema `yaml:"-,inline" json:"-,inline"` +} + +type Schema struct { + Ref string `yaml:"$ref,omitempty" json:"$ref,omitempty"` + Format string `yaml:"format,omitempty" json:"format,omitempty"` + Title string `yaml:"title,omitempty" json:"title,omitempty"` + Description string `yaml:"description" json:"description,omitempty"` + Default interface{} `yaml:"default,omitempty" json:"default,omitempty"` + Maximum interface{} `yaml:"maximum,omitempty" json:"maximum,omitempty"` + Items *Schema `yaml:"items,omitempty" json:"items,omitempty"` + Type string `yaml:"type" json:"type,omitempty"` + AdditionalProperties *Schema `yaml:"additionalProperties,omitempty" json:"additionalProperties,omitempty"` + Enum []string `yaml:"enum,omitempty" json:"enum,omitempty"` +} + +type Response struct { + Description string `yaml:"description" json:"description"` + Schema Schema `yaml:"schema" json:"schema"` +} + +type Definition struct { + Type string `yaml:"type" json:"type"` + Required []string `yaml:"required,omitempty" json:"required,omitempty"` + Embed string `yaml:"x-embed" json:"x-embed"` + Properties map[string]Schema `yaml:"properties" json:"properties"` +} diff --git a/generator/templates/api.gotmpl b/generator/templates/api.gotmpl new file mode 100644 index 0000000..9e49a8e --- /dev/null +++ b/generator/templates/api.gotmpl @@ -0,0 +1,124 @@ +package {{ .APIPackage }} + +import ( + "context" + "log" + "net/http" + "os" + "os/signal" + "syscall" + "time" + "strings" + + "golang.org/x/oauth2" + + "github.com/gin-gonic/gin" + {{range .DefaultImports}}{{printf "%q" .}} + {{end}} + {{range $key, $value := .Imports}}{{$key}} {{ printf "%q" $value}} + {{end}} + "github.com/SecurityBrewery/catalyst/generated/restapi/api" + "github.com/SecurityBrewery/catalyst/role" +) + +// Service is the interface that must be implemented in order to provide +// business logic for the Server service. +type Service interface { + {{range .Operations}}{{ pascalize .Name }}(ctx context.Context{{ if .Params }}, params *{{.Package}}.{{ pascalize .Name }}Params{{ end }}) *api.Response +{{end}} +} + +// Config defines the config options for the API server. +type Config struct { + Address string + InsecureHTTP bool + TLSCertFile string + TLSKeyFile string +} + +// Server defines the Server service. +type Server struct { + *gin.Engine + config *Config + server *http.Server + service Service + + {{ range .Operations | basePaths }}{{ . | export }}Group *gin.RouterGroup +{{end}} + + RoleAuth func([]role.Role) gin.HandlerFunc +} + +// New initializes a new Server service. +func New(svc Service, config *Config) *Server { + engine := gin.New() + engine.Use(gin.Recovery()) + + return &Server{ + Engine: engine, + service: svc, + config: config, + server: &http.Server{ + Addr: config.Address, + Handler: engine, + ReadTimeout: 10 * time.Second, + WriteTimeout: 10 * time.Second, + }, + + {{range .Operations | basePaths }}{{ . | export }}Group: engine.Group("/{{.}}"), +{{end}} + RoleAuth: func(i []role.Role) gin.HandlerFunc { return func(c *gin.Context) { c.Next() } }, + } +} + +// ConfigureRoutes configures the routes for the Server service. +// Configuring of routes includes setting up Auth if it is enabled. +func (s *Server) ConfigureRoutes() { + {{range .Operations}}s.{{ slice .BasePath 1 | export }}Group.{{.Method}}({{ .Path | ginizePath | printf "%q" }}, s.RoleAuth([]role.Role{ {{ .SecurityRequirements | roles }} }), {{.Package}}.{{ pascalize .Name }}Endpoint(s.service.{{ pascalize .Name }})) +{{end}}} + +// run the Server. It will listen on either HTTP or HTTPS depending on the +// config passed to NewServer. +func (s *Server) run() error { + log.Printf("Serving on address %s\n", s.server.Addr) + if s.config.InsecureHTTP { + return s.server.ListenAndServe() + } + return s.server.ListenAndServeTLS(s.config.TLSCertFile, s.config.TLSKeyFile) +} + +// Shutdown will gracefully shutdown the Server. +func (s *Server) Shutdown() error { + return s.server.Shutdown(context.Background()) +} + +// RunWithSigHandler runs the Server with SIGTERM handling automatically +// enabled. The server will listen for a SIGTERM signal and gracefully shutdown +// the web server. +// It's possible to optionally pass any number shutdown functions which will +// execute one by one after the webserver has been shutdown successfully. +func (s *Server) RunWithSigHandler(shutdown ...func() error) error { + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM) + + go func() { + <-sigCh + s.Shutdown() + }() + + err := s.run() + if err != nil { + if err != http.ErrServerClosed { + return err + } + } + + for _, fn := range shutdown { + err := fn() + if err != nil { + return err + } + } + + return nil +} diff --git a/generator/templates/api_server_test.gotmpl b/generator/templates/api_server_test.gotmpl new file mode 100644 index 0000000..f988782 --- /dev/null +++ b/generator/templates/api_server_test.gotmpl @@ -0,0 +1,184 @@ +package test + +import ( + "bytes" + "context" + "encoding/json" + "github.com/SecurityBrewery/catalyst/database" + "github.com/go-openapi/swag" + "io" + "net/http" + "net/http/httptest" + "testing" + "time" + + "github.com/gin-gonic/gin" + "github.com/stretchr/testify/assert" + "github.com/tidwall/gjson" + "github.com/tidwall/sjson" + + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/test" +) + +func TestService(t *testing.T) { + gin.SetMode(gin.TestMode) + + type args struct { + method string + url string + data interface{} + } + type want struct { + status int + body interface{} + } + tests := []struct { + name string + args args + want want + }{ + {{range .Operations}} + { + name: "{{ pascalize .Name }}", + args: args{method: "{{ .Method }}", url: {{ path .BasePath .Path .Params | printf "%#v" }}{{ if .Params | body }}, data: {{ .Params | body | printf "%#v" }}{{ end }}}, + want: want{ + status: {{ with index .Responses 0 }}{{ .Code }}, + body: {{ if ne (len .Examples) 0 }}{{ with index .Examples 0 }}{{ .Example | printf "%#v" }}{{ end }}{{ else }}nil{{ end }}{{ end }}, + }, + }, {{ end }} + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx, _, _, _, _, db, _, server, cleanup, err := test.Server(t) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + if err := test.SetupTestData(ctx, db); err != nil { + t.Fatal(err) + } + + setUser := func(context *gin.Context) { + busdb.SetContext(context, test.Bob) + } + server.ApiGroup.Use(setUser) + + server.ConfigureRoutes() + w := httptest.NewRecorder() + + // setup request + var req *http.Request + if tt.args.data != nil { + b, err := json.Marshal(tt.args.data) + if err != nil { + t.Fatal(err) + } + + req = httptest.NewRequest(tt.args.method, tt.args.url, bytes.NewBuffer(b)) + req.Header.Set("Content-Type", "application/json") + } else { + req = httptest.NewRequest(tt.args.method, tt.args.url, nil) + } + + // run request + server.ServeHTTP(w, req) + + result := w.Result() + + // assert results + if result.StatusCode != tt.want.status { + msg, _ := io.ReadAll(result.Body) + + t.Fatalf("Status got = %v, want %v: %s", result.Status, tt.want.status, msg) + } + if tt.want.status != http.StatusNoContent { + jsonEqual(t, result.Body, tt.want.body) + } + }) + } +} + +func jsonEqual(t *testing.T, got io.Reader, want interface{}) { + var gotObject, wantObject interface{} + + // load bytes + wantBytes, err := json.Marshal(want) + if err != nil { + t.Fatal(err) + } + gotBytes, err := io.ReadAll(got) + if err != nil { + t.Fatal(err) + } + + fields := []string{ + "created", "modified", "logs.0.created", + "artifacts.0.enrichments.hash\\.sha1.created", + "artifacts.1.enrichments.hash\\.sha1.created", + "artifacts.2.enrichments.hash\\.sha1.created", + + "playbooks.simple.tasks.input.created", + "playbooks.simple.tasks.hash.created", + "playbooks.simple.tasks.escalate.created", + + "playbooks.phishing.tasks.input.created", + "playbooks.phishing.tasks.hash.created", + "playbooks.phishing.tasks.escalate.created", + + "playbooks.phishing.tasks.block-ioc.created", + "playbooks.phishing.tasks.block-iocs.created", + "playbooks.phishing.tasks.block-sender.created", + "playbooks.phishing.tasks.board.created", + "playbooks.phishing.tasks.board.closed", + "playbooks.phishing.tasks.escalate.created", + "playbooks.phishing.tasks.extract-iocs.created", + "playbooks.phishing.tasks.fetch-iocs.created", + "playbooks.phishing.tasks.mail-available.created", + "playbooks.phishing.tasks.search-email-gateway.created", + + "0.playbooks.phishing.tasks.block-ioc.created", + "0.playbooks.phishing.tasks.block-iocs.created", + "0.playbooks.phishing.tasks.block-sender.created", + "0.playbooks.phishing.tasks.board.created", + "0.playbooks.phishing.tasks.escalate.created", + "0.playbooks.phishing.tasks.extract-iocs.created", + "0.playbooks.phishing.tasks.fetch-iocs.created", + "0.playbooks.phishing.tasks.mail-available.created", + "0.playbooks.phishing.tasks.search-email-gateway.created", + + "tickets.0.playbooks.phishing.tasks.block-ioc.created", + "tickets.0.playbooks.phishing.tasks.block-iocs.created", + "tickets.0.playbooks.phishing.tasks.block-sender.created", + "tickets.0.playbooks.phishing.tasks.board.created", + "tickets.0.playbooks.phishing.tasks.escalate.created", + "tickets.0.playbooks.phishing.tasks.extract-iocs.created", + "tickets.0.playbooks.phishing.tasks.fetch-iocs.created", + "tickets.0.playbooks.phishing.tasks.mail-available.created", + "tickets.0.playbooks.phishing.tasks.search-email-gateway.created", + + "secret", "0.created", "comments.0.created", + } + for _, field := range fields { + gField := gjson.GetBytes(wantBytes, field) + if gField.Exists() && gjson.GetBytes(gotBytes, field).Exists() { + gotBytes, err = sjson.SetBytes(gotBytes, field, gField.Value()) + if err != nil { + t.Fatal(err) + } + } + } + + // normalize bytes + if err = json.Unmarshal(wantBytes, &wantObject); err != nil { + t.Fatal(err) + } + if err := json.Unmarshal(gotBytes, &gotObject); err != nil { + t.Fatal(string(gotBytes), err) + } + + // compare + assert.Equal(t, wantObject, gotObject) +} diff --git a/generator/templates/parameter.gotmpl b/generator/templates/parameter.gotmpl new file mode 100644 index 0000000..d10eb1a --- /dev/null +++ b/generator/templates/parameter.gotmpl @@ -0,0 +1,347 @@ +{{ define "sliceparamvalidator"}} +{{ if or .MinItems .MaxItems }} +{{ camelize .Name }}Size := int64(len({{ if and (not .IsArray) (not .HasDiscriminator) (not .IsInterface) (not .IsStream) .IsNullable }}*{{ end }}{{ .ValueExpression }})) +{{ end }} +{{ if .MinItems }} +if err := validate.MinItems({{ .Path }}, {{ printf "%q" .Location }}, {{ camelize .Name }}Size, {{ .MinItems }}); err != nil { + return err +} +{{ end }} +{{ if .MaxItems }} +if err := validate.MaxItems({{ .Path }}, {{ printf "%q" .Location }}, {{ camelize .Name }}Size, {{.MaxItems}}); err != nil { + return err +} +{{ end }} +{{ if .UniqueItems }} +if err := validate.UniqueItems({{ .Path }}, {{ printf "%q" .Location }}, {{ if and (not .IsArray) (not .HasDiscriminator) (not .IsInterface) (not .IsStream) .IsNullable }}*{{ end }}{{ .ValueExpression }}); err != nil { + return err +} +{{ end }} +{{ if .Enum }} +if err := validate.Enum({{ .Path }}, {{ printf "%q" .Location }}, {{ if and (not .IsArray) (not .HasDiscriminator) (not .IsInterface) (not .IsStream) .IsNullable }}*{{ end }}{{ .ValueExpression }}, {{ .Enum }}); err != nil { + return err +} +{{ end }} +{{ end }} +{{ define "customValidationPrimitive" }} +{{if .MinLength}} +if err := validate.MinLength({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ if .IsNullable }}(*{{ end }}{{.ValueExpression}}{{ if .IsNullable }}){{ end }}{{ if .IsCustomFormatter }}.String(){{ end }}, {{.MinLength}}); err != nil { + return err +} +{{end}} +{{if .MaxLength}} +if err := validate.MaxLength({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ if .IsNullable }}(*{{ end }}{{.ValueExpression}}{{ if .IsNullable }}){{ end }}{{ if .IsCustomFormatter }}.String(){{ end }}, {{.MaxLength}}); err != nil { + return err +} +{{end}} +{{if .Pattern}} +if err := validate.Pattern({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ if .IsNullable }}(*{{ end }}{{.ValueExpression}}{{ if .IsNullable }}){{ end }}{{ if .IsCustomFormatter }}.String(){{ end }}, `{{.Pattern}}`); err != nil { + return err +} +{{end}} +{{if .Minimum}} +if err := validate.Minimum{{ if eq .SwaggerType "integer" }}Int{{ end }}({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ if eq .SwaggerType "integer" }}int{{ else }}float{{ end }}64({{ if .IsNullable }}*{{ end }}{{.ValueExpression}}), {{.Minimum}}, {{.ExclusiveMinimum}}); err != nil { + return err +} +{{end}} +{{if .Maximum}} +if err := validate.Maximum{{ if eq .SwaggerType "integer" }}Int{{ end }}({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ if eq .SwaggerType "integer" }}int{{ else }}float{{ end }}64({{ if .IsNullable }}*{{ end }}{{.ValueExpression}}), {{.Maximum}}, {{.ExclusiveMaximum}}); err != nil { + return err +} +{{end}} +{{if .MultipleOf}} +if err := validate.MultipleOf({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, float64({{ if .IsNullable }}*{{ end }}{{.ValueExpression}}), {{.MultipleOf}}); err != nil { + return err +} +{{end}} +{{if .Enum}} +if err := validate.Enum({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ if and (not .IsArray) (not .HasDiscriminator) (not .IsInterface) .IsNullable }}*{{ end }}{{.ValueExpression}}{{ if .IsCustomFormatter }}.String(){{ end }}, {{ printf "%#v" .Enum}}); err != nil { + return err +} +{{end}} +{{end}} +{{ define "propertyparamvalidator" }} +{{ if .IsPrimitive }}{{ template "customValidationPrimitive" . }}{{ end }} +{{ if .IsCustomFormatter }} +if err := validate.FormatOf({{.Path}}, "{{.Location}}", "{{.SwaggerFormat}}", {{.ValueExpression}}.String(), formats); err != nil { + return err +}{{ end }} +{{ if .IsArray }}{{ template "sliceparamvalidator" . }}{{ end -}} +{{ end }} +{{define "bindprimitiveparam" }} +{{ end }} +{{ define "sliceparambinder" }} +var {{ varname .Child.ValueExpression }}R {{ .GoType }} +for {{ if or .Child.HasValidations .Child.Converter .Child.IsCustomFormatter }}{{ .IndexVar }}{{ else }}_{{ end }}, {{ varname .Child.ValueExpression }}V := range {{ varname .Child.ValueExpression }}C { + {{ if or .Child.IsArray -}} + {{ .Child.Child.ValueExpression }}C := swag.SplitByFormat({{ varname .Child.ValueExpression }}V, {{ printf "%q" .Child.CollectionFormat }}) + {{ template "sliceparambinder" .Child }} + {{- else -}} + {{ if .Child.Converter -}} + {{ varname .Child.ValueExpression }}, err := {{ .Child.Converter }}({{ varname .Child.ValueExpression }}V) + if err != nil { + return errors.InvalidType({{ .Child.Path }}, {{ printf "%q" .Child.Location }}, "{{ .Child.GoType }}", {{ varname .Child.ValueExpression }}) + } + {{- else if .Child.IsCustomFormatter -}} + {{ varname .Child.ValueExpression }}, err := formats.Parse({{ varname .Child.ValueExpression }}V) + if err != nil { + return errors.InvalidType({{ .Child.Path }}, {{ printf "%q" .Child.Location }}, "{{ .Child.GoType }}", {{ varname .Child.ValueExpression }}) + } + {{- else -}} + {{ varname .Child.ValueExpression }} := {{ varname .Child.ValueExpression }}V + {{ end }} + {{- end }} + + {{ template "propertyparamvalidator" .Child }} + {{ varname .Child.ValueExpression }}R = append({{ varname .Child.ValueExpression }}R, {{ varname .Child.ValueExpression }}) +} +{{ end }} +package {{ .Package }} + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/go-openapi/errors" + "github.com/go-openapi/validate" + "github.com/go-openapi/runtime" + "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/swag" + + strfmt "github.com/go-openapi/strfmt" + + {{ range .DefaultImports }}{{ printf "%q" .}} + {{ end }} + {{ range $key, $value := .Imports }}{{ $key }} {{ printf "%q" $value }} + {{ end }} + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +// {{ pascalize .Name }}Endpoint executes the core logic of the related +// route endpoint. +func {{ pascalize .Name }}Endpoint(handler func(ctx context.Context{{ if .Params }}, params *{{ pascalize .Name }}Params{{ end }}) *api.Response) gin.HandlerFunc { + return func (ctx *gin.Context) { + + {{ if .Params }}// generate params from request + params := New{{ pascalize .Name }}Params() + err := params.ReadRequest(ctx) + if err != nil { + errObj := err.(*errors.CompositeError) + ctx.Writer.Header().Set("Content-Type", "application/problem+json") + ctx.JSON(int(errObj.Code()), gin.H{"error": errObj.Error()}) + return + } + {{ end }} + + resp := handler(ctx{{ if .Params }}, params{{end}}) + + switch resp.Code { + case http.StatusNoContent: + ctx.AbortWithStatus(resp.Code) + default: + ctx.JSON(resp.Code, resp.Body) + } + } +} + +// New{{ pascalize .Name }}Params creates a new {{ pascalize .Name }}Params object +// with the default values initialized. +func New{{ pascalize .Name }}Params() *{{ pascalize .Name }}Params { + var ( + {{ range .Params }}{{ if .HasDefault }}{{ if not .IsFileParam }}{{ varname .ID}}Default = {{ if .IsPrimitive}}{{.GoType}}({{ end}}{{ printf "%#v" .Default }}{{ if .IsPrimitive }}){{ end }} + {{ end }}{{ end }}{{end}} + ) + return &{{ pascalize .Name }}Params{ {{ range .Params }}{{ if .HasDefault }} + {{ pascalize .ID}}: {{ if and (not .IsArray) (not .HasDiscriminator) (not .IsInterface) (not .IsStream) .IsNullable }}&{{ end }}{{ varname .ID }}Default, + {{ end }}{{ end }} } +} + +// {{ pascalize .Name }}Params contains all the bound params for the {{ humanize .Name }} operation +// typically these are obtained from a http.Request +// +// swagger:parameters {{ .Name }} +type {{ pascalize .Name }}Params struct { + + {{ range .Params }}/*{{ if .Description }}{{ .Description }}{{ end }}{{ if .Required }} + Required: true{{ end }}{{ if .Maximum }} + Maximum: {{ if .ExclusiveMaximum }}< {{ end }}{{ .Maximum }}{{ end }}{{ if .Minimum }} + Minimum: {{ if .ExclusiveMinimum }}> {{ end }}{{ .Minimum }}{{ end }}{{ if .MultipleOf }} + Multiple Of: {{ .MultipleOf }}{{ end }}{{ if .MaxLength }} + Max Length: {{ .MaxLength }}{{ end }}{{ if .MinLength }} + Min Length: {{ .MinLength }}{{ end }}{{ if .Pattern }} + Pattern: {{ .Pattern }}{{ end }}{{ if .MaxItems }} + Max Items: {{ .MaxItems }}{{ end }}{{ if .MinItems }} + Min Items: {{ .MinItems }}{{ end }}{{ if .UniqueItems }} + Unique: true{{ end }}{{ if .Location }} + In: {{ .Location }}{{ end }}{{ if .CollectionFormat }} + Collection Format: {{ .CollectionFormat }}{{ end }}{{ if .HasDefault }} + Default: {{ printf "%#v" .Default }}{{ end }} + */ + {{ if not .Schema }}{{ pascalize .ID }} {{ if and (not .IsArray) (not .HasDiscriminator) (not .IsInterface) (not .IsFileParam) (not .IsStream) .IsNullable }}*{{ end }}{{.GoType}}{{ else }}{{ pascalize .Name }} {{ if and (not .Schema.IsBaseType) .IsNullable (not .Schema.IsStream) }}*{{ end }}{{.GoType}}{{ end }} + {{ end}} +} + +// ReadRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls +func ({{ .ReceiverName }} *{{ pascalize .Name }}Params) ReadRequest(ctx *gin.Context) error { + var res []error + {{ if .HasQueryParams }}qs := runtime.Values(ctx.Request.URL.Query()){{ end }} + + {{ if .HasFormParams }}if err := ctx.Request.ParseMultipartForm(32 << 20); err != nil { + if err != http.ErrNotMultipart { + return err + } else if err := ctx.Request.ParseForm(); err != nil { + return err + } + }{{ if .HasFormValueParams }} + fds := runtime.Values(ctx.Request.Form) + {{ end }}{{ end }} + + {{ range .Params }} + {{ if not .IsArray }}{{ if .IsQueryParam }}q{{ pascalize .Name }}, qhk{{ pascalize .Name }}, _ := qs.GetOK({{ .Path }}) + if err := {{ .ReceiverName }}.bind{{ pascalize .ID }}(q{{ pascalize .Name }}, qhk{{ pascalize .Name }}); err != nil { + res = append(res, err) + } + {{ else if .IsPathParam }}r{{ pascalize .Name }} := []string{ctx.Param({{ .Path }})} + if err := {{ .ReceiverName }}.bind{{ pascalize .ID }}(r{{ pascalize .Name }}, true); err != nil { + res = append(res, err) + } + {{ else if .IsHeaderParam }}if err := {{ .ReceiverName }}.bind{{ pascalize .ID }}(ctx.Request.Header[http.CanonicalHeaderKey({{ .Path }})], true); err != nil { + res = append(res, err) + } + {{ else if .IsFormParam }}{{if .IsFileParam }}{{ camelize .Name }}, {{ camelize .Name }}Header, err := ctx.Request.FormFile({{ .Path }}) + if err != nil { + res = append(res, errors.New(400, "reading file %q failed: %v", {{ printf "%q" (camelize .Name) }}, err)) + } else { + {{ .ReceiverName }}.{{ pascalize .Name }} = &runtime.File{Data: {{ camelize .Name }}, Header: {{ camelize .Name }}Header} + } + {{ else }}fd{{ pascalize .Name }}, fdhk{{ pascalize .Name }}, _ := fds.GetOK({{ .Path }}) + if err := {{ .ReceiverName }}.bind{{ pascalize .ID }}(fd{{ pascalize .Name }}, fdhk{{ pascalize .Name }}); err != nil { + res = append(res, err) + } + {{ end }}{{ end }} + {{ else if .IsArray }}{{ if .IsQueryParam }}q{{ pascalize .Name }}, qhk{{ pascalize .Name }}, _ := qs.GetOK({{ .Path }}) + if err := {{ .ReceiverName }}.bind{{ pascalize .ID }}(q{{ pascalize .Name }}, qhk{{ pascalize .Name }}); err != nil { + res = append(res, err) + } + {{ else if and .IsFormParam }}fd{{ pascalize .Name }}, fdhk{{ pascalize .Name }}, _ := fds.GetOK({{ .Path }}) + if err := {{ .ReceiverName }}.bind{{ pascalize .ID }}(fd{{ pascalize .Name }}, fdhk{{ pascalize .Name }}); err != nil { + res = append(res, err) + } + {{ end }}{{ end }} + + {{ if and .IsBodyParam .Schema }}if runtime.HasBody(ctx.Request) { + {{ if .Schema.IsStream }}{{ .ReceiverName }}.{{ pascalize .Name }} = ctx.Request.Body + {{ else }}{{ if and .Schema.IsBaseType .Schema.IsExported }}body, err := {{ .ModelsPackage }}.Unmarshal{{ dropPackage .GoType }}{{ if .IsArray }}Slice{{ end }}(ctx.Request.Body, route.Consumer) + if err != nil { {{ if .Required }} + if err == io.EOF { + err = errors.Required({{ .Path }}, {{ printf "%q" .Location }}, "") + } + {{ end }}res = append(res, err) + {{ else }}var body {{ .GoType }} + if err := ctx.BindJSON(&body); err != nil { {{ if .Required }} + if err == io.EOF { + res = append(res, errors.Required({{ printf "%q" (camelize .Name) }}, {{ printf "%q" .Location }}, "")) + } else { {{ end }} + res = append(res, errors.NewParseError({{ printf "%q" (camelize .Name) }}, {{ printf "%q" .Location }}, "", err)){{ if .Required }} + } + {{ end }} + {{ end }}} else { + {{ .ReceiverName }}.{{ pascalize .Name }} = {{ if and (not .Schema.IsBaseType) .IsNullable }}&{{ end }}body + }{{ end }} + }{{ if .Required }} else { + res = append(res, errors.Required({{ printf "%q" (camelize .Name) }}, {{ printf "%q" .Location }}, "")) + } {{ end }} + + {{ end }} + {{ end }} + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +{{ $className := (pascalize .Name) }} +{{ range .Params }} +{{ if not (or .IsBodyParam .IsFileParam) }} +{{ if or .IsPrimitive .IsCustomFormatter }} +func ({{ .ReceiverName }} *{{ $className }}Params) bind{{ pascalize .ID }}(rawData []string, hasKey bool) error { + {{ if and (not .IsPathParam) .Required }}if !hasKey { + return errors.Required({{ .Path }}, {{ printf "%q" .Location }}, rawData) + } + {{ end }}var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + {{ if and (not .IsPathParam) .Required (not .AllowEmptyValue) }}if err := validate.RequiredString({{ .Path }}, {{ printf "%q" .Location }}, raw); err != nil { + return err + } + {{ else if and ( not .IsPathParam ) (or (not .Required) .AllowEmptyValue) }}if raw == "" { // empty values pass all other validations + {{ if .HasDefault }}var {{ camelize .Name}}Default {{ if not .IsFileParam }}{{ .GoType }}{{ else }}os.File{{end}} = {{ if .IsPrimitive}}{{.GoType}}({{ end}}{{ printf "%#v" .Default }}{{ if .IsPrimitive }}){{ end }} + {{ .ValueExpression }} = {{ if and (not .IsArray) (not .HasDiscriminator) (or .IsNullable ) (not .IsStream) }}&{{ end }}{{ camelize .Name }}Default + {{ end }}return nil + } + {{ end }} + {{ if .Converter }}value, err := {{ .Converter }}(raw) + if err != nil { + return errors.InvalidType({{ .Path }}, {{ printf "%q" .Location }}, {{ printf "%q" .GoType }}, raw) + } + {{ .ValueExpression }} = {{ if .IsNullable }}&{{ end }}value + {{ else if .IsCustomFormatter }}value, err := formats.Parse({{ printf "%q" .SwaggerFormat }}, raw) + if err != nil { + return errors.InvalidType({{ .Path }}, {{ printf "%q" .Location }}, {{ printf "%q" .GoType }}, raw) + } + {{ .ValueExpression }} = {{ if and (not .IsArray) (not .HasDiscriminator) (not .IsFileParam) (not .IsStream) (not .IsNullable) }}*{{ end }}(value.(*{{ .GoType }})) + {{else}}{{ .ValueExpression }} = {{ if .IsNullable }}&{{ end }}raw + {{ end }} + {{if .HasValidations }}if err := {{ .ReceiverName }}.validate{{ pascalize .ID }}(); err != nil { + return err + } + {{ end }} + return nil +} +{{else if .IsArray}} +func ({{ .ReceiverName }} *{{ $className }}Params) bind{{ pascalize .ID }}(rawData []string, hasKey bool) error { + {{if .Required }}if !hasKey { + return errors.Required({{ .Path }}, {{ printf "%q" .Location }}, rawData) + } + {{ end }} + {{ if eq .CollectionFormat "multi" }}{{ varname .Child.ValueExpression }}C := rawData{{ else }}var qv{{ pascalize .Name }} string + if len(rawData) > 0 { + qv{{ pascalize .Name }} = rawData[len(rawData) - 1] + } + + {{ varname .Child.ValueExpression }}C := swag.SplitByFormat(qv{{ pascalize .Name }}, {{ printf "%q" .CollectionFormat }}){{ end }} + {{if and .Required (not .AllowEmptyValue) }} + if len({{ varname .Child.ValueExpression }}C) == 0 { + return errors.Required({{ .Path }}, {{ printf "%q" .Location }}, {{ varname .Child.ValueExpression }}C) + } + {{ end }} + {{ if not .Required }}{{ if .HasDefault }}defValue := swag.SplitByFormat({{ .Default }}, {{ printf "%q" .CollectionFormat }}) + if len({{ varname .Child.ValueExpression }}C) == 0 && len(defValue) > 0 { + {{ .ValueExpression }} = defValue + {{ else }}if len({{ varname .Child.ValueExpression }}C) == 0 { + return nil{{ end }} + }{{ end }} + {{ template "sliceparambinder" . }} + {{ .ValueExpression }} = {{ varname .Child.ValueExpression }}R + {{ if .HasSliceValidations }}if err := {{ .ReceiverName }}.validate{{ pascalize .ID }}(); err != nil { + return err + } + {{ end }} + + return nil +} +{{ end }} +{{ if or .HasValidations .HasSliceValidations }} +func ({{ .ReceiverName }} *{{ $className }}Params) validate{{ pascalize .ID }}() error { + {{ template "propertyparamvalidator" . }} + return nil +} +{{ end }} +{{ end }} +{{ end }} diff --git a/generator/templates/response.gotmpl b/generator/templates/response.gotmpl new file mode 100644 index 0000000..a24ac14 --- /dev/null +++ b/generator/templates/response.gotmpl @@ -0,0 +1,6 @@ +package api + +type Response struct { + Code int + Body interface{} +} diff --git a/generator/templates/simplemodel.gotmpl b/generator/templates/simplemodel.gotmpl new file mode 100644 index 0000000..169d2a5 --- /dev/null +++ b/generator/templates/simplemodel.gotmpl @@ -0,0 +1,64 @@ +{{- /*gotype: github.com/SecurityBrewery/catalyst/generator.Swagger */ -}} +package models + +import ( + "fmt" + "strings" + "time" + + "github.com/xeipuuv/gojsonschema" +) + +var ( + schemaLoader = gojsonschema.NewSchemaLoader() + {{ range $index, $element := .Definitions }}{{ $index }}Schema = new(gojsonschema.Schema) +{{ end }}) + +func init() { + err := schemaLoader.AddSchemas( + {{ range $index, $element := .Definitions }}gojsonschema.NewStringLoader(`{{ tojson $index $element }}`), + {{ end }} + ) + if err != nil { + panic(err) + } + + {{ range $index, $element := .Definitions }}{{ $index }}Schema = mustCompile(`#/definitions/{{ $index }}`) +{{ end }}} + +{{ range $index, $element := .Definitions }} +type {{ $index }} struct { + {{ range $pindex, $pelement := .Properties }} {{ camel $pindex }} {{ gotype $pindex $pelement $element.Required }} `json:"{{ $pindex }}{{ if omitempty $pindex $element.Required }},omitempty{{ end }}"` +{{ end }}} + +{{ end }} + +func mustCompile(uri string) *gojsonschema.Schema { + s, err := schemaLoader.Compile(gojsonschema.NewReferenceLoader(uri)) + if err != nil { + panic(err) + } + return s +} + +func validate(s *gojsonschema.Schema, b []byte) error { + res, err := s.Validate(gojsonschema.NewStringLoader(string(b))) + if err != nil { + return err + } + + if len(res.Errors()) > 0 { + var l []string + for _, e := range res.Errors() { + l = append(l, e.String()) + } + return fmt.Errorf("validation failed: %v", strings.Join(l, ", ")) + } + return nil +} + +const ( +{{ range $index, $element := .Definitions }}{{ range $pindex, $pelement := .Properties }}{{ range $eindex, $eelement := .Enum }} +{{ $index | camel }}{{ $pindex | camel }}{{ $eelement | camel }} = "{{ $eelement }}" +{{ end }}{{ end }}{{ end }} +) diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..e9cfd8a --- /dev/null +++ b/go.mod @@ -0,0 +1,66 @@ +module github.com/SecurityBrewery/catalyst + +go 1.16 + +require ( + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/Microsoft/go-winio v0.5.1 // indirect + github.com/alecthomas/kong v0.2.17 + github.com/alecthomas/kong-yaml v0.1.1 + github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20211101200231-0802afb9c160 + github.com/arangodb/go-driver v1.2.1 + github.com/aws/aws-sdk-go v1.41.19 + github.com/bits-and-blooms/bitset v1.2.1 // indirect + github.com/blevesearch/bleve/v2 v2.2.2 + github.com/bmizerany/pat v0.0.0-20210406213842-e4b6760bdd6f // indirect + github.com/containerd/containerd v1.5.8 // indirect + github.com/coreos/go-oidc/v3 v3.1.0 + // github.com/docker/docker v1.13.1 + github.com/docker/docker v17.12.0-ce-rc1.0.20201201034508-7d75c1d40d88+incompatible + github.com/docker/go-connections v0.4.0 // indirect + github.com/eclipse/paho.mqtt.golang v1.3.5 // indirect + github.com/emitter-io/go/v2 v2.0.9 + github.com/gin-contrib/cors v1.3.1 + github.com/gin-contrib/sessions v0.0.4 + github.com/gin-gonic/gin v1.7.4 + github.com/go-openapi/analysis v0.21.1 + github.com/go-openapi/errors v0.20.1 + github.com/go-openapi/runtime v0.21.0 + github.com/go-openapi/swag v0.19.15 + github.com/go-openapi/validate v0.20.3 + github.com/go-playground/validator/v10 v10.9.0 // indirect + github.com/go-stack/stack v1.8.1 // indirect + github.com/go-swagger/go-swagger v0.27.0 + github.com/gobwas/ws v1.1.0 + github.com/golang/snappy v0.0.4 // indirect + github.com/google/uuid v1.3.0 + github.com/gorilla/mux v1.8.0 // indirect + github.com/gorilla/sessions v1.2.1 // indirect + github.com/iancoleman/strcase v0.2.0 + github.com/icza/dyno v0.0.0-20210726202311-f1bafe5d9996 + github.com/imdario/mergo v0.3.12 + github.com/json-iterator/go v1.1.12 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mingrammer/commonregex v1.0.1 + github.com/mitchellh/mapstructure v1.4.2 // indirect + github.com/morikuni/aec v1.0.0 // indirect + github.com/opencontainers/image-spec v1.0.2 // indirect + github.com/stretchr/testify v1.7.0 + github.com/tidwall/gjson v1.11.0 + github.com/tidwall/sjson v1.2.3 + github.com/tus/tusd v1.8.0 + github.com/ugorji/go v1.2.6 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect + github.com/xeipuuv/gojsonschema v1.2.0 + go.etcd.io/bbolt v1.3.6 // indirect + go.mongodb.org/mongo-driver v1.7.4 // indirect + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect + golang.org/x/net v0.0.0-20211105192438-b53810dc28af + golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 + golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c // indirect + gopkg.in/square/go-jose.v2 v2.6.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b + +) + +replace github.com/xeipuuv/gojsonschema => github.com/warjiang/gojsonschema v1.2.1-0.20210329105853-aa9f9a8cfec7 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..224ecfb --- /dev/null +++ b/go.sum @@ -0,0 +1,1724 @@ +bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.18.2/go.mod h1:AiIj7BWXyhO5gGVmYJ+S8tbkCx3yb0IMjua8Aw4naVM= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k= +github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-storage-blob-go v0.14.0/go.mod h1:SMqIBi+SuiQH32bvyjngEewEeXoPfKMgWlBDaYf6fck= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= +github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= +github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= +github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= +github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY= +github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= +github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= +github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= +github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8= +github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= +github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= +github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= +github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg= +github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= +github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/RoaringBitmap/roaring v0.9.4 h1:ckvZSX5gwCRaJYBNe7syNawCU5oruY9gQmjXlp4riwo= +github.com/RoaringBitmap/roaring v0.9.4/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA= +github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= +github.com/alecthomas/kong v0.2.12/go.mod h1:kQOmtJgV+Lb4aj+I2LEn40cbtawdWJ9Y8QLq+lElKxE= +github.com/alecthomas/kong v0.2.17 h1:URDISCI96MIgcIlQyoCAlhOmrSw6pZScBNkctg8r0W0= +github.com/alecthomas/kong v0.2.17/go.mod h1:ka3VZ8GZNPXv9Ov+j4YNLkI8mTuhXyr/0ktSlqIydQQ= +github.com/alecthomas/kong-yaml v0.1.1 h1:FOzG9AfTze44xhbuC4AJbDsSSgviRstBvKEGO4PaeTQ= +github.com/alecthomas/kong-yaml v0.1.1/go.mod h1:RcZd2uNxAnzxASa+z6rzD+ldFG60hdR2nCzlHOpPCBE= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20211101200231-0802afb9c160 h1:7qzNO1wqchnLQf8sOapBujDO/mFu8gYW/9jGZl1l96E= +github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20211101200231-0802afb9c160/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= +github.com/antonlindstrom/pgstore v0.0.0-20200229204646-b08ebf1105e0/go.mod h1:2Ti6VUHVxpC0VSmTZzEvpzysnaGAfGBOoMIz5ykPyyw= +github.com/arangodb/go-driver v1.2.1 h1:HREDHhDmzdIWxHmfkfTESbYUnRjESjPh4WUuXq7FZa8= +github.com/arangodb/go-driver v1.2.1/go.mod h1:zdDkJJnCj8DAkfbtIjIXnsTrWIiy6VhP3Vy14p+uQeY= +github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e h1:Xg+hGrY2LcQBbxd0ZFdbGSyRKTYMZCfBbw/pMJFOk1g= +github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e/go.mod h1:mq7Shfa/CaixoDxiyAAc5jZ6CVBAyPaNQCGS7mkj4Ho= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= +github.com/aws/aws-sdk-go v1.41.13/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= +github.com/aws/aws-sdk-go v1.41.19 h1:9QR2WTNj5bFdrNjRY9SeoG+3hwQmKXGX16851vdh+N8= +github.com/aws/aws-sdk-go v1.41.19/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= +github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= +github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bits-and-blooms/bitset v1.2.1 h1:M+/hrU9xlMp7t4TyTDQW97d3tRPVuKFC6zBEK16QnXY= +github.com/bits-and-blooms/bitset v1.2.1/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/blevesearch/bleve/v2 v2.2.2 h1:kBLSCEcAs7VvH4S/JkpYwR4Jnpuv/3FNl6LWg6fqCmY= +github.com/blevesearch/bleve/v2 v2.2.2/go.mod h1:D5bhQ5baElbPGQARUm4j+NrWlrmIrndMJqviN+U9ndk= +github.com/blevesearch/bleve_index_api v1.0.1 h1:nx9++0hnyiGOHJwQQYfsUGzpRdEVE5LsylmmngQvaFk= +github.com/blevesearch/bleve_index_api v1.0.1/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4= +github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo= +github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M= +github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+7LMvAB5IbSA= +github.com/blevesearch/mmap-go v1.0.3 h1:7QkALgFNooSq3a46AE+pWeKASAZc9SiNFJhDGF1NDx4= +github.com/blevesearch/mmap-go v1.0.3/go.mod h1:pYvKl/grLQrBxuaRYgoTssa4rVujYYeenDp++2E+yvs= +github.com/blevesearch/scorch_segment_api/v2 v2.1.0 h1:NFwteOpZEvJk5Vg0H6gD0hxupsG3JYocE4DBvsA2GZI= +github.com/blevesearch/scorch_segment_api/v2 v2.1.0/go.mod h1:uch7xyyO/Alxkuxa+CGs79vw0QY8BENSBjg6Mw5L5DE= +github.com/blevesearch/segment v0.9.0 h1:5lG7yBCx98or7gK2cHMKPukPZ/31Kag7nONpoBt22Ac= +github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ= +github.com/blevesearch/snowballstem v0.9.0 h1:lMQ189YspGP6sXvZQ4WZ+MLawfV8wOmPoD/iWeNXm8s= +github.com/blevesearch/snowballstem v0.9.0/go.mod h1:PivSj3JMc8WuaFkTSRDW2SlrulNWPl4ABg1tC/hlgLs= +github.com/blevesearch/upsidedown_store_api v1.0.1 h1:1SYRwyoFLwG3sj0ed89RLtM15amfX2pXlYbFOnF8zNU= +github.com/blevesearch/upsidedown_store_api v1.0.1/go.mod h1:MQDVGpHZrpe3Uy26zJBf/a8h0FZY6xJbthIMm8myH2Q= +github.com/blevesearch/vellum v1.0.7 h1:+vn8rfyCRHxKVRgDLeR0FAXej2+6mEb5Q15aQE/XESQ= +github.com/blevesearch/vellum v1.0.7/go.mod h1:doBZpmRhwTsASB4QdUZANlJvqVAUdUyX0ZK7QJCTeBE= +github.com/blevesearch/zapx/v11 v11.3.1 h1:X88o7rxOK4bTB2SSwvSWMc6dFhFtQoF3n06q5h/Vhps= +github.com/blevesearch/zapx/v11 v11.3.1/go.mod h1:YzTfUm4kS3e8OmTXDHVV8OzC5MWPO/VPJZQgPNVb4Lc= +github.com/blevesearch/zapx/v12 v12.3.1 h1:SNG60aOBXQ64d3rPiUFuxWsyHTW6h9jKlBKSKMUdxdc= +github.com/blevesearch/zapx/v12 v12.3.1/go.mod h1:RMl6lOZqF+sTxKvhQDJ5yK2LT3Mu7E2p/jGdjAaiRxs= +github.com/blevesearch/zapx/v13 v13.3.1 h1:Aj5iQBXJ7xaGZLxwdueadC/s6vJ5/Jo3klKJfFDjpio= +github.com/blevesearch/zapx/v13 v13.3.1/go.mod h1:eppobNM35U4C22yDvTuxV9xPqo10pwfP/jugL4INWG4= +github.com/blevesearch/zapx/v14 v14.3.1 h1:UyCe63mk9ZcEqgxyMS3Ab3ZC3lhDp1UJktvp31U5KA8= +github.com/blevesearch/zapx/v14 v14.3.1/go.mod h1:zXNcVzukh0AvG57oUtT1T0ndi09H0kELNaNmekEy0jw= +github.com/blevesearch/zapx/v15 v15.3.1 h1:TWm6h55pzmLCbKSFb/dgUVSg98LlYUPqtI/MhTHmZAA= +github.com/blevesearch/zapx/v15 v15.3.1/go.mod h1:C+f/97ZzTzK6vt/7sVlZdzZxKu+5+j4SrGCvr9dJzaY= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= +github.com/bmizerany/pat v0.0.0-20210406213842-e4b6760bdd6f h1:gOO/tNZMjjvTKZWpY7YnXC72ULNLErRtp94LountVE8= +github.com/bmizerany/pat v0.0.0-20210406213842-e4b6760bdd6f/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= +github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff/go.mod h1:+RTT1BOk5P97fT2CiHkbFQwkK3mjsFAP6zCYV2aXtjw= +github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= +github.com/bradleypeabody/gorilla-sessions-memcache v0.0.0-20181103040241-659414f458e1/go.mod h1:dkChI7Tbtx7H1Tj7TqGSZMOeGpMP5gLHtjroHd4agiI= +github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= +github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= +github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= +github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= +github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg= +github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= +github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= +github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= +github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= +github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= +github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= +github.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e/go.mod h1:jg2QkJcsabfHugurUvvPhS3E08Oxiuh5W/g1ybB4e0E= +github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss= +github.com/containerd/btrfs v1.0.0/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss= +github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601/go.mod h1:X9rLEHIqSf/wfK8NsPqxJmeZgW4pcfzdXITDrUSJ6uI= +github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= +github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM= +github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= +github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= +github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= +github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU= +github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= +github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= +github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= +github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= +github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= +github.com/containerd/containerd v1.2.10/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.1-0.20191213020239-082f7e3aed57/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.0-beta.2.0.20200729163537-40b22ef07410/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7V960Tmcumvqn8Mc+pCYQ= +github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU= +github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI= +github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= +github.com/containerd/containerd v1.5.8 h1:NmkCC1/QxyZFBny8JogwLpOy2f+VEbO/f6bV2Mqtwuw= +github.com/containerd/containerd v1.5.8/go.mod h1:YdFSv5bTFLpG2HIYmfqDpSYYTDX+mc5qtSuYx1YUb/s= +github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo= +github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y= +github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ= +github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= +github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= +github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= +github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= +github.com/containerd/fifo v0.0.0-20201026212402-0724c46b320c/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= +github.com/containerd/fifo v0.0.0-20210316144830-115abcc95a1d/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= +github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= +github.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZHtSlv++smU= +github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk= +github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= +github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= +github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g= +github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= +github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= +github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak9TYCG3juvb0= +github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA= +github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow= +github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms= +github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c= +github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= +github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= +github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= +github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= +github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8= +github.com/containerd/ttrpc v1.0.1/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= +github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= +github.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ= +github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= +github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk= +github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg= +github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= +github.com/containerd/zfs v0.0.0-20200918131355-0a33824f23a2/go.mod h1:8IgZOBdv8fAgXddBT4dBXJPtxyRsejFIpXoklgxgEjw= +github.com/containerd/zfs v0.0.0-20210301145711-11e8f1707f62/go.mod h1:A9zfAbMlQwE+/is6hi0Xw8ktpL+6glmqZYtevJgaB8Y= +github.com/containerd/zfs v0.0.0-20210315114300-dde8f0fda960/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= +github.com/containerd/zfs v0.0.0-20210324211415-d5c4544f0433/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= +github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= +github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM= +github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= +github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= +github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4= +github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-iptables v0.4.3/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= +github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= +github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= +github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk= +github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-oidc/v3 v3.1.0 h1:6avEvcdvTa1qYsOZ6I5PRkSYHzpTNWgKYmaJfaYbrRw= +github.com/coreos/go-oidc/v3 v3.1.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/couchbase/ghistogram v0.1.0/go.mod h1:s1Jhy76zqfEecpNWJfWUiKZookAFaiGOEoyzgHt9i7k= +github.com/couchbase/moss v0.1.0/go.mod h1:9MaHIaRuy9pvLPUJxB8sh8OrLfyDczECVL37grCIubs= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= +github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= +github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s= +github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= +github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9/go.mod h1:GgB8SF9nRG+GqaDtLcwJZsQFhcogVCJ79j4EdT0c2V4= +github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= +github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= +github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= +github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= +github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v17.12.0-ce-rc1.0.20201201034508-7d75c1d40d88+incompatible h1:rsPfdypSNWulLrsXo3WiBdlNQpokgBqfWLjEa/aXiBc= +github.com/docker/docker v17.12.0-ce-rc1.0.20201201034508-7d75c1d40d88+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= +github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= +github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= +github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= +github.com/eclipse/paho.mqtt.golang v1.3.5 h1:sWtmgNxYM9P2sP+xEItMozsR3w0cqZFlqnNN1bdl41Y= +github.com/eclipse/paho.mqtt.golang v1.3.5/go.mod h1:eTzb4gxwwyWpqBUHGQZ4ABAV7+Jgm1PklsYT/eo8Hcc= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emitter-io/go/v2 v2.0.9 h1:qA+cnG3kS2uLzo5ETFY6zbHBGl+FmNj0cGf3da7foA4= +github.com/emitter-io/go/v2 v2.0.9/go.mod h1:St++epE1u/6ueCVw47xhu4shpkGNxKRVtkWv4Xi33mg= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= +github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/cors v1.3.1 h1:doAsuITavI4IOcd0Y19U4B+O0dNWihRyX//nn4sEmgA= +github.com/gin-contrib/cors v1.3.1/go.mod h1:jjEJ4268OPZUcU7k9Pm653S7lXUGcqMADzFA61xsmDk= +github.com/gin-contrib/sessions v0.0.4 h1:gq4fNa1Zmp564iHP5G6EBuktilEos8VKhe2sza1KMgo= +github.com/gin-contrib/sessions v0.0.4/go.mod h1:pQ3sIyviBBGcxgyR8mkeJuXbeV3h3NYmhJADQTq5+Vo= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= +github.com/gin-gonic/gin v1.7.4 h1:QmUZXrvJ9qZ3GfWvQ+2wnW/1ePrTEJqPKMYEU3lD/DM= +github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= +github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= +github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= +github.com/go-openapi/analysis v0.19.10/go.mod h1:qmhS3VNFxBlquFJ0RGoDtylO9y4pgTAUNE9AEEMdlJQ= +github.com/go-openapi/analysis v0.19.16/go.mod h1:GLInF007N83Ad3m8a/CbQ5TPzdnGT7workfHwuVjNVk= +github.com/go-openapi/analysis v0.20.0/go.mod h1:BMchjvaHDykmRMsK40iPtvyOfFdMMxlOmQr9FBZk+Og= +github.com/go-openapi/analysis v0.20.1/go.mod h1:BMchjvaHDykmRMsK40iPtvyOfFdMMxlOmQr9FBZk+Og= +github.com/go-openapi/analysis v0.21.1 h1:krcNCEvCttpSUFBPOrfvn7nniejvrOkoNYRlZwQFpEs= +github.com/go-openapi/analysis v0.21.1/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= +github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/errors v0.19.6/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.7/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.0/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.1 h1:j23mMDtRxMwIobkpId7sWh7Ddcx4ivaoqUbfXx5P+a8= +github.com/go-openapi/errors v0.20.1/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= +github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= +github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= +github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= +github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI= +github.com/go-openapi/loads v0.19.5/go.mod h1:dswLCAdonkRufe/gSUC3gN8nTSaB9uaS2es0x5/IbjY= +github.com/go-openapi/loads v0.19.6/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= +github.com/go-openapi/loads v0.19.7/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= +github.com/go-openapi/loads v0.20.0/go.mod h1:2LhKquiE513rN5xC6Aan6lYOSddlL8Mp20AW9kpviM4= +github.com/go-openapi/loads v0.20.2/go.mod h1:hTVUotJ+UonAMMZsvakEgmWKgtulweO9vYP2bQYKA/o= +github.com/go-openapi/loads v0.21.0 h1:jYtUO4wwP7psAweisP/MDoOpdzsYEESdoPcsWjHDR68= +github.com/go-openapi/loads v0.21.0/go.mod h1:rHYve9nZrQ4CJhyeIIFJINGCg1tQpx2yJrrNo8sf1ws= +github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= +github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= +github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= +github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= +github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98= +github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk= +github.com/go-openapi/runtime v0.19.27/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M= +github.com/go-openapi/runtime v0.21.0 h1:giZ8eT26R+/rx6RX2MkYjZPY8vPYVKDhP/mOazrQHzM= +github.com/go-openapi/runtime v0.21.0/go.mod h1:aQg+kaIQEn+A2CRSY1TxbM8+sT9g2V3aLc1FbIAnbbs= +github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= +github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= +github.com/go-openapi/spec v0.19.6/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/spec v0.19.8/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/spec v0.19.15/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= +github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= +github.com/go-openapi/spec v0.20.1/go.mod h1:93x7oh+d+FQsmsieroS4cmR3u0p/ywH649a3qwC9OsQ= +github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg= +github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M= +github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= +github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= +github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= +github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= +github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-openapi/strfmt v0.19.11/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= +github.com/go-openapi/strfmt v0.20.0/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= +github.com/go-openapi/strfmt v0.20.1/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk= +github.com/go-openapi/strfmt v0.20.2/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk= +github.com/go-openapi/strfmt v0.21.0 h1:hX2qEZKmYks+t0hKeb4VTJpUm2UYsdL3+DCid5swxIs= +github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= +github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M= +github.com/go-openapi/swag v0.19.13/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= +github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= +github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= +github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= +github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbNMAuKvKB+IaGx8= +github.com/go-openapi/validate v0.19.12/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0waH08tGe6kAQ4= +github.com/go-openapi/validate v0.19.15/go.mod h1:tbn/fdOwYHgrhPBzidZfJC2MIVvs9GA7monOmWBbeCI= +github.com/go-openapi/validate v0.20.1/go.mod h1:b60iJT+xNNLfaQJUqLI7946tYiFEOuE9E4k54HpKcJ0= +github.com/go-openapi/validate v0.20.2/go.mod h1:e7OJoKNgd0twXZwIn0A43tHbvIcr/rZIVCbJBpTUoY0= +github.com/go-openapi/validate v0.20.3 h1:GZPPhhKSZrE8HjB4eEkoYAZmoWA4+tCemSgINH1/vKw= +github.com/go-openapi/validate v0.20.3/go.mod h1:goDdqVGiigM3jChcrYJxD2joalke3ZXeftD16byIjA4= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= +github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= +github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-playground/validator/v10 v10.9.0 h1:NgTtmN58D0m8+UuxtYmGztBJB7VnPgjj221I1QHci2A= +github.com/go-playground/validator/v10 v10.9.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= +github.com/go-swagger/go-swagger v0.27.0 h1:K7+nkBuf4oS1jTBrdvWqYFpqD69V5CN8HamZzCDDhAI= +github.com/go-swagger/go-swagger v0.27.0/go.mod h1:WodZVysInJilkW7e6IRw+dZGp5yW6rlMFZ4cb+THl9A= +github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0= +github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= +github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= +github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= +github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= +github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= +github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= +github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= +github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= +github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= +github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= +github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= +github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= +github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= +github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= +github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= +github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= +github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= +github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= +github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA= +github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0= +github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= +github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= +github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= +github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= +github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.1.1/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w= +github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= +github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/icza/dyno v0.0.0-20210726202311-f1bafe5d9996 h1:ReG4j9+RbIOX2sR0cwPRpPXPaN+O/Hf59Npw3Iv118E= +github.com/icza/dyno v0.0.0-20210726202311-f1bafe5d9996/go.mod h1:c1tRKs5Tx7E2+uHGSyyncziFjvGpgv4H2HrqXeUQ/Uk= +github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= +github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= +github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/kidstuff/mongostore v0.0.0-20181113001930-e650cd85ee4b/go.mod h1:g2nVr8KZVXJSS97Jo8pJ0jgq29P6H7dG0oplUA86MQw= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/kljensen/snowball v0.6.0/go.mod h1:27N7E8fVU5H68RlUmnWwZCfxgt4POBJfENGMvNRhldw= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/lib/pq v1.10.3/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/memcachier/mc v2.0.1+incompatible/go.mod h1:7bkvFE61leUBvXz+yxsOnGBQSZpBSPIMUQSmmSHvuXc= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/mingrammer/commonregex v1.0.1 h1:QY0Z1Bl80jw9M3+488HJXPWnZmvtu3UdvxyodP2FTyY= +github.com/mingrammer/commonregex v1.0.1/go.mod h1:/HNZq7qReKgXBxJxce5SOxf33y0il/ZqL4Kxgo2NLcA= +github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo= +github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= +github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= +github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= +github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= +github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= +github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= +github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= +github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0-rc1.0.20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= +github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= +github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= +github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= +github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= +github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= +github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= +github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= +github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= +github.com/pquerna/cachecontrol v0.0.0-20201205024021-ac21108117ac/go.mod h1:hoLfEwdY11HjRfKFH6KqnPsfxlo3BP6bJehpDv8t6sQ= +github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b/go.mod h1:wTPjTepVu7uJBYgZ0SdWHQlIas582j6cn2jgk4DDdlg= +github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.19.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sethgrid/pester v0.0.0-20190127155807-68a33a018ad0/go.mod h1:Ad7IjTpvzZO8Fl0vh9AzQ+j/jYZfyp2diGwI8m5q+ns= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= +github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= +github.com/steveyen/gtreap v0.1.0 h1:CjhzTa274PyJLJuMZwIzCO1PfC00oRa8d1Kc78bFXJM= +github.com/steveyen/gtreap v0.1.0/go.mod h1:kl/5J7XbrOmlIbYIXdRHDDE5QxHqpk0cmkT7Z4dM9/Y= +github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= +github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.11.0 h1:C16pk7tQNiH6VlCrtIXL1w8GaOsi1X3W8KDkE1BuYd4= +github.com/tidwall/gjson v1.11.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.3 h1:5+deguEhHSEjmuICXZ21uSSsXotWMA0orU783+Z7Cp8= +github.com/tidwall/sjson v1.2.3/go.mod h1:5WdjKx3AQMvCJ4RG6/2UYT7dLrGvJUV1x4jdTAyGvZs= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM= +github.com/tus/tusd v1.8.0 h1:QODQ5uMhL2tFX3Ouk7rUHHqPqeDBvi2+gYIoyUO0n8Q= +github.com/tus/tusd v1.8.0/go.mod h1:stZzKpol4qz7lX2HXy/1H526dn5mRnkIICTW2lrh9NM= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go v1.2.6 h1:tGiWC9HENWE2tqYycIqFTNorMmFRVhNwCpDOpWqnk8E= +github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ= +github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw= +github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= +github.com/vimeo/go-util v1.4.1/go.mod h1:r+yspV//C48HeMXV8nEvtUeNiIiGfVv3bbEHzOgudwE= +github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= +github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= +github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/warjiang/gojsonschema v1.2.1-0.20210329105853-aa9f9a8cfec7 h1:tBx6st54ijBCqyKdj6uE+6J+q/xT1GvD0+JNAMt7zJs= +github.com/warjiang/gojsonschema v1.2.1-0.20210329105853-aa9f9a8cfec7/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= +github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= +github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= +github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= +github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= +go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= +go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= +go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= +go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= +go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= +go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= +go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= +go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= +go.mongodb.org/mongo-driver v1.7.4 h1:sllcioag8Mec0LYkftYWq+cKNPIR4Kqq3iv9ZXY0g/E= +go.mongodb.org/mongo-driver v1.7.4/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= +go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210331060903-cb1fcc7394e5/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211105192438-b53810dc28af h1:SMeNJG/vclJ5wyBBd4xupMsSJIHTd1coW9g7q6KOjmY= +golang.org/x/net v0.0.0-20211105192438-b53810dc28af/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c h1:+8miTPjMCTXwih7BQmvWwd0PjdBZq2MKp/qQaahSzEM= +golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s= +golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E= +google.golang.org/api v0.60.0/go.mod h1:d7rl65NZAkEQ90JFzqBjcRq1TVeG5ZoGV3sSpEnnVb4= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211016002631-37fc39342514/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211021150943-2b146023228c h1:FqrtZMB5Wr+/RecOM3uPJNPfWR8Upb5hAPnt7PU6i4k= +google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.41.0 h1:f+PlOh7QV4iIJkPrx5NQ7qaNGFQ3OTse67yaDHfju4E= +google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/Acconut/lockfile.v1 v1.1.0/go.mod h1:6UCz3wJ8tSFUsPR6uP/j8uegEtDuEEqFxlpi0JI4Umw= +gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= +gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= +gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= +k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= +k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= +k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= +k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= +k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= +k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= +k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= +k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= +k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= +k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= +k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= +k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= +k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= +k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= +k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= +k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc= +k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= +k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= +k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/hooks/hooks.go b/hooks/hooks.go new file mode 100644 index 0000000..bffa129 --- /dev/null +++ b/hooks/hooks.go @@ -0,0 +1,52 @@ +package hooks + +import ( + "context" + + "github.com/arangodb/go-driver" + "github.com/gin-gonic/gin" + + "github.com/SecurityBrewery/catalyst/index" +) + +type Hooks struct { + DatabaseAfterConnectFuncs []func(ctx context.Context, client driver.Client, name string) + IngestionFilterFunc func(ctx context.Context, index *index.Index) (string, error) + TicketReadFilterFunc func(ctx context.Context) (string, map[string]interface{}, error) + TicketWriteFilterFunc func(ctx context.Context) (string, map[string]interface{}, error) + GetGroupsFunc func(ctx context.Context, username string) ([]string, error) +} + +func (h *Hooks) DatabaseAfterConnect(ctx context.Context, client driver.Client, name string) { + for _, f := range h.DatabaseAfterConnectFuncs { + f(ctx, client, name) + } +} + +func (h *Hooks) IngestionFilter(ctx context.Context, index *index.Index) (string, error) { + if h.IngestionFilterFunc != nil { + return h.IngestionFilterFunc(ctx, index) + } + return "[]", nil +} + +func (h *Hooks) TicketReadFilter(ctx context.Context) (string, map[string]interface{}, error) { + if h.TicketReadFilterFunc != nil { + return h.TicketReadFilterFunc(ctx) + } + return "", nil, nil +} + +func (h *Hooks) TicketWriteFilter(ctx context.Context) (string, map[string]interface{}, error) { + if h.TicketWriteFilterFunc != nil { + return h.TicketWriteFilterFunc(ctx) + } + return "", nil, nil +} + +func (h *Hooks) GetGroups(ctx *gin.Context, username string) ([]string, error) { + if h.GetGroupsFunc != nil { + return h.GetGroupsFunc(ctx, username) + } + return nil, nil +} diff --git a/index/index.go b/index/index.go new file mode 100644 index 0000000..e54bee3 --- /dev/null +++ b/index/index.go @@ -0,0 +1,80 @@ +package index + +import ( + "errors" + "fmt" + "log" + "os" + + "github.com/blevesearch/bleve/v2" + + "github.com/SecurityBrewery/catalyst/generated/models" +) + +type Index struct { + name string + internal bleve.Index +} + +func New(name string) (*Index, error) { + var err error + var bleveIndex bleve.Index + if _, oerr := os.Stat(name); os.IsNotExist(oerr) { + bleveIndex, err = bleve.New(name, bleve.NewIndexMapping()) + } else { + bleveIndex, err = bleve.Open(name) + } + if err != nil { + return nil, err + } + + return &Index{name: name, internal: bleveIndex}, nil +} + +func (i *Index) Index(incidents []*models.TicketSimpleResponse) { + b := i.internal.NewBatch() + for _, incident := range incidents { + if incident.ID == 0 { + log.Println(errors.New("no ID"), incident) + continue + } + + err := b.Index(fmt.Sprint(incident.ID), incident) + if err != nil { + log.Println(err) + } + } + err := i.internal.Batch(b) + if err != nil { + log.Println(err) + } +} + +func (i *Index) Search(term string) (ids []string, err error) { + query := bleve.NewQueryStringQuery(term) + result, err := i.internal.Search(bleve.NewSearchRequestOptions(query, 10000, 0, false)) + if err != nil { + return nil, err + } + for _, match := range result.Hits { + ids = append(ids, match.ID) + } + return ids, nil +} + +func (i *Index) Truncate() error { + err := i.internal.Close() + if err != nil { + return err + } + err = os.RemoveAll(i.name) + if err != nil { + return err + } + index, err := bleve.New(i.name, bleve.NewIndexMapping()) + if err != nil { + return err + } + i.internal = index + return nil +} diff --git a/index/index_test.go b/index/index_test.go new file mode 100644 index 0000000..24fd248 --- /dev/null +++ b/index/index_test.go @@ -0,0 +1,83 @@ +package index_test + +import ( + "reflect" + "testing" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/test" +) + +func TestIndex(t *testing.T) { + type args struct { + term string + } + tests := []struct { + name string + args args + wantIds []string + wantErr bool + }{ + {name: "Exists", args: args{"foo"}, wantIds: []string{"1"}}, + {name: "Not exists", args: args{"bar"}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + i, cleanup, err := test.Index(t) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + i.Index([]*models.TicketSimpleResponse{ + {ID: 0, Name: "bar"}, + {ID: 1, Name: "foo"}, + }) + + gotIds, err := i.Search(tt.args.term) + if (err != nil) != tt.wantErr { + t.Errorf("Search() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(gotIds, tt.wantIds) { + t.Errorf("Search() gotIds = %v, want %v", gotIds, tt.wantIds) + } + }) + } +} + +func TestIndex_Truncate(t *testing.T) { + tests := []struct { + name string + wantErr bool + }{ + {name: "Truncate"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + i, cleanup, err := test.Index(t) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + i.Index([]*models.TicketSimpleResponse{ + {ID: 0, Name: "bar"}, + {ID: 1, Name: "foo"}, + }) + + if err := i.Truncate(); (err != nil) != tt.wantErr { + t.Errorf("Truncate() error = %v, wantErr %v", err, tt.wantErr) + } + + ids, err := i.Search("foo") + if err != nil { + t.Fatal(err) + } + + if ids != nil { + t.Fatal("should return no results") + } + }) + } +} diff --git a/pointer/pointer.go b/pointer/pointer.go new file mode 100644 index 0000000..33b94df --- /dev/null +++ b/pointer/pointer.go @@ -0,0 +1,19 @@ +package pointer + +import "time" + +func String(v string) *string { + return &v +} + +func Int64(v int64) *int64 { + return &v +} + +func Bool(v bool) *bool { + return &v +} + +func Time(v time.Time) *time.Time { + return &v +} diff --git a/restore.go b/restore.go new file mode 100644 index 0000000..276cc3c --- /dev/null +++ b/restore.go @@ -0,0 +1,169 @@ +package catalyst + +import ( + "archive/zip" + "bytes" + "context" + "errors" + "fmt" + "io" + "io/fs" + "log" + "net/http" + "os" + "os/exec" + "path" + "strings" + + "github.com/aws/aws-sdk-go/service/s3" + "github.com/aws/aws-sdk-go/service/s3/s3manager" + "github.com/gin-gonic/gin" + + "github.com/SecurityBrewery/catalyst/database" + "github.com/SecurityBrewery/catalyst/pointer" + "github.com/SecurityBrewery/catalyst/storage" +) + +func RestoreHandler(catalystStorage *storage.Storage, db *database.Database, c *database.Config) gin.HandlerFunc { + return func(context *gin.Context) { + uf, err := context.FormFile("backup") + if err != nil { + log.Println(err) + context.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + } + + f, err := uf.Open() + if err != nil { + log.Println(err) + context.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + } + defer f.Close() + + if err = Restore(context, catalystStorage, db, c, f, uf.Size); err != nil { + log.Println(err) + context.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + } + } +} + +func Restore(ctx context.Context, catalystStorage *storage.Storage, db *database.Database, c *database.Config, r io.Reader, size int64) error { + b, err := io.ReadAll(r) + if err != nil { + return err + } + + ra := bytes.NewReader(b) + fsys, err := zip.NewReader(ra, size) + if err != nil { + return err + } + + if fsys.Comment != GetVersion() { + return errors.New(fmt.Sprintf("wrong version, got: %s, want: %s", fsys.Comment, GetVersion())) + } + + dir, err := os.MkdirTemp("", "catalyst-restore") + if err != nil { + return err + } + defer os.RemoveAll(dir) + + if err = unzip(fsys, dir); err != nil { + return err + } + + if err := restoreS3(catalystStorage, path.Join(dir, "minio")); err != nil { + return err + } + + if err := arangorestore(path.Join(dir, "arango"), c); err != nil { + return err + } + + return db.IndexRebuild(ctx) +} + +func restoreS3(catalystStorage *storage.Storage, p string) error { + minioDir := os.DirFS(p) + + entries, err := fs.ReadDir(minioDir, ".") + if err != nil { + return err + } + + for _, entry := range entries { + if err := restoreBucket(catalystStorage, entry, minioDir); err != nil { + return err + } + } + return nil +} + +func restoreBucket(catalystStorage *storage.Storage, entry fs.DirEntry, minioDir fs.FS) error { + _, err := catalystStorage.S3().CreateBucket(&s3.CreateBucketInput{Bucket: pointer.String(entry.Name())}) + if err != nil { + return err + } + + uploader := catalystStorage.Uploader() + + f, err := minioDir.Open(entry.Name()) + if err != nil { + return err + } + defer f.Close() + + err = fs.WalkDir(minioDir, ".", func(path string, d fs.DirEntry, err error) error { + if err != nil { + return nil + } + _, err = uploader.Upload(&s3manager.UploadInput{Body: f, Bucket: pointer.String(entry.Name()), Key: pointer.String(path)}) + return err + }) + if err != nil { + return err + } + return nil +} + +func unzip(archive *zip.Reader, dir string) error { + return fs.WalkDir(archive, "arango", func(p string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + + if d.IsDir() { + _ = os.MkdirAll(path.Join(dir, p), os.ModePerm) + return nil + } + + f, err := archive.Open(p) + if err != nil { + return err + } + defer f.Close() + + b, err := io.ReadAll(f) + if err != nil { + return err + } + + return os.WriteFile(path.Join(dir, p), b, os.ModePerm) + }) +} + +func arangorestore(dir string, config *database.Config) error { + host := strings.Replace(config.Host, "http", "tcp", 1) + + name := config.Name + if config.Name == "" { + name = database.Name + } + args := []string{ + "--input-directory", dir, "--server.endpoint", host, + "--server.username", config.User, "--server.password", config.Password, + "--server.database", name, + } + cmd := exec.Command("arangorestore", args...) + return cmd.Run() +} diff --git a/role/role.go b/role/role.go new file mode 100644 index 0000000..46d3d02 --- /dev/null +++ b/role/role.go @@ -0,0 +1,179 @@ +package role + +import ( + "errors" + "sort" + "strings" + + "github.com/SecurityBrewery/catalyst/generated/models" +) + +type Role string + +const ( + Analyst string = "analyst" + Engineer string = "engineer" + Admin string = "admin" + + AutomationRead Role = "analyst:automation:read" + CurrentuserdataRead Role = "analyst:currentuserdata:read" + CurrentuserdataWrite Role = "analyst:currentsettings:write" + CurrentuserRead Role = "analyst:currentuser:read" + FileReadWrite Role = "analyst:file" + GroupRead Role = "analyst:group:read" + PlaybookRead Role = "analyst:playbook:read" + RuleRead Role = "analyst:rule:read" + SettingsRead Role = "analyst:settings:read" + TemplateRead Role = "analyst:template:read" + TicketRead Role = "analyst:ticket:read" + TickettypeRead Role = "analyst:tickettype:read" + TicketWrite Role = "analyst:ticket:write" + UserRead Role = "analyst:user:read" + + AutomationWrite Role = "engineer:automation:write" + PlaybookWrite Role = "engineer:playbook:write" + RuleWrite Role = "engineer:rule:write" + TemplateWrite Role = "engineer:template:write" + TickettypeWrite Role = "engineer:tickettype:write" + + BackupRead Role = "admin:backup:read" + BackupRestore Role = "admin:backup:restore" + GroupWrite Role = "admin:group:write" + JobWrite Role = "admin:job:write" + JobRead Role = "admin:job:read" + LogRead Role = "admin:log:read" + UserdataRead Role = "admin:userdata:read" + UserdataWrite Role = "admin:userdata:write" + TicketDelete Role = "admin:ticket:delete" + UserWrite Role = "admin:user:write" +) + +func (p Role) String() string { + return string(p) +} + +func UserHasRoles(user *models.UserResponse, roles []Role) bool { + hasRoles := true + for _, role := range roles { + if !UserHasRole(user, role) { + hasRoles = false + break + } + } + return hasRoles +} + +func UserHasRole(user *models.UserResponse, role Role) bool { + return ContainsRole(FromStrings(user.Roles), role) +} + +func ContainsRole(roles []Role, role Role) bool { + for _, r := range roles { + if r.String() == role.String() { // || strings.HasPrefix(role.String(), r.String()+":") + return true + } + } + return false +} + +func Explodes(s []string) []Role { + var roles []Role + for _, e := range s { + roles = append(roles, Explode(e)...) + } + roles = unique(roles) + sort.Slice(roles, func(i, j int) bool { + return roles[i].String() < roles[j].String() + }) + + return roles +} + +func Explode(s string) []Role { + var roles []Role + + switch s { + case Admin: + roles = append(roles, listPrefix(Admin)...) + fallthrough + case Engineer: + roles = append(roles, listPrefix(Engineer)...) + fallthrough + case Analyst: + roles = append(roles, listPrefix(Analyst)...) + return roles + } + + for _, role := range List() { + if role.String() == s { + roles = append(roles, role) + } + } + + return roles +} + +func listPrefix(s string) []Role { + var roles []Role + + for _, role := range List() { + if strings.HasPrefix(role.String(), s+":") { + roles = append(roles, role) + } + } + + return roles +} + +func unique(l []Role) []Role { + keys := make(map[Role]bool) + var list []Role + for _, entry := range l { + if _, value := keys[entry]; !value { + keys[entry] = true + list = append(list, entry) + } + } + return list +} + +func List() []Role { + return []Role{ + AutomationRead, CurrentuserdataRead, CurrentuserdataWrite, + CurrentuserRead, FileReadWrite, GroupRead, PlaybookRead, RuleRead, + UserdataRead, SettingsRead, TemplateRead, TicketRead, TickettypeRead, + TicketWrite, UserRead, AutomationWrite, PlaybookWrite, RuleWrite, + TemplateWrite, TickettypeWrite, BackupRead, BackupRestore, GroupWrite, + LogRead, UserdataWrite, TicketDelete, UserWrite, JobRead, JobWrite, + } +} + +func fromString(s string) (Role, error) { + for _, role := range List() { + if role.String() == s { + return role, nil + } + } + + return "", errors.New("unknown role") +} + +func Strings(roles []Role) []string { + var s []string + for _, role := range roles { + s = append(s, role.String()) + } + return s +} + +func FromStrings(s []string) []Role { + var roles []Role + for _, e := range s { + role, err := fromString(e) + if err != nil { + continue + } + roles = append(roles, role) + } + return roles +} diff --git a/server.go b/server.go new file mode 100644 index 0000000..3643123 --- /dev/null +++ b/server.go @@ -0,0 +1,143 @@ +package catalyst + +import ( + "context" + "time" + + "github.com/gin-contrib/cors" + "github.com/gin-contrib/sessions" + "github.com/gin-contrib/sessions/cookie" + + "github.com/SecurityBrewery/catalyst/automation" + "github.com/SecurityBrewery/catalyst/bus" + "github.com/SecurityBrewery/catalyst/database" + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi" + "github.com/SecurityBrewery/catalyst/hooks" + "github.com/SecurityBrewery/catalyst/index" + "github.com/SecurityBrewery/catalyst/role" + "github.com/SecurityBrewery/catalyst/service" + "github.com/SecurityBrewery/catalyst/storage" +) + +type Config struct { + IndexPath string + DB *database.Config + Storage *storage.Config + Bus *bus.Config + + UISettings *models.Settings + Secret []byte + Auth *AuthConfig + ExternalAddress string + InitialAPIKey string +} + +type Server struct { + Bus *bus.Bus + DB *database.Database + Index *index.Index + Storage *storage.Storage + Server *restapi.Server +} + +func New(hooks *hooks.Hooks, config *Config) (*Server, error) { + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, time.Second*30) + defer cancel() + + err := config.Auth.Load(ctx) + if err != nil { + return nil, err + } + + catalystStorage, err := storage.New(config.Storage) + if err != nil { + return nil, err + } + + catalystIndex, err := index.New(config.IndexPath) + if err != nil { + return nil, err + } + + catalystBus, err := bus.New(config.Bus) + if err != nil { + return nil, err + } + + catalystDatabase, err := database.New(ctx, catalystIndex, catalystBus, hooks, config.DB) + if err != nil { + return nil, err + } + + err = automation.New(config.Bus.APIUrl, config.InitialAPIKey, catalystBus, catalystDatabase) + if err != nil { + return nil, err + } + + catalystService, err := service.New(catalystBus, catalystDatabase, catalystStorage, config.UISettings) + if err != nil { + return nil, err + } + + if config.InitialAPIKey != "" { + _ = catalystDatabase.UserDelete(ctx, "setup") + + ctx = busdb.UserContext(ctx, &models.UserResponse{ + ID: "setup", + Roles: role.Strings(role.Explode(role.Admin)), + Apikey: false, + Blocked: false, + }) + _, err = catalystDatabase.UserCreateSetupAPIKey(ctx, config.InitialAPIKey) + if err != nil { + return nil, err + } + } + + apiServer, err := setupAPI(catalystService, catalystStorage, catalystDatabase, config.DB, catalystBus, config) + if err != nil { + return nil, err + } + + return &Server{ + Bus: catalystBus, + DB: catalystDatabase, + Index: catalystIndex, + Storage: catalystStorage, + Server: apiServer, + }, nil +} + +func setupAPI(catalystService *service.Service, catalystStorage *storage.Storage, catalystDatabase *database.Database, dbConfig *database.Config, bus *bus.Bus, config *Config) (*restapi.Server, error) { + // session + store := cookie.NewStore(config.Secret) + setSession := sessions.Sessions(SessionName, store) + + authenticate := Authenticate(catalystDatabase, config.Auth) + + // create server + apiServer := restapi.New(catalystService, &restapi.Config{Address: "0.0.0.0:8000", InsecureHTTP: true}) + apiServer.UseRawPath = true + + apiServer.ApiGroup.Use(setSession, authenticate, AuthorizeBlockedUser) + apiServer.RoleAuth = AuthorizeRole + + apiServer.ConfigureRoutes() + apiServer.ApiGroup.HEAD("/files/:ticketID/upload/:id", AuthorizeRole([]role.Role{role.FileReadWrite}), upload(catalystStorage.S3(), config.ExternalAddress)) + apiServer.ApiGroup.PATCH("/files/:ticketID/upload/:id", AuthorizeRole([]role.Role{role.FileReadWrite}), upload(catalystStorage.S3(), config.ExternalAddress)) + apiServer.ApiGroup.POST("/files/:ticketID/upload", AuthorizeRole([]role.Role{role.FileReadWrite}), upload(catalystStorage.S3(), config.ExternalAddress)) + apiServer.ApiGroup.GET("/files/:ticketID/download/:key", AuthorizeRole([]role.Role{role.FileReadWrite}), download(catalystStorage.Downloader())) + + apiServer.ApiGroup.GET("/backup/create", AuthorizeRole([]role.Role{role.BackupRead}), BackupHandler(catalystStorage, dbConfig)) + apiServer.ApiGroup.POST("/backup/restore", AuthorizeRole([]role.Role{role.BackupRestore}), RestoreHandler(catalystStorage, catalystDatabase, dbConfig)) + + apiServer.GET("/callback", setSession, callback(config.Auth)) + apiServer.Any("/wss", setSession, authenticate, AuthorizeBlockedUser, handleWebSocket(bus)) + apiServer.NoRoute(setSession, authenticate, AuthorizeBlockedUser, static) + + apiServer.Use(cors.Default()) + return apiServer, nil +} diff --git a/service/artifact.go b/service/artifact.go new file mode 100644 index 0000000..a5a960a --- /dev/null +++ b/service/artifact.go @@ -0,0 +1,34 @@ +package service + +import ( + "context" + + "github.com/google/uuid" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/tickets" +) + +func (s *Service) RunArtifact(ctx context.Context, params *tickets.RunArtifactParams) *api.Response { + artifact, err := s.database.ArtifactGet(ctx, params.ID, params.Name) + if err != nil { + return response(nil, err) + } + + jobID := uuid.NewString() + origin := &models.Origin{ArtifactOrigin: &models.ArtifactOrigin{TicketId: params.ID, Artifact: params.Name}} + return response(nil, s.bus.PublishJob(jobID, params.Automation, params.Name, &models.Context{Artifact: artifact}, origin)) +} + +func (s *Service) EnrichArtifact(ctx context.Context, params *tickets.EnrichArtifactParams) *api.Response { + return response(s.database.EnrichArtifact(ctx, params.ID, params.Name, params.Data)) +} + +func (s *Service) SetArtifact(ctx context.Context, params *tickets.SetArtifactParams) *api.Response { + return response(s.database.ArtifactUpdate(ctx, params.ID, params.Name, params.Artifact)) +} + +func (s *Service) GetArtifact(ctx context.Context, params *tickets.GetArtifactParams) *api.Response { + return response(s.database.ArtifactGet(ctx, params.ID, params.Name)) +} diff --git a/service/automation.go b/service/automation.go new file mode 100644 index 0000000..1461619 --- /dev/null +++ b/service/automation.go @@ -0,0 +1,28 @@ +package service + +import ( + "context" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/automations" +) + +func (s *Service) CreateAutomation(ctx context.Context, params *automations.CreateAutomationParams) *api.Response { + return response(s.database.AutomationCreate(ctx, params.Automation)) +} + +func (s *Service) GetAutomation(ctx context.Context, params *automations.GetAutomationParams) *api.Response { + return response(s.database.AutomationGet(ctx, params.ID)) +} + +func (s *Service) UpdateAutomation(ctx context.Context, params *automations.UpdateAutomationParams) *api.Response { + return response(s.database.AutomationUpdate(ctx, params.ID, params.Automation)) +} + +func (s *Service) DeleteAutomation(ctx context.Context, params *automations.DeleteAutomationParams) *api.Response { + return response(nil, s.database.AutomationDelete(ctx, params.ID)) +} + +func (s *Service) ListAutomations(ctx context.Context) *api.Response { + return response(s.database.AutomationList(ctx)) +} diff --git a/service/job.go b/service/job.go new file mode 100644 index 0000000..cc5bf03 --- /dev/null +++ b/service/job.go @@ -0,0 +1,29 @@ +package service + +import ( + "context" + + "github.com/google/uuid" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/jobs" +) + +func (s *Service) RunJob(_ context.Context, params *jobs.RunJobParams) *api.Response { + msgContext := &models.Context{} + jobID := uuid.NewString() + return response(nil, s.bus.PublishJob(jobID, params.Job.Automation, params.Job.Payload, msgContext, params.Job.Origin)) +} + +func (s *Service) GetJob(ctx context.Context, params *jobs.GetJobParams) *api.Response { + return response(s.database.JobGet(ctx, params.ID)) +} + +func (s *Service) ListJobs(ctx context.Context) *api.Response { + return response(s.database.JobList(ctx)) +} + +func (s *Service) UpdateJob(ctx context.Context, params *jobs.UpdateJobParams) *api.Response { + return response(s.database.JobUpdate(ctx, params.ID, params.Job)) +} diff --git a/service/log.go b/service/log.go new file mode 100644 index 0000000..4c8892f --- /dev/null +++ b/service/log.go @@ -0,0 +1,14 @@ +package service + +import ( + "context" + "net/url" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/logs" +) + +func (s *Service) GetLogs(ctx context.Context, params *logs.GetLogsParams) *api.Response { + id, _ := url.QueryUnescape(params.Reference) + return response(s.database.LogList(ctx, id)) +} diff --git a/service/playbook.go b/service/playbook.go new file mode 100644 index 0000000..c36430f --- /dev/null +++ b/service/playbook.go @@ -0,0 +1,53 @@ +package service + +import ( + "context" + "fmt" + "strings" + + "github.com/xeipuuv/gojsonschema" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/playbooks" +) + +func (s *Service) CreatePlaybook(ctx context.Context, params *playbooks.CreatePlaybookParams) *api.Response { + return response(s.database.PlaybookCreate(ctx, params.Playbook)) +} + +func (s *Service) GetPlaybook(ctx context.Context, params *playbooks.GetPlaybookParams) *api.Response { + return response(s.database.PlaybookGet(ctx, params.ID)) +} + +func (s *Service) UpdatePlaybook(ctx context.Context, params *playbooks.UpdatePlaybookParams) *api.Response { + if err := validate(params.Playbook, models.PlaybookTemplateFormSchema); err != nil { + return response(nil, err) + } + + return response(s.database.PlaybookUpdate(ctx, params.ID, params.Playbook)) +} + +func (s *Service) DeletePlaybook(ctx context.Context, params *playbooks.DeletePlaybookParams) *api.Response { + return response(nil, s.database.PlaybookDelete(ctx, params.ID)) +} + +func (s *Service) ListPlaybooks(ctx context.Context) *api.Response { + return response(s.database.PlaybookList(ctx)) +} + +func validate(e interface{}, schema *gojsonschema.Schema) error { + res, err := schema.Validate(gojsonschema.NewGoLoader(e)) + if err != nil { + return err + } + + if len(res.Errors()) > 0 { + var l []string + for _, e := range res.Errors() { + l = append(l, e.String()) + } + return fmt.Errorf("validation failed: %v", strings.Join(l, ", ")) + } + return nil +} diff --git a/service/service.go b/service/service.go new file mode 100644 index 0000000..9e23fa7 --- /dev/null +++ b/service/service.go @@ -0,0 +1,51 @@ +package service + +import ( + "errors" + "log" + "net/http" + + "github.com/arangodb/go-driver" + "github.com/gin-gonic/gin" + + "github.com/SecurityBrewery/catalyst/bus" + "github.com/SecurityBrewery/catalyst/database" + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" + "github.com/SecurityBrewery/catalyst/storage" +) + +type Service struct { + bus *bus.Bus + database *database.Database + settings *models.Settings + storage *storage.Storage +} + +func New(bus *bus.Bus, database *database.Database, storage *storage.Storage, settings *models.Settings) (*Service, error) { + return &Service{database: database, bus: bus, settings: settings, storage: storage}, nil +} + +func (s *Service) Healthy() bool { + return true +} + +func response(v interface{}, err error) *api.Response { + if err != nil { + log.Println(err) + return &api.Response{Code: httpStatus(err), Body: gin.H{"error": err.Error()}} + } + if v == nil { + return &api.Response{Code: http.StatusNoContent, Body: v} + } + return &api.Response{Code: http.StatusOK, Body: v} +} + +func httpStatus(err error) int { + ae := driver.ArangoError{} + if errors.As(err, &ae) { + return ae.Code + } + + return http.StatusInternalServerError +} diff --git a/service/statistics.go b/service/statistics.go new file mode 100644 index 0000000..f0ea6f2 --- /dev/null +++ b/service/statistics.go @@ -0,0 +1,11 @@ +package service + +import ( + "context" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +func (s *Service) GetStatistics(ctx context.Context) *api.Response { + return response(s.database.Statistics(ctx)) +} diff --git a/service/task.go b/service/task.go new file mode 100644 index 0000000..5343f9e --- /dev/null +++ b/service/task.go @@ -0,0 +1,11 @@ +package service + +import ( + "context" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" +) + +func (s *Service) ListTasks(ctx context.Context) *api.Response { + return response(s.database.TaskList(ctx)) +} diff --git a/service/template.go b/service/template.go new file mode 100644 index 0000000..3321fe2 --- /dev/null +++ b/service/template.go @@ -0,0 +1,28 @@ +package service + +import ( + "context" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/templates" +) + +func (s *Service) CreateTemplate(ctx context.Context, params *templates.CreateTemplateParams) *api.Response { + return response(s.database.TemplateCreate(ctx, params.Template)) +} + +func (s *Service) GetTemplate(ctx context.Context, params *templates.GetTemplateParams) *api.Response { + return response(s.database.TemplateGet(ctx, params.ID)) +} + +func (s *Service) UpdateTemplate(ctx context.Context, params *templates.UpdateTemplateParams) *api.Response { + return response(s.database.TemplateUpdate(ctx, params.ID, params.Template)) +} + +func (s *Service) DeleteTemplate(ctx context.Context, params *templates.DeleteTemplateParams) *api.Response { + return response(nil, s.database.TemplateDelete(ctx, params.ID)) +} + +func (s *Service) ListTemplates(ctx context.Context) *api.Response { + return response(s.database.TemplateList(ctx)) +} diff --git a/service/ticket.go b/service/ticket.go new file mode 100644 index 0000000..bf4a71d --- /dev/null +++ b/service/ticket.go @@ -0,0 +1,52 @@ +package service + +import ( + "context" + "fmt" + + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/tickets" +) + +func (s *Service) CreateTicket(ctx context.Context, params *tickets.CreateTicketParams) *api.Response { + createdTickets, err := s.database.TicketBatchCreate(ctx, []*models.TicketForm{params.Ticket}) + if len(createdTickets) > 0 { + return response(createdTickets[0], err) + } + return response(nil, err) +} + +func (s *Service) CreateTicketBatch(ctx context.Context, params *tickets.CreateTicketBatchParams) *api.Response { + _, err := s.database.TicketBatchCreate(ctx, params.Ticket) + return response(nil, err) +} + +func (s *Service) GetTicket(ctx context.Context, params *tickets.GetTicketParams) *api.Response { + return response(s.database.TicketGet(ctx, params.ID)) +} + +func (s *Service) UpdateTicket(ctx context.Context, params *tickets.UpdateTicketParams) *api.Response { + return response(s.database.TicketUpdate(ctx, params.ID, params.Ticket)) +} + +func (s *Service) DeleteTicket(ctx context.Context, params *tickets.DeleteTicketParams) *api.Response { + if err := s.database.TicketDelete(ctx, params.ID); err != nil { + return response(nil, err) + } + + _ = s.storage.DeleteBucket(fmt.Sprint(params.ID)) + return response(nil, nil) +} + +func (s *Service) ListTickets(ctx context.Context, params *tickets.ListTicketsParams) *api.Response { + q := "" + if params.Query != nil && *params.Query != "" { + q = *params.Query + } + t := "" + if params.Type != nil && *params.Type != "" { + t = *params.Type + } + return response(s.database.TicketList(ctx, t, q, params.Sort, params.Desc, *params.Offset, *params.Count)) +} diff --git a/service/ticket_field.go b/service/ticket_field.go new file mode 100644 index 0000000..d01adaf --- /dev/null +++ b/service/ticket_field.go @@ -0,0 +1,74 @@ +package service + +import ( + "context" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/tickets" +) + +func (s *Service) AddArtifact(ctx context.Context, params *tickets.AddArtifactParams) *api.Response { + return response(s.database.AddArtifact(ctx, params.ID, params.Artifact)) +} + +func (s *Service) RemoveArtifact(ctx context.Context, params *tickets.RemoveArtifactParams) *api.Response { + return response(s.database.RemoveArtifact(ctx, params.ID, params.Name)) +} + +func (s *Service) SetSchema(ctx context.Context, params *tickets.SetSchemaParams) *api.Response { + return response(s.database.SetTemplate(ctx, params.ID, params.Schema)) +} + +func (s *Service) AddComment(ctx context.Context, params *tickets.AddCommentParams) *api.Response { + return response(s.database.AddComment(ctx, params.ID, params.Comment)) +} + +func (s *Service) RemoveComment(ctx context.Context, params *tickets.RemoveCommentParams) *api.Response { + return response(s.database.RemoveComment(ctx, params.ID, params.CommentID)) +} + +func (s *Service) LinkTicket(ctx context.Context, params *tickets.LinkTicketParams) *api.Response { + err := s.database.RelatedCreate(ctx, params.ID, params.LinkedID) + if err != nil { + return response(nil, err) + } + + return s.GetTicket(ctx, &tickets.GetTicketParams{ID: params.ID}) +} + +func (s *Service) UnlinkTicket(ctx context.Context, params *tickets.UnlinkTicketParams) *api.Response { + err := s.database.RelatedRemove(ctx, params.ID, params.LinkedID) + if err != nil { + return response(nil, err) + } + + return s.GetTicket(ctx, &tickets.GetTicketParams{ID: params.ID}) +} + +func (s Service) SetReferences(ctx context.Context, params *tickets.SetReferencesParams) *api.Response { + return response(s.database.SetReferences(ctx, params.ID, params.References)) +} + +func (s Service) LinkFiles(ctx context.Context, params *tickets.LinkFilesParams) *api.Response { + return response(s.database.LinkFiles(ctx, params.ID, params.Files)) +} + +func (s Service) AddTicketPlaybook(ctx context.Context, params *tickets.AddTicketPlaybookParams) *api.Response { + return response(s.database.AddTicketPlaybook(ctx, params.ID, params.Playbook)) +} + +func (s Service) RemoveTicketPlaybook(ctx context.Context, params *tickets.RemoveTicketPlaybookParams) *api.Response { + return response(s.database.RemoveTicketPlaybook(ctx, params.ID, params.PlaybookID)) +} + +func (s Service) CompleteTask(ctx context.Context, params *tickets.CompleteTaskParams) *api.Response { + return response(s.database.TaskComplete(ctx, params.ID, params.PlaybookID, params.TaskID, params.Data)) +} + +func (s Service) SetTask(ctx context.Context, params *tickets.SetTaskParams) *api.Response { + return response(s.database.TaskUpdate(ctx, params.ID, params.PlaybookID, params.TaskID, params.Task)) +} + +func (s *Service) RunTask(ctx context.Context, params *tickets.RunTaskParams) *api.Response { + return response(nil, s.database.TaskRun(ctx, params.ID, params.PlaybookID, params.TaskID)) +} diff --git a/service/tickettype.go b/service/tickettype.go new file mode 100644 index 0000000..e42346a --- /dev/null +++ b/service/tickettype.go @@ -0,0 +1,28 @@ +package service + +import ( + "context" + + "github.com/SecurityBrewery/catalyst/generated/restapi/api" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/tickettypes" +) + +func (s *Service) CreateTicketType(ctx context.Context, params *tickettypes.CreateTicketTypeParams) *api.Response { + return response(s.database.TicketTypeCreate(ctx, params.Tickettype)) +} + +func (s *Service) GetTicketType(ctx context.Context, params *tickettypes.GetTicketTypeParams) *api.Response { + return response(s.database.TicketTypeGet(ctx, params.ID)) +} + +func (s *Service) UpdateTicketType(ctx context.Context, params *tickettypes.UpdateTicketTypeParams) *api.Response { + return response(s.database.TicketTypeUpdate(ctx, params.ID, params.Tickettype)) +} + +func (s *Service) DeleteTicketType(ctx context.Context, params *tickettypes.DeleteTicketTypeParams) *api.Response { + return response(nil, s.database.TicketTypeDelete(ctx, params.ID)) +} + +func (s *Service) ListTicketTypes(ctx context.Context) *api.Response { + return response(s.database.TicketTypeList(ctx)) +} diff --git a/service/uisettings.go b/service/uisettings.go new file mode 100644 index 0000000..56c48d8 --- /dev/null +++ b/service/uisettings.go @@ -0,0 +1,46 @@ +package service + +import ( + "context" + "errors" + "sort" + + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" + "github.com/SecurityBrewery/catalyst/role" +) + +func (s *Service) GetSettings(ctx context.Context) *api.Response { + user, ok := busdb.UserFromContext(ctx) + if !ok { + return response(nil, errors.New("no user in context")) + } + + setting, err := s.database.UserDataGet(ctx, user.ID) + if err != nil { + return response(nil, err) + } + + settings := mergeSettings(s.settings, setting) + + ticketTypeList, err := s.database.TicketTypeList(ctx) + if err != nil { + return response(nil, err) + } + + settings.TicketTypes = ticketTypeList + + return response(settings, nil) +} + +func mergeSettings(globalSettings *models.Settings, user *models.UserDataResponse) *models.Settings { + if user.Timeformat != nil { + globalSettings.Timeformat = *user.Timeformat + } + roles := role.Strings(role.List()) + sort.Strings(roles) + globalSettings.Roles = roles + + return globalSettings +} diff --git a/service/user.go b/service/user.go new file mode 100644 index 0000000..56c7fea --- /dev/null +++ b/service/user.go @@ -0,0 +1,38 @@ +package service + +import ( + "context" + "errors" + + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/users" +) + +func (s *Service) GetUser(ctx context.Context, params *users.GetUserParams) *api.Response { + return response(s.database.UserGet(ctx, params.ID)) +} + +func (s *Service) ListUsers(ctx context.Context) *api.Response { + return response(s.database.UserList(ctx)) +} + +func (s *Service) CreateUser(ctx context.Context, params *users.CreateUserParams) *api.Response { + return response(s.database.UserCreate(ctx, params.User)) +} + +func (s *Service) DeleteUser(ctx context.Context, params *users.DeleteUserParams) *api.Response { + return response(nil, s.database.UserDelete(ctx, params.ID)) +} + +func (s *Service) CurrentUser(ctx context.Context) *api.Response { + user, ok := busdb.UserFromContext(ctx) + if !ok { + return response(nil, errors.New("no user in context")) + } + return response(user, nil) +} + +func (s *Service) UpdateUser(ctx context.Context, params *users.UpdateUserParams) *api.Response { + return response(s.database.UserUpdate(ctx, params.ID, params.User)) +} diff --git a/service/userdata.go b/service/userdata.go new file mode 100644 index 0000000..7e8e10e --- /dev/null +++ b/service/userdata.go @@ -0,0 +1,39 @@ +package service + +import ( + "context" + "errors" + + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/restapi/api" + "github.com/SecurityBrewery/catalyst/generated/restapi/operations/userdata" +) + +func (s *Service) GetUserData(ctx context.Context, params *userdata.GetUserDataParams) *api.Response { + return response(s.database.UserDataGet(ctx, params.ID)) +} + +func (s *Service) ListUserData(ctx context.Context) *api.Response { + return response(s.database.UserDataList(ctx)) +} + +func (s *Service) UpdateUserData(ctx context.Context, params *userdata.UpdateUserDataParams) *api.Response { + return response(s.database.UserDataUpdate(ctx, params.ID, params.Userdata)) +} + +func (s *Service) CurrentUserData(ctx context.Context) *api.Response { + user, ok := busdb.UserFromContext(ctx) + if !ok { + return response(nil, errors.New("no user in context")) + } + return s.GetUserData(ctx, &userdata.GetUserDataParams{ID: user.ID}) +} + +func (s *Service) UpdateCurrentUserData(ctx context.Context, params *userdata.UpdateCurrentUserDataParams) *api.Response { + user, ok := busdb.UserFromContext(ctx) + if !ok { + return response(nil, errors.New("no user in context")) + } + + return response(s.database.UserDataUpdate(ctx, user.ID, params.Userdata)) +} diff --git a/start_dev.sh b/start_dev.sh new file mode 100644 index 0000000..ae152c3 --- /dev/null +++ b/start_dev.sh @@ -0,0 +1,20 @@ +export SECRET=4ef5b29539b70233dd40c02a1799d25079595565e05a193b09da2c3e60ada1cd + +export OIDC_ISSUER=http://localhost:9002/auth/realms/catalyst +export OIDC_CLIENT_SECRET=d3ec0d91-b6ea-482d-8a4e-2f5a7ca0b4cb + +export ARANGO_DB_HOST=http://localhost:8529 +export ARANGO_DB_PASSWORD=foobar +export S3_HOST=http://localhost:9000 +export S3_PASSWORD=minio123 +export EMITTER_IO_HOST=tcp://localhost:9001 +export EMITTER_IO_KEY=A9RysEsPJni8RaHeg_K0FKXQNfBrUyw- + +export AUTH_BLOCK_NEW=false +export AUTH_DEFAULT_ROLES=analyst,admin + +export EXTERNAL_ADDRESS=http://localhost +export CATALYST_ADDRESS=http://host.docker.internal +export INITIAL_API_KEY=d0169af94c40981eb4452a42fae536b6caa9be3a + +go run cmd/catalyst-dev/*.go diff --git a/static.go b/static.go new file mode 100644 index 0000000..7ecc7ef --- /dev/null +++ b/static.go @@ -0,0 +1,24 @@ +package catalyst + +import ( + "io/fs" + "net/http" + "strings" + + "github.com/gin-gonic/gin" + + "github.com/SecurityBrewery/catalyst/ui" +) + +func static(ctx *gin.Context) { + fsys, _ := fs.Sub(ui.UI, "dist") + + upath := strings.TrimPrefix(ctx.Request.URL.Path, "/") + + if _, err := fs.Stat(fsys, upath); err != nil { + ctx.Request.URL.Path = "/" + ctx.Request.URL.RawPath = "/" + } + + http.FileServer(http.FS(fsys)).ServeHTTP(ctx.Writer, ctx.Request) +} diff --git a/storage/storage.go b/storage/storage.go new file mode 100644 index 0000000..25472d4 --- /dev/null +++ b/storage/storage.go @@ -0,0 +1,71 @@ +package storage + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/s3" + "github.com/aws/aws-sdk-go/service/s3/s3manager" + + "github.com/SecurityBrewery/catalyst/pointer" +) + +type Storage struct { + session *session.Session +} + +type Config struct { + Host string + User string + Password string +} + +func New(config *Config) (*Storage, error) { + s, err := session.NewSession(&aws.Config{ + Credentials: credentials.NewStaticCredentials(config.User, config.Password, ""), + Endpoint: aws.String(config.Host), + Region: aws.String("us-east-1"), + DisableSSL: aws.Bool(true), + S3ForcePathStyle: aws.Bool(true), + }) + return &Storage{s}, err +} + +func (s *Storage) S3() *s3.S3 { + return s3.New(s.session) +} + +func (s *Storage) Downloader() *s3manager.Downloader { + d := s3manager.NewDownloader(s.session) + d.Concurrency = 1 + return d +} + +func (s *Storage) Uploader() *s3manager.Uploader { + d := s3manager.NewUploader(s.session) + d.Concurrency = 1 + return d +} + +func (s *Storage) DeleteBucket(name string) error { + _, err := s.S3().DeleteBucket(&s3.DeleteBucketInput{Bucket: pointer.String("catalyst-" + name)}) + return err +} + +func CreateBucket(client *s3.S3, ticketID string) error { + _, err := client.CreateBucket(&s3.CreateBucketInput{Bucket: pointer.String("catalyst-" + ticketID)}) + if err == nil { + err = client.WaitUntilBucketExists(&s3.HeadBucketInput{Bucket: pointer.String("catalyst-" + ticketID)}) + if err != nil { + return err + } + } else { + awsError, ok := err.(awserr.Error) + if !ok || (awsError.Code() != s3.ErrCodeBucketAlreadyExists && awsError.Code() != s3.ErrCodeBucketAlreadyOwnedByYou) { + return err + } + return nil + } + return err +} diff --git a/test/data.go b/test/data.go new file mode 100644 index 0000000..fcbd4ab --- /dev/null +++ b/test/data.go @@ -0,0 +1,93 @@ +package test + +import ( + "context" + "time" + + "github.com/SecurityBrewery/catalyst/database" + "github.com/SecurityBrewery/catalyst/database/migrations" + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/pointer" +) + +var bobSetting = &models.UserData{Email: pointer.String("bob@example.org"), Name: pointer.String("Bob Bad")} +var bobForm = &models.UserForm{ID: "bob", Blocked: false, Roles: []string{"admin"}} +var Bob = &models.UserResponse{ID: "bob", Blocked: false, Roles: []string{"admin"}} + +func SetupTestData(ctx context.Context, db *database.Database) error { + if err := db.UserDataCreate(ctx, "bob", bobSetting); err != nil { + return err + } + + if _, err := db.UserCreate(ctx, bobForm); err != nil { + return err + } + if _, err := db.UserCreate(ctx, &models.UserForm{ID: "script", Roles: []string{"engineer"}, Apikey: true}); err != nil { + return err + } + + if _, err := db.TicketBatchCreate(ctx, []*models.TicketForm{ + { + ID: pointer.Int64(8125), + Created: parse("2021-10-02T18:04:59.078186+02:00"), + Modified: parse("2021-10-02T18:04:59.078186+02:00"), + Name: "phishing from selenafadel@von.com detected", + Owner: pointer.String("demo"), + References: []*models.Reference{{Href: "https://www.seniorleading-edge.name/users/efficient", Name: "recovery"}, {Href: "http://www.dynamicseamless.com/clicks-and-mortar", Name: "force"}, {Href: "http://www.leadscalable.biz/envisioneer", Name: "fund"}}, + Schema: pointer.String("{}"), + Status: "closed", + Type: "alert", + }, { + ID: pointer.Int64(8126), + Created: parse("2021-10-02T18:04:59.078186+02:00"), + Modified: parse("2021-10-02T18:04:59.078186+02:00"), + Name: "Surfaceintroduce virus detected", + Owner: pointer.String("demo"), + References: []*models.Reference{{Href: "http://www.centralworld-class.io/synthesize", Name: "university"}, {Href: "https://www.futurevirtual.org/supply-chains/markets/sticky/iterate", Name: "goal"}, {Href: "http://www.chiefsyndicate.io/action-items", Name: "unemployment"}}, + Schema: pointer.String("{}"), + Status: "closed", + Type: "alert", + }, { + ID: pointer.Int64(8123), + Created: parse("2021-10-02T18:04:59.078206+02:00"), + Modified: parse("2021-10-02T18:04:59.078206+02:00"), + Artifacts: []*models.Artifact{ + {Name: "94d5cab6f5fe3422a447ab15436e7a672bc0c09a", Status: pointer.String("unknown")}, + {Name: "http://www.customerviral.io/scalable/vertical/killer", Status: pointer.String("clean")}, + {Name: "leadreintermediate.io", Status: pointer.String("malicious")}, + }, + Name: "live zebra", + Owner: pointer.String("demo"), + References: []*models.Reference{{Href: "https://www.leadmaximize.net/e-services/back-end", Name: "performance"}, {Href: "http://www.corporateinteractive.name/rich", Name: "autumn"}, {Href: "https://www.corporateintuitive.org/intuitive/platforms/integrate", Name: "suggest"}}, + Schema: pointer.String("{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n"), + Status: "closed", + Type: "incident", + Playbooks: []*models.PlaybookTemplateForm{ + {Yaml: migrations.PhishingPlaybook}, + }, + }, + }); err != nil { + return err + } + + if err := db.RelatedCreate(ctx, 8125, 8126); err != nil { + return err + } + if _, err := db.PlaybookCreate(ctx, &models.PlaybookTemplateForm{Yaml: "name: Simple\ntasks:\n input:\n name: Enter something to hash\n type: input\n schema:\n title: Something\n type: object\n properties:\n something:\n type: string\n title: Something\n default: \"\"\n next:\n hash: \"something != ''\"\n\n hash:\n name: Hash the something\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['something']\"\n next:\n comment: \"hash != ''\"\n\n comment:\n name: Comment the hash\n type: automation\n automation: comment\n payload:\n default: \"playbook.tasks['hash'].data['hash']\"\n next:\n done: \"done\"\n\n done:\n name: You can close this case now\n type: task\n"}); err != nil { + return err + } + + if _, err := db.LogCreate(ctx, "tickets/294511", "Fail run account resist lend solve incident centre priority temperature. Cause change distribution examine location technique shape partner milk customer. Rail tea plate soil report cook railway interpretation breath action. Exercise dream accept park conclusion addition shoot assistance may answer. Gold writer link stop combine hear power name commitment operation. Determine lifespan support grow degree henry exclude detail set religion. Direct library policy convention chain retain discover ride walk student. Gather proposal select march aspect play noise avoid encourage employ. Assessment preserve transport combine wish influence income guess run stand. Charge limit crime ignore statement foundation study issue stop claim."); err != nil { + return err + } + + return nil +} + +func parse(s string) *time.Time { + modified, err := time.Parse(time.RFC3339, s) + if err != nil { + panic(err) + } + return &modified +} diff --git a/test/server_test.go b/test/server_test.go new file mode 100644 index 0000000..d12b1dc --- /dev/null +++ b/test/server_test.go @@ -0,0 +1,104 @@ +package test + +import ( + "bytes" + "encoding/json" + "io" + "net/http" + "net/http/httptest" + "reflect" + "testing" + + "github.com/gin-gonic/gin" + + "github.com/SecurityBrewery/catalyst/database/busdb" +) + +func TestService(t *testing.T) { + gin.SetMode(gin.TestMode) + + type args struct { + method string + url string + data interface{} + } + type want struct { + status int + body interface{} + } + tests := []struct { + name string + args args + want want + }{ + {name: "GetUser not existing", args: args{method: http.MethodGet, url: "/api/users/123"}, want: want{status: http.StatusNotFound, body: gin.H{"error": "document not found"}}}, + {name: "ListUsers", args: args{method: http.MethodGet, url: "/api/users"}, want: want{status: http.StatusOK}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, _, _, _, _, _, _, server, cleanup, err := Server(t) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + setUser := func(context *gin.Context) { + busdb.SetContext(context, Bob) + } + server.Use(setUser) + + server.ConfigureRoutes() + w := httptest.NewRecorder() + + // setup request + var req *http.Request + if tt.args.data != nil { + b, err := json.Marshal(tt.args.data) + if err != nil { + t.Fatal(err) + } + + req = httptest.NewRequest(tt.args.method, tt.args.url, bytes.NewBuffer(b)) + req.Header.Set("Content-Type", "application/json") + } else { + req = httptest.NewRequest(tt.args.method, tt.args.url, nil) + } + + // run request + server.ServeHTTP(w, req) + + result := w.Result() + + // assert results + if result.StatusCode != tt.want.status { + t.Fatalf("Status got = %v, want %v", result.Status, tt.want.status) + } + if tt.want.status != http.StatusNoContent { + jsonEqual(t, result.Body, tt.want.body) + } + }) + } +} + +func jsonEqual(t *testing.T, got io.Reader, want interface{}) { + var j, j2 interface{} + c, err := io.ReadAll(got) + if err != nil { + t.Fatal(err) + } + if err := json.Unmarshal(c, &j); err != nil { + t.Fatal(string(c), err) + } + + b, err := json.Marshal(want) + if err != nil { + t.Fatal(err) + } + if err = json.Unmarshal(b, &j2); err != nil { + t.Fatal(err) + } + + if !reflect.DeepEqual(j2, j) { + t.Errorf("Body got = %T:%v, want %T:%v", j, j, j2, j2) + } +} diff --git a/test/test.go b/test/test.go new file mode 100644 index 0000000..e6f1929 --- /dev/null +++ b/test/test.go @@ -0,0 +1,213 @@ +package test + +import ( + "context" + "log" + "net/http/httptest" + "os" + "path" + "strings" + "testing" + + "github.com/arangodb/go-driver" + "github.com/coreos/go-oidc/v3/oidc" + "github.com/gin-gonic/gin" + "golang.org/x/oauth2" + + "github.com/SecurityBrewery/catalyst" + "github.com/SecurityBrewery/catalyst/bus" + "github.com/SecurityBrewery/catalyst/database" + "github.com/SecurityBrewery/catalyst/database/busdb" + "github.com/SecurityBrewery/catalyst/generated/models" + "github.com/SecurityBrewery/catalyst/generated/restapi" + "github.com/SecurityBrewery/catalyst/hooks" + "github.com/SecurityBrewery/catalyst/index" + "github.com/SecurityBrewery/catalyst/pointer" + "github.com/SecurityBrewery/catalyst/service" + "github.com/SecurityBrewery/catalyst/storage" +) + +func Context() context.Context { + w := httptest.NewRecorder() + gctx, _ := gin.CreateTestContext(w) + busdb.SetContext(gctx, Bob) + return gctx +} + +func Config(ctx context.Context) (*catalyst.Config, error) { + config := &catalyst.Config{ + IndexPath: "index.bleve", + DB: &database.Config{ + Host: "http://localhost:8529", + User: "root", + Password: "foobar", + }, + Storage: &storage.Config{ + Host: "http://localhost:9000", + User: "minio", + Password: "minio123", + }, + Bus: &bus.Config{ + Host: "tcp://localhost:9001", + Key: "A9RysEsPJni8RaHeg_K0FKXQNfBrUyw-", + APIUrl: "http://localhost:8002/api", + }, + UISettings: &models.Settings{ + ArtifactStates: []*models.Type{ + {Icon: "mdi-help-circle-outline", ID: "unknown", Name: "Unknown", Color: pointer.String(models.TypeColorInfo)}, + {Icon: "mdi-skull", ID: "malicious", Name: "Malicious", Color: pointer.String(models.TypeColorError)}, + {Icon: "mdi-check", ID: "clean", Name: "Clean", Color: pointer.String(models.TypeColorSuccess)}, + }, + TicketTypes: []*models.TicketTypeResponse{ + {ID: "alert", Icon: "mdi-alert", Name: "Alerts"}, + {ID: "incident", Icon: "mdi-radioactive", Name: "Incidents"}, + {ID: "investigation", Icon: "mdi-fingerprint", Name: "Forensic Investigations"}, + {ID: "hunt", Icon: "mdi-target", Name: "Threat Hunting"}, + }, + Version: "0.0.0-test", + Tier: models.SettingsTierCommunity, + Timeformat: "YYYY-MM-DDThh:mm:ss", + }, + Secret: []byte("4ef5b29539b70233dd40c02a1799d25079595565e05a193b09da2c3e60ada1cd"), + Auth: &catalyst.AuthConfig{ + OIDCIssuer: "http://localhost:9002/auth/realms/catalyst", + OAuth2: &oauth2.Config{ + ClientID: "catalyst", + ClientSecret: "13d4a081-7395-4f71-a911-bc098d8d3c45", + RedirectURL: "http://localhost:8002/callback", + Scopes: []string{oidc.ScopeOpenID, "profile", "email"}, + }, + // OIDCClaimUsername: "", + // OIDCClaimEmail: "", + // OIDCClaimName: "", + // AuthBlockNew: false, + // AuthDefaultRoles: nil, + }, + } + err := config.Auth.Load(ctx) + if err != nil { + return nil, err + } + + return config, err +} + +func Index(t *testing.T) (*index.Index, func(), error) { + dir, err := os.MkdirTemp("", "catalyst-test-"+cleanName(t)) + if err != nil { + return nil, nil, err + } + + catalystIndex, err := index.New(path.Join(dir, "index.bleve")) + if err != nil { + return nil, nil, err + } + return catalystIndex, func() { os.RemoveAll(dir) }, nil +} + +func Bus(t *testing.T) (context.Context, *catalyst.Config, *bus.Bus, error) { + ctx := Context() + + config, err := Config(ctx) + if err != nil { + t.Fatal(err) + } + + catalystBus, err := bus.New(config.Bus) + if err != nil { + t.Fatal(err) + } + return ctx, config, catalystBus, err +} + +func DB(t *testing.T) (context.Context, *catalyst.Config, *bus.Bus, *index.Index, *storage.Storage, *database.Database, func(), error) { + ctx, config, rbus, err := Bus(t) + if err != nil { + return nil, nil, nil, nil, nil, nil, nil, err + } + + catalystStorage, err := storage.New(config.Storage) + if err != nil { + return nil, nil, nil, nil, nil, nil, nil, err + } + + catalystIndex, cleanup, err := Index(t) + if err != nil { + return nil, nil, nil, nil, nil, nil, nil, err + } + + c := config.DB + c.Name = cleanName(t) + db, err := database.New(ctx, catalystIndex, rbus, &hooks.Hooks{ + DatabaseAfterConnectFuncs: []func(ctx context.Context, client driver.Client, name string){Clear}, + }, c) + if err != nil { + return nil, nil, nil, nil, nil, nil, nil, err + } + + _, err = db.JobCreate(ctx, "99cd67131b48", &models.JobForm{ + Automation: "hash.sha1", + Payload: "test", + Origin: nil, + }) + if err != nil { + return nil, nil, nil, nil, nil, nil, nil, err + } + + return ctx, config, rbus, catalystIndex, catalystStorage, db, func() { + err := db.Remove(context.Background()) + if err != nil { + log.Println(err) + } + cleanup() + }, err +} + +func Service(t *testing.T) (context.Context, *catalyst.Config, *bus.Bus, *index.Index, *storage.Storage, *database.Database, *service.Service, func(), error) { + ctx, config, rbus, catalystIndex, catalystStorage, db, cleanup, err := DB(t) + if err != nil { + t.Fatal(err) + } + + catalystService, err := service.New(rbus, db, catalystStorage, config.UISettings) + if err != nil { + t.Fatal(err) + } + + return ctx, config, rbus, catalystIndex, catalystStorage, db, catalystService, cleanup, err +} + +func Server(t *testing.T) (context.Context, *catalyst.Config, *bus.Bus, *index.Index, *storage.Storage, *database.Database, *service.Service, *restapi.Server, func(), error) { + ctx, config, rbus, catalystIndex, catalystStorage, db, catalystService, cleanup, err := Service(t) + if err != nil { + t.Fatal(err) + } + + catalystServer := restapi.New(catalystService, &restapi.Config{Address: "0.0.0.0:8000", InsecureHTTP: true}) + + return ctx, config, rbus, catalystIndex, catalystStorage, db, catalystService, catalystServer, cleanup, err +} + +func cleanName(t *testing.T) string { + name := t.Name() + name = strings.ReplaceAll(name, " ", "") + name = strings.ReplaceAll(name, "/", "_") + return strings.ReplaceAll(name, "#", "_") +} + +func Clear(ctx context.Context, client driver.Client, name string) { + if exists, _ := client.DatabaseExists(ctx, name); exists { + if db, err := client.Database(ctx, name); err == nil { + if exists, _ = db.GraphExists(ctx, database.TicketArtifactsGraphName); exists { + if g, err := db.Graph(ctx, database.TicketArtifactsGraphName); err == nil { + if err := g.Remove(ctx); err != nil { + log.Println(err) + } + } + } + if err := db.Remove(ctx); err != nil { + log.Println(err) + } + } + } +} diff --git a/ui/.browserslistrc b/ui/.browserslistrc new file mode 100644 index 0000000..214388f --- /dev/null +++ b/ui/.browserslistrc @@ -0,0 +1,3 @@ +> 1% +last 2 versions +not dead diff --git a/ui/.eslintrc.js b/ui/.eslintrc.js new file mode 100644 index 0000000..ba02536 --- /dev/null +++ b/ui/.eslintrc.js @@ -0,0 +1,30 @@ +module.exports = { + root: true, + env: { + node: true, + }, + extends: [ + "plugin:vue/essential", + "eslint:recommended", + "@vue/typescript/recommended", + ], + parserOptions: { + ecmaVersion: 2020, + }, + rules: { + "no-console": process.env.NODE_ENV === "production" ? "warn" : "off", + "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off", + 'vue/valid-v-slot': ['error', { + allowModifiers: true, + }], + }, + overrides: [ + { + files: ["**/__tests__/*.{j,t}s?(x)", "**/tests/unit/**/*.spec.{j,t}s?(x)"], + env: { + jest: true, + }, + }, + ], + ignorePatterns: ["src/suggestions/grammar/*.js", "src/views/playbook/vue-blocks/"], +}; diff --git a/ui/README.md b/ui/README.md new file mode 100644 index 0000000..609de9f --- /dev/null +++ b/ui/README.md @@ -0,0 +1,27 @@ +## Project setup + +``` +yarn install +``` + +### Compiles and hot-reloads for development + +``` +yarn serve +``` + +### Compiles and minifies for production + +``` +yarn build +``` + +### Lints and fixes files + +``` +yarn lint +``` + +### Customize configuration + +See [Configuration Reference](https://cli.vuejs.org/config/). diff --git a/ui/babel.config.js b/ui/babel.config.js new file mode 100644 index 0000000..e955840 --- /dev/null +++ b/ui/babel.config.js @@ -0,0 +1,5 @@ +module.exports = { + presets: [ + '@vue/cli-plugin-babel/preset' + ] +} diff --git a/ui/jest.config.js b/ui/jest.config.js new file mode 100644 index 0000000..f9d5bfe --- /dev/null +++ b/ui/jest.config.js @@ -0,0 +1,3 @@ +module.exports = { + preset: "@vue/cli-plugin-unit-jest/presets/typescript-and-babel", +}; diff --git a/ui/package.json b/ui/package.json new file mode 100644 index 0000000..068ce51 --- /dev/null +++ b/ui/package.json @@ -0,0 +1,82 @@ +{ + "name": "catalyst", + "version": "0.2.0", + "private": true, + "scripts": { + "serve": "vue-cli-service serve", + "build": "vue-cli-service build", + "test": "vue-cli-service test:unit", + "lint": "vue-cli-service lint" + }, + "dependencies": { + "@koumoul/vjsf": "2.0.3", + "@mdi/font": "5.9.55", + "@mdi/util": "^0.3.2", + "@types/luxon": "^1.27.0", + "@types/prismjs": "^1.16.5", + "@uppy/core": "^1.18.0", + "@uppy/tus": "^1.8.7", + "@uppy/vue": "^0.2.1", + "ajv": "^8.6.3", + "ant-design-vue": "^1.7.8", + "antlr4": "^4.9.2", + "axios": "^0.21.1", + "chart.js": "2", + "core-js": "^3.15.2", + "graphlib": "^2.1.8", + "json-schema-editor-vue": "^1.2.5", + "just-kebab-case": "^1.1.0", + "less": "3.0.4", + "less-loader": "5.0.0", + "lodash": "^4.17.21", + "luxon": "^1.27.0", + "register-service-worker": "^1.7.2", + "swagger-ui": "^3.50.0", + "vue": "2.6.14", + "vue-axios": "^3.2.4", + "vue-chartjs": "^3.5.1", + "vue-class-component": "^7.2.6", + "vue-cropperjs": "^4.2.0", + "vue-d3-network": "^0.1.28", + "vue-lodash": "^2.1.2", + "vue-luxon": "^0.10.0", + "vue-markdown": "^2.2.4", + "vue-native-websocket": "^2.0.14", + "vue-pipeline": "^1.0.12", + "vue-prism-editor": "^1.2.2", + "vue-property-decorator": "^9.1.2", + "vue-router": "^3.2.0", + "vuetify": "2.4.6", + "vuex": "^3.6.2", + "yaml": "^1.10.2" + }, + "devDependencies": { + "@testing-library/vue": "^5.6.2", + "@types/jest": "^26.0.23", + "@types/lodash": "^4.14.168", + "@types/vue-markdown": "^2.2.1", + "@typescript-eslint/eslint-plugin": "^4.22.1", + "@typescript-eslint/parser": "^4.22.1", + "@vue/cli-plugin-babel": "^4.5.12", + "@vue/cli-plugin-eslint": "^4.5.12", + "@vue/cli-plugin-pwa": "^4.5.12", + "@vue/cli-plugin-router": "^4.5.12", + "@vue/cli-plugin-typescript": "^4.5.12", + "@vue/cli-plugin-unit-jest": "^4.5.12", + "@vue/cli-plugin-vuex": "^4.5.12", + "@vue/cli-service": "^4.5.12", + "@vue/compiler-sfc": "^3.1.2", + "@vue/eslint-config-typescript": "^7.0.0", + "@vue/test-utils": "^1.2.0", + "babel-eslint": "^10.1.0", + "eslint": "^7.25.0", + "eslint-plugin-jest": "^24.3.6", + "eslint-plugin-vue": "^7.9.0", + "sass": "1.32.12", + "sass-loader": "^10", + "typescript": "^4.2.4", + "vue-cli-plugin-vuetify": "~2.3.1", + "vue-template-compiler": "^2.6.14", + "vuetify-loader": "1.7.2" + } +} diff --git a/ui/public/favicon.ico b/ui/public/favicon.ico new file mode 100644 index 0000000..8a916b2 Binary files /dev/null and b/ui/public/favicon.ico differ diff --git a/ui/public/flask.svg b/ui/public/flask.svg new file mode 100644 index 0000000..f758b78 --- /dev/null +++ b/ui/public/flask.svg @@ -0,0 +1,125 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui/public/flask_white.svg b/ui/public/flask_white.svg new file mode 100644 index 0000000..1476170 --- /dev/null +++ b/ui/public/flask_white.svg @@ -0,0 +1,130 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui/public/img/icons/android-chrome-192x192.png b/ui/public/img/icons/android-chrome-192x192.png new file mode 100644 index 0000000..fa3c74d Binary files /dev/null and b/ui/public/img/icons/android-chrome-192x192.png differ diff --git a/ui/public/img/icons/android-chrome-512x512.png b/ui/public/img/icons/android-chrome-512x512.png new file mode 100644 index 0000000..5cef2ef Binary files /dev/null and b/ui/public/img/icons/android-chrome-512x512.png differ diff --git a/ui/public/img/icons/android-chrome-maskable-192x192.png b/ui/public/img/icons/android-chrome-maskable-192x192.png new file mode 100644 index 0000000..fa3c74d Binary files /dev/null and b/ui/public/img/icons/android-chrome-maskable-192x192.png differ diff --git a/ui/public/img/icons/android-chrome-maskable-512x512.png b/ui/public/img/icons/android-chrome-maskable-512x512.png new file mode 100644 index 0000000..5cef2ef Binary files /dev/null and b/ui/public/img/icons/android-chrome-maskable-512x512.png differ diff --git a/ui/public/img/icons/apple-touch-icon-120x120.png b/ui/public/img/icons/apple-touch-icon-120x120.png new file mode 100644 index 0000000..a2d9e7e Binary files /dev/null and b/ui/public/img/icons/apple-touch-icon-120x120.png differ diff --git a/ui/public/img/icons/apple-touch-icon-152x152.png b/ui/public/img/icons/apple-touch-icon-152x152.png new file mode 100644 index 0000000..a62830b Binary files /dev/null and b/ui/public/img/icons/apple-touch-icon-152x152.png differ diff --git a/ui/public/img/icons/apple-touch-icon-180x180.png b/ui/public/img/icons/apple-touch-icon-180x180.png new file mode 100644 index 0000000..576825d Binary files /dev/null and b/ui/public/img/icons/apple-touch-icon-180x180.png differ diff --git a/ui/public/img/icons/apple-touch-icon-60x60.png b/ui/public/img/icons/apple-touch-icon-60x60.png new file mode 100644 index 0000000..d8f6e7c Binary files /dev/null and b/ui/public/img/icons/apple-touch-icon-60x60.png differ diff --git a/ui/public/img/icons/apple-touch-icon-76x76.png b/ui/public/img/icons/apple-touch-icon-76x76.png new file mode 100644 index 0000000..0d99887 Binary files /dev/null and b/ui/public/img/icons/apple-touch-icon-76x76.png differ diff --git a/ui/public/img/icons/apple-touch-icon.png b/ui/public/img/icons/apple-touch-icon.png new file mode 100644 index 0000000..576825d Binary files /dev/null and b/ui/public/img/icons/apple-touch-icon.png differ diff --git a/ui/public/img/icons/favicon-16x16.png b/ui/public/img/icons/favicon-16x16.png new file mode 100644 index 0000000..cb72d8d Binary files /dev/null and b/ui/public/img/icons/favicon-16x16.png differ diff --git a/ui/public/img/icons/favicon-32x32.png b/ui/public/img/icons/favicon-32x32.png new file mode 100644 index 0000000..e586f11 Binary files /dev/null and b/ui/public/img/icons/favicon-32x32.png differ diff --git a/ui/public/img/icons/msapplication-icon-144x144.png b/ui/public/img/icons/msapplication-icon-144x144.png new file mode 100644 index 0000000..9ebb285 Binary files /dev/null and b/ui/public/img/icons/msapplication-icon-144x144.png differ diff --git a/ui/public/img/icons/mstile-150x150.png b/ui/public/img/icons/mstile-150x150.png new file mode 100644 index 0000000..a740f77 Binary files /dev/null and b/ui/public/img/icons/mstile-150x150.png differ diff --git a/ui/public/img/icons/safari-pinned-tab.svg b/ui/public/img/icons/safari-pinned-tab.svg new file mode 100644 index 0000000..1476170 --- /dev/null +++ b/ui/public/img/icons/safari-pinned-tab.svg @@ -0,0 +1,130 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui/public/index.html b/ui/public/index.html new file mode 100644 index 0000000..bb8b158 --- /dev/null +++ b/ui/public/index.html @@ -0,0 +1,19 @@ + + + + + + + + Catalyst + + + +
+ + + + + diff --git a/ui/public/manifest.json b/ui/public/manifest.json new file mode 100644 index 0000000..2c3ebae --- /dev/null +++ b/ui/public/manifest.json @@ -0,0 +1,76 @@ +{ + "icons": [ + { + "src": "./img/icons/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "./img/icons/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "./img/icons/android-chrome-maskable-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "./img/icons/android-chrome-maskable-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "./img/icons/apple-touch-icon-60x60.png", + "sizes": "60x60", + "type": "image/png" + }, + { + "src": "./img/icons/apple-touch-icon-76x76.png", + "sizes": "76x76", + "type": "image/png" + }, + { + "src": "./img/icons/apple-touch-icon-120x120.png", + "sizes": "120x120", + "type": "image/png" + }, + { + "src": "./img/icons/apple-touch-icon-152x152.png", + "sizes": "152x152", + "type": "image/png" + }, + { + "src": "./img/icons/apple-touch-icon-180x180.png", + "sizes": "180x180", + "type": "image/png" + }, + { + "src": "./img/icons/apple-touch-icon.png", + "sizes": "180x180", + "type": "image/png" + }, + { + "src": "./img/icons/favicon-16x16.png", + "sizes": "16x16", + "type": "image/png" + }, + { + "src": "./img/icons/favicon-32x32.png", + "sizes": "32x32", + "type": "image/png" + }, + { + "src": "./img/icons/msapplication-icon-144x144.png", + "sizes": "144x144", + "type": "image/png" + }, + { + "src": "./img/icons/mstile-150x150.png", + "sizes": "150x150", + "type": "image/png" + } + ] +} \ No newline at end of file diff --git a/ui/public/silent-renew-oidc.html b/ui/public/silent-renew-oidc.html new file mode 100644 index 0000000..1022e8b --- /dev/null +++ b/ui/public/silent-renew-oidc.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ui/src/App.vue b/ui/src/App.vue new file mode 100644 index 0000000..e065924 --- /dev/null +++ b/ui/src/App.vue @@ -0,0 +1,248 @@ + + + + + diff --git a/ui/src/client/.npmignore b/ui/src/client/.npmignore new file mode 100644 index 0000000..999d88d --- /dev/null +++ b/ui/src/client/.npmignore @@ -0,0 +1 @@ +# empty npmignore to ensure all required files (e.g., in the dist folder) are published by npm \ No newline at end of file diff --git a/ui/src/client/api.ts b/ui/src/client/api.ts new file mode 100644 index 0000000..4f7f2fd --- /dev/null +++ b/ui/src/client/api.ts @@ -0,0 +1,8104 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * + * API for the catalyst incident response platform. + * + * The version of the OpenAPI document: + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import { Configuration } from './configuration'; +import globalAxios, { AxiosPromise, AxiosInstance } from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from './common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from './base'; + +/** + * + * @export + * @interface Artifact + */ +export interface Artifact { + /** + * + * @type {{ [key: string]: Enrichment; }} + * @memberof Artifact + */ + enrichments?: { [key: string]: Enrichment; }; + /** + * + * @type {string} + * @memberof Artifact + */ + name: string; + /** + * + * @type {string} + * @memberof Artifact + */ + status?: string; + /** + * + * @type {string} + * @memberof Artifact + */ + type?: string; +} +/** + * + * @export + * @interface ArtifactOrigin + */ +export interface ArtifactOrigin { + /** + * + * @type {string} + * @memberof ArtifactOrigin + */ + artifact: string; + /** + * + * @type {number} + * @memberof ArtifactOrigin + */ + ticket_id: number; +} +/** + * + * @export + * @interface Automation + */ +export interface Automation { + /** + * + * @type {string} + * @memberof Automation + */ + image: string; + /** + * + * @type {string} + * @memberof Automation + */ + schema?: string; + /** + * + * @type {string} + * @memberof Automation + */ + script: string; + /** + * + * @type {Array} + * @memberof Automation + */ + type: Array; +} + +/** + * @export + * @enum {string} + */ +export enum AutomationTypeEnum { + Artifact = 'artifact', + Playbook = 'playbook', + Global = 'global' +} + +/** + * + * @export + * @interface AutomationForm + */ +export interface AutomationForm { + /** + * + * @type {string} + * @memberof AutomationForm + */ + id: string; + /** + * + * @type {string} + * @memberof AutomationForm + */ + image: string; + /** + * + * @type {string} + * @memberof AutomationForm + */ + schema?: string; + /** + * + * @type {string} + * @memberof AutomationForm + */ + script: string; + /** + * + * @type {Array} + * @memberof AutomationForm + */ + type: Array; +} + +/** + * @export + * @enum {string} + */ +export enum AutomationFormTypeEnum { + Artifact = 'artifact', + Playbook = 'playbook', + Global = 'global' +} + +/** + * + * @export + * @interface AutomationResponse + */ +export interface AutomationResponse { + /** + * + * @type {string} + * @memberof AutomationResponse + */ + id: string; + /** + * + * @type {string} + * @memberof AutomationResponse + */ + image: string; + /** + * + * @type {string} + * @memberof AutomationResponse + */ + schema?: string; + /** + * + * @type {string} + * @memberof AutomationResponse + */ + script: string; + /** + * + * @type {Array} + * @memberof AutomationResponse + */ + type: Array; +} + +/** + * @export + * @enum {string} + */ +export enum AutomationResponseTypeEnum { + Artifact = 'artifact', + Playbook = 'playbook', + Global = 'global' +} + +/** + * + * @export + * @interface Comment + */ +export interface Comment { + /** + * + * @type {string} + * @memberof Comment + */ + created: string; + /** + * + * @type {string} + * @memberof Comment + */ + creator: string; + /** + * + * @type {string} + * @memberof Comment + */ + message: string; +} +/** + * + * @export + * @interface CommentForm + */ +export interface CommentForm { + /** + * + * @type {string} + * @memberof CommentForm + */ + created?: string; + /** + * + * @type {string} + * @memberof CommentForm + */ + creator?: string; + /** + * + * @type {string} + * @memberof CommentForm + */ + message: string; +} +/** + * + * @export + * @interface Context + */ +export interface Context { + /** + * + * @type {Artifact} + * @memberof Context + */ + artifact?: Artifact; + /** + * + * @type {PlaybookResponse} + * @memberof Context + */ + playbook?: PlaybookResponse; + /** + * + * @type {TaskResponse} + * @memberof Context + */ + task?: TaskResponse; + /** + * + * @type {TicketResponse} + * @memberof Context + */ + ticket?: TicketResponse; +} +/** + * + * @export + * @interface Enrichment + */ +export interface Enrichment { + /** + * + * @type {string} + * @memberof Enrichment + */ + created: string; + /** + * + * @type {object} + * @memberof Enrichment + */ + data: object; + /** + * + * @type {string} + * @memberof Enrichment + */ + name: string; +} +/** + * + * @export + * @interface EnrichmentForm + */ +export interface EnrichmentForm { + /** + * + * @type {object} + * @memberof EnrichmentForm + */ + data: object; + /** + * + * @type {string} + * @memberof EnrichmentForm + */ + name: string; +} +/** + * + * @export + * @interface Graph + */ +export interface Graph { + /** + * + * @type {Array} + * @memberof Graph + */ + links?: Array; + /** + * + * @type {Array} + * @memberof Graph + */ + nodes?: Array; +} +/** + * + * @export + * @interface Group + */ +export interface Group { + /** + * + * @type {string} + * @memberof Group + */ + name: string; + /** + * + * @type {Array} + * @memberof Group + */ + users: Array; +} +/** + * + * @export + * @interface GroupForm + */ +export interface GroupForm { + /** + * + * @type {string} + * @memberof GroupForm + */ + id?: string; + /** + * + * @type {string} + * @memberof GroupForm + */ + name: string; + /** + * + * @type {Array} + * @memberof GroupForm + */ + users: Array; +} +/** + * + * @export + * @interface GroupResponse + */ +export interface GroupResponse { + /** + * + * @type {string} + * @memberof GroupResponse + */ + id: string; + /** + * + * @type {string} + * @memberof GroupResponse + */ + name: string; + /** + * + * @type {Array} + * @memberof GroupResponse + */ + users: Array; +} +/** + * + * @export + * @interface Job + */ +export interface Job { + /** + * + * @type {string} + * @memberof Job + */ + automation: string; + /** + * + * @type {string} + * @memberof Job + */ + container?: string; + /** + * + * @type {string} + * @memberof Job + */ + log?: string; + /** + * + * @type {Origin} + * @memberof Job + */ + origin?: Origin; + /** + * + * @type {object} + * @memberof Job + */ + output?: object; + /** + * + * @type {object} + * @memberof Job + */ + payload?: object; + /** + * + * @type {boolean} + * @memberof Job + */ + running: boolean; + /** + * + * @type {string} + * @memberof Job + */ + status: string; +} +/** + * + * @export + * @interface JobForm + */ +export interface JobForm { + /** + * + * @type {string} + * @memberof JobForm + */ + automation: string; + /** + * + * @type {Origin} + * @memberof JobForm + */ + origin?: Origin; + /** + * + * @type {object} + * @memberof JobForm + */ + payload?: object; +} +/** + * + * @export + * @interface JobResponse + */ +export interface JobResponse { + /** + * + * @type {string} + * @memberof JobResponse + */ + automation: string; + /** + * + * @type {string} + * @memberof JobResponse + */ + container?: string; + /** + * + * @type {string} + * @memberof JobResponse + */ + id: string; + /** + * + * @type {string} + * @memberof JobResponse + */ + log?: string; + /** + * + * @type {Origin} + * @memberof JobResponse + */ + origin?: Origin; + /** + * + * @type {object} + * @memberof JobResponse + */ + output?: object; + /** + * + * @type {object} + * @memberof JobResponse + */ + payload?: object; + /** + * + * @type {string} + * @memberof JobResponse + */ + status: string; +} +/** + * + * @export + * @interface Link + */ +export interface Link { + /** + * + * @type {string} + * @memberof Link + */ + id: string; + /** + * + * @type {string} + * @memberof Link + */ + sid: string; + /** + * + * @type {string} + * @memberof Link + */ + tid: string; +} +/** + * + * @export + * @interface LogEntry + */ +export interface LogEntry { + /** + * + * @type {string} + * @memberof LogEntry + */ + created: string; + /** + * + * @type {string} + * @memberof LogEntry + */ + creator: string; + /** + * + * @type {string} + * @memberof LogEntry + */ + message: string; + /** + * + * @type {string} + * @memberof LogEntry + */ + reference: string; +} +/** + * + * @export + * @interface Message + */ +export interface Message { + /** + * + * @type {Context} + * @memberof Message + */ + context?: Context; + /** + * + * @type {object} + * @memberof Message + */ + payload?: object; + /** + * + * @type {{ [key: string]: string; }} + * @memberof Message + */ + secrets?: { [key: string]: string; }; +} +/** + * + * @export + * @interface ModelFile + */ +export interface ModelFile { + /** + * + * @type {string} + * @memberof ModelFile + */ + key: string; + /** + * + * @type {string} + * @memberof ModelFile + */ + name: string; +} +/** + * + * @export + * @interface NewUserResponse + */ +export interface NewUserResponse { + /** + * + * @type {boolean} + * @memberof NewUserResponse + */ + blocked: boolean; + /** + * + * @type {string} + * @memberof NewUserResponse + */ + id: string; + /** + * + * @type {Array} + * @memberof NewUserResponse + */ + roles: Array; + /** + * + * @type {string} + * @memberof NewUserResponse + */ + secret?: string; +} +/** + * + * @export + * @interface Node + */ +export interface Node { + /** + * + * @type {string} + * @memberof Node + */ + id: string; + /** + * + * @type {string} + * @memberof Node + */ + name: string; +} +/** + * + * @export + * @interface Origin + */ +export interface Origin { + /** + * + * @type {ArtifactOrigin} + * @memberof Origin + */ + artifact_origin?: ArtifactOrigin; + /** + * + * @type {TaskOrigin} + * @memberof Origin + */ + task_origin?: TaskOrigin; +} +/** + * + * @export + * @interface Playbook + */ +export interface Playbook { + /** + * + * @type {string} + * @memberof Playbook + */ + name: string; + /** + * + * @type {{ [key: string]: Task; }} + * @memberof Playbook + */ + tasks: { [key: string]: Task; }; +} +/** + * + * @export + * @interface PlaybookResponse + */ +export interface PlaybookResponse { + /** + * + * @type {string} + * @memberof PlaybookResponse + */ + name: string; + /** + * + * @type {{ [key: string]: TaskResponse; }} + * @memberof PlaybookResponse + */ + tasks: { [key: string]: TaskResponse; }; +} +/** + * + * @export + * @interface PlaybookTemplate + */ +export interface PlaybookTemplate { + /** + * + * @type {string} + * @memberof PlaybookTemplate + */ + name: string; + /** + * + * @type {string} + * @memberof PlaybookTemplate + */ + yaml: string; +} +/** + * + * @export + * @interface PlaybookTemplateForm + */ +export interface PlaybookTemplateForm { + /** + * + * @type {string} + * @memberof PlaybookTemplateForm + */ + id?: string; + /** + * + * @type {string} + * @memberof PlaybookTemplateForm + */ + yaml: string; +} +/** + * + * @export + * @interface PlaybookTemplateResponse + */ +export interface PlaybookTemplateResponse { + /** + * + * @type {string} + * @memberof PlaybookTemplateResponse + */ + id: string; + /** + * + * @type {string} + * @memberof PlaybookTemplateResponse + */ + name: string; + /** + * + * @type {string} + * @memberof PlaybookTemplateResponse + */ + yaml: string; +} +/** + * + * @export + * @interface Reference + */ +export interface Reference { + /** + * + * @type {string} + * @memberof Reference + */ + href: string; + /** + * + * @type {string} + * @memberof Reference + */ + name: string; +} +/** + * + * @export + * @interface Rule + */ +export interface Rule { + /** + * + * @type {string} + * @memberof Rule + */ + condition: string; + /** + * + * @type {string} + * @memberof Rule + */ + name: string; + /** + * + * @type {object} + * @memberof Rule + */ + update: object; +} +/** + * + * @export + * @interface RuleForm + */ +export interface RuleForm { + /** + * + * @type {string} + * @memberof RuleForm + */ + condition: string; + /** + * + * @type {string} + * @memberof RuleForm + */ + id?: string; + /** + * + * @type {string} + * @memberof RuleForm + */ + name: string; + /** + * + * @type {object} + * @memberof RuleForm + */ + update: object; +} +/** + * + * @export + * @interface RuleResponse + */ +export interface RuleResponse { + /** + * + * @type {string} + * @memberof RuleResponse + */ + condition: string; + /** + * + * @type {string} + * @memberof RuleResponse + */ + id: string; + /** + * + * @type {string} + * @memberof RuleResponse + */ + name: string; + /** + * + * @type {object} + * @memberof RuleResponse + */ + update: object; +} +/** + * + * @export + * @interface Settings + */ +export interface Settings { + /** + * + * @type {Array} + * @memberof Settings + */ + artifactStates: Array; + /** + * + * @type {Array} + * @memberof Settings + */ + roles?: Array; + /** + * + * @type {Array} + * @memberof Settings + */ + ticketTypes: Array; + /** + * + * @type {string} + * @memberof Settings + */ + tier: SettingsTierEnum; + /** + * + * @type {string} + * @memberof Settings + */ + timeformat: string; + /** + * + * @type {string} + * @memberof Settings + */ + version: string; +} + +/** + * @export + * @enum {string} + */ +export enum SettingsTierEnum { + Community = 'community', + Enterprise = 'enterprise' +} + +/** + * + * @export + * @interface Statistics + */ +export interface Statistics { + /** + * + * @type {{ [key: string]: number; }} + * @memberof Statistics + */ + open_tickets_per_user: { [key: string]: number; }; + /** + * + * @type {{ [key: string]: number; }} + * @memberof Statistics + */ + tickets_per_type: { [key: string]: number; }; + /** + * + * @type {{ [key: string]: number; }} + * @memberof Statistics + */ + tickets_per_week: { [key: string]: number; }; + /** + * + * @type {number} + * @memberof Statistics + */ + unassigned: number; +} +/** + * + * @export + * @interface Task + */ +export interface Task { + /** + * + * @type {string} + * @memberof Task + */ + automation?: string; + /** + * + * @type {string} + * @memberof Task + */ + closed?: string; + /** + * + * @type {string} + * @memberof Task + */ + created: string; + /** + * + * @type {object} + * @memberof Task + */ + data?: object; + /** + * + * @type {boolean} + * @memberof Task + */ + done: boolean; + /** + * + * @type {boolean} + * @memberof Task + */ + join?: boolean; + /** + * + * @type {string} + * @memberof Task + */ + name: string; + /** + * + * @type {{ [key: string]: string; }} + * @memberof Task + */ + next?: { [key: string]: string; }; + /** + * + * @type {string} + * @memberof Task + */ + owner?: string; + /** + * + * @type {{ [key: string]: string; }} + * @memberof Task + */ + payload?: { [key: string]: string; }; + /** + * + * @type {object} + * @memberof Task + */ + schema?: object; + /** + * + * @type {string} + * @memberof Task + */ + type: TaskTypeEnum; +} + +/** + * @export + * @enum {string} + */ +export enum TaskTypeEnum { + Task = 'task', + Input = 'input', + Automation = 'automation' +} + +/** + * + * @export + * @interface TaskForm + */ +export interface TaskForm { + /** + * + * @type {string} + * @memberof TaskForm + */ + automation?: string; + /** + * + * @type {string} + * @memberof TaskForm + */ + closed?: string; + /** + * + * @type {string} + * @memberof TaskForm + */ + created?: string; + /** + * + * @type {object} + * @memberof TaskForm + */ + data?: object; + /** + * + * @type {boolean} + * @memberof TaskForm + */ + done?: boolean; + /** + * + * @type {boolean} + * @memberof TaskForm + */ + join?: boolean; + /** + * + * @type {string} + * @memberof TaskForm + */ + name: string; + /** + * + * @type {{ [key: string]: string; }} + * @memberof TaskForm + */ + next?: { [key: string]: string; }; + /** + * + * @type {string} + * @memberof TaskForm + */ + owner?: string; + /** + * + * @type {{ [key: string]: string; }} + * @memberof TaskForm + */ + payload?: { [key: string]: string; }; + /** + * + * @type {object} + * @memberof TaskForm + */ + schema?: object; + /** + * + * @type {string} + * @memberof TaskForm + */ + type: TaskFormTypeEnum; +} + +/** + * @export + * @enum {string} + */ +export enum TaskFormTypeEnum { + Task = 'task', + Input = 'input', + Automation = 'automation' +} + +/** + * + * @export + * @interface TaskOrigin + */ +export interface TaskOrigin { + /** + * + * @type {string} + * @memberof TaskOrigin + */ + playbook_id: string; + /** + * + * @type {string} + * @memberof TaskOrigin + */ + task_id: string; + /** + * + * @type {number} + * @memberof TaskOrigin + */ + ticket_id: number; +} +/** + * + * @export + * @interface TaskResponse + */ +export interface TaskResponse { + /** + * + * @type {boolean} + * @memberof TaskResponse + */ + active: boolean; + /** + * + * @type {string} + * @memberof TaskResponse + */ + automation?: string; + /** + * + * @type {string} + * @memberof TaskResponse + */ + closed?: string; + /** + * + * @type {string} + * @memberof TaskResponse + */ + created: string; + /** + * + * @type {object} + * @memberof TaskResponse + */ + data?: object; + /** + * + * @type {boolean} + * @memberof TaskResponse + */ + done: boolean; + /** + * + * @type {boolean} + * @memberof TaskResponse + */ + join?: boolean; + /** + * + * @type {string} + * @memberof TaskResponse + */ + name: string; + /** + * + * @type {{ [key: string]: string; }} + * @memberof TaskResponse + */ + next?: { [key: string]: string; }; + /** + * + * @type {number} + * @memberof TaskResponse + */ + order: number; + /** + * + * @type {string} + * @memberof TaskResponse + */ + owner?: string; + /** + * + * @type {{ [key: string]: string; }} + * @memberof TaskResponse + */ + payload?: { [key: string]: string; }; + /** + * + * @type {object} + * @memberof TaskResponse + */ + schema?: object; + /** + * + * @type {string} + * @memberof TaskResponse + */ + type: TaskResponseTypeEnum; +} + +/** + * @export + * @enum {string} + */ +export enum TaskResponseTypeEnum { + Task = 'task', + Input = 'input', + Automation = 'automation' +} + +/** + * + * @export + * @interface TaskWithContext + */ +export interface TaskWithContext { + /** + * + * @type {string} + * @memberof TaskWithContext + */ + playbook_id: string; + /** + * + * @type {string} + * @memberof TaskWithContext + */ + playbook_name: string; + /** + * + * @type {TaskResponse} + * @memberof TaskWithContext + */ + task: TaskResponse; + /** + * + * @type {string} + * @memberof TaskWithContext + */ + task_id: string; + /** + * + * @type {number} + * @memberof TaskWithContext + */ + ticket_id: number; + /** + * + * @type {string} + * @memberof TaskWithContext + */ + ticket_name: string; +} +/** + * + * @export + * @interface Ticket + */ +export interface Ticket { + /** + * + * @type {Array} + * @memberof Ticket + */ + artifacts?: Array; + /** + * + * @type {Array} + * @memberof Ticket + */ + comments?: Array; + /** + * + * @type {string} + * @memberof Ticket + */ + created: string; + /** + * + * @type {object} + * @memberof Ticket + */ + details?: object; + /** + * + * @type {Array} + * @memberof Ticket + */ + files?: Array; + /** + * + * @type {string} + * @memberof Ticket + */ + modified: string; + /** + * + * @type {string} + * @memberof Ticket + */ + name: string; + /** + * + * @type {string} + * @memberof Ticket + */ + owner?: string; + /** + * + * @type {{ [key: string]: Playbook; }} + * @memberof Ticket + */ + playbooks?: { [key: string]: Playbook; }; + /** + * + * @type {Array} + * @memberof Ticket + */ + read?: Array; + /** + * + * @type {Array} + * @memberof Ticket + */ + references?: Array; + /** + * + * @type {string} + * @memberof Ticket + */ + schema: string; + /** + * + * @type {string} + * @memberof Ticket + */ + status: string; + /** + * + * @type {string} + * @memberof Ticket + */ + type: string; + /** + * + * @type {Array} + * @memberof Ticket + */ + write?: Array; +} +/** + * + * @export + * @interface TicketForm + */ +export interface TicketForm { + /** + * + * @type {Array} + * @memberof TicketForm + */ + artifacts?: Array; + /** + * + * @type {Array} + * @memberof TicketForm + */ + comments?: Array; + /** + * + * @type {string} + * @memberof TicketForm + */ + created?: string; + /** + * + * @type {object} + * @memberof TicketForm + */ + details?: object; + /** + * + * @type {Array} + * @memberof TicketForm + */ + files?: Array; + /** + * + * @type {number} + * @memberof TicketForm + */ + id?: number; + /** + * + * @type {string} + * @memberof TicketForm + */ + modified?: string; + /** + * + * @type {string} + * @memberof TicketForm + */ + name: string; + /** + * + * @type {string} + * @memberof TicketForm + */ + owner?: string; + /** + * + * @type {Array} + * @memberof TicketForm + */ + playbooks?: Array; + /** + * + * @type {Array} + * @memberof TicketForm + */ + read?: Array; + /** + * + * @type {Array} + * @memberof TicketForm + */ + references?: Array; + /** + * + * @type {string} + * @memberof TicketForm + */ + schema?: string; + /** + * + * @type {string} + * @memberof TicketForm + */ + status: string; + /** + * + * @type {string} + * @memberof TicketForm + */ + type: string; + /** + * + * @type {Array} + * @memberof TicketForm + */ + write?: Array; +} +/** + * + * @export + * @interface TicketList + */ +export interface TicketList { + /** + * + * @type {number} + * @memberof TicketList + */ + count: number; + /** + * + * @type {Array} + * @memberof TicketList + */ + tickets: Array; +} +/** + * + * @export + * @interface TicketResponse + */ +export interface TicketResponse { + /** + * + * @type {Array} + * @memberof TicketResponse + */ + artifacts?: Array; + /** + * + * @type {Array} + * @memberof TicketResponse + */ + comments?: Array; + /** + * + * @type {string} + * @memberof TicketResponse + */ + created: string; + /** + * + * @type {object} + * @memberof TicketResponse + */ + details?: object; + /** + * + * @type {Array} + * @memberof TicketResponse + */ + files?: Array; + /** + * + * @type {number} + * @memberof TicketResponse + */ + id: number; + /** + * + * @type {string} + * @memberof TicketResponse + */ + modified: string; + /** + * + * @type {string} + * @memberof TicketResponse + */ + name: string; + /** + * + * @type {string} + * @memberof TicketResponse + */ + owner?: string; + /** + * + * @type {{ [key: string]: PlaybookResponse; }} + * @memberof TicketResponse + */ + playbooks?: { [key: string]: PlaybookResponse; }; + /** + * + * @type {Array} + * @memberof TicketResponse + */ + read?: Array; + /** + * + * @type {Array} + * @memberof TicketResponse + */ + references?: Array; + /** + * + * @type {string} + * @memberof TicketResponse + */ + schema: string; + /** + * + * @type {string} + * @memberof TicketResponse + */ + status: string; + /** + * + * @type {string} + * @memberof TicketResponse + */ + type: string; + /** + * + * @type {Array} + * @memberof TicketResponse + */ + write?: Array; +} +/** + * + * @export + * @interface TicketSimpleResponse + */ +export interface TicketSimpleResponse { + /** + * + * @type {Array} + * @memberof TicketSimpleResponse + */ + artifacts?: Array; + /** + * + * @type {Array} + * @memberof TicketSimpleResponse + */ + comments?: Array; + /** + * + * @type {string} + * @memberof TicketSimpleResponse + */ + created: string; + /** + * + * @type {object} + * @memberof TicketSimpleResponse + */ + details?: object; + /** + * + * @type {Array} + * @memberof TicketSimpleResponse + */ + files?: Array; + /** + * + * @type {number} + * @memberof TicketSimpleResponse + */ + id: number; + /** + * + * @type {string} + * @memberof TicketSimpleResponse + */ + modified: string; + /** + * + * @type {string} + * @memberof TicketSimpleResponse + */ + name: string; + /** + * + * @type {string} + * @memberof TicketSimpleResponse + */ + owner?: string; + /** + * + * @type {{ [key: string]: Playbook; }} + * @memberof TicketSimpleResponse + */ + playbooks?: { [key: string]: Playbook; }; + /** + * + * @type {Array} + * @memberof TicketSimpleResponse + */ + read?: Array; + /** + * + * @type {Array} + * @memberof TicketSimpleResponse + */ + references?: Array; + /** + * + * @type {string} + * @memberof TicketSimpleResponse + */ + schema: string; + /** + * + * @type {string} + * @memberof TicketSimpleResponse + */ + status: string; + /** + * + * @type {string} + * @memberof TicketSimpleResponse + */ + type: string; + /** + * + * @type {Array} + * @memberof TicketSimpleResponse + */ + write?: Array; +} +/** + * + * @export + * @interface TicketTemplate + */ +export interface TicketTemplate { + /** + * + * @type {string} + * @memberof TicketTemplate + */ + name: string; + /** + * + * @type {string} + * @memberof TicketTemplate + */ + schema: string; +} +/** + * + * @export + * @interface TicketTemplateForm + */ +export interface TicketTemplateForm { + /** + * + * @type {string} + * @memberof TicketTemplateForm + */ + id?: string; + /** + * + * @type {string} + * @memberof TicketTemplateForm + */ + name: string; + /** + * + * @type {string} + * @memberof TicketTemplateForm + */ + schema: string; +} +/** + * + * @export + * @interface TicketTemplateResponse + */ +export interface TicketTemplateResponse { + /** + * + * @type {string} + * @memberof TicketTemplateResponse + */ + id: string; + /** + * + * @type {string} + * @memberof TicketTemplateResponse + */ + name: string; + /** + * + * @type {string} + * @memberof TicketTemplateResponse + */ + schema: string; +} +/** + * + * @export + * @interface TicketType + */ +export interface TicketType { + /** + * + * @type {Array} + * @memberof TicketType + */ + default_groups?: Array; + /** + * + * @type {Array} + * @memberof TicketType + */ + default_playbooks: Array; + /** + * + * @type {string} + * @memberof TicketType + */ + default_template: string; + /** + * + * @type {string} + * @memberof TicketType + */ + icon: string; + /** + * + * @type {string} + * @memberof TicketType + */ + name: string; +} +/** + * + * @export + * @interface TicketTypeForm + */ +export interface TicketTypeForm { + /** + * + * @type {Array} + * @memberof TicketTypeForm + */ + default_groups?: Array; + /** + * + * @type {Array} + * @memberof TicketTypeForm + */ + default_playbooks: Array; + /** + * + * @type {string} + * @memberof TicketTypeForm + */ + default_template: string; + /** + * + * @type {string} + * @memberof TicketTypeForm + */ + icon: string; + /** + * + * @type {string} + * @memberof TicketTypeForm + */ + id?: string; + /** + * + * @type {string} + * @memberof TicketTypeForm + */ + name: string; +} +/** + * + * @export + * @interface TicketTypeResponse + */ +export interface TicketTypeResponse { + /** + * + * @type {Array} + * @memberof TicketTypeResponse + */ + default_groups?: Array; + /** + * + * @type {Array} + * @memberof TicketTypeResponse + */ + default_playbooks: Array; + /** + * + * @type {string} + * @memberof TicketTypeResponse + */ + default_template: string; + /** + * + * @type {string} + * @memberof TicketTypeResponse + */ + icon: string; + /** + * + * @type {string} + * @memberof TicketTypeResponse + */ + id: string; + /** + * + * @type {string} + * @memberof TicketTypeResponse + */ + name: string; +} +/** + * + * @export + * @interface TicketWithTickets + */ +export interface TicketWithTickets { + /** + * + * @type {Array} + * @memberof TicketWithTickets + */ + artifacts?: Array; + /** + * + * @type {Array} + * @memberof TicketWithTickets + */ + comments?: Array; + /** + * + * @type {string} + * @memberof TicketWithTickets + */ + created: string; + /** + * + * @type {object} + * @memberof TicketWithTickets + */ + details?: object; + /** + * + * @type {Array} + * @memberof TicketWithTickets + */ + files?: Array; + /** + * + * @type {number} + * @memberof TicketWithTickets + */ + id: number; + /** + * + * @type {string} + * @memberof TicketWithTickets + */ + modified: string; + /** + * + * @type {string} + * @memberof TicketWithTickets + */ + name: string; + /** + * + * @type {string} + * @memberof TicketWithTickets + */ + owner?: string; + /** + * + * @type {{ [key: string]: PlaybookResponse; }} + * @memberof TicketWithTickets + */ + playbooks?: { [key: string]: PlaybookResponse; }; + /** + * + * @type {Array} + * @memberof TicketWithTickets + */ + read?: Array; + /** + * + * @type {Array} + * @memberof TicketWithTickets + */ + references?: Array; + /** + * + * @type {string} + * @memberof TicketWithTickets + */ + schema: string; + /** + * + * @type {string} + * @memberof TicketWithTickets + */ + status: string; + /** + * + * @type {Array} + * @memberof TicketWithTickets + */ + tickets?: Array; + /** + * + * @type {string} + * @memberof TicketWithTickets + */ + type: string; + /** + * + * @type {Array} + * @memberof TicketWithTickets + */ + write?: Array; +} +/** + * + * @export + * @interface Type + */ +export interface Type { + /** + * + * @type {string} + * @memberof Type + */ + color?: TypeColorEnum; + /** + * + * @type {string} + * @memberof Type + */ + icon: string; + /** + * + * @type {string} + * @memberof Type + */ + id: string; + /** + * + * @type {string} + * @memberof Type + */ + name: string; +} + +/** + * @export + * @enum {string} + */ +export enum TypeColorEnum { + Error = 'error', + Info = 'info', + Success = 'success', + Warning = 'warning' +} + +/** + * + * @export + * @interface User + */ +export interface User { + /** + * + * @type {boolean} + * @memberof User + */ + apikey: boolean; + /** + * + * @type {boolean} + * @memberof User + */ + blocked: boolean; + /** + * + * @type {Array} + * @memberof User + */ + roles: Array; + /** + * + * @type {string} + * @memberof User + */ + sha256?: string; +} +/** + * + * @export + * @interface UserData + */ +export interface UserData { + /** + * + * @type {string} + * @memberof UserData + */ + email?: string; + /** + * + * @type {string} + * @memberof UserData + */ + image?: string; + /** + * + * @type {string} + * @memberof UserData + */ + name?: string; + /** + * + * @type {string} + * @memberof UserData + */ + timeformat?: string; +} +/** + * + * @export + * @interface UserDataResponse + */ +export interface UserDataResponse { + /** + * + * @type {string} + * @memberof UserDataResponse + */ + email?: string; + /** + * + * @type {string} + * @memberof UserDataResponse + */ + id: string; + /** + * + * @type {string} + * @memberof UserDataResponse + */ + image?: string; + /** + * + * @type {string} + * @memberof UserDataResponse + */ + name?: string; + /** + * + * @type {string} + * @memberof UserDataResponse + */ + timeformat?: string; +} +/** + * + * @export + * @interface UserForm + */ +export interface UserForm { + /** + * + * @type {boolean} + * @memberof UserForm + */ + apikey: boolean; + /** + * + * @type {boolean} + * @memberof UserForm + */ + blocked: boolean; + /** + * + * @type {string} + * @memberof UserForm + */ + id: string; + /** + * + * @type {Array} + * @memberof UserForm + */ + roles: Array; +} +/** + * + * @export + * @interface UserResponse + */ +export interface UserResponse { + /** + * + * @type {boolean} + * @memberof UserResponse + */ + apikey: boolean; + /** + * + * @type {boolean} + * @memberof UserResponse + */ + blocked: boolean; + /** + * + * @type {string} + * @memberof UserResponse + */ + id: string; + /** + * + * @type {Array} + * @memberof UserResponse + */ + roles: Array; +} + +/** + * AutomationsApi - axios parameter creator + * @export + */ +export const AutomationsApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @summary Create a new automation + * @param {AutomationForm} automation New automation + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createAutomation: async (automation: AutomationForm, options: any = {}): Promise => { + // verify required parameter 'automation' is not null or undefined + assertParamExists('createAutomation', 'automation', automation) + const localVarPath = `/automations`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(automation, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Delete a automation + * @param {string} id Automation ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteAutomation: async (id: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('deleteAutomation', 'id', id) + const localVarPath = `/automations/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Get a single automation + * @param {string} id Automation ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAutomation: async (id: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('getAutomation', 'id', id) + const localVarPath = `/automations/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary List automations + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listAutomations: async (options: any = {}): Promise => { + const localVarPath = `/automations`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Update an existing automation + * @param {string} id Automation ID + * @param {AutomationForm} automation Automation object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateAutomation: async (id: string, automation: AutomationForm, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('updateAutomation', 'id', id) + // verify required parameter 'automation' is not null or undefined + assertParamExists('updateAutomation', 'automation', automation) + const localVarPath = `/automations/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(automation, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * AutomationsApi - functional programming interface + * @export + */ +export const AutomationsApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = AutomationsApiAxiosParamCreator(configuration) + return { + /** + * + * @summary Create a new automation + * @param {AutomationForm} automation New automation + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createAutomation(automation: AutomationForm, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createAutomation(automation, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Delete a automation + * @param {string} id Automation ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async deleteAutomation(id: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deleteAutomation(id, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Get a single automation + * @param {string} id Automation ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getAutomation(id: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getAutomation(id, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary List automations + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listAutomations(options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listAutomations(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Update an existing automation + * @param {string} id Automation ID + * @param {AutomationForm} automation Automation object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateAutomation(id: string, automation: AutomationForm, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateAutomation(id, automation, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * AutomationsApi - factory interface + * @export + */ +export const AutomationsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = AutomationsApiFp(configuration) + return { + /** + * + * @summary Create a new automation + * @param {AutomationForm} automation New automation + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createAutomation(automation: AutomationForm, options?: any): AxiosPromise { + return localVarFp.createAutomation(automation, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Delete a automation + * @param {string} id Automation ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteAutomation(id: string, options?: any): AxiosPromise { + return localVarFp.deleteAutomation(id, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Get a single automation + * @param {string} id Automation ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAutomation(id: string, options?: any): AxiosPromise { + return localVarFp.getAutomation(id, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary List automations + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listAutomations(options?: any): AxiosPromise> { + return localVarFp.listAutomations(options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Update an existing automation + * @param {string} id Automation ID + * @param {AutomationForm} automation Automation object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateAutomation(id: string, automation: AutomationForm, options?: any): AxiosPromise { + return localVarFp.updateAutomation(id, automation, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * AutomationsApi - object-oriented interface + * @export + * @class AutomationsApi + * @extends {BaseAPI} + */ +export class AutomationsApi extends BaseAPI { + /** + * + * @summary Create a new automation + * @param {AutomationForm} automation New automation + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AutomationsApi + */ + public createAutomation(automation: AutomationForm, options?: any) { + return AutomationsApiFp(this.configuration).createAutomation(automation, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Delete a automation + * @param {string} id Automation ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AutomationsApi + */ + public deleteAutomation(id: string, options?: any) { + return AutomationsApiFp(this.configuration).deleteAutomation(id, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Get a single automation + * @param {string} id Automation ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AutomationsApi + */ + public getAutomation(id: string, options?: any) { + return AutomationsApiFp(this.configuration).getAutomation(id, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary List automations + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AutomationsApi + */ + public listAutomations(options?: any) { + return AutomationsApiFp(this.configuration).listAutomations(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Update an existing automation + * @param {string} id Automation ID + * @param {AutomationForm} automation Automation object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AutomationsApi + */ + public updateAutomation(id: string, automation: AutomationForm, options?: any) { + return AutomationsApiFp(this.configuration).updateAutomation(id, automation, options).then((request) => request(this.axios, this.basePath)); + } +} + + +/** + * GraphApi - axios parameter creator + * @export + */ +export const GraphApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @summary Graph + * @param {string} col Graph Start + * @param {string} id Graph Start + * @param {number} depth Graph Start + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + graph: async (col: string, id: string, depth: number, options: any = {}): Promise => { + // verify required parameter 'col' is not null or undefined + assertParamExists('graph', 'col', col) + // verify required parameter 'id' is not null or undefined + assertParamExists('graph', 'id', id) + // verify required parameter 'depth' is not null or undefined + assertParamExists('graph', 'depth', depth) + const localVarPath = `/graph/{col}/{id}` + .replace(`{${"col"}}`, encodeURIComponent(String(col))) + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (depth !== undefined) { + localVarQueryParameter['depth'] = depth; + } + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * GraphApi - functional programming interface + * @export + */ +export const GraphApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = GraphApiAxiosParamCreator(configuration) + return { + /** + * + * @summary Graph + * @param {string} col Graph Start + * @param {string} id Graph Start + * @param {number} depth Graph Start + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async graph(col: string, id: string, depth: number, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.graph(col, id, depth, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * GraphApi - factory interface + * @export + */ +export const GraphApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = GraphApiFp(configuration) + return { + /** + * + * @summary Graph + * @param {string} col Graph Start + * @param {string} id Graph Start + * @param {number} depth Graph Start + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + graph(col: string, id: string, depth: number, options?: any): AxiosPromise { + return localVarFp.graph(col, id, depth, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * GraphApi - object-oriented interface + * @export + * @class GraphApi + * @extends {BaseAPI} + */ +export class GraphApi extends BaseAPI { + /** + * + * @summary Graph + * @param {string} col Graph Start + * @param {string} id Graph Start + * @param {number} depth Graph Start + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof GraphApi + */ + public graph(col: string, id: string, depth: number, options?: any) { + return GraphApiFp(this.configuration).graph(col, id, depth, options).then((request) => request(this.axios, this.basePath)); + } +} + + +/** + * GroupsApi - axios parameter creator + * @export + */ +export const GroupsApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @summary Create a new group + * @param {GroupForm} group New group + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createGroup: async (group: GroupForm, options: any = {}): Promise => { + // verify required parameter 'group' is not null or undefined + assertParamExists('createGroup', 'group', group) + const localVarPath = `/groups`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(group, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Delete a group + * @param {string} id Group ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteGroup: async (id: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('deleteGroup', 'id', id) + const localVarPath = `/groups/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Get a single group + * @param {string} id Group ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getGroup: async (id: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('getGroup', 'id', id) + const localVarPath = `/groups/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary List groups + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listGroups: async (options: any = {}): Promise => { + const localVarPath = `/groups`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Update an existing group + * @param {string} id Group ID + * @param {Group} group Group object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateGroup: async (id: string, group: Group, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('updateGroup', 'id', id) + // verify required parameter 'group' is not null or undefined + assertParamExists('updateGroup', 'group', group) + const localVarPath = `/groups/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(group, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * GroupsApi - functional programming interface + * @export + */ +export const GroupsApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = GroupsApiAxiosParamCreator(configuration) + return { + /** + * + * @summary Create a new group + * @param {GroupForm} group New group + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createGroup(group: GroupForm, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createGroup(group, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Delete a group + * @param {string} id Group ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async deleteGroup(id: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deleteGroup(id, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Get a single group + * @param {string} id Group ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getGroup(id: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getGroup(id, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary List groups + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listGroups(options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listGroups(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Update an existing group + * @param {string} id Group ID + * @param {Group} group Group object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateGroup(id: string, group: Group, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateGroup(id, group, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * GroupsApi - factory interface + * @export + */ +export const GroupsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = GroupsApiFp(configuration) + return { + /** + * + * @summary Create a new group + * @param {GroupForm} group New group + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createGroup(group: GroupForm, options?: any): AxiosPromise { + return localVarFp.createGroup(group, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Delete a group + * @param {string} id Group ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteGroup(id: string, options?: any): AxiosPromise { + return localVarFp.deleteGroup(id, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Get a single group + * @param {string} id Group ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getGroup(id: string, options?: any): AxiosPromise { + return localVarFp.getGroup(id, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary List groups + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listGroups(options?: any): AxiosPromise> { + return localVarFp.listGroups(options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Update an existing group + * @param {string} id Group ID + * @param {Group} group Group object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateGroup(id: string, group: Group, options?: any): AxiosPromise { + return localVarFp.updateGroup(id, group, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * GroupsApi - object-oriented interface + * @export + * @class GroupsApi + * @extends {BaseAPI} + */ +export class GroupsApi extends BaseAPI { + /** + * + * @summary Create a new group + * @param {GroupForm} group New group + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof GroupsApi + */ + public createGroup(group: GroupForm, options?: any) { + return GroupsApiFp(this.configuration).createGroup(group, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Delete a group + * @param {string} id Group ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof GroupsApi + */ + public deleteGroup(id: string, options?: any) { + return GroupsApiFp(this.configuration).deleteGroup(id, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Get a single group + * @param {string} id Group ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof GroupsApi + */ + public getGroup(id: string, options?: any) { + return GroupsApiFp(this.configuration).getGroup(id, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary List groups + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof GroupsApi + */ + public listGroups(options?: any) { + return GroupsApiFp(this.configuration).listGroups(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Update an existing group + * @param {string} id Group ID + * @param {Group} group Group object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof GroupsApi + */ + public updateGroup(id: string, group: Group, options?: any) { + return GroupsApiFp(this.configuration).updateGroup(id, group, options).then((request) => request(this.axios, this.basePath)); + } +} + + +/** + * JobsApi - axios parameter creator + * @export + */ +export const JobsApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @summary Get a single job + * @param {string} id Job ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getJob: async (id: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('getJob', 'id', id) + const localVarPath = `/jobs/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary List jobs + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listJobs: async (options: any = {}): Promise => { + const localVarPath = `/jobs`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Start a new job + * @param {JobForm} job New job + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + runJob: async (job: JobForm, options: any = {}): Promise => { + // verify required parameter 'job' is not null or undefined + assertParamExists('runJob', 'job', job) + const localVarPath = `/jobs`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(job, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Update an existing job + * @param {string} id Job ID + * @param {Job} job Job object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateJob: async (id: string, job: Job, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('updateJob', 'id', id) + // verify required parameter 'job' is not null or undefined + assertParamExists('updateJob', 'job', job) + const localVarPath = `/jobs/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(job, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * JobsApi - functional programming interface + * @export + */ +export const JobsApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = JobsApiAxiosParamCreator(configuration) + return { + /** + * + * @summary Get a single job + * @param {string} id Job ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getJob(id: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getJob(id, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary List jobs + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listJobs(options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listJobs(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Start a new job + * @param {JobForm} job New job + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async runJob(job: JobForm, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.runJob(job, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Update an existing job + * @param {string} id Job ID + * @param {Job} job Job object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateJob(id: string, job: Job, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateJob(id, job, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * JobsApi - factory interface + * @export + */ +export const JobsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = JobsApiFp(configuration) + return { + /** + * + * @summary Get a single job + * @param {string} id Job ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getJob(id: string, options?: any): AxiosPromise { + return localVarFp.getJob(id, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary List jobs + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listJobs(options?: any): AxiosPromise> { + return localVarFp.listJobs(options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Start a new job + * @param {JobForm} job New job + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + runJob(job: JobForm, options?: any): AxiosPromise { + return localVarFp.runJob(job, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Update an existing job + * @param {string} id Job ID + * @param {Job} job Job object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateJob(id: string, job: Job, options?: any): AxiosPromise { + return localVarFp.updateJob(id, job, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * JobsApi - object-oriented interface + * @export + * @class JobsApi + * @extends {BaseAPI} + */ +export class JobsApi extends BaseAPI { + /** + * + * @summary Get a single job + * @param {string} id Job ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof JobsApi + */ + public getJob(id: string, options?: any) { + return JobsApiFp(this.configuration).getJob(id, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary List jobs + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof JobsApi + */ + public listJobs(options?: any) { + return JobsApiFp(this.configuration).listJobs(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Start a new job + * @param {JobForm} job New job + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof JobsApi + */ + public runJob(job: JobForm, options?: any) { + return JobsApiFp(this.configuration).runJob(job, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Update an existing job + * @param {string} id Job ID + * @param {Job} job Job object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof JobsApi + */ + public updateJob(id: string, job: Job, options?: any) { + return JobsApiFp(this.configuration).updateJob(id, job, options).then((request) => request(this.axios, this.basePath)); + } +} + + +/** + * LogsApi - axios parameter creator + * @export + */ +export const LogsApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @summary Get log entries + * @param {string} reference Reference + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getLogs: async (reference: string, options: any = {}): Promise => { + // verify required parameter 'reference' is not null or undefined + assertParamExists('getLogs', 'reference', reference) + const localVarPath = `/logs/{reference}` + .replace(`{${"reference"}}`, encodeURIComponent(String(reference))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * LogsApi - functional programming interface + * @export + */ +export const LogsApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = LogsApiAxiosParamCreator(configuration) + return { + /** + * + * @summary Get log entries + * @param {string} reference Reference + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getLogs(reference: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getLogs(reference, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * LogsApi - factory interface + * @export + */ +export const LogsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = LogsApiFp(configuration) + return { + /** + * + * @summary Get log entries + * @param {string} reference Reference + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getLogs(reference: string, options?: any): AxiosPromise> { + return localVarFp.getLogs(reference, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * LogsApi - object-oriented interface + * @export + * @class LogsApi + * @extends {BaseAPI} + */ +export class LogsApi extends BaseAPI { + /** + * + * @summary Get log entries + * @param {string} reference Reference + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof LogsApi + */ + public getLogs(reference: string, options?: any) { + return LogsApiFp(this.configuration).getLogs(reference, options).then((request) => request(this.axios, this.basePath)); + } +} + + +/** + * PlaybooksApi - axios parameter creator + * @export + */ +export const PlaybooksApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @summary Create a playbook + * @param {PlaybookTemplateForm} playbook New playbook + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createPlaybook: async (playbook: PlaybookTemplateForm, options: any = {}): Promise => { + // verify required parameter 'playbook' is not null or undefined + assertParamExists('createPlaybook', 'playbook', playbook) + const localVarPath = `/playbooks`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(playbook, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Delete a playbook + * @param {string} id Playbook name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deletePlaybook: async (id: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('deletePlaybook', 'id', id) + const localVarPath = `/playbooks/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Get a single playbook + * @param {string} id Playbook name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getPlaybook: async (id: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('getPlaybook', 'id', id) + const localVarPath = `/playbooks/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary List playbooks + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listPlaybooks: async (options: any = {}): Promise => { + const localVarPath = `/playbooks`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Update an existing ticket playbook + * @param {string} id Playbook ID + * @param {PlaybookTemplateForm} playbook Updated playbook + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updatePlaybook: async (id: string, playbook: PlaybookTemplateForm, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('updatePlaybook', 'id', id) + // verify required parameter 'playbook' is not null or undefined + assertParamExists('updatePlaybook', 'playbook', playbook) + const localVarPath = `/playbooks/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(playbook, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * PlaybooksApi - functional programming interface + * @export + */ +export const PlaybooksApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = PlaybooksApiAxiosParamCreator(configuration) + return { + /** + * + * @summary Create a playbook + * @param {PlaybookTemplateForm} playbook New playbook + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createPlaybook(playbook: PlaybookTemplateForm, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createPlaybook(playbook, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Delete a playbook + * @param {string} id Playbook name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async deletePlaybook(id: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deletePlaybook(id, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Get a single playbook + * @param {string} id Playbook name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getPlaybook(id: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getPlaybook(id, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary List playbooks + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listPlaybooks(options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listPlaybooks(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Update an existing ticket playbook + * @param {string} id Playbook ID + * @param {PlaybookTemplateForm} playbook Updated playbook + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updatePlaybook(id: string, playbook: PlaybookTemplateForm, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updatePlaybook(id, playbook, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * PlaybooksApi - factory interface + * @export + */ +export const PlaybooksApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = PlaybooksApiFp(configuration) + return { + /** + * + * @summary Create a playbook + * @param {PlaybookTemplateForm} playbook New playbook + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createPlaybook(playbook: PlaybookTemplateForm, options?: any): AxiosPromise> { + return localVarFp.createPlaybook(playbook, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Delete a playbook + * @param {string} id Playbook name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deletePlaybook(id: string, options?: any): AxiosPromise { + return localVarFp.deletePlaybook(id, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Get a single playbook + * @param {string} id Playbook name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getPlaybook(id: string, options?: any): AxiosPromise { + return localVarFp.getPlaybook(id, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary List playbooks + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listPlaybooks(options?: any): AxiosPromise> { + return localVarFp.listPlaybooks(options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Update an existing ticket playbook + * @param {string} id Playbook ID + * @param {PlaybookTemplateForm} playbook Updated playbook + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updatePlaybook(id: string, playbook: PlaybookTemplateForm, options?: any): AxiosPromise { + return localVarFp.updatePlaybook(id, playbook, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * PlaybooksApi - object-oriented interface + * @export + * @class PlaybooksApi + * @extends {BaseAPI} + */ +export class PlaybooksApi extends BaseAPI { + /** + * + * @summary Create a playbook + * @param {PlaybookTemplateForm} playbook New playbook + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof PlaybooksApi + */ + public createPlaybook(playbook: PlaybookTemplateForm, options?: any) { + return PlaybooksApiFp(this.configuration).createPlaybook(playbook, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Delete a playbook + * @param {string} id Playbook name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof PlaybooksApi + */ + public deletePlaybook(id: string, options?: any) { + return PlaybooksApiFp(this.configuration).deletePlaybook(id, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Get a single playbook + * @param {string} id Playbook name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof PlaybooksApi + */ + public getPlaybook(id: string, options?: any) { + return PlaybooksApiFp(this.configuration).getPlaybook(id, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary List playbooks + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof PlaybooksApi + */ + public listPlaybooks(options?: any) { + return PlaybooksApiFp(this.configuration).listPlaybooks(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Update an existing ticket playbook + * @param {string} id Playbook ID + * @param {PlaybookTemplateForm} playbook Updated playbook + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof PlaybooksApi + */ + public updatePlaybook(id: string, playbook: PlaybookTemplateForm, options?: any) { + return PlaybooksApiFp(this.configuration).updatePlaybook(id, playbook, options).then((request) => request(this.axios, this.basePath)); + } +} + + +/** + * RulesApi - axios parameter creator + * @export + */ +export const RulesApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @summary Create a rule + * @param {RuleForm} rule New rule + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createRule: async (rule: RuleForm, options: any = {}): Promise => { + // verify required parameter 'rule' is not null or undefined + assertParamExists('createRule', 'rule', rule) + const localVarPath = `/rules`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(rule, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Delete a rule + * @param {string} id Rule name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteRule: async (id: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('deleteRule', 'id', id) + const localVarPath = `/rules/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Get a single rule + * @param {string} id Rule name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getRule: async (id: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('getRule', 'id', id) + const localVarPath = `/rules/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary List rules + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listRules: async (options: any = {}): Promise => { + const localVarPath = `/rules`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Update an existing ticket rule + * @param {string} id Rule ID + * @param {RuleForm} rule Updated rule + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateRule: async (id: string, rule: RuleForm, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('updateRule', 'id', id) + // verify required parameter 'rule' is not null or undefined + assertParamExists('updateRule', 'rule', rule) + const localVarPath = `/rules/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(rule, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * RulesApi - functional programming interface + * @export + */ +export const RulesApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = RulesApiAxiosParamCreator(configuration) + return { + /** + * + * @summary Create a rule + * @param {RuleForm} rule New rule + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createRule(rule: RuleForm, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createRule(rule, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Delete a rule + * @param {string} id Rule name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async deleteRule(id: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deleteRule(id, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Get a single rule + * @param {string} id Rule name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getRule(id: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getRule(id, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary List rules + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listRules(options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listRules(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Update an existing ticket rule + * @param {string} id Rule ID + * @param {RuleForm} rule Updated rule + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateRule(id: string, rule: RuleForm, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateRule(id, rule, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * RulesApi - factory interface + * @export + */ +export const RulesApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = RulesApiFp(configuration) + return { + /** + * + * @summary Create a rule + * @param {RuleForm} rule New rule + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createRule(rule: RuleForm, options?: any): AxiosPromise> { + return localVarFp.createRule(rule, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Delete a rule + * @param {string} id Rule name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteRule(id: string, options?: any): AxiosPromise { + return localVarFp.deleteRule(id, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Get a single rule + * @param {string} id Rule name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getRule(id: string, options?: any): AxiosPromise { + return localVarFp.getRule(id, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary List rules + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listRules(options?: any): AxiosPromise> { + return localVarFp.listRules(options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Update an existing ticket rule + * @param {string} id Rule ID + * @param {RuleForm} rule Updated rule + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateRule(id: string, rule: RuleForm, options?: any): AxiosPromise { + return localVarFp.updateRule(id, rule, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * RulesApi - object-oriented interface + * @export + * @class RulesApi + * @extends {BaseAPI} + */ +export class RulesApi extends BaseAPI { + /** + * + * @summary Create a rule + * @param {RuleForm} rule New rule + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof RulesApi + */ + public createRule(rule: RuleForm, options?: any) { + return RulesApiFp(this.configuration).createRule(rule, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Delete a rule + * @param {string} id Rule name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof RulesApi + */ + public deleteRule(id: string, options?: any) { + return RulesApiFp(this.configuration).deleteRule(id, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Get a single rule + * @param {string} id Rule name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof RulesApi + */ + public getRule(id: string, options?: any) { + return RulesApiFp(this.configuration).getRule(id, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary List rules + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof RulesApi + */ + public listRules(options?: any) { + return RulesApiFp(this.configuration).listRules(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Update an existing ticket rule + * @param {string} id Rule ID + * @param {RuleForm} rule Updated rule + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof RulesApi + */ + public updateRule(id: string, rule: RuleForm, options?: any) { + return RulesApiFp(this.configuration).updateRule(id, rule, options).then((request) => request(this.axios, this.basePath)); + } +} + + +/** + * SettingsApi - axios parameter creator + * @export + */ +export const SettingsApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @summary Get settings + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getSettings: async (options: any = {}): Promise => { + const localVarPath = `/settings`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * SettingsApi - functional programming interface + * @export + */ +export const SettingsApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = SettingsApiAxiosParamCreator(configuration) + return { + /** + * + * @summary Get settings + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getSettings(options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getSettings(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * SettingsApi - factory interface + * @export + */ +export const SettingsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = SettingsApiFp(configuration) + return { + /** + * + * @summary Get settings + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getSettings(options?: any): AxiosPromise { + return localVarFp.getSettings(options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * SettingsApi - object-oriented interface + * @export + * @class SettingsApi + * @extends {BaseAPI} + */ +export class SettingsApi extends BaseAPI { + /** + * + * @summary Get settings + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SettingsApi + */ + public getSettings(options?: any) { + return SettingsApiFp(this.configuration).getSettings(options).then((request) => request(this.axios, this.basePath)); + } +} + + +/** + * StatisticsApi - axios parameter creator + * @export + */ +export const StatisticsApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @summary Get statistics + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getStatistics: async (options: any = {}): Promise => { + const localVarPath = `/statistics`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * StatisticsApi - functional programming interface + * @export + */ +export const StatisticsApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = StatisticsApiAxiosParamCreator(configuration) + return { + /** + * + * @summary Get statistics + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getStatistics(options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getStatistics(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * StatisticsApi - factory interface + * @export + */ +export const StatisticsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = StatisticsApiFp(configuration) + return { + /** + * + * @summary Get statistics + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getStatistics(options?: any): AxiosPromise { + return localVarFp.getStatistics(options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * StatisticsApi - object-oriented interface + * @export + * @class StatisticsApi + * @extends {BaseAPI} + */ +export class StatisticsApi extends BaseAPI { + /** + * + * @summary Get statistics + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof StatisticsApi + */ + public getStatistics(options?: any) { + return StatisticsApiFp(this.configuration).getStatistics(options).then((request) => request(this.axios, this.basePath)); + } +} + + +/** + * TasksApi - axios parameter creator + * @export + */ +export const TasksApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @summary List tasks + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listTasks: async (options: any = {}): Promise => { + const localVarPath = `/tasks`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * TasksApi - functional programming interface + * @export + */ +export const TasksApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = TasksApiAxiosParamCreator(configuration) + return { + /** + * + * @summary List tasks + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listTasks(options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listTasks(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * TasksApi - factory interface + * @export + */ +export const TasksApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = TasksApiFp(configuration) + return { + /** + * + * @summary List tasks + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listTasks(options?: any): AxiosPromise> { + return localVarFp.listTasks(options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * TasksApi - object-oriented interface + * @export + * @class TasksApi + * @extends {BaseAPI} + */ +export class TasksApi extends BaseAPI { + /** + * + * @summary List tasks + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TasksApi + */ + public listTasks(options?: any) { + return TasksApiFp(this.configuration).listTasks(options).then((request) => request(this.axios, this.basePath)); + } +} + + +/** + * TemplatesApi - axios parameter creator + * @export + */ +export const TemplatesApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @summary Create a new template + * @param {TicketTemplateForm} template New template + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createTemplate: async (template: TicketTemplateForm, options: any = {}): Promise => { + // verify required parameter 'template' is not null or undefined + assertParamExists('createTemplate', 'template', template) + const localVarPath = `/templates`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(template, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Delete a template + * @param {string} id Template ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteTemplate: async (id: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('deleteTemplate', 'id', id) + const localVarPath = `/templates/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Get a single template + * @param {string} id Template ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getTemplate: async (id: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('getTemplate', 'id', id) + const localVarPath = `/templates/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary List templates + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listTemplates: async (options: any = {}): Promise => { + const localVarPath = `/templates`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Update an existing template + * @param {string} id Template ID + * @param {TicketTemplateForm} template Template object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateTemplate: async (id: string, template: TicketTemplateForm, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('updateTemplate', 'id', id) + // verify required parameter 'template' is not null or undefined + assertParamExists('updateTemplate', 'template', template) + const localVarPath = `/templates/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(template, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * TemplatesApi - functional programming interface + * @export + */ +export const TemplatesApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = TemplatesApiAxiosParamCreator(configuration) + return { + /** + * + * @summary Create a new template + * @param {TicketTemplateForm} template New template + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createTemplate(template: TicketTemplateForm, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createTemplate(template, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Delete a template + * @param {string} id Template ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async deleteTemplate(id: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deleteTemplate(id, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Get a single template + * @param {string} id Template ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getTemplate(id: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getTemplate(id, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary List templates + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listTemplates(options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listTemplates(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Update an existing template + * @param {string} id Template ID + * @param {TicketTemplateForm} template Template object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateTemplate(id: string, template: TicketTemplateForm, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateTemplate(id, template, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * TemplatesApi - factory interface + * @export + */ +export const TemplatesApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = TemplatesApiFp(configuration) + return { + /** + * + * @summary Create a new template + * @param {TicketTemplateForm} template New template + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createTemplate(template: TicketTemplateForm, options?: any): AxiosPromise { + return localVarFp.createTemplate(template, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Delete a template + * @param {string} id Template ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteTemplate(id: string, options?: any): AxiosPromise { + return localVarFp.deleteTemplate(id, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Get a single template + * @param {string} id Template ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getTemplate(id: string, options?: any): AxiosPromise { + return localVarFp.getTemplate(id, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary List templates + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listTemplates(options?: any): AxiosPromise> { + return localVarFp.listTemplates(options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Update an existing template + * @param {string} id Template ID + * @param {TicketTemplateForm} template Template object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateTemplate(id: string, template: TicketTemplateForm, options?: any): AxiosPromise { + return localVarFp.updateTemplate(id, template, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * TemplatesApi - object-oriented interface + * @export + * @class TemplatesApi + * @extends {BaseAPI} + */ +export class TemplatesApi extends BaseAPI { + /** + * + * @summary Create a new template + * @param {TicketTemplateForm} template New template + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TemplatesApi + */ + public createTemplate(template: TicketTemplateForm, options?: any) { + return TemplatesApiFp(this.configuration).createTemplate(template, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Delete a template + * @param {string} id Template ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TemplatesApi + */ + public deleteTemplate(id: string, options?: any) { + return TemplatesApiFp(this.configuration).deleteTemplate(id, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Get a single template + * @param {string} id Template ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TemplatesApi + */ + public getTemplate(id: string, options?: any) { + return TemplatesApiFp(this.configuration).getTemplate(id, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary List templates + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TemplatesApi + */ + public listTemplates(options?: any) { + return TemplatesApiFp(this.configuration).listTemplates(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Update an existing template + * @param {string} id Template ID + * @param {TicketTemplateForm} template Template object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TemplatesApi + */ + public updateTemplate(id: string, template: TicketTemplateForm, options?: any) { + return TemplatesApiFp(this.configuration).updateTemplate(id, template, options).then((request) => request(this.axios, this.basePath)); + } +} + + +/** + * TicketsApi - axios parameter creator + * @export + */ +export const TicketsApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @summary Add a single artifact + * @param {number} id Ticket ID + * @param {Artifact} artifact Artifact object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + addArtifact: async (id: number, artifact: Artifact, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('addArtifact', 'id', id) + // verify required parameter 'artifact' is not null or undefined + assertParamExists('addArtifact', 'artifact', artifact) + const localVarPath = `/tickets/{id}/artifacts` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(artifact, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Add ticket comment + * @param {number} id Ticket ID + * @param {CommentForm} comment Ticket comment + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + addComment: async (id: number, comment: CommentForm, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('addComment', 'id', id) + // verify required parameter 'comment' is not null or undefined + assertParamExists('addComment', 'comment', comment) + const localVarPath = `/tickets/{id}/comments` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(comment, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Add a new ticket playbook + * @param {number} id Ticket ID + * @param {PlaybookTemplateForm} playbook Ticket playbook object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + addTicketPlaybook: async (id: number, playbook: PlaybookTemplateForm, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('addTicketPlaybook', 'id', id) + // verify required parameter 'playbook' is not null or undefined + assertParamExists('addTicketPlaybook', 'playbook', playbook) + const localVarPath = `/tickets/{id}/playbooks` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(playbook, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Complete ticket playbook task + * @param {number} id Ticket ID + * @param {string} playbookID Playbook ID + * @param {string} taskID Task ID + * @param {object} data Ticket playbook object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + completeTask: async (id: number, playbookID: string, taskID: string, data: object, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('completeTask', 'id', id) + // verify required parameter 'playbookID' is not null or undefined + assertParamExists('completeTask', 'playbookID', playbookID) + // verify required parameter 'taskID' is not null or undefined + assertParamExists('completeTask', 'taskID', taskID) + // verify required parameter 'data' is not null or undefined + assertParamExists('completeTask', 'data', data) + const localVarPath = `/tickets/{id}/playbooks/{playbookID}/task/{taskID}/complete` + .replace(`{${"id"}}`, encodeURIComponent(String(id))) + .replace(`{${"playbookID"}}`, encodeURIComponent(String(playbookID))) + .replace(`{${"taskID"}}`, encodeURIComponent(String(taskID))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(data, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Create a new ticket + * @param {TicketForm} ticket New ticket + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createTicket: async (ticket: TicketForm, options: any = {}): Promise => { + // verify required parameter 'ticket' is not null or undefined + assertParamExists('createTicket', 'ticket', ticket) + const localVarPath = `/tickets`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(ticket, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Create a new tickets in batch + * @param {Array} ticket New ticket + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createTicketBatch: async (ticket: Array, options: any = {}): Promise => { + // verify required parameter 'ticket' is not null or undefined + assertParamExists('createTicketBatch', 'ticket', ticket) + const localVarPath = `/tickets/batch`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(ticket, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Delete an ticket + * @param {number} id Ticket ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteTicket: async (id: number, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('deleteTicket', 'id', id) + const localVarPath = `/tickets/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Enrich a single artifact + * @param {number} id Ticket ID + * @param {string} name + * @param {EnrichmentForm} data + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + enrichArtifact: async (id: number, name: string, data: EnrichmentForm, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('enrichArtifact', 'id', id) + // verify required parameter 'name' is not null or undefined + assertParamExists('enrichArtifact', 'name', name) + // verify required parameter 'data' is not null or undefined + assertParamExists('enrichArtifact', 'data', data) + const localVarPath = `/tickets/{id}/artifacts/{name}/enrich` + .replace(`{${"id"}}`, encodeURIComponent(String(id))) + .replace(`{${"name"}}`, encodeURIComponent(String(name))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(data, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Get a single artifact + * @param {number} id Ticket ID + * @param {string} name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getArtifact: async (id: number, name: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('getArtifact', 'id', id) + // verify required parameter 'name' is not null or undefined + assertParamExists('getArtifact', 'name', name) + const localVarPath = `/tickets/{id}/artifacts/{name}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))) + .replace(`{${"name"}}`, encodeURIComponent(String(name))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Get a single ticket + * @param {number} id Ticket ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getTicket: async (id: number, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('getTicket', 'id', id) + const localVarPath = `/tickets/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Link files to an ticket. The files themself will be stored in object storage. + * @summary Link files to an ticket + * @param {number} id Ticket ID + * @param {Array} files Added files + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + linkFiles: async (id: number, files: Array, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('linkFiles', 'id', id) + // verify required parameter 'files' is not null or undefined + assertParamExists('linkFiles', 'files', files) + const localVarPath = `/tickets/{id}/files` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(files, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Link an ticket to an ticket + * @param {number} id Ticket ID + * @param {number} linkedID Added ticket ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + linkTicket: async (id: number, linkedID: number, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('linkTicket', 'id', id) + // verify required parameter 'linkedID' is not null or undefined + assertParamExists('linkTicket', 'linkedID', linkedID) + const localVarPath = `/tickets/{id}/tickets` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PATCH', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(linkedID, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary List tickets + * @param {string} [type] Ticket Type + * @param {number} [offset] Offset of the list + * @param {number} [count] Number of tickets + * @param {Array} [sort] Sort columns + * @param {Array} [desc] Sort descending + * @param {string} [query] Search query + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listTickets: async (type?: string, offset?: number, count?: number, sort?: Array, desc?: Array, query?: string, options: any = {}): Promise => { + const localVarPath = `/tickets`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (type !== undefined) { + localVarQueryParameter['type'] = type; + } + + if (offset !== undefined) { + localVarQueryParameter['offset'] = offset; + } + + if (count !== undefined) { + localVarQueryParameter['count'] = count; + } + + if (sort) { + localVarQueryParameter['sort'] = sort.join(COLLECTION_FORMATS.csv); + } + + if (desc) { + localVarQueryParameter['desc'] = desc.join(COLLECTION_FORMATS.csv); + } + + if (query !== undefined) { + localVarQueryParameter['query'] = query; + } + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Remove an artifact + * @param {number} id Ticket ID + * @param {string} name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + removeArtifact: async (id: number, name: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('removeArtifact', 'id', id) + // verify required parameter 'name' is not null or undefined + assertParamExists('removeArtifact', 'name', name) + const localVarPath = `/tickets/{id}/artifacts/{name}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))) + .replace(`{${"name"}}`, encodeURIComponent(String(name))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Comment will be removed from the ticket. + * @summary Remove an comment from an ticket + * @param {number} id Ticket ID + * @param {number} commentID Comment ID to remove + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + removeComment: async (id: number, commentID: number, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('removeComment', 'id', id) + // verify required parameter 'commentID' is not null or undefined + assertParamExists('removeComment', 'commentID', commentID) + const localVarPath = `/tickets/{id}/comments/{commentID}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))) + .replace(`{${"commentID"}}`, encodeURIComponent(String(commentID))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Remove an ticket playbook + * @param {number} id Ticket ID + * @param {string} playbookID Playbook ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + removeTicketPlaybook: async (id: number, playbookID: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('removeTicketPlaybook', 'id', id) + // verify required parameter 'playbookID' is not null or undefined + assertParamExists('removeTicketPlaybook', 'playbookID', playbookID) + const localVarPath = `/tickets/{id}/playbooks/{playbookID}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))) + .replace(`{${"playbookID"}}`, encodeURIComponent(String(playbookID))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Run automation on a single artifact + * @param {number} id Ticket ID + * @param {string} name + * @param {string} automation + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + runArtifact: async (id: number, name: string, automation: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('runArtifact', 'id', id) + // verify required parameter 'name' is not null or undefined + assertParamExists('runArtifact', 'name', name) + // verify required parameter 'automation' is not null or undefined + assertParamExists('runArtifact', 'automation', automation) + const localVarPath = `/tickets/{id}/artifacts/{name}/run/{automation}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))) + .replace(`{${"name"}}`, encodeURIComponent(String(name))) + .replace(`{${"automation"}}`, encodeURIComponent(String(automation))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Run ticket playbook task + * @param {number} id Ticket ID + * @param {string} playbookID Playbook ID + * @param {string} taskID Task ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + runTask: async (id: number, playbookID: string, taskID: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('runTask', 'id', id) + // verify required parameter 'playbookID' is not null or undefined + assertParamExists('runTask', 'playbookID', playbookID) + // verify required parameter 'taskID' is not null or undefined + assertParamExists('runTask', 'taskID', taskID) + const localVarPath = `/tickets/{id}/playbooks/{playbookID}/task/{taskID}/run` + .replace(`{${"id"}}`, encodeURIComponent(String(id))) + .replace(`{${"playbookID"}}`, encodeURIComponent(String(playbookID))) + .replace(`{${"taskID"}}`, encodeURIComponent(String(taskID))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Set a single artifact + * @param {number} id Ticket ID + * @param {string} name + * @param {Artifact} artifact + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + setArtifact: async (id: number, name: string, artifact: Artifact, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('setArtifact', 'id', id) + // verify required parameter 'name' is not null or undefined + assertParamExists('setArtifact', 'name', name) + // verify required parameter 'artifact' is not null or undefined + assertParamExists('setArtifact', 'artifact', artifact) + const localVarPath = `/tickets/{id}/artifacts/{name}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))) + .replace(`{${"name"}}`, encodeURIComponent(String(name))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(artifact, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Set ticket references + * @param {number} id Ticket ID + * @param {Array} references All ticket references + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + setReferences: async (id: number, references: Array, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('setReferences', 'id', id) + // verify required parameter 'references' is not null or undefined + assertParamExists('setReferences', 'references', references) + const localVarPath = `/tickets/{id}/references` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(references, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Set ticket schema + * @param {number} id Ticket ID + * @param {string} [schema] New ticket schema + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + setSchema: async (id: number, schema?: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('setSchema', 'id', id) + const localVarPath = `/tickets/{id}/schema` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(schema, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Set a ticket playbook task + * @param {number} id Ticket ID + * @param {string} playbookID Playbook ID + * @param {string} taskID Task ID + * @param {Task} task Task + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + setTask: async (id: number, playbookID: string, taskID: string, task: Task, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('setTask', 'id', id) + // verify required parameter 'playbookID' is not null or undefined + assertParamExists('setTask', 'playbookID', playbookID) + // verify required parameter 'taskID' is not null or undefined + assertParamExists('setTask', 'taskID', taskID) + // verify required parameter 'task' is not null or undefined + assertParamExists('setTask', 'task', task) + const localVarPath = `/tickets/{id}/playbooks/{playbookID}/task/{taskID}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))) + .replace(`{${"playbookID"}}`, encodeURIComponent(String(playbookID))) + .replace(`{${"taskID"}}`, encodeURIComponent(String(taskID))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(task, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Unlink an ticket to an ticket + * @param {number} id Ticket ID + * @param {number} linkedID Added ticket ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + unlinkTicket: async (id: number, linkedID: number, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('unlinkTicket', 'id', id) + // verify required parameter 'linkedID' is not null or undefined + assertParamExists('unlinkTicket', 'linkedID', linkedID) + const localVarPath = `/tickets/{id}/tickets` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(linkedID, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Update an existing ticket + * @param {number} id Ticket ID + * @param {Ticket} ticket Updated ticket + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateTicket: async (id: number, ticket: Ticket, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('updateTicket', 'id', id) + // verify required parameter 'ticket' is not null or undefined + assertParamExists('updateTicket', 'ticket', ticket) + const localVarPath = `/tickets/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(ticket, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * TicketsApi - functional programming interface + * @export + */ +export const TicketsApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = TicketsApiAxiosParamCreator(configuration) + return { + /** + * + * @summary Add a single artifact + * @param {number} id Ticket ID + * @param {Artifact} artifact Artifact object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async addArtifact(id: number, artifact: Artifact, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.addArtifact(id, artifact, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Add ticket comment + * @param {number} id Ticket ID + * @param {CommentForm} comment Ticket comment + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async addComment(id: number, comment: CommentForm, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.addComment(id, comment, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Add a new ticket playbook + * @param {number} id Ticket ID + * @param {PlaybookTemplateForm} playbook Ticket playbook object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async addTicketPlaybook(id: number, playbook: PlaybookTemplateForm, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.addTicketPlaybook(id, playbook, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Complete ticket playbook task + * @param {number} id Ticket ID + * @param {string} playbookID Playbook ID + * @param {string} taskID Task ID + * @param {object} data Ticket playbook object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async completeTask(id: number, playbookID: string, taskID: string, data: object, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.completeTask(id, playbookID, taskID, data, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Create a new ticket + * @param {TicketForm} ticket New ticket + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createTicket(ticket: TicketForm, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createTicket(ticket, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Create a new tickets in batch + * @param {Array} ticket New ticket + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createTicketBatch(ticket: Array, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createTicketBatch(ticket, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Delete an ticket + * @param {number} id Ticket ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async deleteTicket(id: number, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deleteTicket(id, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Enrich a single artifact + * @param {number} id Ticket ID + * @param {string} name + * @param {EnrichmentForm} data + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async enrichArtifact(id: number, name: string, data: EnrichmentForm, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.enrichArtifact(id, name, data, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Get a single artifact + * @param {number} id Ticket ID + * @param {string} name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getArtifact(id: number, name: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getArtifact(id, name, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Get a single ticket + * @param {number} id Ticket ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getTicket(id: number, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getTicket(id, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * Link files to an ticket. The files themself will be stored in object storage. + * @summary Link files to an ticket + * @param {number} id Ticket ID + * @param {Array} files Added files + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async linkFiles(id: number, files: Array, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.linkFiles(id, files, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Link an ticket to an ticket + * @param {number} id Ticket ID + * @param {number} linkedID Added ticket ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async linkTicket(id: number, linkedID: number, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.linkTicket(id, linkedID, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary List tickets + * @param {string} [type] Ticket Type + * @param {number} [offset] Offset of the list + * @param {number} [count] Number of tickets + * @param {Array} [sort] Sort columns + * @param {Array} [desc] Sort descending + * @param {string} [query] Search query + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listTickets(type?: string, offset?: number, count?: number, sort?: Array, desc?: Array, query?: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listTickets(type, offset, count, sort, desc, query, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Remove an artifact + * @param {number} id Ticket ID + * @param {string} name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async removeArtifact(id: number, name: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.removeArtifact(id, name, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * Comment will be removed from the ticket. + * @summary Remove an comment from an ticket + * @param {number} id Ticket ID + * @param {number} commentID Comment ID to remove + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async removeComment(id: number, commentID: number, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.removeComment(id, commentID, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Remove an ticket playbook + * @param {number} id Ticket ID + * @param {string} playbookID Playbook ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async removeTicketPlaybook(id: number, playbookID: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.removeTicketPlaybook(id, playbookID, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Run automation on a single artifact + * @param {number} id Ticket ID + * @param {string} name + * @param {string} automation + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async runArtifact(id: number, name: string, automation: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.runArtifact(id, name, automation, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Run ticket playbook task + * @param {number} id Ticket ID + * @param {string} playbookID Playbook ID + * @param {string} taskID Task ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async runTask(id: number, playbookID: string, taskID: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.runTask(id, playbookID, taskID, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Set a single artifact + * @param {number} id Ticket ID + * @param {string} name + * @param {Artifact} artifact + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async setArtifact(id: number, name: string, artifact: Artifact, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.setArtifact(id, name, artifact, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Set ticket references + * @param {number} id Ticket ID + * @param {Array} references All ticket references + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async setReferences(id: number, references: Array, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.setReferences(id, references, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Set ticket schema + * @param {number} id Ticket ID + * @param {string} [schema] New ticket schema + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async setSchema(id: number, schema?: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.setSchema(id, schema, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Set a ticket playbook task + * @param {number} id Ticket ID + * @param {string} playbookID Playbook ID + * @param {string} taskID Task ID + * @param {Task} task Task + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async setTask(id: number, playbookID: string, taskID: string, task: Task, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.setTask(id, playbookID, taskID, task, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Unlink an ticket to an ticket + * @param {number} id Ticket ID + * @param {number} linkedID Added ticket ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async unlinkTicket(id: number, linkedID: number, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.unlinkTicket(id, linkedID, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Update an existing ticket + * @param {number} id Ticket ID + * @param {Ticket} ticket Updated ticket + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateTicket(id: number, ticket: Ticket, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateTicket(id, ticket, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * TicketsApi - factory interface + * @export + */ +export const TicketsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = TicketsApiFp(configuration) + return { + /** + * + * @summary Add a single artifact + * @param {number} id Ticket ID + * @param {Artifact} artifact Artifact object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + addArtifact(id: number, artifact: Artifact, options?: any): AxiosPromise { + return localVarFp.addArtifact(id, artifact, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Add ticket comment + * @param {number} id Ticket ID + * @param {CommentForm} comment Ticket comment + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + addComment(id: number, comment: CommentForm, options?: any): AxiosPromise { + return localVarFp.addComment(id, comment, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Add a new ticket playbook + * @param {number} id Ticket ID + * @param {PlaybookTemplateForm} playbook Ticket playbook object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + addTicketPlaybook(id: number, playbook: PlaybookTemplateForm, options?: any): AxiosPromise { + return localVarFp.addTicketPlaybook(id, playbook, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Complete ticket playbook task + * @param {number} id Ticket ID + * @param {string} playbookID Playbook ID + * @param {string} taskID Task ID + * @param {object} data Ticket playbook object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + completeTask(id: number, playbookID: string, taskID: string, data: object, options?: any): AxiosPromise { + return localVarFp.completeTask(id, playbookID, taskID, data, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Create a new ticket + * @param {TicketForm} ticket New ticket + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createTicket(ticket: TicketForm, options?: any): AxiosPromise { + return localVarFp.createTicket(ticket, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Create a new tickets in batch + * @param {Array} ticket New ticket + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createTicketBatch(ticket: Array, options?: any): AxiosPromise { + return localVarFp.createTicketBatch(ticket, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Delete an ticket + * @param {number} id Ticket ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteTicket(id: number, options?: any): AxiosPromise { + return localVarFp.deleteTicket(id, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Enrich a single artifact + * @param {number} id Ticket ID + * @param {string} name + * @param {EnrichmentForm} data + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + enrichArtifact(id: number, name: string, data: EnrichmentForm, options?: any): AxiosPromise { + return localVarFp.enrichArtifact(id, name, data, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Get a single artifact + * @param {number} id Ticket ID + * @param {string} name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getArtifact(id: number, name: string, options?: any): AxiosPromise { + return localVarFp.getArtifact(id, name, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Get a single ticket + * @param {number} id Ticket ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getTicket(id: number, options?: any): AxiosPromise { + return localVarFp.getTicket(id, options).then((request) => request(axios, basePath)); + }, + /** + * Link files to an ticket. The files themself will be stored in object storage. + * @summary Link files to an ticket + * @param {number} id Ticket ID + * @param {Array} files Added files + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + linkFiles(id: number, files: Array, options?: any): AxiosPromise { + return localVarFp.linkFiles(id, files, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Link an ticket to an ticket + * @param {number} id Ticket ID + * @param {number} linkedID Added ticket ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + linkTicket(id: number, linkedID: number, options?: any): AxiosPromise { + return localVarFp.linkTicket(id, linkedID, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary List tickets + * @param {string} [type] Ticket Type + * @param {number} [offset] Offset of the list + * @param {number} [count] Number of tickets + * @param {Array} [sort] Sort columns + * @param {Array} [desc] Sort descending + * @param {string} [query] Search query + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listTickets(type?: string, offset?: number, count?: number, sort?: Array, desc?: Array, query?: string, options?: any): AxiosPromise { + return localVarFp.listTickets(type, offset, count, sort, desc, query, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Remove an artifact + * @param {number} id Ticket ID + * @param {string} name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + removeArtifact(id: number, name: string, options?: any): AxiosPromise { + return localVarFp.removeArtifact(id, name, options).then((request) => request(axios, basePath)); + }, + /** + * Comment will be removed from the ticket. + * @summary Remove an comment from an ticket + * @param {number} id Ticket ID + * @param {number} commentID Comment ID to remove + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + removeComment(id: number, commentID: number, options?: any): AxiosPromise { + return localVarFp.removeComment(id, commentID, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Remove an ticket playbook + * @param {number} id Ticket ID + * @param {string} playbookID Playbook ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + removeTicketPlaybook(id: number, playbookID: string, options?: any): AxiosPromise { + return localVarFp.removeTicketPlaybook(id, playbookID, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Run automation on a single artifact + * @param {number} id Ticket ID + * @param {string} name + * @param {string} automation + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + runArtifact(id: number, name: string, automation: string, options?: any): AxiosPromise { + return localVarFp.runArtifact(id, name, automation, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Run ticket playbook task + * @param {number} id Ticket ID + * @param {string} playbookID Playbook ID + * @param {string} taskID Task ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + runTask(id: number, playbookID: string, taskID: string, options?: any): AxiosPromise { + return localVarFp.runTask(id, playbookID, taskID, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Set a single artifact + * @param {number} id Ticket ID + * @param {string} name + * @param {Artifact} artifact + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + setArtifact(id: number, name: string, artifact: Artifact, options?: any): AxiosPromise { + return localVarFp.setArtifact(id, name, artifact, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Set ticket references + * @param {number} id Ticket ID + * @param {Array} references All ticket references + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + setReferences(id: number, references: Array, options?: any): AxiosPromise { + return localVarFp.setReferences(id, references, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Set ticket schema + * @param {number} id Ticket ID + * @param {string} [schema] New ticket schema + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + setSchema(id: number, schema?: string, options?: any): AxiosPromise { + return localVarFp.setSchema(id, schema, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Set a ticket playbook task + * @param {number} id Ticket ID + * @param {string} playbookID Playbook ID + * @param {string} taskID Task ID + * @param {Task} task Task + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + setTask(id: number, playbookID: string, taskID: string, task: Task, options?: any): AxiosPromise { + return localVarFp.setTask(id, playbookID, taskID, task, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Unlink an ticket to an ticket + * @param {number} id Ticket ID + * @param {number} linkedID Added ticket ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + unlinkTicket(id: number, linkedID: number, options?: any): AxiosPromise { + return localVarFp.unlinkTicket(id, linkedID, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Update an existing ticket + * @param {number} id Ticket ID + * @param {Ticket} ticket Updated ticket + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateTicket(id: number, ticket: Ticket, options?: any): AxiosPromise { + return localVarFp.updateTicket(id, ticket, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * TicketsApi - object-oriented interface + * @export + * @class TicketsApi + * @extends {BaseAPI} + */ +export class TicketsApi extends BaseAPI { + /** + * + * @summary Add a single artifact + * @param {number} id Ticket ID + * @param {Artifact} artifact Artifact object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public addArtifact(id: number, artifact: Artifact, options?: any) { + return TicketsApiFp(this.configuration).addArtifact(id, artifact, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Add ticket comment + * @param {number} id Ticket ID + * @param {CommentForm} comment Ticket comment + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public addComment(id: number, comment: CommentForm, options?: any) { + return TicketsApiFp(this.configuration).addComment(id, comment, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Add a new ticket playbook + * @param {number} id Ticket ID + * @param {PlaybookTemplateForm} playbook Ticket playbook object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public addTicketPlaybook(id: number, playbook: PlaybookTemplateForm, options?: any) { + return TicketsApiFp(this.configuration).addTicketPlaybook(id, playbook, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Complete ticket playbook task + * @param {number} id Ticket ID + * @param {string} playbookID Playbook ID + * @param {string} taskID Task ID + * @param {object} data Ticket playbook object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public completeTask(id: number, playbookID: string, taskID: string, data: object, options?: any) { + return TicketsApiFp(this.configuration).completeTask(id, playbookID, taskID, data, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Create a new ticket + * @param {TicketForm} ticket New ticket + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public createTicket(ticket: TicketForm, options?: any) { + return TicketsApiFp(this.configuration).createTicket(ticket, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Create a new tickets in batch + * @param {Array} ticket New ticket + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public createTicketBatch(ticket: Array, options?: any) { + return TicketsApiFp(this.configuration).createTicketBatch(ticket, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Delete an ticket + * @param {number} id Ticket ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public deleteTicket(id: number, options?: any) { + return TicketsApiFp(this.configuration).deleteTicket(id, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Enrich a single artifact + * @param {number} id Ticket ID + * @param {string} name + * @param {EnrichmentForm} data + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public enrichArtifact(id: number, name: string, data: EnrichmentForm, options?: any) { + return TicketsApiFp(this.configuration).enrichArtifact(id, name, data, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Get a single artifact + * @param {number} id Ticket ID + * @param {string} name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public getArtifact(id: number, name: string, options?: any) { + return TicketsApiFp(this.configuration).getArtifact(id, name, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Get a single ticket + * @param {number} id Ticket ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public getTicket(id: number, options?: any) { + return TicketsApiFp(this.configuration).getTicket(id, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Link files to an ticket. The files themself will be stored in object storage. + * @summary Link files to an ticket + * @param {number} id Ticket ID + * @param {Array} files Added files + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public linkFiles(id: number, files: Array, options?: any) { + return TicketsApiFp(this.configuration).linkFiles(id, files, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Link an ticket to an ticket + * @param {number} id Ticket ID + * @param {number} linkedID Added ticket ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public linkTicket(id: number, linkedID: number, options?: any) { + return TicketsApiFp(this.configuration).linkTicket(id, linkedID, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary List tickets + * @param {string} [type] Ticket Type + * @param {number} [offset] Offset of the list + * @param {number} [count] Number of tickets + * @param {Array} [sort] Sort columns + * @param {Array} [desc] Sort descending + * @param {string} [query] Search query + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public listTickets(type?: string, offset?: number, count?: number, sort?: Array, desc?: Array, query?: string, options?: any) { + return TicketsApiFp(this.configuration).listTickets(type, offset, count, sort, desc, query, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Remove an artifact + * @param {number} id Ticket ID + * @param {string} name + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public removeArtifact(id: number, name: string, options?: any) { + return TicketsApiFp(this.configuration).removeArtifact(id, name, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Comment will be removed from the ticket. + * @summary Remove an comment from an ticket + * @param {number} id Ticket ID + * @param {number} commentID Comment ID to remove + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public removeComment(id: number, commentID: number, options?: any) { + return TicketsApiFp(this.configuration).removeComment(id, commentID, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Remove an ticket playbook + * @param {number} id Ticket ID + * @param {string} playbookID Playbook ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public removeTicketPlaybook(id: number, playbookID: string, options?: any) { + return TicketsApiFp(this.configuration).removeTicketPlaybook(id, playbookID, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Run automation on a single artifact + * @param {number} id Ticket ID + * @param {string} name + * @param {string} automation + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public runArtifact(id: number, name: string, automation: string, options?: any) { + return TicketsApiFp(this.configuration).runArtifact(id, name, automation, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Run ticket playbook task + * @param {number} id Ticket ID + * @param {string} playbookID Playbook ID + * @param {string} taskID Task ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public runTask(id: number, playbookID: string, taskID: string, options?: any) { + return TicketsApiFp(this.configuration).runTask(id, playbookID, taskID, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Set a single artifact + * @param {number} id Ticket ID + * @param {string} name + * @param {Artifact} artifact + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public setArtifact(id: number, name: string, artifact: Artifact, options?: any) { + return TicketsApiFp(this.configuration).setArtifact(id, name, artifact, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Set ticket references + * @param {number} id Ticket ID + * @param {Array} references All ticket references + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public setReferences(id: number, references: Array, options?: any) { + return TicketsApiFp(this.configuration).setReferences(id, references, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Set ticket schema + * @param {number} id Ticket ID + * @param {string} [schema] New ticket schema + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public setSchema(id: number, schema?: string, options?: any) { + return TicketsApiFp(this.configuration).setSchema(id, schema, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Set a ticket playbook task + * @param {number} id Ticket ID + * @param {string} playbookID Playbook ID + * @param {string} taskID Task ID + * @param {Task} task Task + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public setTask(id: number, playbookID: string, taskID: string, task: Task, options?: any) { + return TicketsApiFp(this.configuration).setTask(id, playbookID, taskID, task, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Unlink an ticket to an ticket + * @param {number} id Ticket ID + * @param {number} linkedID Added ticket ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public unlinkTicket(id: number, linkedID: number, options?: any) { + return TicketsApiFp(this.configuration).unlinkTicket(id, linkedID, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Update an existing ticket + * @param {number} id Ticket ID + * @param {Ticket} ticket Updated ticket + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TicketsApi + */ + public updateTicket(id: number, ticket: Ticket, options?: any) { + return TicketsApiFp(this.configuration).updateTicket(id, ticket, options).then((request) => request(this.axios, this.basePath)); + } +} + + +/** + * TickettypesApi - axios parameter creator + * @export + */ +export const TickettypesApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @summary Create a new tickettype + * @param {TicketTypeForm} tickettype New tickettype + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createTicketType: async (tickettype: TicketTypeForm, options: any = {}): Promise => { + // verify required parameter 'tickettype' is not null or undefined + assertParamExists('createTicketType', 'tickettype', tickettype) + const localVarPath = `/tickettypes`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(tickettype, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Delete a tickettype + * @param {string} id TicketType ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteTicketType: async (id: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('deleteTicketType', 'id', id) + const localVarPath = `/tickettypes/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Get a single tickettype + * @param {string} id TicketType ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getTicketType: async (id: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('getTicketType', 'id', id) + const localVarPath = `/tickettypes/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary List tickettypes + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listTicketTypes: async (options: any = {}): Promise => { + const localVarPath = `/tickettypes`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Update an existing tickettype + * @param {string} id TicketType ID + * @param {TicketTypeForm} tickettype TicketType object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateTicketType: async (id: string, tickettype: TicketTypeForm, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('updateTicketType', 'id', id) + // verify required parameter 'tickettype' is not null or undefined + assertParamExists('updateTicketType', 'tickettype', tickettype) + const localVarPath = `/tickettypes/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(tickettype, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * TickettypesApi - functional programming interface + * @export + */ +export const TickettypesApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = TickettypesApiAxiosParamCreator(configuration) + return { + /** + * + * @summary Create a new tickettype + * @param {TicketTypeForm} tickettype New tickettype + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createTicketType(tickettype: TicketTypeForm, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createTicketType(tickettype, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Delete a tickettype + * @param {string} id TicketType ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async deleteTicketType(id: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deleteTicketType(id, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Get a single tickettype + * @param {string} id TicketType ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getTicketType(id: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getTicketType(id, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary List tickettypes + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listTicketTypes(options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listTicketTypes(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Update an existing tickettype + * @param {string} id TicketType ID + * @param {TicketTypeForm} tickettype TicketType object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateTicketType(id: string, tickettype: TicketTypeForm, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateTicketType(id, tickettype, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * TickettypesApi - factory interface + * @export + */ +export const TickettypesApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = TickettypesApiFp(configuration) + return { + /** + * + * @summary Create a new tickettype + * @param {TicketTypeForm} tickettype New tickettype + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createTicketType(tickettype: TicketTypeForm, options?: any): AxiosPromise { + return localVarFp.createTicketType(tickettype, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Delete a tickettype + * @param {string} id TicketType ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteTicketType(id: string, options?: any): AxiosPromise { + return localVarFp.deleteTicketType(id, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Get a single tickettype + * @param {string} id TicketType ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getTicketType(id: string, options?: any): AxiosPromise { + return localVarFp.getTicketType(id, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary List tickettypes + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listTicketTypes(options?: any): AxiosPromise> { + return localVarFp.listTicketTypes(options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Update an existing tickettype + * @param {string} id TicketType ID + * @param {TicketTypeForm} tickettype TicketType object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateTicketType(id: string, tickettype: TicketTypeForm, options?: any): AxiosPromise { + return localVarFp.updateTicketType(id, tickettype, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * TickettypesApi - object-oriented interface + * @export + * @class TickettypesApi + * @extends {BaseAPI} + */ +export class TickettypesApi extends BaseAPI { + /** + * + * @summary Create a new tickettype + * @param {TicketTypeForm} tickettype New tickettype + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TickettypesApi + */ + public createTicketType(tickettype: TicketTypeForm, options?: any) { + return TickettypesApiFp(this.configuration).createTicketType(tickettype, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Delete a tickettype + * @param {string} id TicketType ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TickettypesApi + */ + public deleteTicketType(id: string, options?: any) { + return TickettypesApiFp(this.configuration).deleteTicketType(id, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Get a single tickettype + * @param {string} id TicketType ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TickettypesApi + */ + public getTicketType(id: string, options?: any) { + return TickettypesApiFp(this.configuration).getTicketType(id, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary List tickettypes + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TickettypesApi + */ + public listTicketTypes(options?: any) { + return TickettypesApiFp(this.configuration).listTicketTypes(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Update an existing tickettype + * @param {string} id TicketType ID + * @param {TicketTypeForm} tickettype TicketType object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TickettypesApi + */ + public updateTicketType(id: string, tickettype: TicketTypeForm, options?: any) { + return TickettypesApiFp(this.configuration).updateTicketType(id, tickettype, options).then((request) => request(this.axios, this.basePath)); + } +} + + +/** + * UserdataApi - axios parameter creator + * @export + */ +export const UserdataApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @summary Get current user data + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + currentUserData: async (options: any = {}): Promise => { + const localVarPath = `/currentuserdata`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Get a single user data + * @param {string} id User Data ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUserData: async (id: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('getUserData', 'id', id) + const localVarPath = `/userdata/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary List userdata + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listUserData: async (options: any = {}): Promise => { + const localVarPath = `/userdata`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Update current user data + * @param {UserData} userdata User data object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateCurrentUserData: async (userdata: UserData, options: any = {}): Promise => { + // verify required parameter 'userdata' is not null or undefined + assertParamExists('updateCurrentUserData', 'userdata', userdata) + const localVarPath = `/currentuserdata`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(userdata, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Update an existing user data + * @param {string} id User Data ID + * @param {UserData} userdata User data object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateUserData: async (id: string, userdata: UserData, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('updateUserData', 'id', id) + // verify required parameter 'userdata' is not null or undefined + assertParamExists('updateUserData', 'userdata', userdata) + const localVarPath = `/userdata/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(userdata, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * UserdataApi - functional programming interface + * @export + */ +export const UserdataApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = UserdataApiAxiosParamCreator(configuration) + return { + /** + * + * @summary Get current user data + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async currentUserData(options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.currentUserData(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Get a single user data + * @param {string} id User Data ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getUserData(id: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getUserData(id, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary List userdata + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listUserData(options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listUserData(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Update current user data + * @param {UserData} userdata User data object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateCurrentUserData(userdata: UserData, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateCurrentUserData(userdata, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Update an existing user data + * @param {string} id User Data ID + * @param {UserData} userdata User data object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateUserData(id: string, userdata: UserData, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateUserData(id, userdata, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * UserdataApi - factory interface + * @export + */ +export const UserdataApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = UserdataApiFp(configuration) + return { + /** + * + * @summary Get current user data + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + currentUserData(options?: any): AxiosPromise { + return localVarFp.currentUserData(options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Get a single user data + * @param {string} id User Data ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUserData(id: string, options?: any): AxiosPromise { + return localVarFp.getUserData(id, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary List userdata + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listUserData(options?: any): AxiosPromise> { + return localVarFp.listUserData(options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Update current user data + * @param {UserData} userdata User data object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateCurrentUserData(userdata: UserData, options?: any): AxiosPromise { + return localVarFp.updateCurrentUserData(userdata, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Update an existing user data + * @param {string} id User Data ID + * @param {UserData} userdata User data object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateUserData(id: string, userdata: UserData, options?: any): AxiosPromise { + return localVarFp.updateUserData(id, userdata, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * UserdataApi - object-oriented interface + * @export + * @class UserdataApi + * @extends {BaseAPI} + */ +export class UserdataApi extends BaseAPI { + /** + * + * @summary Get current user data + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UserdataApi + */ + public currentUserData(options?: any) { + return UserdataApiFp(this.configuration).currentUserData(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Get a single user data + * @param {string} id User Data ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UserdataApi + */ + public getUserData(id: string, options?: any) { + return UserdataApiFp(this.configuration).getUserData(id, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary List userdata + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UserdataApi + */ + public listUserData(options?: any) { + return UserdataApiFp(this.configuration).listUserData(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Update current user data + * @param {UserData} userdata User data object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UserdataApi + */ + public updateCurrentUserData(userdata: UserData, options?: any) { + return UserdataApiFp(this.configuration).updateCurrentUserData(userdata, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Update an existing user data + * @param {string} id User Data ID + * @param {UserData} userdata User data object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UserdataApi + */ + public updateUserData(id: string, userdata: UserData, options?: any) { + return UserdataApiFp(this.configuration).updateUserData(id, userdata, options).then((request) => request(this.axios, this.basePath)); + } +} + + +/** + * UsersApi - axios parameter creator + * @export + */ +export const UsersApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @summary Create user + * @param {UserForm} user user object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createUser: async (user: UserForm, options: any = {}): Promise => { + // verify required parameter 'user' is not null or undefined + assertParamExists('createUser', 'user', user) + const localVarPath = `/users`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(user, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Get current user + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + currentUser: async (options: any = {}): Promise => { + const localVarPath = `/currentuser`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Delete user + * @param {string} id user ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteUser: async (id: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('deleteUser', 'id', id) + const localVarPath = `/users/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Get a single user + * @param {string} id user ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUser: async (id: string, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('getUser', 'id', id) + const localVarPath = `/users/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary List users + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listUsers: async (options: any = {}): Promise => { + const localVarPath = `/users`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Update user + * @param {string} id Template ID + * @param {UserForm} user user object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateUser: async (id: string, user: UserForm, options: any = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('updateUser', 'id', id) + // verify required parameter 'user' is not null or undefined + assertParamExists('updateUser', 'user', user) + const localVarPath = `/users/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(user, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * UsersApi - functional programming interface + * @export + */ +export const UsersApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = UsersApiAxiosParamCreator(configuration) + return { + /** + * + * @summary Create user + * @param {UserForm} user user object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createUser(user: UserForm, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createUser(user, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Get current user + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async currentUser(options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.currentUser(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Delete user + * @param {string} id user ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async deleteUser(id: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deleteUser(id, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Get a single user + * @param {string} id user ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getUser(id: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getUser(id, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary List users + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listUsers(options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listUsers(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Update user + * @param {string} id Template ID + * @param {UserForm} user user object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateUser(id: string, user: UserForm, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateUser(id, user, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * UsersApi - factory interface + * @export + */ +export const UsersApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = UsersApiFp(configuration) + return { + /** + * + * @summary Create user + * @param {UserForm} user user object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createUser(user: UserForm, options?: any): AxiosPromise { + return localVarFp.createUser(user, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Get current user + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + currentUser(options?: any): AxiosPromise { + return localVarFp.currentUser(options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Delete user + * @param {string} id user ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteUser(id: string, options?: any): AxiosPromise { + return localVarFp.deleteUser(id, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Get a single user + * @param {string} id user ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUser(id: string, options?: any): AxiosPromise { + return localVarFp.getUser(id, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary List users + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listUsers(options?: any): AxiosPromise> { + return localVarFp.listUsers(options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Update user + * @param {string} id Template ID + * @param {UserForm} user user object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateUser(id: string, user: UserForm, options?: any): AxiosPromise { + return localVarFp.updateUser(id, user, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * UsersApi - object-oriented interface + * @export + * @class UsersApi + * @extends {BaseAPI} + */ +export class UsersApi extends BaseAPI { + /** + * + * @summary Create user + * @param {UserForm} user user object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UsersApi + */ + public createUser(user: UserForm, options?: any) { + return UsersApiFp(this.configuration).createUser(user, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Get current user + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UsersApi + */ + public currentUser(options?: any) { + return UsersApiFp(this.configuration).currentUser(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Delete user + * @param {string} id user ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UsersApi + */ + public deleteUser(id: string, options?: any) { + return UsersApiFp(this.configuration).deleteUser(id, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Get a single user + * @param {string} id user ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UsersApi + */ + public getUser(id: string, options?: any) { + return UsersApiFp(this.configuration).getUser(id, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary List users + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UsersApi + */ + public listUsers(options?: any) { + return UsersApiFp(this.configuration).listUsers(options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Update user + * @param {string} id Template ID + * @param {UserForm} user user object that needs to be added + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UsersApi + */ + public updateUser(id: string, user: UserForm, options?: any) { + return UsersApiFp(this.configuration).updateUser(id, user, options).then((request) => request(this.axios, this.basePath)); + } +} + + diff --git a/ui/src/client/base.ts b/ui/src/client/base.ts new file mode 100644 index 0000000..d4ff370 --- /dev/null +++ b/ui/src/client/base.ts @@ -0,0 +1,71 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * + * API for the catalyst incident response platform. + * + * The version of the OpenAPI document: + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import { Configuration } from "./configuration"; +// Some imports not used depending on template conditions +// @ts-ignore +import globalAxios, { AxiosPromise, AxiosInstance } from 'axios'; + +export const BASE_PATH = "http://./api".replace(/\/+$/, ""); + +/** + * + * @export + */ +export const COLLECTION_FORMATS = { + csv: ",", + ssv: " ", + tsv: "\t", + pipes: "|", +}; + +/** + * + * @export + * @interface RequestArgs + */ +export interface RequestArgs { + url: string; + options: any; +} + +/** + * + * @export + * @class BaseAPI + */ +export class BaseAPI { + protected configuration: Configuration | undefined; + + constructor(configuration?: Configuration, protected basePath: string = BASE_PATH, protected axios: AxiosInstance = globalAxios) { + if (configuration) { + this.configuration = configuration; + this.basePath = configuration.basePath || this.basePath; + } + } +}; + +/** + * + * @export + * @class RequiredError + * @extends {Error} + */ +export class RequiredError extends Error { + name: "RequiredError" = "RequiredError"; + constructor(public field: string, msg?: string) { + super(msg); + } +} diff --git a/ui/src/client/common.ts b/ui/src/client/common.ts new file mode 100644 index 0000000..3d1fd99 --- /dev/null +++ b/ui/src/client/common.ts @@ -0,0 +1,138 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * + * API for the catalyst incident response platform. + * + * The version of the OpenAPI document: + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import { Configuration } from "./configuration"; +import { RequiredError, RequestArgs } from "./base"; +import { AxiosInstance } from 'axios'; + +/** + * + * @export + */ +export const DUMMY_BASE_URL = 'https://example.com' + +/** + * + * @throws {RequiredError} + * @export + */ +export const assertParamExists = function (functionName: string, paramName: string, paramValue: unknown) { + if (paramValue === null || paramValue === undefined) { + throw new RequiredError(paramName, `Required parameter ${paramName} was null or undefined when calling ${functionName}.`); + } +} + +/** + * + * @export + */ +export const setApiKeyToObject = async function (object: any, keyParamName: string, configuration?: Configuration) { + if (configuration && configuration.apiKey) { + const localVarApiKeyValue = typeof configuration.apiKey === 'function' + ? await configuration.apiKey(keyParamName) + : await configuration.apiKey; + object[keyParamName] = localVarApiKeyValue; + } +} + +/** + * + * @export + */ +export const setBasicAuthToObject = function (object: any, configuration?: Configuration) { + if (configuration && (configuration.username || configuration.password)) { + object["auth"] = { username: configuration.username, password: configuration.password }; + } +} + +/** + * + * @export + */ +export const setBearerAuthToObject = async function (object: any, configuration?: Configuration) { + if (configuration && configuration.accessToken) { + const accessToken = typeof configuration.accessToken === 'function' + ? await configuration.accessToken() + : await configuration.accessToken; + object["Authorization"] = "Bearer " + accessToken; + } +} + +/** + * + * @export + */ +export const setOAuthToObject = async function (object: any, name: string, scopes: string[], configuration?: Configuration) { + if (configuration && configuration.accessToken) { + const localVarAccessTokenValue = typeof configuration.accessToken === 'function' + ? await configuration.accessToken(name, scopes) + : await configuration.accessToken; + object["Authorization"] = "Bearer " + localVarAccessTokenValue; + } +} + +/** + * + * @export + */ +export const setSearchParams = function (url: URL, ...objects: any[]) { + const searchParams = new URLSearchParams(url.search); + for (const object of objects) { + for (const key in object) { + if (Array.isArray(object[key])) { + searchParams.delete(key); + for (const item of object[key]) { + searchParams.append(key, item); + } + } else { + searchParams.set(key, object[key]); + } + } + } + url.search = searchParams.toString(); +} + +/** + * + * @export + */ +export const serializeDataIfNeeded = function (value: any, requestOptions: any, configuration?: Configuration) { + const nonString = typeof value !== 'string'; + const needsSerialization = nonString && configuration && configuration.isJsonMime + ? configuration.isJsonMime(requestOptions.headers['Content-Type']) + : nonString; + return needsSerialization + ? JSON.stringify(value !== undefined ? value : {}) + : (value || ""); +} + +/** + * + * @export + */ +export const toPathString = function (url: URL) { + return url.pathname + url.search + url.hash +} + +/** + * + * @export + */ +export const createRequestFunction = function (axiosArgs: RequestArgs, globalAxios: AxiosInstance, BASE_PATH: string, configuration?: Configuration) { + return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => { + const axiosRequestArgs = {...axiosArgs.options, url: (configuration?.basePath || basePath) + axiosArgs.url}; + return axios.request(axiosRequestArgs); + }; +} diff --git a/ui/src/client/configuration.ts b/ui/src/client/configuration.ts new file mode 100644 index 0000000..d88cb01 --- /dev/null +++ b/ui/src/client/configuration.ts @@ -0,0 +1,101 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * + * API for the catalyst incident response platform. + * + * The version of the OpenAPI document: + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +export interface ConfigurationParameters { + apiKey?: string | Promise | ((name: string) => string) | ((name: string) => Promise); + username?: string; + password?: string; + accessToken?: string | Promise | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise); + basePath?: string; + baseOptions?: any; + formDataCtor?: new () => any; +} + +export class Configuration { + /** + * parameter for apiKey security + * @param name security name + * @memberof Configuration + */ + apiKey?: string | Promise | ((name: string) => string) | ((name: string) => Promise); + /** + * parameter for basic security + * + * @type {string} + * @memberof Configuration + */ + username?: string; + /** + * parameter for basic security + * + * @type {string} + * @memberof Configuration + */ + password?: string; + /** + * parameter for oauth2 security + * @param name security name + * @param scopes oauth2 scope + * @memberof Configuration + */ + accessToken?: string | Promise | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise); + /** + * override base path + * + * @type {string} + * @memberof Configuration + */ + basePath?: string; + /** + * base options for axios calls + * + * @type {any} + * @memberof Configuration + */ + baseOptions?: any; + /** + * The FormData constructor that will be used to create multipart form data + * requests. You can inject this here so that execution environments that + * do not support the FormData class can still run the generated client. + * + * @type {new () => FormData} + */ + formDataCtor?: new () => any; + + constructor(param: ConfigurationParameters = {}) { + this.apiKey = param.apiKey; + this.username = param.username; + this.password = param.password; + this.accessToken = param.accessToken; + this.basePath = param.basePath; + this.baseOptions = param.baseOptions; + this.formDataCtor = param.formDataCtor; + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime - MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + public isJsonMime(mime: string): boolean { + const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i'); + return mime !== null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json'); + } +} diff --git a/ui/src/client/index.ts b/ui/src/client/index.ts new file mode 100644 index 0000000..714cae3 --- /dev/null +++ b/ui/src/client/index.ts @@ -0,0 +1,18 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * + * API for the catalyst incident response platform. + * + * The version of the OpenAPI document: + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +export * from "./api"; +export * from "./configuration"; + diff --git a/ui/src/components/AdvancedJSONSchemaEditor.vue b/ui/src/components/AdvancedJSONSchemaEditor.vue new file mode 100644 index 0000000..a73abf2 --- /dev/null +++ b/ui/src/components/AdvancedJSONSchemaEditor.vue @@ -0,0 +1,195 @@ + + + + + diff --git a/ui/src/components/AppLink.vue b/ui/src/components/AppLink.vue new file mode 100644 index 0000000..7734e12 --- /dev/null +++ b/ui/src/components/AppLink.vue @@ -0,0 +1,64 @@ + + + diff --git a/ui/src/components/Editor.vue b/ui/src/components/Editor.vue new file mode 100644 index 0000000..d30d9df --- /dev/null +++ b/ui/src/components/Editor.vue @@ -0,0 +1,115 @@ + + + + + diff --git a/ui/src/components/JSONHTML.vue b/ui/src/components/JSONHTML.vue new file mode 100644 index 0000000..14b3941 --- /dev/null +++ b/ui/src/components/JSONHTML.vue @@ -0,0 +1,20 @@ + + + diff --git a/ui/src/components/List.vue b/ui/src/components/List.vue new file mode 100644 index 0000000..d97678b --- /dev/null +++ b/ui/src/components/List.vue @@ -0,0 +1,153 @@ + + + + + diff --git a/ui/src/components/TicketList.vue b/ui/src/components/TicketList.vue new file mode 100644 index 0000000..d73ef49 --- /dev/null +++ b/ui/src/components/TicketList.vue @@ -0,0 +1,325 @@ + + + + + diff --git a/ui/src/components/Timeline.vue b/ui/src/components/Timeline.vue new file mode 100644 index 0000000..811126c --- /dev/null +++ b/ui/src/components/Timeline.vue @@ -0,0 +1,139 @@ + + + diff --git a/ui/src/components/UserDataEditor.vue b/ui/src/components/UserDataEditor.vue new file mode 100644 index 0000000..6d9a3da --- /dev/null +++ b/ui/src/components/UserDataEditor.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/ui/src/components/VJsfCropImg.vue b/ui/src/components/VJsfCropImg.vue new file mode 100644 index 0000000..124a62d --- /dev/null +++ b/ui/src/components/VJsfCropImg.vue @@ -0,0 +1,85 @@ + + + + + diff --git a/ui/src/components/charts/Bar.ts b/ui/src/components/charts/Bar.ts new file mode 100644 index 0000000..82f5c1d --- /dev/null +++ b/ui/src/components/charts/Bar.ts @@ -0,0 +1,20 @@ +import { Component, Mixins } from 'vue-property-decorator' +import {HorizontalBar, mixins} from 'vue-chartjs'; +import ChartOptions from "chart.js"; + +@Component({ + extends: HorizontalBar, + mixins: [mixins.reactiveProp], + props: { + chartOptions: { + type: ChartOptions, + default: null + } + }, +}) +export default class BarChart extends Mixins(mixins.reactiveProp, HorizontalBar) { + mounted () { + // @ts-expect-error chartOptions are not expected + this.renderChart(this.chartData, this.chartOptions); + } +} diff --git a/ui/src/components/charts/Doughnut.ts b/ui/src/components/charts/Doughnut.ts new file mode 100644 index 0000000..cccc149 --- /dev/null +++ b/ui/src/components/charts/Doughnut.ts @@ -0,0 +1,20 @@ +import { Component, Mixins } from "vue-property-decorator"; +import { mixins, Pie } from "vue-chartjs"; +import ChartOptions from "chart.js"; + +@Component({ + extends: Pie, + mixins: [mixins.reactiveProp], + props: { + chartOptions: { + type: ChartOptions, + default: null + } + } +}) +export default class DoughnutChart extends Mixins(mixins.reactiveProp, Pie) { + mounted() { + // @ts-expect-error chartOptions are not expected + this.renderChart(this.chartData, this.chartOptions); + } +} diff --git a/ui/src/components/charts/Line.ts b/ui/src/components/charts/Line.ts new file mode 100644 index 0000000..d801ed5 --- /dev/null +++ b/ui/src/components/charts/Line.ts @@ -0,0 +1,20 @@ +import { Component, Mixins } from 'vue-property-decorator' +import {Line, mixins} from 'vue-chartjs'; +import ChartOptions from "chart.js"; + +@Component({ + extends: Line, + mixins: [mixins.reactiveProp], + props: { + chartOptions: { + type: ChartOptions, + default: null, + } + }, +}) +export default class LineChart extends Mixins(mixins.reactiveProp, Line) { + mounted () { + // @ts-expect-error chartOptions are not expected + this.renderChart(this.chartData, this.chartOptions); + } +} diff --git a/ui/src/components/icons/ArangoIcon.vue b/ui/src/components/icons/ArangoIcon.vue new file mode 100644 index 0000000..e493148 --- /dev/null +++ b/ui/src/components/icons/ArangoIcon.vue @@ -0,0 +1,34 @@ + + + + + diff --git a/ui/src/components/icons/EmitterIcon.vue b/ui/src/components/icons/EmitterIcon.vue new file mode 100644 index 0000000..b87c639 --- /dev/null +++ b/ui/src/components/icons/EmitterIcon.vue @@ -0,0 +1,31 @@ + + + + + diff --git a/ui/src/components/icons/MinioIcon.vue b/ui/src/components/icons/MinioIcon.vue new file mode 100644 index 0000000..197ea11 --- /dev/null +++ b/ui/src/components/icons/MinioIcon.vue @@ -0,0 +1,22 @@ + + + + + diff --git a/ui/src/components/icons/NodeRedIcon.vue b/ui/src/components/icons/NodeRedIcon.vue new file mode 100644 index 0000000..3457ea5 --- /dev/null +++ b/ui/src/components/icons/NodeRedIcon.vue @@ -0,0 +1,43 @@ + + + + + diff --git a/ui/src/components/snippets/ArtifactSnippet.vue b/ui/src/components/snippets/ArtifactSnippet.vue new file mode 100644 index 0000000..4b573dd --- /dev/null +++ b/ui/src/components/snippets/ArtifactSnippet.vue @@ -0,0 +1,64 @@ + + + diff --git a/ui/src/components/snippets/IDSnippet.vue b/ui/src/components/snippets/IDSnippet.vue new file mode 100644 index 0000000..b80a6e7 --- /dev/null +++ b/ui/src/components/snippets/IDSnippet.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/ui/src/components/snippets/TicketSnippet.vue b/ui/src/components/snippets/TicketSnippet.vue new file mode 100644 index 0000000..3c79df5 --- /dev/null +++ b/ui/src/components/snippets/TicketSnippet.vue @@ -0,0 +1,91 @@ + + + diff --git a/ui/src/main.ts b/ui/src/main.ts new file mode 100644 index 0000000..ef7a24b --- /dev/null +++ b/ui/src/main.ts @@ -0,0 +1,86 @@ +import Vue from "vue"; +import App from "./App.vue"; +import router from "./router"; +import store from "./store"; + +import JsonSchemaEditor from "json-schema-editor-vue"; +import vuetify from "./plugins/vuetify"; +import VuePipeline from "vue-pipeline"; +import VueLodash from "vue-lodash"; +import lodash from "lodash"; +import axios from "axios"; +import { DateTime } from 'luxon'; +import VueNativeSock from 'vue-native-websocket'; +import antInputDirective from 'ant-design-vue/es/_util/antInputDirective' +import antDirective from 'ant-design-vue/es/_util/antDirective' + +import VueAxios from "vue-axios"; +import VueLuxon from "vue-luxon"; + +import "./registerServiceWorker"; + +import "json-schema-editor-vue/lib/json-schema-editor-vue.css"; +import "@mdi/font/css/materialdesignicons.css"; +import "vue-d3-network/dist/vue-d3-network.css"; +import '@koumoul/vjsf/dist/main.css' + +import { Problem } from "@/types/types"; +Vue.use(VueLodash, { lodash: lodash }); +Vue.use(antDirective); +Vue.use(antInputDirective); +Vue.use(JsonSchemaEditor); +Vue.use(VuePipeline); +Vue.use(VueAxios, axios); +Vue.use(VueLuxon); + +// import VJsf from '@koumoul/vjsf' +import VJsf from '@koumoul/vjsf/lib/VJsf.js'; +import '@koumoul/vjsf/lib/deps/third-party.js'; + +Vue.component('VJsf', VJsf) + +Vue.config.productionTip = false; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +Vue.filter("capitalize", function(value: any) { + if (!value) return ""; + return lodash.startCase(value.toString()); +}); + +Vue.filter("formatdate", function(s: string, format: string) { + if (!format) { + return DateTime.fromISO(s).toLocaleString(DateTime.DATETIME_SHORT); + } + return DateTime.fromISO(s).toFormat(format); +}); + +let protocol = "ws" +if (location.protocol === "https:") { + protocol = "wss" +} +Vue.use(VueNativeSock, protocol + '://' + location.hostname + ':'+ location.port +'/wss', { store: store, format: 'json' }) + +const v = new Vue({ + router, + vuetify, + store, + render: h => h(App) +}).$mount("#app"); + +axios.interceptors.response.use( + response => response, + error => { + console.log(error) + if (error.response.data && 'title' in error.response.data && 'detail' in error.response.data) { + const problem = error.response.data as Problem; + v.$store.dispatch("alertError", { name: problem.title, detail: problem.detail }); + return Promise.reject(error); + } + if (error.response.data && 'error' in error.response.data) { + v.$store.dispatch("alertError", { name: "Error", detail: error.response.data.error }); + return Promise.reject(error); + } + v.$store.dispatch("alertError", { name: "Error", detail: JSON.stringify(error.response.data) }); + return Promise.reject(error); + } +); diff --git a/ui/src/plugins/vuetify.ts b/ui/src/plugins/vuetify.ts new file mode 100644 index 0000000..e8a8003 --- /dev/null +++ b/ui/src/plugins/vuetify.ts @@ -0,0 +1,90 @@ +import "@mdi/font/css/materialdesignicons.css"; +import Vue from "vue"; +import Vuetify from "vuetify/lib"; +import MinioIcon from "../components/icons/MinioIcon.vue"; +import NodeRedIcon from "../components/icons/NodeRedIcon.vue"; +import ArangoIcon from "../components/icons/ArangoIcon.vue"; +import EmitterIcon from "../components/icons/EmitterIcon.vue"; + +Vue.use(Vuetify); + +export const colors = [ + '#c62828', '#6a1b9a', + '#283593', '#0277bd', + '#00695c', '#558b2f', + '#f9a825', '#ef6c00', + '#ad1457', '#4527a0', + '#1565c0', '#00838f', + '#2e7d32', '#9e9d24', + '#ff8f00', '#d84315', +] + +export default new Vuetify({ + theme: { + dark: false, + themes: { + light: { + statusbar: "#212121", // "#1c313a", + appbar: "#eeeeee", //'#28282e', + background: "#f5f5f5", //'#393a3f', + cards: "#e0e0e0", //'#393a3f', + + primary: "#607d8b", + yellow: "#FFC107", // "#FFEB3B", + error: "#C62828", // "#d32f2f", + info: "#1565C0", // "#2196F3", + success: "#2E7D32", // "#689f38", + warning: "#D84315", // "#fbc02d", + + red: "#C62828", // "#d32f2f", + }, + dark: { + // statusbar: "#d35400", + // statusbar: "#f03f24", //'#18181c', 240 63 36 + // appbar: "#212121", //'#28282e', + // background: "#303030", //'#393a3f', + // cards: "#424242", //'#393a3f', + + statusbar: "#121212", + appbar: "#212121", //'#28282e', + background: "#303030", //'#393a3f', + cards: "#424242", //'#393a3f', + + // alertmanager: "#ef6c00", + // catalyst: "#ad1457", + // blocklist: "#2e7d32", + // uploadportal: "#283593", + // search: "#c62828", + + // darksteel: "#1c313a", + // steel: "#455a64", + // lightsteel: "#718792", + primary: "#FFC107", // "#00bcd4", // "#FFEB3B", + yellow: "#FFC107", // "#FFEB3B", + // accent: "#82B1FF", + error: "#ef9a9a", // "#d32f2f", + info: "#90caf9", // "#2196F3", + success: "#a5d6a7", // "#689f38", + warning: "#ffab91", // "#fbc02d", + + red: "#C62828", // "#d32f2f", + }, + }, + }, + icons: { + values: { + minio: { + component: MinioIcon, + }, + nodered: { + component: NodeRedIcon, + }, + arango: { + component: ArangoIcon, + }, + emitter: { + component: EmitterIcon, + }, + }, + }, +}); diff --git a/ui/src/registerServiceWorker.ts b/ui/src/registerServiceWorker.ts new file mode 100644 index 0000000..1473a0a --- /dev/null +++ b/ui/src/registerServiceWorker.ts @@ -0,0 +1,34 @@ +/* eslint-disable no-console */ + +import { register } from "register-service-worker"; + +if (process.env.NODE_ENV === "production") { + register(`${process.env.BASE_URL}service-worker.js`, { + ready() { + console.log( + "App is being served from cache by a service worker.\n" + + "For more details, visit https://goo.gl/AFskqB" + ); + }, + registered() { + console.log("Service worker has been registered."); + }, + cached() { + console.log("Content has been cached for offline use."); + }, + updatefound() { + console.log("New content is downloading."); + }, + updated() { + console.log("New content is available; please refresh."); + }, + offline() { + console.log( + "No internet connection found. App is running in offline mode." + ); + }, + error(error) { + console.error("Error during service worker registration:", error); + }, + }); +} diff --git a/ui/src/router/index.ts b/ui/src/router/index.ts new file mode 100644 index 0000000..e8a7376 --- /dev/null +++ b/ui/src/router/index.ts @@ -0,0 +1,236 @@ +import Vue from "vue"; +import VueRouter, { RouteConfig, RawLocation, Route } from "vue-router"; +import ArtifactPopup from "../views/ArtifactPopup.vue"; +import Ticket from "../views/Ticket.vue"; +import TicketNew from "../views/TicketNew.vue"; +import TicketList from "../views/TicketList.vue"; +import Graph from "../views/Graph.vue"; +import Playbook from "../views/Playbook.vue"; +import PlaybookList from "../views/PlaybookList.vue"; +import Automation from "../views/Automation.vue"; +import UserData from "../views/UserData.vue"; +import Profile from "../views/Profile.vue"; +import UserDataList from "../views/UserDataList.vue"; +import AutomationList from "../views/AutomationList.vue"; +import Rule from "../views/Rule.vue"; +import RuleList from "../views/RuleList.vue"; +import Template from "../views/Template.vue"; +import TemplateList from "../views/TemplateList.vue"; +import API from "../views/API.vue"; +import User from '../views/User.vue'; +import UserList from "@/views/UserList.vue"; +import Job from '../views/Job.vue'; +import JobList from "@/views/JobList.vue"; +import GroupList from "@/views/GroupList.vue"; +import Dashboard from "@/views/Dashboard.vue"; +import Group from "@/views/Group.vue"; +import TicketType from '../views/TicketType.vue'; +import TicketTypeList from "@/views/TicketTypeList.vue"; +import TaskList from "@/views/TaskList.vue"; + +Vue.use(VueRouter); + +const originalPush = VueRouter.prototype.push; +VueRouter.prototype.push = function push(location: RawLocation): Promise { + return new Promise((resolve, reject) => { + originalPush.call(this, location, () => { + // on complete + + resolve(this.currentRoute); + }, (error) => { + // on abort + + // only ignore NavigationDuplicated error + if (error.name === 'NavigationDuplicated') { + resolve(this.currentRoute); + } else { + reject(error); + } + }); + }); +}; + + +const routes: Array = [ + { + path: "/", + name: "Catalyst", + redirect: { name: "Dashboard" }, + }, + + { + path: "/dashboard", + name: "Dashboard", + component: Dashboard, + }, + + { + path: "/profile", + name: "Profile", + component: Profile, + }, + + { + path: "/tickets/:type?", + name: "TicketList", + component: TicketList, + props: true, + }, + { + path: "/tickets/:type?/:id", + name: "Ticket", + component: Ticket, + }, + { + path: "/tickets/:type/new", + name: "TicketNew", + component: TicketNew, + }, + { + path: "/tickets/:type?/:id/artifact/:artifact", + name: "ArtifactPopup", + component: ArtifactPopup, + }, + + { + path: "/tasks", + name: "TaskList", + component: TaskList, + }, + + { + path: "/templates", + name: "TemplateList", + component: TemplateList, + children: [ + { + path: ":id", + name: "Template", + component: Template, + }, + ] + }, + + { + path: "/tickettype", + name: "TicketTypeList", + component: TicketTypeList, + children: [ + { + path: ":id", + name: "TicketType", + component: TicketType, + }, + ] + }, + + { + path: "/playbooks", + name: "PlaybookList", + component: PlaybookList, + children: [ + { + path: ":id", + name: "Playbook", + component: Playbook, + }, + ] + }, + + { + path: "/userdata", + name: "UserDataList", + component: UserDataList, + children: [ + { + path: ":id", + name: "UserData", + component: UserData, + }, + ] + }, + + { + path: "/jobs", + name: "JobList", + component: JobList, + children: [ + { + path: ":id", + name: "Job", + component: Job, + }, + ] + }, + + { + path: "/automations", + name: "AutomationList", + component: AutomationList, + children: [ + { + path: ":id", + name: "Automation", + component: Automation, + }, + ] + }, + + { + path: "/rules", + name: "RuleList", + component: RuleList, + children: [ + { + path: ":id", + name: "Rule", + component: Rule, + }, + ] + }, + + { + path: "/users", + name: "UserList", + component: UserList, + children: [ + { + path: ":id", + name: "User", + component: User, + }, + ] + }, + + { + path: "/groups", + name: "GroupList", + component: GroupList, + children: [ + { + path: ":id", + name: "Group", + component: Group, + }, + ] + }, + + { + path: "/apidocs", + name: "API", + component: API, + }, + + { + path: "/graph/:col/:id", + name: "Graph", + component: Graph, + }, +]; + +const router = new VueRouter({ + mode: 'history', + routes, +}); + +export default router; diff --git a/ui/src/sass/variables.scss.bak b/ui/src/sass/variables.scss.bak new file mode 100644 index 0000000..5db630b --- /dev/null +++ b/ui/src/sass/variables.scss.bak @@ -0,0 +1,29 @@ +// Globals +// $body-font-family: 'Work Sans', serif; +$border-radius-root: 6px; +$font-size-root: 14px; + +// Variables must come before the import +$btn-letter-spacing: 0; +$btn-font-weight: 400; +$list-item-title-font-size: 0.929rem; +$list-item-dense-title-font-size: 0.929rem; +$list-item-dense-title-font-weight: initial; +$fab-icon-sizes: ( + 'small': 20 +); +$btn-sizes: ( + 'default': 41, + 'large': 54 +); + +$headings: ( + 'h1': ( + 'size': 3.3125rem, + 'line-height': 1.15em + ), + 'h2': ( + 'size': 2.25rem, + 'line-height': 1.5em + ) +); diff --git a/ui/src/services/api.ts b/ui/src/services/api.ts new file mode 100644 index 0000000..51b032c --- /dev/null +++ b/ui/src/services/api.ts @@ -0,0 +1,78 @@ +import { + UserdataApi, + UserdataApiFactory, + AutomationsApi, + AutomationsApiFactory, + Configuration, + GraphApi, + GraphApiFactory, + GroupsApi, + GroupsApiFactory, + LogsApi, + LogsApiFactory, + PlaybooksApi, + PlaybooksApiFactory, + RulesApi, + RulesApiFactory, + StatisticsApi, + StatisticsApiFactory, + TasksApi, + TasksApiFactory, + TemplatesApi, + TemplatesApiFactory, + TicketsApi, + TicketsApiFactory, + TickettypesApi, + TickettypesApiFactory, + UsersApi, + UsersApiFactory, + SettingsApi, + SettingsApiFactory, + JobsApi, + JobsApiFactory, +} from "@/client"; + +const config = new Configuration({ + basePath: + window.location.protocol + + "//" + + window.location.hostname + + ":" + + window.location.port + + "/api" +}); + +export const API: TicketsApi & + TemplatesApi & + PlaybooksApi & + RulesApi & + AutomationsApi & + UserdataApi & + LogsApi & + GraphApi & + UsersApi & + GroupsApi & + StatisticsApi & + SettingsApi & + TickettypesApi & + JobsApi & + TasksApi = Object.assign( + {}, + TicketsApiFactory(config), + PlaybooksApiFactory(config), + TemplatesApiFactory(config), + RulesApiFactory(config), + AutomationsApiFactory(config), + SettingsApiFactory(config), + LogsApiFactory(config), + GraphApiFactory(config), + UsersApiFactory(config), + UserdataApiFactory(config), + GroupsApiFactory(config), + StatisticsApiFactory(config), + SettingsApiFactory(config), + TickettypesApiFactory(config), + TasksApiFactory(config), + SettingsApiFactory(config), + JobsApiFactory(config) +); diff --git a/ui/src/shims-tsx.d.ts b/ui/src/shims-tsx.d.ts new file mode 100644 index 0000000..2bcdf9f --- /dev/null +++ b/ui/src/shims-tsx.d.ts @@ -0,0 +1,13 @@ +import Vue, { VNode } from "vue"; + +declare global { + namespace JSX { + // tslint:disable no-empty-interface + interface Element extends VNode {} + // tslint:disable no-empty-interface + interface ElementClass extends Vue {} + interface IntrinsicElements { + [elem: string]: any; + } + } +} diff --git a/ui/src/shims-vue.d.ts b/ui/src/shims-vue.d.ts new file mode 100644 index 0000000..326b35b --- /dev/null +++ b/ui/src/shims-vue.d.ts @@ -0,0 +1,22 @@ +declare module "*.vue" { + import Vue from "vue"; + export default Vue; +} + +declare module "v-jsoneditor/src/index"; +declare module "@koumoul/vjsf"; +declare module "@koumoul/vjsf/lib/VJsf.js"; +declare module "vue-pipeline"; +declare module "json-schema-editor-vue"; +declare module "vue-json-to-html"; +declare module "vue-d3-network"; +declare module "vue-luxon"; +declare module 'swagger-ui'; +declare module 'prismjs/components/prism-core'; +declare module 'vue-native-websocket'; +declare module 'antlr4'; +declare module 'vue-cropperjs'; +declare module 'graphlib'; +declare module 'ant-design-vue/es/_util/antInputDirective'; +declare module 'flat'; +declare module 'crypto'; diff --git a/ui/src/store/index.ts b/ui/src/store/index.ts new file mode 100644 index 0000000..fd68b3b --- /dev/null +++ b/ui/src/store/index.ts @@ -0,0 +1,104 @@ +import Vue from "vue"; +import Vuex, {ActionContext} from "vuex"; +import {API} from "@/services/api"; +import {UserData, TicketList, Settings, UserResponse} from "@/client"; +import {AxiosResponse} from "axios"; +import {Alert} from "@/types/types"; +import {templateStore} from "./modules/templates"; +import {socketStore} from "@/store/modules/socket"; + +Vue.use(Vuex); + +export default new Vuex.Store({ + modules: { + templates: templateStore, + socket: socketStore, + }, + state: { + user: {} as UserResponse, + counts: {} as Record, + task_count: 0 as number, + + settings: {} as Settings, + userdata: {} as UserData, + + alert: {} as Alert, + showAlert: false as boolean, + }, + getters: { + timeformat: (state) => { + if ('timeformat' in state.settings && state.settings.timeformat) { + return state.settings.timeformat + } + return 'dd-MM-yyyy' + } + }, + mutations: { + setUser (state, msg) { + state.user = msg; + }, + setCount (state, msg) { + Vue.set(state.counts, msg.name, msg.count); + }, + setTaskCount (state, msg) { + state.task_count = msg; + }, + setUserData (state, msg: UserData) { + state.userdata = msg + }, + setSettings (state, msg: Settings) { + state.settings = msg + }, + setAlert (state, msg: Alert) { + state.showAlert = false; + state.showAlert = true; + state.alert = msg; + } + }, + actions: { + getUser (context: ActionContext) { + API.currentUser().then((response) => { + context.commit("setUser", response.data); + context.dispatch("fetchCount"); + }) + }, + getUserData (context: ActionContext) { + API.currentUserData().then((response: AxiosResponse) => { + context.commit("setUserData", response.data); + }) + }, + getSettings (context: ActionContext) { + API.getSettings().then((response: AxiosResponse) => { + context.commit("setSettings", response.data); + context.dispatch("fetchCount"); + }) + }, + fetchCount (context: ActionContext) { + if (!context.state.user.id || !context.state.settings.ticketTypes) { + return + } + + const username = context.state.user.id; + Vue.lodash.forEach(context.state.settings.ticketTypes, (t) => { + + API.listTickets(t.id,0,10,[],[], "status == 'open' AND (owner == '"+username+"' OR !owner)") + .then((response: AxiosResponse) => { + context.commit("setCount", {"name": t.id, "count": response.data.count}); + }); + API.listTasks().then((response) => { + if (response.data) { + context.commit("setTaskCount", response.data.length ); + } + }) + }) + }, + alertSuccess(context: ActionContext, msg) { + msg.type = "success" + context.commit("setAlert", msg) + }, + alertError(context: ActionContext, msg) { + msg.type = "error" + context.commit("setAlert", msg) + }, + }, +}); diff --git a/ui/src/store/modules/socket.ts b/ui/src/store/modules/socket.ts new file mode 100644 index 0000000..a3acbed --- /dev/null +++ b/ui/src/store/modules/socket.ts @@ -0,0 +1,64 @@ +import Vue from "vue"; +import Vuex, {ActionContext} from "vuex"; +import lodash from "lodash"; + +Vue.use(Vuex); + +interface State { + socket: any; +} + +export const socketStore = { + state: (): State => ({ + socket: { + isConnected: false, + message: '', + reconnectError: false, + } + }), + mutations: { + SOCKET_ONOPEN (state: State, event: any) { + // console.log("SOCKET_ONOPEN"); + Vue.prototype.$socket = event.currentTarget; + state.socket.isConnected = true; + }, + SOCKET_ONCLOSE (state: State, event: any) { + // console.log("SOCKET_ONCLOSE"); + state.socket.isConnected = false; + }, + SOCKET_ONERROR (state: State, event: any) { + // console.log("SOCKET_ONERROR"); + console.error(state, event); + }, + // default handler called for all methods + SOCKET_ONMESSAGE (state: State, message: any) { + // console.log("SOCKET_ONMESSAGE"); + state.socket.message = message; + }, + // mutations for reconnect methods + SOCKET_RECONNECT(state: State, count: any) { + // console.log("SOCKET_RECONNECT"); + console.info(state, count); + }, + SOCKET_RECONNECT_ERROR(state: State) { + // console.log("SOCKET_RECONNECT_ERROR"); + state.socket.reconnectError = true; + }, + }, + actions: { + sendMessage: function(context: ActionContext, msg: any) { + Vue.prototype.$socket.send(msg); + }, + update: function (context: ActionContext, msg: any) { + // console.log("update", msg); + if (!msg || !(lodash.has(msg, "ids")) || !msg["ids"]) { + return + } + Vue.lodash.forEach(msg["ids"], (id) => { + if (lodash.startsWith(id, "settings/")) { + context.dispatch("getSetting") + } + }); + } + } +} diff --git a/ui/src/store/modules/templates.ts b/ui/src/store/modules/templates.ts new file mode 100644 index 0000000..2d71c10 --- /dev/null +++ b/ui/src/store/modules/templates.ts @@ -0,0 +1,75 @@ +import Vue from "vue"; +import Vuex, {ActionContext} from "vuex"; +import {TicketTemplate} from "@/client"; +import {API} from "@/services/api"; +import {AxiosResponse} from "axios"; + +Vue.use(Vuex); + +interface State { + templates: Array; +} + +export const templateStore = { + state: (): State => ({ + templates: [], + }), + mutations: { + setTemplates(state: State, msg: Array) { + state.templates = msg; + }, + }, + actions: { + listTemplates(context: ActionContext) { + API.listTemplates().then((response: AxiosResponse>) => { + context.commit("setTemplates", response.data) + }); + }, + getTemplate(context: ActionContext, id: string) { + return new Promise((resolve) => { + API.getTemplate(id).then((response: AxiosResponse) => { + resolve(response.data); + }).catch(error => { + context.dispatch("alertError", {name: "Template could not be loaded", details: error}); + }); + }); + }, + addTemplate(context: ActionContext, template: TicketTemplate) { + return new Promise((resolve) => { + API.createTemplate(template).then(() => { + context.dispatch("listTemplates").then(() => { + context.dispatch("alertSuccess", {name: "Template created"}).then(() => { + resolve({}) + }); + }).catch(error => { + context.dispatch("alertError", {name: "Template created, but reload failed", details: error}); + }); + }).catch(error => { + context.dispatch("alertError", {name: "Template could not be created", details: error}); + }); + }); + }, + updateTemplate(context: ActionContext, msg: any) { + API.updateTemplate(msg.id, msg.template).then(() => { + context.dispatch("alertSuccess", {name: "Template updated"}); + }).catch(error => { + context.dispatch("alertError", {name: "Template could not be updated", details: error}); + }); + }, + deleteTemplate(context: ActionContext, id: string) { + return new Promise((resolve) => { + API.deleteTemplate(id).then(() => { + context.dispatch("listTemplates").then(() => { + context.dispatch("alertSuccess", {name: "Template deleted"}).then(() => { + resolve({}); + }); + }).catch(error => { + context.dispatch("alertError", {name: "Template deleted, but reload failed", details: error}); + }); + }).catch(error => { + context.dispatch("alertError", {name: "Template could not be deleted", details: error}); + }); + }); + }, + } +} diff --git a/ui/src/suggestions/grammar/CAQLLexer.interp b/ui/src/suggestions/grammar/CAQLLexer.interp new file mode 100644 index 0000000..7633444 --- /dev/null +++ b/ui/src/suggestions/grammar/CAQLLexer.interp @@ -0,0 +1,282 @@ +token literal names: +null +'.' +'=~' +'!~' +'==' +'!=' +'<' +'>' +'<=' +'>=' +'+' +'-' +'*' +'/' +'%' +'?' +':' +'::' +'..' +',' +'(' +')' +'{' +'}' +'[' +']' +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null + +token symbolic names: +null +DOT +T_REGEX_MATCH +T_REGEX_NON_MATCH +T_EQ +T_NE +T_LT +T_GT +T_LE +T_GE +T_PLUS +T_MINUS +T_TIMES +T_DIV +T_MOD +T_QUESTION +T_COLON +T_SCOPE +T_RANGE +T_COMMA +T_OPEN +T_CLOSE +T_OBJECT_OPEN +T_OBJECT_CLOSE +T_ARRAY_OPEN +T_ARRAY_CLOSE +T_AGGREGATE +T_ALL +T_AND +T_ANY +T_ASC +T_COLLECT +T_DESC +T_DISTINCT +T_FALSE +T_FILTER +T_FOR +T_GRAPH +T_IN +T_INBOUND +T_INSERT +T_INTO +T_K_SHORTEST_PATHS +T_LET +T_LIKE +T_LIMIT +T_NONE +T_NOT +T_NULL +T_OR +T_OUTBOUND +T_REMOVE +T_REPLACE +T_RETURN +T_SHORTEST_PATH +T_SORT +T_TRUE +T_UPDATE +T_UPSERT +T_WITH +T_KEEP +T_COUNT +T_OPTIONS +T_PRUNE +T_SEARCH +T_TO +T_CURRENT +T_NEW +T_OLD +T_STRING +T_INT +T_FLOAT +T_PARAMETER +T_QUOTED_STRING +SINGLE_LINE_COMMENT +MULTILINE_COMMENT +SPACES +UNEXPECTED_CHAR +ERROR_RECONGNIGION + +rule names: +DOT +T_REGEX_MATCH +T_REGEX_NON_MATCH +T_EQ +T_NE +T_LT +T_GT +T_LE +T_GE +T_PLUS +T_MINUS +T_TIMES +T_DIV +T_MOD +T_QUESTION +T_COLON +T_SCOPE +T_RANGE +T_COMMA +T_OPEN +T_CLOSE +T_OBJECT_OPEN +T_OBJECT_CLOSE +T_ARRAY_OPEN +T_ARRAY_CLOSE +T_AGGREGATE +T_ALL +T_AND +T_ANY +T_ASC +T_COLLECT +T_DESC +T_DISTINCT +T_FALSE +T_FILTER +T_FOR +T_GRAPH +T_IN +T_INBOUND +T_INSERT +T_INTO +T_K_SHORTEST_PATHS +T_LET +T_LIKE +T_LIMIT +T_NONE +T_NOT +T_NULL +T_OR +T_OUTBOUND +T_REMOVE +T_REPLACE +T_RETURN +T_SHORTEST_PATH +T_SORT +T_TRUE +T_UPDATE +T_UPSERT +T_WITH +T_KEEP +T_COUNT +T_OPTIONS +T_PRUNE +T_SEARCH +T_TO +T_CURRENT +T_NEW +T_OLD +T_STRING +T_INT +T_FLOAT +T_PARAMETER +T_QUOTED_STRING +SINGLE_LINE_COMMENT +MULTILINE_COMMENT +SPACES +UNEXPECTED_CHAR +HEX_DIGIT +DIGIT +A +B +C +D +E +F +G +H +I +J +K +L +M +N +O +P +Q +R +S +T +U +V +W +X +Y +Z +ERROR_RECONGNIGION + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN +null +null +ERRORCHANNEL + +mode names: +DEFAULT_MODE + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 80, 739, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, 9, 106, 4, 107, 9, 107, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 5, 29, 294, 10, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 5, 48, 414, 10, 48, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 5, 50, 426, 10, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 54, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 3, 70, 3, 70, 7, 70, 555, 10, 70, 12, 70, 14, 70, 558, 11, 70, 3, 71, 3, 71, 7, 71, 562, 10, 71, 12, 71, 14, 71, 565, 11, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 6, 71, 572, 10, 71, 13, 71, 14, 71, 573, 3, 71, 3, 71, 3, 71, 3, 71, 6, 71, 580, 10, 71, 13, 71, 14, 71, 581, 5, 71, 584, 10, 71, 3, 72, 3, 72, 7, 72, 588, 10, 72, 12, 72, 14, 72, 591, 11, 72, 3, 72, 5, 72, 594, 10, 72, 3, 72, 3, 72, 6, 72, 598, 10, 72, 13, 72, 14, 72, 599, 3, 72, 3, 72, 5, 72, 604, 10, 72, 3, 72, 6, 72, 607, 10, 72, 13, 72, 14, 72, 608, 5, 72, 611, 10, 72, 3, 73, 3, 73, 3, 73, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 7, 74, 622, 10, 74, 12, 74, 14, 74, 625, 11, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 7, 74, 634, 10, 74, 12, 74, 14, 74, 637, 11, 74, 3, 74, 5, 74, 640, 10, 74, 3, 75, 3, 75, 3, 75, 3, 75, 7, 75, 646, 10, 75, 12, 75, 14, 75, 649, 11, 75, 3, 75, 5, 75, 652, 10, 75, 3, 75, 3, 75, 5, 75, 656, 10, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 7, 76, 664, 10, 76, 12, 76, 14, 76, 667, 11, 76, 3, 76, 3, 76, 3, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 3, 79, 3, 79, 3, 80, 3, 80, 3, 81, 3, 81, 3, 82, 3, 82, 3, 83, 3, 83, 3, 84, 3, 84, 3, 85, 3, 85, 3, 86, 3, 86, 3, 87, 3, 87, 3, 88, 3, 88, 3, 89, 3, 89, 3, 90, 3, 90, 3, 91, 3, 91, 3, 92, 3, 92, 3, 93, 3, 93, 3, 94, 3, 94, 3, 95, 3, 95, 3, 96, 3, 96, 3, 97, 3, 97, 3, 98, 3, 98, 3, 99, 3, 99, 3, 100, 3, 100, 3, 101, 3, 101, 3, 102, 3, 102, 3, 103, 3, 103, 3, 104, 3, 104, 3, 105, 3, 105, 3, 106, 3, 106, 3, 107, 3, 107, 3, 107, 3, 107, 3, 665, 2, 108, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 41, 22, 43, 23, 45, 24, 47, 25, 49, 26, 51, 27, 53, 28, 55, 29, 57, 30, 59, 31, 61, 32, 63, 33, 65, 34, 67, 35, 69, 36, 71, 37, 73, 38, 75, 39, 77, 40, 79, 41, 81, 42, 83, 43, 85, 44, 87, 45, 89, 46, 91, 47, 93, 48, 95, 49, 97, 50, 99, 51, 101, 52, 103, 53, 105, 54, 107, 55, 109, 56, 111, 57, 113, 58, 115, 59, 117, 60, 119, 61, 121, 62, 123, 63, 125, 64, 127, 65, 129, 66, 131, 67, 133, 68, 135, 69, 137, 70, 139, 71, 141, 72, 143, 73, 145, 74, 147, 75, 149, 76, 151, 77, 153, 78, 155, 79, 157, 2, 159, 2, 161, 2, 163, 2, 165, 2, 167, 2, 169, 2, 171, 2, 173, 2, 175, 2, 177, 2, 179, 2, 181, 2, 183, 2, 185, 2, 187, 2, 189, 2, 191, 2, 193, 2, 195, 2, 197, 2, 199, 2, 201, 2, 203, 2, 205, 2, 207, 2, 209, 2, 211, 2, 213, 80, 3, 2, 39, 5, 2, 67, 92, 97, 97, 99, 124, 6, 2, 50, 59, 67, 92, 97, 97, 99, 124, 3, 2, 51, 59, 3, 2, 50, 51, 4, 2, 45, 45, 47, 47, 4, 2, 41, 41, 94, 94, 4, 2, 36, 36, 94, 94, 4, 2, 12, 12, 15, 15, 5, 2, 11, 13, 15, 15, 34, 34, 5, 2, 50, 59, 67, 72, 99, 104, 3, 2, 50, 59, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 71, 71, 103, 103, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 77, 77, 109, 109, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 91, 91, 123, 123, 4, 2, 92, 92, 124, 124, 2, 738, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 49, 3, 2, 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2, 97, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2, 2, 2, 105, 3, 2, 2, 2, 2, 107, 3, 2, 2, 2, 2, 109, 3, 2, 2, 2, 2, 111, 3, 2, 2, 2, 2, 113, 3, 2, 2, 2, 2, 115, 3, 2, 2, 2, 2, 117, 3, 2, 2, 2, 2, 119, 3, 2, 2, 2, 2, 121, 3, 2, 2, 2, 2, 123, 3, 2, 2, 2, 2, 125, 3, 2, 2, 2, 2, 127, 3, 2, 2, 2, 2, 129, 3, 2, 2, 2, 2, 131, 3, 2, 2, 2, 2, 133, 3, 2, 2, 2, 2, 135, 3, 2, 2, 2, 2, 137, 3, 2, 2, 2, 2, 139, 3, 2, 2, 2, 2, 141, 3, 2, 2, 2, 2, 143, 3, 2, 2, 2, 2, 145, 3, 2, 2, 2, 2, 147, 3, 2, 2, 2, 2, 149, 3, 2, 2, 2, 2, 151, 3, 2, 2, 2, 2, 153, 3, 2, 2, 2, 2, 155, 3, 2, 2, 2, 2, 213, 3, 2, 2, 2, 3, 215, 3, 2, 2, 2, 5, 217, 3, 2, 2, 2, 7, 220, 3, 2, 2, 2, 9, 223, 3, 2, 2, 2, 11, 226, 3, 2, 2, 2, 13, 229, 3, 2, 2, 2, 15, 231, 3, 2, 2, 2, 17, 233, 3, 2, 2, 2, 19, 236, 3, 2, 2, 2, 21, 239, 3, 2, 2, 2, 23, 241, 3, 2, 2, 2, 25, 243, 3, 2, 2, 2, 27, 245, 3, 2, 2, 2, 29, 247, 3, 2, 2, 2, 31, 249, 3, 2, 2, 2, 33, 251, 3, 2, 2, 2, 35, 253, 3, 2, 2, 2, 37, 256, 3, 2, 2, 2, 39, 259, 3, 2, 2, 2, 41, 261, 3, 2, 2, 2, 43, 263, 3, 2, 2, 2, 45, 265, 3, 2, 2, 2, 47, 267, 3, 2, 2, 2, 49, 269, 3, 2, 2, 2, 51, 271, 3, 2, 2, 2, 53, 273, 3, 2, 2, 2, 55, 283, 3, 2, 2, 2, 57, 293, 3, 2, 2, 2, 59, 295, 3, 2, 2, 2, 61, 299, 3, 2, 2, 2, 63, 303, 3, 2, 2, 2, 65, 311, 3, 2, 2, 2, 67, 316, 3, 2, 2, 2, 69, 325, 3, 2, 2, 2, 71, 331, 3, 2, 2, 2, 73, 338, 3, 2, 2, 2, 75, 342, 3, 2, 2, 2, 77, 348, 3, 2, 2, 2, 79, 351, 3, 2, 2, 2, 81, 359, 3, 2, 2, 2, 83, 366, 3, 2, 2, 2, 85, 371, 3, 2, 2, 2, 87, 388, 3, 2, 2, 2, 89, 392, 3, 2, 2, 2, 91, 397, 3, 2, 2, 2, 93, 403, 3, 2, 2, 2, 95, 413, 3, 2, 2, 2, 97, 415, 3, 2, 2, 2, 99, 425, 3, 2, 2, 2, 101, 427, 3, 2, 2, 2, 103, 436, 3, 2, 2, 2, 105, 443, 3, 2, 2, 2, 107, 451, 3, 2, 2, 2, 109, 458, 3, 2, 2, 2, 111, 472, 3, 2, 2, 2, 113, 477, 3, 2, 2, 2, 115, 482, 3, 2, 2, 2, 117, 489, 3, 2, 2, 2, 119, 496, 3, 2, 2, 2, 121, 501, 3, 2, 2, 2, 123, 506, 3, 2, 2, 2, 125, 512, 3, 2, 2, 2, 127, 520, 3, 2, 2, 2, 129, 526, 3, 2, 2, 2, 131, 533, 3, 2, 2, 2, 133, 536, 3, 2, 2, 2, 135, 544, 3, 2, 2, 2, 137, 548, 3, 2, 2, 2, 139, 552, 3, 2, 2, 2, 141, 583, 3, 2, 2, 2, 143, 593, 3, 2, 2, 2, 145, 612, 3, 2, 2, 2, 147, 639, 3, 2, 2, 2, 149, 641, 3, 2, 2, 2, 151, 659, 3, 2, 2, 2, 153, 673, 3, 2, 2, 2, 155, 677, 3, 2, 2, 2, 157, 679, 3, 2, 2, 2, 159, 681, 3, 2, 2, 2, 161, 683, 3, 2, 2, 2, 163, 685, 3, 2, 2, 2, 165, 687, 3, 2, 2, 2, 167, 689, 3, 2, 2, 2, 169, 691, 3, 2, 2, 2, 171, 693, 3, 2, 2, 2, 173, 695, 3, 2, 2, 2, 175, 697, 3, 2, 2, 2, 177, 699, 3, 2, 2, 2, 179, 701, 3, 2, 2, 2, 181, 703, 3, 2, 2, 2, 183, 705, 3, 2, 2, 2, 185, 707, 3, 2, 2, 2, 187, 709, 3, 2, 2, 2, 189, 711, 3, 2, 2, 2, 191, 713, 3, 2, 2, 2, 193, 715, 3, 2, 2, 2, 195, 717, 3, 2, 2, 2, 197, 719, 3, 2, 2, 2, 199, 721, 3, 2, 2, 2, 201, 723, 3, 2, 2, 2, 203, 725, 3, 2, 2, 2, 205, 727, 3, 2, 2, 2, 207, 729, 3, 2, 2, 2, 209, 731, 3, 2, 2, 2, 211, 733, 3, 2, 2, 2, 213, 735, 3, 2, 2, 2, 215, 216, 7, 48, 2, 2, 216, 4, 3, 2, 2, 2, 217, 218, 7, 63, 2, 2, 218, 219, 7, 128, 2, 2, 219, 6, 3, 2, 2, 2, 220, 221, 7, 35, 2, 2, 221, 222, 7, 128, 2, 2, 222, 8, 3, 2, 2, 2, 223, 224, 7, 63, 2, 2, 224, 225, 7, 63, 2, 2, 225, 10, 3, 2, 2, 2, 226, 227, 7, 35, 2, 2, 227, 228, 7, 63, 2, 2, 228, 12, 3, 2, 2, 2, 229, 230, 7, 62, 2, 2, 230, 14, 3, 2, 2, 2, 231, 232, 7, 64, 2, 2, 232, 16, 3, 2, 2, 2, 233, 234, 7, 62, 2, 2, 234, 235, 7, 63, 2, 2, 235, 18, 3, 2, 2, 2, 236, 237, 7, 64, 2, 2, 237, 238, 7, 63, 2, 2, 238, 20, 3, 2, 2, 2, 239, 240, 7, 45, 2, 2, 240, 22, 3, 2, 2, 2, 241, 242, 7, 47, 2, 2, 242, 24, 3, 2, 2, 2, 243, 244, 7, 44, 2, 2, 244, 26, 3, 2, 2, 2, 245, 246, 7, 49, 2, 2, 246, 28, 3, 2, 2, 2, 247, 248, 7, 39, 2, 2, 248, 30, 3, 2, 2, 2, 249, 250, 7, 65, 2, 2, 250, 32, 3, 2, 2, 2, 251, 252, 7, 60, 2, 2, 252, 34, 3, 2, 2, 2, 253, 254, 7, 60, 2, 2, 254, 255, 7, 60, 2, 2, 255, 36, 3, 2, 2, 2, 256, 257, 7, 48, 2, 2, 257, 258, 7, 48, 2, 2, 258, 38, 3, 2, 2, 2, 259, 260, 7, 46, 2, 2, 260, 40, 3, 2, 2, 2, 261, 262, 7, 42, 2, 2, 262, 42, 3, 2, 2, 2, 263, 264, 7, 43, 2, 2, 264, 44, 3, 2, 2, 2, 265, 266, 7, 125, 2, 2, 266, 46, 3, 2, 2, 2, 267, 268, 7, 127, 2, 2, 268, 48, 3, 2, 2, 2, 269, 270, 7, 93, 2, 2, 270, 50, 3, 2, 2, 2, 271, 272, 7, 95, 2, 2, 272, 52, 3, 2, 2, 2, 273, 274, 5, 161, 81, 2, 274, 275, 5, 173, 87, 2, 275, 276, 5, 173, 87, 2, 276, 277, 5, 195, 98, 2, 277, 278, 5, 169, 85, 2, 278, 279, 5, 173, 87, 2, 279, 280, 5, 161, 81, 2, 280, 281, 5, 199, 100, 2, 281, 282, 5, 169, 85, 2, 282, 54, 3, 2, 2, 2, 283, 284, 5, 161, 81, 2, 284, 285, 5, 183, 92, 2, 285, 286, 5, 183, 92, 2, 286, 56, 3, 2, 2, 2, 287, 288, 5, 161, 81, 2, 288, 289, 5, 187, 94, 2, 289, 290, 5, 167, 84, 2, 290, 294, 3, 2, 2, 2, 291, 292, 7, 40, 2, 2, 292, 294, 7, 40, 2, 2, 293, 287, 3, 2, 2, 2, 293, 291, 3, 2, 2, 2, 294, 58, 3, 2, 2, 2, 295, 296, 5, 161, 81, 2, 296, 297, 5, 187, 94, 2, 297, 298, 5, 209, 105, 2, 298, 60, 3, 2, 2, 2, 299, 300, 5, 161, 81, 2, 300, 301, 5, 197, 99, 2, 301, 302, 5, 165, 83, 2, 302, 62, 3, 2, 2, 2, 303, 304, 5, 165, 83, 2, 304, 305, 5, 189, 95, 2, 305, 306, 5, 183, 92, 2, 306, 307, 5, 183, 92, 2, 307, 308, 5, 169, 85, 2, 308, 309, 5, 165, 83, 2, 309, 310, 5, 199, 100, 2, 310, 64, 3, 2, 2, 2, 311, 312, 5, 167, 84, 2, 312, 313, 5, 169, 85, 2, 313, 314, 5, 197, 99, 2, 314, 315, 5, 165, 83, 2, 315, 66, 3, 2, 2, 2, 316, 317, 5, 167, 84, 2, 317, 318, 5, 177, 89, 2, 318, 319, 5, 197, 99, 2, 319, 320, 5, 199, 100, 2, 320, 321, 5, 177, 89, 2, 321, 322, 5, 187, 94, 2, 322, 323, 5, 165, 83, 2, 323, 324, 5, 199, 100, 2, 324, 68, 3, 2, 2, 2, 325, 326, 5, 171, 86, 2, 326, 327, 5, 161, 81, 2, 327, 328, 5, 183, 92, 2, 328, 329, 5, 197, 99, 2, 329, 330, 5, 169, 85, 2, 330, 70, 3, 2, 2, 2, 331, 332, 5, 171, 86, 2, 332, 333, 5, 177, 89, 2, 333, 334, 5, 183, 92, 2, 334, 335, 5, 199, 100, 2, 335, 336, 5, 169, 85, 2, 336, 337, 5, 195, 98, 2, 337, 72, 3, 2, 2, 2, 338, 339, 5, 171, 86, 2, 339, 340, 5, 189, 95, 2, 340, 341, 5, 195, 98, 2, 341, 74, 3, 2, 2, 2, 342, 343, 5, 173, 87, 2, 343, 344, 5, 195, 98, 2, 344, 345, 5, 161, 81, 2, 345, 346, 5, 191, 96, 2, 346, 347, 5, 175, 88, 2, 347, 76, 3, 2, 2, 2, 348, 349, 5, 177, 89, 2, 349, 350, 5, 187, 94, 2, 350, 78, 3, 2, 2, 2, 351, 352, 5, 177, 89, 2, 352, 353, 5, 187, 94, 2, 353, 354, 5, 163, 82, 2, 354, 355, 5, 189, 95, 2, 355, 356, 5, 201, 101, 2, 356, 357, 5, 187, 94, 2, 357, 358, 5, 167, 84, 2, 358, 80, 3, 2, 2, 2, 359, 360, 5, 177, 89, 2, 360, 361, 5, 187, 94, 2, 361, 362, 5, 197, 99, 2, 362, 363, 5, 169, 85, 2, 363, 364, 5, 195, 98, 2, 364, 365, 5, 199, 100, 2, 365, 82, 3, 2, 2, 2, 366, 367, 5, 177, 89, 2, 367, 368, 5, 187, 94, 2, 368, 369, 5, 199, 100, 2, 369, 370, 5, 189, 95, 2, 370, 84, 3, 2, 2, 2, 371, 372, 5, 181, 91, 2, 372, 373, 7, 97, 2, 2, 373, 374, 5, 197, 99, 2, 374, 375, 5, 175, 88, 2, 375, 376, 5, 189, 95, 2, 376, 377, 5, 195, 98, 2, 377, 378, 5, 199, 100, 2, 378, 379, 5, 169, 85, 2, 379, 380, 5, 197, 99, 2, 380, 381, 5, 199, 100, 2, 381, 382, 7, 97, 2, 2, 382, 383, 5, 191, 96, 2, 383, 384, 5, 161, 81, 2, 384, 385, 5, 199, 100, 2, 385, 386, 5, 175, 88, 2, 386, 387, 5, 197, 99, 2, 387, 86, 3, 2, 2, 2, 388, 389, 5, 183, 92, 2, 389, 390, 5, 169, 85, 2, 390, 391, 5, 199, 100, 2, 391, 88, 3, 2, 2, 2, 392, 393, 5, 183, 92, 2, 393, 394, 5, 177, 89, 2, 394, 395, 5, 181, 91, 2, 395, 396, 5, 169, 85, 2, 396, 90, 3, 2, 2, 2, 397, 398, 5, 183, 92, 2, 398, 399, 5, 177, 89, 2, 399, 400, 5, 185, 93, 2, 400, 401, 5, 177, 89, 2, 401, 402, 5, 199, 100, 2, 402, 92, 3, 2, 2, 2, 403, 404, 5, 187, 94, 2, 404, 405, 5, 189, 95, 2, 405, 406, 5, 187, 94, 2, 406, 407, 5, 169, 85, 2, 407, 94, 3, 2, 2, 2, 408, 409, 5, 187, 94, 2, 409, 410, 5, 189, 95, 2, 410, 411, 5, 199, 100, 2, 411, 414, 3, 2, 2, 2, 412, 414, 7, 35, 2, 2, 413, 408, 3, 2, 2, 2, 413, 412, 3, 2, 2, 2, 414, 96, 3, 2, 2, 2, 415, 416, 5, 187, 94, 2, 416, 417, 5, 201, 101, 2, 417, 418, 5, 183, 92, 2, 418, 419, 5, 183, 92, 2, 419, 98, 3, 2, 2, 2, 420, 421, 5, 189, 95, 2, 421, 422, 5, 195, 98, 2, 422, 426, 3, 2, 2, 2, 423, 424, 7, 126, 2, 2, 424, 426, 7, 126, 2, 2, 425, 420, 3, 2, 2, 2, 425, 423, 3, 2, 2, 2, 426, 100, 3, 2, 2, 2, 427, 428, 5, 189, 95, 2, 428, 429, 5, 201, 101, 2, 429, 430, 5, 199, 100, 2, 430, 431, 5, 163, 82, 2, 431, 432, 5, 189, 95, 2, 432, 433, 5, 201, 101, 2, 433, 434, 5, 187, 94, 2, 434, 435, 5, 167, 84, 2, 435, 102, 3, 2, 2, 2, 436, 437, 5, 195, 98, 2, 437, 438, 5, 169, 85, 2, 438, 439, 5, 185, 93, 2, 439, 440, 5, 189, 95, 2, 440, 441, 5, 203, 102, 2, 441, 442, 5, 169, 85, 2, 442, 104, 3, 2, 2, 2, 443, 444, 5, 195, 98, 2, 444, 445, 5, 169, 85, 2, 445, 446, 5, 191, 96, 2, 446, 447, 5, 183, 92, 2, 447, 448, 5, 161, 81, 2, 448, 449, 5, 165, 83, 2, 449, 450, 5, 169, 85, 2, 450, 106, 3, 2, 2, 2, 451, 452, 5, 195, 98, 2, 452, 453, 5, 169, 85, 2, 453, 454, 5, 199, 100, 2, 454, 455, 5, 201, 101, 2, 455, 456, 5, 195, 98, 2, 456, 457, 5, 187, 94, 2, 457, 108, 3, 2, 2, 2, 458, 459, 5, 197, 99, 2, 459, 460, 5, 175, 88, 2, 460, 461, 5, 189, 95, 2, 461, 462, 5, 195, 98, 2, 462, 463, 5, 199, 100, 2, 463, 464, 5, 169, 85, 2, 464, 465, 5, 197, 99, 2, 465, 466, 5, 199, 100, 2, 466, 467, 7, 97, 2, 2, 467, 468, 5, 191, 96, 2, 468, 469, 5, 161, 81, 2, 469, 470, 5, 199, 100, 2, 470, 471, 5, 175, 88, 2, 471, 110, 3, 2, 2, 2, 472, 473, 5, 197, 99, 2, 473, 474, 5, 189, 95, 2, 474, 475, 5, 195, 98, 2, 475, 476, 5, 199, 100, 2, 476, 112, 3, 2, 2, 2, 477, 478, 5, 199, 100, 2, 478, 479, 5, 195, 98, 2, 479, 480, 5, 201, 101, 2, 480, 481, 5, 169, 85, 2, 481, 114, 3, 2, 2, 2, 482, 483, 5, 201, 101, 2, 483, 484, 5, 191, 96, 2, 484, 485, 5, 167, 84, 2, 485, 486, 5, 161, 81, 2, 486, 487, 5, 199, 100, 2, 487, 488, 5, 169, 85, 2, 488, 116, 3, 2, 2, 2, 489, 490, 5, 201, 101, 2, 490, 491, 5, 191, 96, 2, 491, 492, 5, 197, 99, 2, 492, 493, 5, 169, 85, 2, 493, 494, 5, 195, 98, 2, 494, 495, 5, 199, 100, 2, 495, 118, 3, 2, 2, 2, 496, 497, 5, 205, 103, 2, 497, 498, 5, 177, 89, 2, 498, 499, 5, 199, 100, 2, 499, 500, 5, 175, 88, 2, 500, 120, 3, 2, 2, 2, 501, 502, 5, 181, 91, 2, 502, 503, 5, 169, 85, 2, 503, 504, 5, 169, 85, 2, 504, 505, 5, 191, 96, 2, 505, 122, 3, 2, 2, 2, 506, 507, 5, 165, 83, 2, 507, 508, 5, 189, 95, 2, 508, 509, 5, 201, 101, 2, 509, 510, 5, 187, 94, 2, 510, 511, 5, 199, 100, 2, 511, 124, 3, 2, 2, 2, 512, 513, 5, 189, 95, 2, 513, 514, 5, 191, 96, 2, 514, 515, 5, 199, 100, 2, 515, 516, 5, 177, 89, 2, 516, 517, 5, 189, 95, 2, 517, 518, 5, 187, 94, 2, 518, 519, 5, 197, 99, 2, 519, 126, 3, 2, 2, 2, 520, 521, 5, 191, 96, 2, 521, 522, 5, 195, 98, 2, 522, 523, 5, 201, 101, 2, 523, 524, 5, 187, 94, 2, 524, 525, 5, 169, 85, 2, 525, 128, 3, 2, 2, 2, 526, 527, 5, 197, 99, 2, 527, 528, 5, 169, 85, 2, 528, 529, 5, 161, 81, 2, 529, 530, 5, 195, 98, 2, 530, 531, 5, 165, 83, 2, 531, 532, 5, 175, 88, 2, 532, 130, 3, 2, 2, 2, 533, 534, 5, 199, 100, 2, 534, 535, 5, 189, 95, 2, 535, 132, 3, 2, 2, 2, 536, 537, 5, 165, 83, 2, 537, 538, 5, 201, 101, 2, 538, 539, 5, 195, 98, 2, 539, 540, 5, 195, 98, 2, 540, 541, 5, 169, 85, 2, 541, 542, 5, 187, 94, 2, 542, 543, 5, 199, 100, 2, 543, 134, 3, 2, 2, 2, 544, 545, 5, 187, 94, 2, 545, 546, 5, 169, 85, 2, 546, 547, 5, 205, 103, 2, 547, 136, 3, 2, 2, 2, 548, 549, 5, 189, 95, 2, 549, 550, 5, 183, 92, 2, 550, 551, 5, 167, 84, 2, 551, 138, 3, 2, 2, 2, 552, 556, 9, 2, 2, 2, 553, 555, 9, 3, 2, 2, 554, 553, 3, 2, 2, 2, 555, 558, 3, 2, 2, 2, 556, 554, 3, 2, 2, 2, 556, 557, 3, 2, 2, 2, 557, 140, 3, 2, 2, 2, 558, 556, 3, 2, 2, 2, 559, 563, 9, 4, 2, 2, 560, 562, 5, 159, 80, 2, 561, 560, 3, 2, 2, 2, 562, 565, 3, 2, 2, 2, 563, 561, 3, 2, 2, 2, 563, 564, 3, 2, 2, 2, 564, 584, 3, 2, 2, 2, 565, 563, 3, 2, 2, 2, 566, 584, 7, 50, 2, 2, 567, 568, 7, 50, 2, 2, 568, 569, 7, 122, 2, 2, 569, 571, 3, 2, 2, 2, 570, 572, 5, 157, 79, 2, 571, 570, 3, 2, 2, 2, 572, 573, 3, 2, 2, 2, 573, 571, 3, 2, 2, 2, 573, 574, 3, 2, 2, 2, 574, 584, 3, 2, 2, 2, 575, 576, 7, 50, 2, 2, 576, 577, 7, 100, 2, 2, 577, 579, 3, 2, 2, 2, 578, 580, 9, 5, 2, 2, 579, 578, 3, 2, 2, 2, 580, 581, 3, 2, 2, 2, 581, 579, 3, 2, 2, 2, 581, 582, 3, 2, 2, 2, 582, 584, 3, 2, 2, 2, 583, 559, 3, 2, 2, 2, 583, 566, 3, 2, 2, 2, 583, 567, 3, 2, 2, 2, 583, 575, 3, 2, 2, 2, 584, 142, 3, 2, 2, 2, 585, 589, 9, 4, 2, 2, 586, 588, 5, 159, 80, 2, 587, 586, 3, 2, 2, 2, 588, 591, 3, 2, 2, 2, 589, 587, 3, 2, 2, 2, 589, 590, 3, 2, 2, 2, 590, 594, 3, 2, 2, 2, 591, 589, 3, 2, 2, 2, 592, 594, 7, 50, 2, 2, 593, 585, 3, 2, 2, 2, 593, 592, 3, 2, 2, 2, 593, 594, 3, 2, 2, 2, 594, 595, 3, 2, 2, 2, 595, 597, 7, 48, 2, 2, 596, 598, 5, 159, 80, 2, 597, 596, 3, 2, 2, 2, 598, 599, 3, 2, 2, 2, 599, 597, 3, 2, 2, 2, 599, 600, 3, 2, 2, 2, 600, 610, 3, 2, 2, 2, 601, 603, 5, 169, 85, 2, 602, 604, 9, 6, 2, 2, 603, 602, 3, 2, 2, 2, 603, 604, 3, 2, 2, 2, 604, 606, 3, 2, 2, 2, 605, 607, 5, 159, 80, 2, 606, 605, 3, 2, 2, 2, 607, 608, 3, 2, 2, 2, 608, 606, 3, 2, 2, 2, 608, 609, 3, 2, 2, 2, 609, 611, 3, 2, 2, 2, 610, 601, 3, 2, 2, 2, 610, 611, 3, 2, 2, 2, 611, 144, 3, 2, 2, 2, 612, 613, 7, 66, 2, 2, 613, 614, 5, 139, 70, 2, 614, 146, 3, 2, 2, 2, 615, 623, 7, 41, 2, 2, 616, 617, 7, 94, 2, 2, 617, 622, 11, 2, 2, 2, 618, 619, 7, 41, 2, 2, 619, 622, 7, 41, 2, 2, 620, 622, 10, 7, 2, 2, 621, 616, 3, 2, 2, 2, 621, 618, 3, 2, 2, 2, 621, 620, 3, 2, 2, 2, 622, 625, 3, 2, 2, 2, 623, 621, 3, 2, 2, 2, 623, 624, 3, 2, 2, 2, 624, 626, 3, 2, 2, 2, 625, 623, 3, 2, 2, 2, 626, 640, 7, 41, 2, 2, 627, 635, 7, 36, 2, 2, 628, 629, 7, 94, 2, 2, 629, 634, 11, 2, 2, 2, 630, 631, 7, 36, 2, 2, 631, 634, 7, 36, 2, 2, 632, 634, 10, 8, 2, 2, 633, 628, 3, 2, 2, 2, 633, 630, 3, 2, 2, 2, 633, 632, 3, 2, 2, 2, 634, 637, 3, 2, 2, 2, 635, 633, 3, 2, 2, 2, 635, 636, 3, 2, 2, 2, 636, 638, 3, 2, 2, 2, 637, 635, 3, 2, 2, 2, 638, 640, 7, 36, 2, 2, 639, 615, 3, 2, 2, 2, 639, 627, 3, 2, 2, 2, 640, 148, 3, 2, 2, 2, 641, 642, 7, 49, 2, 2, 642, 643, 7, 49, 2, 2, 643, 647, 3, 2, 2, 2, 644, 646, 10, 9, 2, 2, 645, 644, 3, 2, 2, 2, 646, 649, 3, 2, 2, 2, 647, 645, 3, 2, 2, 2, 647, 648, 3, 2, 2, 2, 648, 655, 3, 2, 2, 2, 649, 647, 3, 2, 2, 2, 650, 652, 7, 15, 2, 2, 651, 650, 3, 2, 2, 2, 651, 652, 3, 2, 2, 2, 652, 653, 3, 2, 2, 2, 653, 656, 7, 12, 2, 2, 654, 656, 7, 2, 2, 3, 655, 651, 3, 2, 2, 2, 655, 654, 3, 2, 2, 2, 656, 657, 3, 2, 2, 2, 657, 658, 8, 75, 2, 2, 658, 150, 3, 2, 2, 2, 659, 660, 7, 49, 2, 2, 660, 661, 7, 44, 2, 2, 661, 665, 3, 2, 2, 2, 662, 664, 11, 2, 2, 2, 663, 662, 3, 2, 2, 2, 664, 667, 3, 2, 2, 2, 665, 666, 3, 2, 2, 2, 665, 663, 3, 2, 2, 2, 666, 668, 3, 2, 2, 2, 667, 665, 3, 2, 2, 2, 668, 669, 7, 44, 2, 2, 669, 670, 7, 49, 2, 2, 670, 671, 3, 2, 2, 2, 671, 672, 8, 76, 2, 2, 672, 152, 3, 2, 2, 2, 673, 674, 9, 10, 2, 2, 674, 675, 3, 2, 2, 2, 675, 676, 8, 77, 2, 2, 676, 154, 3, 2, 2, 2, 677, 678, 11, 2, 2, 2, 678, 156, 3, 2, 2, 2, 679, 680, 9, 11, 2, 2, 680, 158, 3, 2, 2, 2, 681, 682, 9, 12, 2, 2, 682, 160, 3, 2, 2, 2, 683, 684, 9, 13, 2, 2, 684, 162, 3, 2, 2, 2, 685, 686, 9, 14, 2, 2, 686, 164, 3, 2, 2, 2, 687, 688, 9, 15, 2, 2, 688, 166, 3, 2, 2, 2, 689, 690, 9, 16, 2, 2, 690, 168, 3, 2, 2, 2, 691, 692, 9, 17, 2, 2, 692, 170, 3, 2, 2, 2, 693, 694, 9, 18, 2, 2, 694, 172, 3, 2, 2, 2, 695, 696, 9, 19, 2, 2, 696, 174, 3, 2, 2, 2, 697, 698, 9, 20, 2, 2, 698, 176, 3, 2, 2, 2, 699, 700, 9, 21, 2, 2, 700, 178, 3, 2, 2, 2, 701, 702, 9, 22, 2, 2, 702, 180, 3, 2, 2, 2, 703, 704, 9, 23, 2, 2, 704, 182, 3, 2, 2, 2, 705, 706, 9, 24, 2, 2, 706, 184, 3, 2, 2, 2, 707, 708, 9, 25, 2, 2, 708, 186, 3, 2, 2, 2, 709, 710, 9, 26, 2, 2, 710, 188, 3, 2, 2, 2, 711, 712, 9, 27, 2, 2, 712, 190, 3, 2, 2, 2, 713, 714, 9, 28, 2, 2, 714, 192, 3, 2, 2, 2, 715, 716, 9, 29, 2, 2, 716, 194, 3, 2, 2, 2, 717, 718, 9, 30, 2, 2, 718, 196, 3, 2, 2, 2, 719, 720, 9, 31, 2, 2, 720, 198, 3, 2, 2, 2, 721, 722, 9, 32, 2, 2, 722, 200, 3, 2, 2, 2, 723, 724, 9, 33, 2, 2, 724, 202, 3, 2, 2, 2, 725, 726, 9, 34, 2, 2, 726, 204, 3, 2, 2, 2, 727, 728, 9, 35, 2, 2, 728, 206, 3, 2, 2, 2, 729, 730, 9, 36, 2, 2, 730, 208, 3, 2, 2, 2, 731, 732, 9, 37, 2, 2, 732, 210, 3, 2, 2, 2, 733, 734, 9, 38, 2, 2, 734, 212, 3, 2, 2, 2, 735, 736, 11, 2, 2, 2, 736, 737, 3, 2, 2, 2, 737, 738, 8, 107, 3, 2, 738, 214, 3, 2, 2, 2, 26, 2, 293, 413, 425, 556, 563, 573, 581, 583, 589, 593, 599, 603, 608, 610, 621, 623, 633, 635, 639, 647, 651, 655, 665, 4, 2, 3, 2, 2, 4, 2] \ No newline at end of file diff --git a/ui/src/suggestions/grammar/CAQLLexer.js b/ui/src/suggestions/grammar/CAQLLexer.js new file mode 100644 index 0000000..3a65707 --- /dev/null +++ b/ui/src/suggestions/grammar/CAQLLexer.js @@ -0,0 +1,607 @@ +// Generated from CAQLLexer.g4 by ANTLR 4.9.2 +// jshint ignore: start +import antlr4 from 'antlr4'; + + + +const serializedATN = ["\u0003\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786", + "\u5964\u0002P\u02e3\b\u0001\u0004\u0002\t\u0002\u0004\u0003\t\u0003", + "\u0004\u0004\t\u0004\u0004\u0005\t\u0005\u0004\u0006\t\u0006\u0004\u0007", + "\t\u0007\u0004\b\t\b\u0004\t\t\t\u0004\n\t\n\u0004\u000b\t\u000b\u0004", + "\f\t\f\u0004\r\t\r\u0004\u000e\t\u000e\u0004\u000f\t\u000f\u0004\u0010", + "\t\u0010\u0004\u0011\t\u0011\u0004\u0012\t\u0012\u0004\u0013\t\u0013", + "\u0004\u0014\t\u0014\u0004\u0015\t\u0015\u0004\u0016\t\u0016\u0004\u0017", + "\t\u0017\u0004\u0018\t\u0018\u0004\u0019\t\u0019\u0004\u001a\t\u001a", + "\u0004\u001b\t\u001b\u0004\u001c\t\u001c\u0004\u001d\t\u001d\u0004\u001e", + "\t\u001e\u0004\u001f\t\u001f\u0004 \t \u0004!\t!\u0004\"\t\"\u0004#", + "\t#\u0004$\t$\u0004%\t%\u0004&\t&\u0004\'\t\'\u0004(\t(\u0004)\t)\u0004", + "*\t*\u0004+\t+\u0004,\t,\u0004-\t-\u0004.\t.\u0004/\t/\u00040\t0\u0004", + "1\t1\u00042\t2\u00043\t3\u00044\t4\u00045\t5\u00046\t6\u00047\t7\u0004", + "8\t8\u00049\t9\u0004:\t:\u0004;\t;\u0004<\t<\u0004=\t=\u0004>\t>\u0004", + "?\t?\u0004@\t@\u0004A\tA\u0004B\tB\u0004C\tC\u0004D\tD\u0004E\tE\u0004", + "F\tF\u0004G\tG\u0004H\tH\u0004I\tI\u0004J\tJ\u0004K\tK\u0004L\tL\u0004", + "M\tM\u0004N\tN\u0004O\tO\u0004P\tP\u0004Q\tQ\u0004R\tR\u0004S\tS\u0004", + "T\tT\u0004U\tU\u0004V\tV\u0004W\tW\u0004X\tX\u0004Y\tY\u0004Z\tZ\u0004", + "[\t[\u0004\\\t\\\u0004]\t]\u0004^\t^\u0004_\t_\u0004`\t`\u0004a\ta\u0004", + "b\tb\u0004c\tc\u0004d\td\u0004e\te\u0004f\tf\u0004g\tg\u0004h\th\u0004", + "i\ti\u0004j\tj\u0004k\tk\u0003\u0002\u0003\u0002\u0003\u0003\u0003\u0003", + "\u0003\u0003\u0003\u0004\u0003\u0004\u0003\u0004\u0003\u0005\u0003\u0005", + "\u0003\u0005\u0003\u0006\u0003\u0006\u0003\u0006\u0003\u0007\u0003\u0007", + "\u0003\b\u0003\b\u0003\t\u0003\t\u0003\t\u0003\n\u0003\n\u0003\n\u0003", + "\u000b\u0003\u000b\u0003\f\u0003\f\u0003\r\u0003\r\u0003\u000e\u0003", + "\u000e\u0003\u000f\u0003\u000f\u0003\u0010\u0003\u0010\u0003\u0011\u0003", + "\u0011\u0003\u0012\u0003\u0012\u0003\u0012\u0003\u0013\u0003\u0013\u0003", + "\u0013\u0003\u0014\u0003\u0014\u0003\u0015\u0003\u0015\u0003\u0016\u0003", + "\u0016\u0003\u0017\u0003\u0017\u0003\u0018\u0003\u0018\u0003\u0019\u0003", + "\u0019\u0003\u001a\u0003\u001a\u0003\u001b\u0003\u001b\u0003\u001b\u0003", + "\u001b\u0003\u001b\u0003\u001b\u0003\u001b\u0003\u001b\u0003\u001b\u0003", + "\u001b\u0003\u001c\u0003\u001c\u0003\u001c\u0003\u001c\u0003\u001d\u0003", + "\u001d\u0003\u001d\u0003\u001d\u0003\u001d\u0003\u001d\u0005\u001d\u0126", + "\n\u001d\u0003\u001e\u0003\u001e\u0003\u001e\u0003\u001e\u0003\u001f", + "\u0003\u001f\u0003\u001f\u0003\u001f\u0003 \u0003 \u0003 \u0003 \u0003", + " \u0003 \u0003 \u0003 \u0003!\u0003!\u0003!\u0003!\u0003!\u0003\"\u0003", + "\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003#\u0003", + "#\u0003#\u0003#\u0003#\u0003#\u0003$\u0003$\u0003$\u0003$\u0003$\u0003", + "$\u0003$\u0003%\u0003%\u0003%\u0003%\u0003&\u0003&\u0003&\u0003&\u0003", + "&\u0003&\u0003\'\u0003\'\u0003\'\u0003(\u0003(\u0003(\u0003(\u0003(", + "\u0003(\u0003(\u0003(\u0003)\u0003)\u0003)\u0003)\u0003)\u0003)\u0003", + ")\u0003*\u0003*\u0003*\u0003*\u0003*\u0003+\u0003+\u0003+\u0003+\u0003", + "+\u0003+\u0003+\u0003+\u0003+\u0003+\u0003+\u0003+\u0003+\u0003+\u0003", + "+\u0003+\u0003+\u0003,\u0003,\u0003,\u0003,\u0003-\u0003-\u0003-\u0003", + "-\u0003-\u0003.\u0003.\u0003.\u0003.\u0003.\u0003.\u0003/\u0003/\u0003", + "/\u0003/\u0003/\u00030\u00030\u00030\u00030\u00030\u00050\u019e\n0\u0003", + "1\u00031\u00031\u00031\u00031\u00032\u00032\u00032\u00032\u00032\u0005", + "2\u01aa\n2\u00033\u00033\u00033\u00033\u00033\u00033\u00033\u00033\u0003", + "3\u00034\u00034\u00034\u00034\u00034\u00034\u00034\u00035\u00035\u0003", + "5\u00035\u00035\u00035\u00035\u00035\u00036\u00036\u00036\u00036\u0003", + "6\u00036\u00036\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u0003", + "7\u00037\u00037\u00037\u00037\u00037\u00037\u00038\u00038\u00038\u0003", + "8\u00038\u00039\u00039\u00039\u00039\u00039\u0003:\u0003:\u0003:\u0003", + ":\u0003:\u0003:\u0003:\u0003;\u0003;\u0003;\u0003;\u0003;\u0003;\u0003", + ";\u0003<\u0003<\u0003<\u0003<\u0003<\u0003=\u0003=\u0003=\u0003=\u0003", + "=\u0003>\u0003>\u0003>\u0003>\u0003>\u0003>\u0003?\u0003?\u0003?\u0003", + "?\u0003?\u0003?\u0003?\u0003?\u0003@\u0003@\u0003@\u0003@\u0003@\u0003", + "@\u0003A\u0003A\u0003A\u0003A\u0003A\u0003A\u0003A\u0003B\u0003B\u0003", + "B\u0003C\u0003C\u0003C\u0003C\u0003C\u0003C\u0003C\u0003C\u0003D\u0003", + "D\u0003D\u0003D\u0003E\u0003E\u0003E\u0003E\u0003F\u0003F\u0007F\u022b", + "\nF\fF\u000eF\u022e\u000bF\u0003G\u0003G\u0007G\u0232\nG\fG\u000eG\u0235", + "\u000bG\u0003G\u0003G\u0003G\u0003G\u0003G\u0006G\u023c\nG\rG\u000e", + "G\u023d\u0003G\u0003G\u0003G\u0003G\u0006G\u0244\nG\rG\u000eG\u0245", + "\u0005G\u0248\nG\u0003H\u0003H\u0007H\u024c\nH\fH\u000eH\u024f\u000b", + "H\u0003H\u0005H\u0252\nH\u0003H\u0003H\u0006H\u0256\nH\rH\u000eH\u0257", + "\u0003H\u0003H\u0005H\u025c\nH\u0003H\u0006H\u025f\nH\rH\u000eH\u0260", + "\u0005H\u0263\nH\u0003I\u0003I\u0003I\u0003J\u0003J\u0003J\u0003J\u0003", + "J\u0003J\u0007J\u026e\nJ\fJ\u000eJ\u0271\u000bJ\u0003J\u0003J\u0003", + "J\u0003J\u0003J\u0003J\u0003J\u0007J\u027a\nJ\fJ\u000eJ\u027d\u000b", + "J\u0003J\u0005J\u0280\nJ\u0003K\u0003K\u0003K\u0003K\u0007K\u0286\n", + "K\fK\u000eK\u0289\u000bK\u0003K\u0005K\u028c\nK\u0003K\u0003K\u0005", + "K\u0290\nK\u0003K\u0003K\u0003L\u0003L\u0003L\u0003L\u0007L\u0298\n", + "L\fL\u000eL\u029b\u000bL\u0003L\u0003L\u0003L\u0003L\u0003L\u0003M\u0003", + "M\u0003M\u0003M\u0003N\u0003N\u0003O\u0003O\u0003P\u0003P\u0003Q\u0003", + "Q\u0003R\u0003R\u0003S\u0003S\u0003T\u0003T\u0003U\u0003U\u0003V\u0003", + "V\u0003W\u0003W\u0003X\u0003X\u0003Y\u0003Y\u0003Z\u0003Z\u0003[\u0003", + "[\u0003\\\u0003\\\u0003]\u0003]\u0003^\u0003^\u0003_\u0003_\u0003`\u0003", + "`\u0003a\u0003a\u0003b\u0003b\u0003c\u0003c\u0003d\u0003d\u0003e\u0003", + "e\u0003f\u0003f\u0003g\u0003g\u0003h\u0003h\u0003i\u0003i\u0003j\u0003", + "j\u0003k\u0003k\u0003k\u0003k\u0003\u0299\u0002l\u0003\u0003\u0005\u0004", + "\u0007\u0005\t\u0006\u000b\u0007\r\b\u000f\t\u0011\n\u0013\u000b\u0015", + "\f\u0017\r\u0019\u000e\u001b\u000f\u001d\u0010\u001f\u0011!\u0012#\u0013", + "%\u0014\'\u0015)\u0016+\u0017-\u0018/\u00191\u001a3\u001b5\u001c7\u001d", + "9\u001e;\u001f= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]0_1a2c3e4g5i6k7m8o", + "9q:s;u{?}@\u007fA\u0081B\u0083C\u0085D\u0087E\u0089F\u008bG\u008d", + "H\u008fI\u0091J\u0093K\u0095L\u0097M\u0099N\u009bO\u009d\u0002\u009f", + "\u0002\u00a1\u0002\u00a3\u0002\u00a5\u0002\u00a7\u0002\u00a9\u0002\u00ab", + "\u0002\u00ad\u0002\u00af\u0002\u00b1\u0002\u00b3\u0002\u00b5\u0002\u00b7", + "\u0002\u00b9\u0002\u00bb\u0002\u00bd\u0002\u00bf\u0002\u00c1\u0002\u00c3", + "\u0002\u00c5\u0002\u00c7\u0002\u00c9\u0002\u00cb\u0002\u00cd\u0002\u00cf", + "\u0002\u00d1\u0002\u00d3\u0002\u00d5P\u0003\u0002\'\u0005\u0002C\\a", + "ac|\u0006\u00022;C\\aac|\u0003\u00023;\u0003\u000223\u0004\u0002--/", + "/\u0004\u0002))^^\u0004\u0002$$^^\u0004\u0002\f\f\u000f\u000f\u0005", + "\u0002\u000b\r\u000f\u000f\"\"\u0005\u00022;CHch\u0003\u00022;\u0004", + "\u0002CCcc\u0004\u0002DDdd\u0004\u0002EEee\u0004\u0002FFff\u0004\u0002", + "GGgg\u0004\u0002HHhh\u0004\u0002IIii\u0004\u0002JJjj\u0004\u0002KKk", + "k\u0004\u0002LLll\u0004\u0002MMmm\u0004\u0002NNnn\u0004\u0002OOoo\u0004", + "\u0002PPpp\u0004\u0002QQqq\u0004\u0002RRrr\u0004\u0002SSss\u0004\u0002", + "TTtt\u0004\u0002UUuu\u0004\u0002VVvv\u0004\u0002WWww\u0004\u0002XXx", + "x\u0004\u0002YYyy\u0004\u0002ZZzz\u0004\u0002[[{{\u0004\u0002\\\\||", + "\u0002\u02e2\u0002\u0003\u0003\u0002\u0002\u0002\u0002\u0005\u0003\u0002", + "\u0002\u0002\u0002\u0007\u0003\u0002\u0002\u0002\u0002\t\u0003\u0002", + "\u0002\u0002\u0002\u000b\u0003\u0002\u0002\u0002\u0002\r\u0003\u0002", + "\u0002\u0002\u0002\u000f\u0003\u0002\u0002\u0002\u0002\u0011\u0003\u0002", + "\u0002\u0002\u0002\u0013\u0003\u0002\u0002\u0002\u0002\u0015\u0003\u0002", + "\u0002\u0002\u0002\u0017\u0003\u0002\u0002\u0002\u0002\u0019\u0003\u0002", + "\u0002\u0002\u0002\u001b\u0003\u0002\u0002\u0002\u0002\u001d\u0003\u0002", + "\u0002\u0002\u0002\u001f\u0003\u0002\u0002\u0002\u0002!\u0003\u0002", + "\u0002\u0002\u0002#\u0003\u0002\u0002\u0002\u0002%\u0003\u0002\u0002", + "\u0002\u0002\'\u0003\u0002\u0002\u0002\u0002)\u0003\u0002\u0002\u0002", + "\u0002+\u0003\u0002\u0002\u0002\u0002-\u0003\u0002\u0002\u0002\u0002", + "/\u0003\u0002\u0002\u0002\u00021\u0003\u0002\u0002\u0002\u00023\u0003", + "\u0002\u0002\u0002\u00025\u0003\u0002\u0002\u0002\u00027\u0003\u0002", + "\u0002\u0002\u00029\u0003\u0002\u0002\u0002\u0002;\u0003\u0002\u0002", + "\u0002\u0002=\u0003\u0002\u0002\u0002\u0002?\u0003\u0002\u0002\u0002", + "\u0002A\u0003\u0002\u0002\u0002\u0002C\u0003\u0002\u0002\u0002\u0002", + "E\u0003\u0002\u0002\u0002\u0002G\u0003\u0002\u0002\u0002\u0002I\u0003", + "\u0002\u0002\u0002\u0002K\u0003\u0002\u0002\u0002\u0002M\u0003\u0002", + "\u0002\u0002\u0002O\u0003\u0002\u0002\u0002\u0002Q\u0003\u0002\u0002", + "\u0002\u0002S\u0003\u0002\u0002\u0002\u0002U\u0003\u0002\u0002\u0002", + "\u0002W\u0003\u0002\u0002\u0002\u0002Y\u0003\u0002\u0002\u0002\u0002", + "[\u0003\u0002\u0002\u0002\u0002]\u0003\u0002\u0002\u0002\u0002_\u0003", + "\u0002\u0002\u0002\u0002a\u0003\u0002\u0002\u0002\u0002c\u0003\u0002", + "\u0002\u0002\u0002e\u0003\u0002\u0002\u0002\u0002g\u0003\u0002\u0002", + "\u0002\u0002i\u0003\u0002\u0002\u0002\u0002k\u0003\u0002\u0002\u0002", + "\u0002m\u0003\u0002\u0002\u0002\u0002o\u0003\u0002\u0002\u0002\u0002", + "q\u0003\u0002\u0002\u0002\u0002s\u0003\u0002\u0002\u0002\u0002u\u0003", + "\u0002\u0002\u0002\u0002w\u0003\u0002\u0002\u0002\u0002y\u0003\u0002", + "\u0002\u0002\u0002{\u0003\u0002\u0002\u0002\u0002}\u0003\u0002\u0002", + "\u0002\u0002\u007f\u0003\u0002\u0002\u0002\u0002\u0081\u0003\u0002\u0002", + "\u0002\u0002\u0083\u0003\u0002\u0002\u0002\u0002\u0085\u0003\u0002\u0002", + "\u0002\u0002\u0087\u0003\u0002\u0002\u0002\u0002\u0089\u0003\u0002\u0002", + "\u0002\u0002\u008b\u0003\u0002\u0002\u0002\u0002\u008d\u0003\u0002\u0002", + "\u0002\u0002\u008f\u0003\u0002\u0002\u0002\u0002\u0091\u0003\u0002\u0002", + "\u0002\u0002\u0093\u0003\u0002\u0002\u0002\u0002\u0095\u0003\u0002\u0002", + "\u0002\u0002\u0097\u0003\u0002\u0002\u0002\u0002\u0099\u0003\u0002\u0002", + "\u0002\u0002\u009b\u0003\u0002\u0002\u0002\u0002\u00d5\u0003\u0002\u0002", + "\u0002\u0003\u00d7\u0003\u0002\u0002\u0002\u0005\u00d9\u0003\u0002\u0002", + "\u0002\u0007\u00dc\u0003\u0002\u0002\u0002\t\u00df\u0003\u0002\u0002", + "\u0002\u000b\u00e2\u0003\u0002\u0002\u0002\r\u00e5\u0003\u0002\u0002", + "\u0002\u000f\u00e7\u0003\u0002\u0002\u0002\u0011\u00e9\u0003\u0002\u0002", + "\u0002\u0013\u00ec\u0003\u0002\u0002\u0002\u0015\u00ef\u0003\u0002\u0002", + "\u0002\u0017\u00f1\u0003\u0002\u0002\u0002\u0019\u00f3\u0003\u0002\u0002", + "\u0002\u001b\u00f5\u0003\u0002\u0002\u0002\u001d\u00f7\u0003\u0002\u0002", + "\u0002\u001f\u00f9\u0003\u0002\u0002\u0002!\u00fb\u0003\u0002\u0002", + "\u0002#\u00fd\u0003\u0002\u0002\u0002%\u0100\u0003\u0002\u0002\u0002", + "\'\u0103\u0003\u0002\u0002\u0002)\u0105\u0003\u0002\u0002\u0002+\u0107", + "\u0003\u0002\u0002\u0002-\u0109\u0003\u0002\u0002\u0002/\u010b\u0003", + "\u0002\u0002\u00021\u010d\u0003\u0002\u0002\u00023\u010f\u0003\u0002", + "\u0002\u00025\u0111\u0003\u0002\u0002\u00027\u011b\u0003\u0002\u0002", + "\u00029\u0125\u0003\u0002\u0002\u0002;\u0127\u0003\u0002\u0002\u0002", + "=\u012b\u0003\u0002\u0002\u0002?\u012f\u0003\u0002\u0002\u0002A\u0137", + "\u0003\u0002\u0002\u0002C\u013c\u0003\u0002\u0002\u0002E\u0145\u0003", + "\u0002\u0002\u0002G\u014b\u0003\u0002\u0002\u0002I\u0152\u0003\u0002", + "\u0002\u0002K\u0156\u0003\u0002\u0002\u0002M\u015c\u0003\u0002\u0002", + "\u0002O\u015f\u0003\u0002\u0002\u0002Q\u0167\u0003\u0002\u0002\u0002", + "S\u016e\u0003\u0002\u0002\u0002U\u0173\u0003\u0002\u0002\u0002W\u0184", + "\u0003\u0002\u0002\u0002Y\u0188\u0003\u0002\u0002\u0002[\u018d\u0003", + "\u0002\u0002\u0002]\u0193\u0003\u0002\u0002\u0002_\u019d\u0003\u0002", + "\u0002\u0002a\u019f\u0003\u0002\u0002\u0002c\u01a9\u0003\u0002\u0002", + "\u0002e\u01ab\u0003\u0002\u0002\u0002g\u01b4\u0003\u0002\u0002\u0002", + "i\u01bb\u0003\u0002\u0002\u0002k\u01c3\u0003\u0002\u0002\u0002m\u01ca", + "\u0003\u0002\u0002\u0002o\u01d8\u0003\u0002\u0002\u0002q\u01dd\u0003", + "\u0002\u0002\u0002s\u01e2\u0003\u0002\u0002\u0002u\u01e9\u0003\u0002", + "\u0002\u0002w\u01f0\u0003\u0002\u0002\u0002y\u01f5\u0003\u0002\u0002", + "\u0002{\u01fa\u0003\u0002\u0002\u0002}\u0200\u0003\u0002\u0002\u0002", + "\u007f\u0208\u0003\u0002\u0002\u0002\u0081\u020e\u0003\u0002\u0002\u0002", + "\u0083\u0215\u0003\u0002\u0002\u0002\u0085\u0218\u0003\u0002\u0002\u0002", + "\u0087\u0220\u0003\u0002\u0002\u0002\u0089\u0224\u0003\u0002\u0002\u0002", + "\u008b\u0228\u0003\u0002\u0002\u0002\u008d\u0247\u0003\u0002\u0002\u0002", + "\u008f\u0251\u0003\u0002\u0002\u0002\u0091\u0264\u0003\u0002\u0002\u0002", + "\u0093\u027f\u0003\u0002\u0002\u0002\u0095\u0281\u0003\u0002\u0002\u0002", + "\u0097\u0293\u0003\u0002\u0002\u0002\u0099\u02a1\u0003\u0002\u0002\u0002", + "\u009b\u02a5\u0003\u0002\u0002\u0002\u009d\u02a7\u0003\u0002\u0002\u0002", + "\u009f\u02a9\u0003\u0002\u0002\u0002\u00a1\u02ab\u0003\u0002\u0002\u0002", + "\u00a3\u02ad\u0003\u0002\u0002\u0002\u00a5\u02af\u0003\u0002\u0002\u0002", + "\u00a7\u02b1\u0003\u0002\u0002\u0002\u00a9\u02b3\u0003\u0002\u0002\u0002", + "\u00ab\u02b5\u0003\u0002\u0002\u0002\u00ad\u02b7\u0003\u0002\u0002\u0002", + "\u00af\u02b9\u0003\u0002\u0002\u0002\u00b1\u02bb\u0003\u0002\u0002\u0002", + "\u00b3\u02bd\u0003\u0002\u0002\u0002\u00b5\u02bf\u0003\u0002\u0002\u0002", + "\u00b7\u02c1\u0003\u0002\u0002\u0002\u00b9\u02c3\u0003\u0002\u0002\u0002", + "\u00bb\u02c5\u0003\u0002\u0002\u0002\u00bd\u02c7\u0003\u0002\u0002\u0002", + "\u00bf\u02c9\u0003\u0002\u0002\u0002\u00c1\u02cb\u0003\u0002\u0002\u0002", + "\u00c3\u02cd\u0003\u0002\u0002\u0002\u00c5\u02cf\u0003\u0002\u0002\u0002", + "\u00c7\u02d1\u0003\u0002\u0002\u0002\u00c9\u02d3\u0003\u0002\u0002\u0002", + "\u00cb\u02d5\u0003\u0002\u0002\u0002\u00cd\u02d7\u0003\u0002\u0002\u0002", + "\u00cf\u02d9\u0003\u0002\u0002\u0002\u00d1\u02db\u0003\u0002\u0002\u0002", + "\u00d3\u02dd\u0003\u0002\u0002\u0002\u00d5\u02df\u0003\u0002\u0002\u0002", + "\u00d7\u00d8\u00070\u0002\u0002\u00d8\u0004\u0003\u0002\u0002\u0002", + "\u00d9\u00da\u0007?\u0002\u0002\u00da\u00db\u0007\u0080\u0002\u0002", + "\u00db\u0006\u0003\u0002\u0002\u0002\u00dc\u00dd\u0007#\u0002\u0002", + "\u00dd\u00de\u0007\u0080\u0002\u0002\u00de\b\u0003\u0002\u0002\u0002", + "\u00df\u00e0\u0007?\u0002\u0002\u00e0\u00e1\u0007?\u0002\u0002\u00e1", + "\n\u0003\u0002\u0002\u0002\u00e2\u00e3\u0007#\u0002\u0002\u00e3\u00e4", + "\u0007?\u0002\u0002\u00e4\f\u0003\u0002\u0002\u0002\u00e5\u00e6\u0007", + ">\u0002\u0002\u00e6\u000e\u0003\u0002\u0002\u0002\u00e7\u00e8\u0007", + "@\u0002\u0002\u00e8\u0010\u0003\u0002\u0002\u0002\u00e9\u00ea\u0007", + ">\u0002\u0002\u00ea\u00eb\u0007?\u0002\u0002\u00eb\u0012\u0003\u0002", + "\u0002\u0002\u00ec\u00ed\u0007@\u0002\u0002\u00ed\u00ee\u0007?\u0002", + "\u0002\u00ee\u0014\u0003\u0002\u0002\u0002\u00ef\u00f0\u0007-\u0002", + "\u0002\u00f0\u0016\u0003\u0002\u0002\u0002\u00f1\u00f2\u0007/\u0002", + "\u0002\u00f2\u0018\u0003\u0002\u0002\u0002\u00f3\u00f4\u0007,\u0002", + "\u0002\u00f4\u001a\u0003\u0002\u0002\u0002\u00f5\u00f6\u00071\u0002", + "\u0002\u00f6\u001c\u0003\u0002\u0002\u0002\u00f7\u00f8\u0007\'\u0002", + "\u0002\u00f8\u001e\u0003\u0002\u0002\u0002\u00f9\u00fa\u0007A\u0002", + "\u0002\u00fa \u0003\u0002\u0002\u0002\u00fb\u00fc\u0007<\u0002\u0002", + "\u00fc\"\u0003\u0002\u0002\u0002\u00fd\u00fe\u0007<\u0002\u0002\u00fe", + "\u00ff\u0007<\u0002\u0002\u00ff$\u0003\u0002\u0002\u0002\u0100\u0101", + "\u00070\u0002\u0002\u0101\u0102\u00070\u0002\u0002\u0102&\u0003\u0002", + "\u0002\u0002\u0103\u0104\u0007.\u0002\u0002\u0104(\u0003\u0002\u0002", + "\u0002\u0105\u0106\u0007*\u0002\u0002\u0106*\u0003\u0002\u0002\u0002", + "\u0107\u0108\u0007+\u0002\u0002\u0108,\u0003\u0002\u0002\u0002\u0109", + "\u010a\u0007}\u0002\u0002\u010a.\u0003\u0002\u0002\u0002\u010b\u010c", + "\u0007\u007f\u0002\u0002\u010c0\u0003\u0002\u0002\u0002\u010d\u010e", + "\u0007]\u0002\u0002\u010e2\u0003\u0002\u0002\u0002\u010f\u0110\u0007", + "_\u0002\u0002\u01104\u0003\u0002\u0002\u0002\u0111\u0112\u0005\u00a1", + "Q\u0002\u0112\u0113\u0005\u00adW\u0002\u0113\u0114\u0005\u00adW\u0002", + "\u0114\u0115\u0005\u00c3b\u0002\u0115\u0116\u0005\u00a9U\u0002\u0116", + "\u0117\u0005\u00adW\u0002\u0117\u0118\u0005\u00a1Q\u0002\u0118\u0119", + "\u0005\u00c7d\u0002\u0119\u011a\u0005\u00a9U\u0002\u011a6\u0003\u0002", + "\u0002\u0002\u011b\u011c\u0005\u00a1Q\u0002\u011c\u011d\u0005\u00b7", + "\\\u0002\u011d\u011e\u0005\u00b7\\\u0002\u011e8\u0003\u0002\u0002\u0002", + "\u011f\u0120\u0005\u00a1Q\u0002\u0120\u0121\u0005\u00bb^\u0002\u0121", + "\u0122\u0005\u00a7T\u0002\u0122\u0126\u0003\u0002\u0002\u0002\u0123", + "\u0124\u0007(\u0002\u0002\u0124\u0126\u0007(\u0002\u0002\u0125\u011f", + "\u0003\u0002\u0002\u0002\u0125\u0123\u0003\u0002\u0002\u0002\u0126:", + "\u0003\u0002\u0002\u0002\u0127\u0128\u0005\u00a1Q\u0002\u0128\u0129", + "\u0005\u00bb^\u0002\u0129\u012a\u0005\u00d1i\u0002\u012a<\u0003\u0002", + "\u0002\u0002\u012b\u012c\u0005\u00a1Q\u0002\u012c\u012d\u0005\u00c5", + "c\u0002\u012d\u012e\u0005\u00a5S\u0002\u012e>\u0003\u0002\u0002\u0002", + "\u012f\u0130\u0005\u00a5S\u0002\u0130\u0131\u0005\u00bd_\u0002\u0131", + "\u0132\u0005\u00b7\\\u0002\u0132\u0133\u0005\u00b7\\\u0002\u0133\u0134", + "\u0005\u00a9U\u0002\u0134\u0135\u0005\u00a5S\u0002\u0135\u0136\u0005", + "\u00c7d\u0002\u0136@\u0003\u0002\u0002\u0002\u0137\u0138\u0005\u00a7", + "T\u0002\u0138\u0139\u0005\u00a9U\u0002\u0139\u013a\u0005\u00c5c\u0002", + "\u013a\u013b\u0005\u00a5S\u0002\u013bB\u0003\u0002\u0002\u0002\u013c", + "\u013d\u0005\u00a7T\u0002\u013d\u013e\u0005\u00b1Y\u0002\u013e\u013f", + "\u0005\u00c5c\u0002\u013f\u0140\u0005\u00c7d\u0002\u0140\u0141\u0005", + "\u00b1Y\u0002\u0141\u0142\u0005\u00bb^\u0002\u0142\u0143\u0005\u00a5", + "S\u0002\u0143\u0144\u0005\u00c7d\u0002\u0144D\u0003\u0002\u0002\u0002", + "\u0145\u0146\u0005\u00abV\u0002\u0146\u0147\u0005\u00a1Q\u0002\u0147", + "\u0148\u0005\u00b7\\\u0002\u0148\u0149\u0005\u00c5c\u0002\u0149\u014a", + "\u0005\u00a9U\u0002\u014aF\u0003\u0002\u0002\u0002\u014b\u014c\u0005", + "\u00abV\u0002\u014c\u014d\u0005\u00b1Y\u0002\u014d\u014e\u0005\u00b7", + "\\\u0002\u014e\u014f\u0005\u00c7d\u0002\u014f\u0150\u0005\u00a9U\u0002", + "\u0150\u0151\u0005\u00c3b\u0002\u0151H\u0003\u0002\u0002\u0002\u0152", + "\u0153\u0005\u00abV\u0002\u0153\u0154\u0005\u00bd_\u0002\u0154\u0155", + "\u0005\u00c3b\u0002\u0155J\u0003\u0002\u0002\u0002\u0156\u0157\u0005", + "\u00adW\u0002\u0157\u0158\u0005\u00c3b\u0002\u0158\u0159\u0005\u00a1", + "Q\u0002\u0159\u015a\u0005\u00bf`\u0002\u015a\u015b\u0005\u00afX\u0002", + "\u015bL\u0003\u0002\u0002\u0002\u015c\u015d\u0005\u00b1Y\u0002\u015d", + "\u015e\u0005\u00bb^\u0002\u015eN\u0003\u0002\u0002\u0002\u015f\u0160", + "\u0005\u00b1Y\u0002\u0160\u0161\u0005\u00bb^\u0002\u0161\u0162\u0005", + "\u00a3R\u0002\u0162\u0163\u0005\u00bd_\u0002\u0163\u0164\u0005\u00c9", + "e\u0002\u0164\u0165\u0005\u00bb^\u0002\u0165\u0166\u0005\u00a7T\u0002", + "\u0166P\u0003\u0002\u0002\u0002\u0167\u0168\u0005\u00b1Y\u0002\u0168", + "\u0169\u0005\u00bb^\u0002\u0169\u016a\u0005\u00c5c\u0002\u016a\u016b", + "\u0005\u00a9U\u0002\u016b\u016c\u0005\u00c3b\u0002\u016c\u016d\u0005", + "\u00c7d\u0002\u016dR\u0003\u0002\u0002\u0002\u016e\u016f\u0005\u00b1", + "Y\u0002\u016f\u0170\u0005\u00bb^\u0002\u0170\u0171\u0005\u00c7d\u0002", + "\u0171\u0172\u0005\u00bd_\u0002\u0172T\u0003\u0002\u0002\u0002\u0173", + "\u0174\u0005\u00b5[\u0002\u0174\u0175\u0007a\u0002\u0002\u0175\u0176", + "\u0005\u00c5c\u0002\u0176\u0177\u0005\u00afX\u0002\u0177\u0178\u0005", + "\u00bd_\u0002\u0178\u0179\u0005\u00c3b\u0002\u0179\u017a\u0005\u00c7", + "d\u0002\u017a\u017b\u0005\u00a9U\u0002\u017b\u017c\u0005\u00c5c\u0002", + "\u017c\u017d\u0005\u00c7d\u0002\u017d\u017e\u0007a\u0002\u0002\u017e", + "\u017f\u0005\u00bf`\u0002\u017f\u0180\u0005\u00a1Q\u0002\u0180\u0181", + "\u0005\u00c7d\u0002\u0181\u0182\u0005\u00afX\u0002\u0182\u0183\u0005", + "\u00c5c\u0002\u0183V\u0003\u0002\u0002\u0002\u0184\u0185\u0005\u00b7", + "\\\u0002\u0185\u0186\u0005\u00a9U\u0002\u0186\u0187\u0005\u00c7d\u0002", + "\u0187X\u0003\u0002\u0002\u0002\u0188\u0189\u0005\u00b7\\\u0002\u0189", + "\u018a\u0005\u00b1Y\u0002\u018a\u018b\u0005\u00b5[\u0002\u018b\u018c", + "\u0005\u00a9U\u0002\u018cZ\u0003\u0002\u0002\u0002\u018d\u018e\u0005", + "\u00b7\\\u0002\u018e\u018f\u0005\u00b1Y\u0002\u018f\u0190\u0005\u00b9", + "]\u0002\u0190\u0191\u0005\u00b1Y\u0002\u0191\u0192\u0005\u00c7d\u0002", + "\u0192\\\u0003\u0002\u0002\u0002\u0193\u0194\u0005\u00bb^\u0002\u0194", + "\u0195\u0005\u00bd_\u0002\u0195\u0196\u0005\u00bb^\u0002\u0196\u0197", + "\u0005\u00a9U\u0002\u0197^\u0003\u0002\u0002\u0002\u0198\u0199\u0005", + "\u00bb^\u0002\u0199\u019a\u0005\u00bd_\u0002\u019a\u019b\u0005\u00c7", + "d\u0002\u019b\u019e\u0003\u0002\u0002\u0002\u019c\u019e\u0007#\u0002", + "\u0002\u019d\u0198\u0003\u0002\u0002\u0002\u019d\u019c\u0003\u0002\u0002", + "\u0002\u019e`\u0003\u0002\u0002\u0002\u019f\u01a0\u0005\u00bb^\u0002", + "\u01a0\u01a1\u0005\u00c9e\u0002\u01a1\u01a2\u0005\u00b7\\\u0002\u01a2", + "\u01a3\u0005\u00b7\\\u0002\u01a3b\u0003\u0002\u0002\u0002\u01a4\u01a5", + "\u0005\u00bd_\u0002\u01a5\u01a6\u0005\u00c3b\u0002\u01a6\u01aa\u0003", + "\u0002\u0002\u0002\u01a7\u01a8\u0007~\u0002\u0002\u01a8\u01aa\u0007", + "~\u0002\u0002\u01a9\u01a4\u0003\u0002\u0002\u0002\u01a9\u01a7\u0003", + "\u0002\u0002\u0002\u01aad\u0003\u0002\u0002\u0002\u01ab\u01ac\u0005", + "\u00bd_\u0002\u01ac\u01ad\u0005\u00c9e\u0002\u01ad\u01ae\u0005\u00c7", + "d\u0002\u01ae\u01af\u0005\u00a3R\u0002\u01af\u01b0\u0005\u00bd_\u0002", + "\u01b0\u01b1\u0005\u00c9e\u0002\u01b1\u01b2\u0005\u00bb^\u0002\u01b2", + "\u01b3\u0005\u00a7T\u0002\u01b3f\u0003\u0002\u0002\u0002\u01b4\u01b5", + "\u0005\u00c3b\u0002\u01b5\u01b6\u0005\u00a9U\u0002\u01b6\u01b7\u0005", + "\u00b9]\u0002\u01b7\u01b8\u0005\u00bd_\u0002\u01b8\u01b9\u0005\u00cb", + "f\u0002\u01b9\u01ba\u0005\u00a9U\u0002\u01bah\u0003\u0002\u0002\u0002", + "\u01bb\u01bc\u0005\u00c3b\u0002\u01bc\u01bd\u0005\u00a9U\u0002\u01bd", + "\u01be\u0005\u00bf`\u0002\u01be\u01bf\u0005\u00b7\\\u0002\u01bf\u01c0", + "\u0005\u00a1Q\u0002\u01c0\u01c1\u0005\u00a5S\u0002\u01c1\u01c2\u0005", + "\u00a9U\u0002\u01c2j\u0003\u0002\u0002\u0002\u01c3\u01c4\u0005\u00c3", + "b\u0002\u01c4\u01c5\u0005\u00a9U\u0002\u01c5\u01c6\u0005\u00c7d\u0002", + "\u01c6\u01c7\u0005\u00c9e\u0002\u01c7\u01c8\u0005\u00c3b\u0002\u01c8", + "\u01c9\u0005\u00bb^\u0002\u01c9l\u0003\u0002\u0002\u0002\u01ca\u01cb", + "\u0005\u00c5c\u0002\u01cb\u01cc\u0005\u00afX\u0002\u01cc\u01cd\u0005", + "\u00bd_\u0002\u01cd\u01ce\u0005\u00c3b\u0002\u01ce\u01cf\u0005\u00c7", + "d\u0002\u01cf\u01d0\u0005\u00a9U\u0002\u01d0\u01d1\u0005\u00c5c\u0002", + "\u01d1\u01d2\u0005\u00c7d\u0002\u01d2\u01d3\u0007a\u0002\u0002\u01d3", + "\u01d4\u0005\u00bf`\u0002\u01d4\u01d5\u0005\u00a1Q\u0002\u01d5\u01d6", + "\u0005\u00c7d\u0002\u01d6\u01d7\u0005\u00afX\u0002\u01d7n\u0003\u0002", + "\u0002\u0002\u01d8\u01d9\u0005\u00c5c\u0002\u01d9\u01da\u0005\u00bd", + "_\u0002\u01da\u01db\u0005\u00c3b\u0002\u01db\u01dc\u0005\u00c7d\u0002", + "\u01dcp\u0003\u0002\u0002\u0002\u01dd\u01de\u0005\u00c7d\u0002\u01de", + "\u01df\u0005\u00c3b\u0002\u01df\u01e0\u0005\u00c9e\u0002\u01e0\u01e1", + "\u0005\u00a9U\u0002\u01e1r\u0003\u0002\u0002\u0002\u01e2\u01e3\u0005", + "\u00c9e\u0002\u01e3\u01e4\u0005\u00bf`\u0002\u01e4\u01e5\u0005\u00a7", + "T\u0002\u01e5\u01e6\u0005\u00a1Q\u0002\u01e6\u01e7\u0005\u00c7d\u0002", + "\u01e7\u01e8\u0005\u00a9U\u0002\u01e8t\u0003\u0002\u0002\u0002\u01e9", + "\u01ea\u0005\u00c9e\u0002\u01ea\u01eb\u0005\u00bf`\u0002\u01eb\u01ec", + "\u0005\u00c5c\u0002\u01ec\u01ed\u0005\u00a9U\u0002\u01ed\u01ee\u0005", + "\u00c3b\u0002\u01ee\u01ef\u0005\u00c7d\u0002\u01efv\u0003\u0002\u0002", + "\u0002\u01f0\u01f1\u0005\u00cdg\u0002\u01f1\u01f2\u0005\u00b1Y\u0002", + "\u01f2\u01f3\u0005\u00c7d\u0002\u01f3\u01f4\u0005\u00afX\u0002\u01f4", + "x\u0003\u0002\u0002\u0002\u01f5\u01f6\u0005\u00b5[\u0002\u01f6\u01f7", + "\u0005\u00a9U\u0002\u01f7\u01f8\u0005\u00a9U\u0002\u01f8\u01f9\u0005", + "\u00bf`\u0002\u01f9z\u0003\u0002\u0002\u0002\u01fa\u01fb\u0005\u00a5", + "S\u0002\u01fb\u01fc\u0005\u00bd_\u0002\u01fc\u01fd\u0005\u00c9e\u0002", + "\u01fd\u01fe\u0005\u00bb^\u0002\u01fe\u01ff\u0005\u00c7d\u0002\u01ff", + "|\u0003\u0002\u0002\u0002\u0200\u0201\u0005\u00bd_\u0002\u0201\u0202", + "\u0005\u00bf`\u0002\u0202\u0203\u0005\u00c7d\u0002\u0203\u0204\u0005", + "\u00b1Y\u0002\u0204\u0205\u0005\u00bd_\u0002\u0205\u0206\u0005\u00bb", + "^\u0002\u0206\u0207\u0005\u00c5c\u0002\u0207~\u0003\u0002\u0002\u0002", + "\u0208\u0209\u0005\u00bf`\u0002\u0209\u020a\u0005\u00c3b\u0002\u020a", + "\u020b\u0005\u00c9e\u0002\u020b\u020c\u0005\u00bb^\u0002\u020c\u020d", + "\u0005\u00a9U\u0002\u020d\u0080\u0003\u0002\u0002\u0002\u020e\u020f", + "\u0005\u00c5c\u0002\u020f\u0210\u0005\u00a9U\u0002\u0210\u0211\u0005", + "\u00a1Q\u0002\u0211\u0212\u0005\u00c3b\u0002\u0212\u0213\u0005\u00a5", + "S\u0002\u0213\u0214\u0005\u00afX\u0002\u0214\u0082\u0003\u0002\u0002", + "\u0002\u0215\u0216\u0005\u00c7d\u0002\u0216\u0217\u0005\u00bd_\u0002", + "\u0217\u0084\u0003\u0002\u0002\u0002\u0218\u0219\u0005\u00a5S\u0002", + "\u0219\u021a\u0005\u00c9e\u0002\u021a\u021b\u0005\u00c3b\u0002\u021b", + "\u021c\u0005\u00c3b\u0002\u021c\u021d\u0005\u00a9U\u0002\u021d\u021e", + "\u0005\u00bb^\u0002\u021e\u021f\u0005\u00c7d\u0002\u021f\u0086\u0003", + "\u0002\u0002\u0002\u0220\u0221\u0005\u00bb^\u0002\u0221\u0222\u0005", + "\u00a9U\u0002\u0222\u0223\u0005\u00cdg\u0002\u0223\u0088\u0003\u0002", + "\u0002\u0002\u0224\u0225\u0005\u00bd_\u0002\u0225\u0226\u0005\u00b7", + "\\\u0002\u0226\u0227\u0005\u00a7T\u0002\u0227\u008a\u0003\u0002\u0002", + "\u0002\u0228\u022c\t\u0002\u0002\u0002\u0229\u022b\t\u0003\u0002\u0002", + "\u022a\u0229\u0003\u0002\u0002\u0002\u022b\u022e\u0003\u0002\u0002\u0002", + "\u022c\u022a\u0003\u0002\u0002\u0002\u022c\u022d\u0003\u0002\u0002\u0002", + "\u022d\u008c\u0003\u0002\u0002\u0002\u022e\u022c\u0003\u0002\u0002\u0002", + "\u022f\u0233\t\u0004\u0002\u0002\u0230\u0232\u0005\u009fP\u0002\u0231", + "\u0230\u0003\u0002\u0002\u0002\u0232\u0235\u0003\u0002\u0002\u0002\u0233", + "\u0231\u0003\u0002\u0002\u0002\u0233\u0234\u0003\u0002\u0002\u0002\u0234", + "\u0248\u0003\u0002\u0002\u0002\u0235\u0233\u0003\u0002\u0002\u0002\u0236", + "\u0248\u00072\u0002\u0002\u0237\u0238\u00072\u0002\u0002\u0238\u0239", + "\u0007z\u0002\u0002\u0239\u023b\u0003\u0002\u0002\u0002\u023a\u023c", + "\u0005\u009dO\u0002\u023b\u023a\u0003\u0002\u0002\u0002\u023c\u023d", + "\u0003\u0002\u0002\u0002\u023d\u023b\u0003\u0002\u0002\u0002\u023d\u023e", + "\u0003\u0002\u0002\u0002\u023e\u0248\u0003\u0002\u0002\u0002\u023f\u0240", + "\u00072\u0002\u0002\u0240\u0241\u0007d\u0002\u0002\u0241\u0243\u0003", + "\u0002\u0002\u0002\u0242\u0244\t\u0005\u0002\u0002\u0243\u0242\u0003", + "\u0002\u0002\u0002\u0244\u0245\u0003\u0002\u0002\u0002\u0245\u0243\u0003", + "\u0002\u0002\u0002\u0245\u0246\u0003\u0002\u0002\u0002\u0246\u0248\u0003", + "\u0002\u0002\u0002\u0247\u022f\u0003\u0002\u0002\u0002\u0247\u0236\u0003", + "\u0002\u0002\u0002\u0247\u0237\u0003\u0002\u0002\u0002\u0247\u023f\u0003", + "\u0002\u0002\u0002\u0248\u008e\u0003\u0002\u0002\u0002\u0249\u024d\t", + "\u0004\u0002\u0002\u024a\u024c\u0005\u009fP\u0002\u024b\u024a\u0003", + "\u0002\u0002\u0002\u024c\u024f\u0003\u0002\u0002\u0002\u024d\u024b\u0003", + "\u0002\u0002\u0002\u024d\u024e\u0003\u0002\u0002\u0002\u024e\u0252\u0003", + "\u0002\u0002\u0002\u024f\u024d\u0003\u0002\u0002\u0002\u0250\u0252\u0007", + "2\u0002\u0002\u0251\u0249\u0003\u0002\u0002\u0002\u0251\u0250\u0003", + "\u0002\u0002\u0002\u0251\u0252\u0003\u0002\u0002\u0002\u0252\u0253\u0003", + "\u0002\u0002\u0002\u0253\u0255\u00070\u0002\u0002\u0254\u0256\u0005", + "\u009fP\u0002\u0255\u0254\u0003\u0002\u0002\u0002\u0256\u0257\u0003", + "\u0002\u0002\u0002\u0257\u0255\u0003\u0002\u0002\u0002\u0257\u0258\u0003", + "\u0002\u0002\u0002\u0258\u0262\u0003\u0002\u0002\u0002\u0259\u025b\u0005", + "\u00a9U\u0002\u025a\u025c\t\u0006\u0002\u0002\u025b\u025a\u0003\u0002", + "\u0002\u0002\u025b\u025c\u0003\u0002\u0002\u0002\u025c\u025e\u0003\u0002", + "\u0002\u0002\u025d\u025f\u0005\u009fP\u0002\u025e\u025d\u0003\u0002", + "\u0002\u0002\u025f\u0260\u0003\u0002\u0002\u0002\u0260\u025e\u0003\u0002", + "\u0002\u0002\u0260\u0261\u0003\u0002\u0002\u0002\u0261\u0263\u0003\u0002", + "\u0002\u0002\u0262\u0259\u0003\u0002\u0002\u0002\u0262\u0263\u0003\u0002", + "\u0002\u0002\u0263\u0090\u0003\u0002\u0002\u0002\u0264\u0265\u0007B", + "\u0002\u0002\u0265\u0266\u0005\u008bF\u0002\u0266\u0092\u0003\u0002", + "\u0002\u0002\u0267\u026f\u0007)\u0002\u0002\u0268\u0269\u0007^\u0002", + "\u0002\u0269\u026e\u000b\u0002\u0002\u0002\u026a\u026b\u0007)\u0002", + "\u0002\u026b\u026e\u0007)\u0002\u0002\u026c\u026e\n\u0007\u0002\u0002", + "\u026d\u0268\u0003\u0002\u0002\u0002\u026d\u026a\u0003\u0002\u0002\u0002", + "\u026d\u026c\u0003\u0002\u0002\u0002\u026e\u0271\u0003\u0002\u0002\u0002", + "\u026f\u026d\u0003\u0002\u0002\u0002\u026f\u0270\u0003\u0002\u0002\u0002", + "\u0270\u0272\u0003\u0002\u0002\u0002\u0271\u026f\u0003\u0002\u0002\u0002", + "\u0272\u0280\u0007)\u0002\u0002\u0273\u027b\u0007$\u0002\u0002\u0274", + "\u0275\u0007^\u0002\u0002\u0275\u027a\u000b\u0002\u0002\u0002\u0276", + "\u0277\u0007$\u0002\u0002\u0277\u027a\u0007$\u0002\u0002\u0278\u027a", + "\n\b\u0002\u0002\u0279\u0274\u0003\u0002\u0002\u0002\u0279\u0276\u0003", + "\u0002\u0002\u0002\u0279\u0278\u0003\u0002\u0002\u0002\u027a\u027d\u0003", + "\u0002\u0002\u0002\u027b\u0279\u0003\u0002\u0002\u0002\u027b\u027c\u0003", + "\u0002\u0002\u0002\u027c\u027e\u0003\u0002\u0002\u0002\u027d\u027b\u0003", + "\u0002\u0002\u0002\u027e\u0280\u0007$\u0002\u0002\u027f\u0267\u0003", + "\u0002\u0002\u0002\u027f\u0273\u0003\u0002\u0002\u0002\u0280\u0094\u0003", + "\u0002\u0002\u0002\u0281\u0282\u00071\u0002\u0002\u0282\u0283\u0007", + "1\u0002\u0002\u0283\u0287\u0003\u0002\u0002\u0002\u0284\u0286\n\t\u0002", + "\u0002\u0285\u0284\u0003\u0002\u0002\u0002\u0286\u0289\u0003\u0002\u0002", + "\u0002\u0287\u0285\u0003\u0002\u0002\u0002\u0287\u0288\u0003\u0002\u0002", + "\u0002\u0288\u028f\u0003\u0002\u0002\u0002\u0289\u0287\u0003\u0002\u0002", + "\u0002\u028a\u028c\u0007\u000f\u0002\u0002\u028b\u028a\u0003\u0002\u0002", + "\u0002\u028b\u028c\u0003\u0002\u0002\u0002\u028c\u028d\u0003\u0002\u0002", + "\u0002\u028d\u0290\u0007\f\u0002\u0002\u028e\u0290\u0007\u0002\u0002", + "\u0003\u028f\u028b\u0003\u0002\u0002\u0002\u028f\u028e\u0003\u0002\u0002", + "\u0002\u0290\u0291\u0003\u0002\u0002\u0002\u0291\u0292\bK\u0002\u0002", + "\u0292\u0096\u0003\u0002\u0002\u0002\u0293\u0294\u00071\u0002\u0002", + "\u0294\u0295\u0007,\u0002\u0002\u0295\u0299\u0003\u0002\u0002\u0002", + "\u0296\u0298\u000b\u0002\u0002\u0002\u0297\u0296\u0003\u0002\u0002\u0002", + "\u0298\u029b\u0003\u0002\u0002\u0002\u0299\u029a\u0003\u0002\u0002\u0002", + "\u0299\u0297\u0003\u0002\u0002\u0002\u029a\u029c\u0003\u0002\u0002\u0002", + "\u029b\u0299\u0003\u0002\u0002\u0002\u029c\u029d\u0007,\u0002\u0002", + "\u029d\u029e\u00071\u0002\u0002\u029e\u029f\u0003\u0002\u0002\u0002", + "\u029f\u02a0\bL\u0002\u0002\u02a0\u0098\u0003\u0002\u0002\u0002\u02a1", + "\u02a2\t\n\u0002\u0002\u02a2\u02a3\u0003\u0002\u0002\u0002\u02a3\u02a4", + "\bM\u0002\u0002\u02a4\u009a\u0003\u0002\u0002\u0002\u02a5\u02a6\u000b", + "\u0002\u0002\u0002\u02a6\u009c\u0003\u0002\u0002\u0002\u02a7\u02a8\t", + "\u000b\u0002\u0002\u02a8\u009e\u0003\u0002\u0002\u0002\u02a9\u02aa\t", + "\f\u0002\u0002\u02aa\u00a0\u0003\u0002\u0002\u0002\u02ab\u02ac\t\r\u0002", + "\u0002\u02ac\u00a2\u0003\u0002\u0002\u0002\u02ad\u02ae\t\u000e\u0002", + "\u0002\u02ae\u00a4\u0003\u0002\u0002\u0002\u02af\u02b0\t\u000f\u0002", + "\u0002\u02b0\u00a6\u0003\u0002\u0002\u0002\u02b1\u02b2\t\u0010\u0002", + "\u0002\u02b2\u00a8\u0003\u0002\u0002\u0002\u02b3\u02b4\t\u0011\u0002", + "\u0002\u02b4\u00aa\u0003\u0002\u0002\u0002\u02b5\u02b6\t\u0012\u0002", + "\u0002\u02b6\u00ac\u0003\u0002\u0002\u0002\u02b7\u02b8\t\u0013\u0002", + "\u0002\u02b8\u00ae\u0003\u0002\u0002\u0002\u02b9\u02ba\t\u0014\u0002", + "\u0002\u02ba\u00b0\u0003\u0002\u0002\u0002\u02bb\u02bc\t\u0015\u0002", + "\u0002\u02bc\u00b2\u0003\u0002\u0002\u0002\u02bd\u02be\t\u0016\u0002", + "\u0002\u02be\u00b4\u0003\u0002\u0002\u0002\u02bf\u02c0\t\u0017\u0002", + "\u0002\u02c0\u00b6\u0003\u0002\u0002\u0002\u02c1\u02c2\t\u0018\u0002", + "\u0002\u02c2\u00b8\u0003\u0002\u0002\u0002\u02c3\u02c4\t\u0019\u0002", + "\u0002\u02c4\u00ba\u0003\u0002\u0002\u0002\u02c5\u02c6\t\u001a\u0002", + "\u0002\u02c6\u00bc\u0003\u0002\u0002\u0002\u02c7\u02c8\t\u001b\u0002", + "\u0002\u02c8\u00be\u0003\u0002\u0002\u0002\u02c9\u02ca\t\u001c\u0002", + "\u0002\u02ca\u00c0\u0003\u0002\u0002\u0002\u02cb\u02cc\t\u001d\u0002", + "\u0002\u02cc\u00c2\u0003\u0002\u0002\u0002\u02cd\u02ce\t\u001e\u0002", + "\u0002\u02ce\u00c4\u0003\u0002\u0002\u0002\u02cf\u02d0\t\u001f\u0002", + "\u0002\u02d0\u00c6\u0003\u0002\u0002\u0002\u02d1\u02d2\t \u0002\u0002", + "\u02d2\u00c8\u0003\u0002\u0002\u0002\u02d3\u02d4\t!\u0002\u0002\u02d4", + "\u00ca\u0003\u0002\u0002\u0002\u02d5\u02d6\t\"\u0002\u0002\u02d6\u00cc", + "\u0003\u0002\u0002\u0002\u02d7\u02d8\t#\u0002\u0002\u02d8\u00ce\u0003", + "\u0002\u0002\u0002\u02d9\u02da\t$\u0002\u0002\u02da\u00d0\u0003\u0002", + "\u0002\u0002\u02db\u02dc\t%\u0002\u0002\u02dc\u00d2\u0003\u0002\u0002", + "\u0002\u02dd\u02de\t&\u0002\u0002\u02de\u00d4\u0003\u0002\u0002\u0002", + "\u02df\u02e0\u000b\u0002\u0002\u0002\u02e0\u02e1\u0003\u0002\u0002\u0002", + "\u02e1\u02e2\bk\u0003\u0002\u02e2\u00d6\u0003\u0002\u0002\u0002\u001a", + "\u0002\u0125\u019d\u01a9\u022c\u0233\u023d\u0245\u0247\u024d\u0251\u0257", + "\u025b\u0260\u0262\u026d\u026f\u0279\u027b\u027f\u0287\u028b\u028f\u0299", + "\u0004\u0002\u0003\u0002\u0002\u0004\u0002"].join(""); + + +const atn = new antlr4.atn.ATNDeserializer().deserialize(serializedATN); + +const decisionsToDFA = atn.decisionToState.map( (ds, index) => new antlr4.dfa.DFA(ds, index) ); + +export default class CAQLLexer extends antlr4.Lexer { + + static grammarFileName = "CAQLLexer.g4"; + static channelNames = [ "DEFAULT_TOKEN_CHANNEL", "HIDDEN", "ERRORCHANNEL" ]; + static modeNames = [ "DEFAULT_MODE" ]; + static literalNames = [ null, "'.'", "'=~'", "'!~'", "'=='", "'!='", "'<'", + "'>'", "'<='", "'>='", "'+'", "'-'", "'*'", "'/'", + "'%'", "'?'", "':'", "'::'", "'..'", "','", "'('", + "')'", "'{'", "'}'", "'['", "']'" ]; + static symbolicNames = [ null, "DOT", "T_REGEX_MATCH", "T_REGEX_NON_MATCH", + "T_EQ", "T_NE", "T_LT", "T_GT", "T_LE", "T_GE", + "T_PLUS", "T_MINUS", "T_TIMES", "T_DIV", "T_MOD", + "T_QUESTION", "T_COLON", "T_SCOPE", "T_RANGE", + "T_COMMA", "T_OPEN", "T_CLOSE", "T_OBJECT_OPEN", + "T_OBJECT_CLOSE", "T_ARRAY_OPEN", "T_ARRAY_CLOSE", + "T_AGGREGATE", "T_ALL", "T_AND", "T_ANY", "T_ASC", + "T_COLLECT", "T_DESC", "T_DISTINCT", "T_FALSE", + "T_FILTER", "T_FOR", "T_GRAPH", "T_IN", "T_INBOUND", + "T_INSERT", "T_INTO", "T_K_SHORTEST_PATHS", "T_LET", + "T_LIKE", "T_LIMIT", "T_NONE", "T_NOT", "T_NULL", + "T_OR", "T_OUTBOUND", "T_REMOVE", "T_REPLACE", + "T_RETURN", "T_SHORTEST_PATH", "T_SORT", "T_TRUE", + "T_UPDATE", "T_UPSERT", "T_WITH", "T_KEEP", "T_COUNT", + "T_OPTIONS", "T_PRUNE", "T_SEARCH", "T_TO", "T_CURRENT", + "T_NEW", "T_OLD", "T_STRING", "T_INT", "T_FLOAT", + "T_PARAMETER", "T_QUOTED_STRING", "SINGLE_LINE_COMMENT", + "MULTILINE_COMMENT", "SPACES", "UNEXPECTED_CHAR", + "ERROR_RECONGNIGION" ]; + static ruleNames = [ "DOT", "T_REGEX_MATCH", "T_REGEX_NON_MATCH", "T_EQ", + "T_NE", "T_LT", "T_GT", "T_LE", "T_GE", "T_PLUS", + "T_MINUS", "T_TIMES", "T_DIV", "T_MOD", "T_QUESTION", + "T_COLON", "T_SCOPE", "T_RANGE", "T_COMMA", "T_OPEN", + "T_CLOSE", "T_OBJECT_OPEN", "T_OBJECT_CLOSE", "T_ARRAY_OPEN", + "T_ARRAY_CLOSE", "T_AGGREGATE", "T_ALL", "T_AND", + "T_ANY", "T_ASC", "T_COLLECT", "T_DESC", "T_DISTINCT", + "T_FALSE", "T_FILTER", "T_FOR", "T_GRAPH", "T_IN", + "T_INBOUND", "T_INSERT", "T_INTO", "T_K_SHORTEST_PATHS", + "T_LET", "T_LIKE", "T_LIMIT", "T_NONE", "T_NOT", "T_NULL", + "T_OR", "T_OUTBOUND", "T_REMOVE", "T_REPLACE", "T_RETURN", + "T_SHORTEST_PATH", "T_SORT", "T_TRUE", "T_UPDATE", + "T_UPSERT", "T_WITH", "T_KEEP", "T_COUNT", "T_OPTIONS", + "T_PRUNE", "T_SEARCH", "T_TO", "T_CURRENT", "T_NEW", + "T_OLD", "T_STRING", "T_INT", "T_FLOAT", "T_PARAMETER", + "T_QUOTED_STRING", "SINGLE_LINE_COMMENT", "MULTILINE_COMMENT", + "SPACES", "UNEXPECTED_CHAR", "HEX_DIGIT", "DIGIT", + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", + "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", + "U", "V", "W", "X", "Y", "Z", "ERROR_RECONGNIGION" ]; + + constructor(input) { + super(input) + this._interp = new antlr4.atn.LexerATNSimulator(this, atn, decisionsToDFA, new antlr4.PredictionContextCache()); + } + + get atn() { + return atn; + } +} + +CAQLLexer.EOF = antlr4.Token.EOF; +CAQLLexer.DOT = 1; +CAQLLexer.T_REGEX_MATCH = 2; +CAQLLexer.T_REGEX_NON_MATCH = 3; +CAQLLexer.T_EQ = 4; +CAQLLexer.T_NE = 5; +CAQLLexer.T_LT = 6; +CAQLLexer.T_GT = 7; +CAQLLexer.T_LE = 8; +CAQLLexer.T_GE = 9; +CAQLLexer.T_PLUS = 10; +CAQLLexer.T_MINUS = 11; +CAQLLexer.T_TIMES = 12; +CAQLLexer.T_DIV = 13; +CAQLLexer.T_MOD = 14; +CAQLLexer.T_QUESTION = 15; +CAQLLexer.T_COLON = 16; +CAQLLexer.T_SCOPE = 17; +CAQLLexer.T_RANGE = 18; +CAQLLexer.T_COMMA = 19; +CAQLLexer.T_OPEN = 20; +CAQLLexer.T_CLOSE = 21; +CAQLLexer.T_OBJECT_OPEN = 22; +CAQLLexer.T_OBJECT_CLOSE = 23; +CAQLLexer.T_ARRAY_OPEN = 24; +CAQLLexer.T_ARRAY_CLOSE = 25; +CAQLLexer.T_AGGREGATE = 26; +CAQLLexer.T_ALL = 27; +CAQLLexer.T_AND = 28; +CAQLLexer.T_ANY = 29; +CAQLLexer.T_ASC = 30; +CAQLLexer.T_COLLECT = 31; +CAQLLexer.T_DESC = 32; +CAQLLexer.T_DISTINCT = 33; +CAQLLexer.T_FALSE = 34; +CAQLLexer.T_FILTER = 35; +CAQLLexer.T_FOR = 36; +CAQLLexer.T_GRAPH = 37; +CAQLLexer.T_IN = 38; +CAQLLexer.T_INBOUND = 39; +CAQLLexer.T_INSERT = 40; +CAQLLexer.T_INTO = 41; +CAQLLexer.T_K_SHORTEST_PATHS = 42; +CAQLLexer.T_LET = 43; +CAQLLexer.T_LIKE = 44; +CAQLLexer.T_LIMIT = 45; +CAQLLexer.T_NONE = 46; +CAQLLexer.T_NOT = 47; +CAQLLexer.T_NULL = 48; +CAQLLexer.T_OR = 49; +CAQLLexer.T_OUTBOUND = 50; +CAQLLexer.T_REMOVE = 51; +CAQLLexer.T_REPLACE = 52; +CAQLLexer.T_RETURN = 53; +CAQLLexer.T_SHORTEST_PATH = 54; +CAQLLexer.T_SORT = 55; +CAQLLexer.T_TRUE = 56; +CAQLLexer.T_UPDATE = 57; +CAQLLexer.T_UPSERT = 58; +CAQLLexer.T_WITH = 59; +CAQLLexer.T_KEEP = 60; +CAQLLexer.T_COUNT = 61; +CAQLLexer.T_OPTIONS = 62; +CAQLLexer.T_PRUNE = 63; +CAQLLexer.T_SEARCH = 64; +CAQLLexer.T_TO = 65; +CAQLLexer.T_CURRENT = 66; +CAQLLexer.T_NEW = 67; +CAQLLexer.T_OLD = 68; +CAQLLexer.T_STRING = 69; +CAQLLexer.T_INT = 70; +CAQLLexer.T_FLOAT = 71; +CAQLLexer.T_PARAMETER = 72; +CAQLLexer.T_QUOTED_STRING = 73; +CAQLLexer.SINGLE_LINE_COMMENT = 74; +CAQLLexer.MULTILINE_COMMENT = 75; +CAQLLexer.SPACES = 76; +CAQLLexer.UNEXPECTED_CHAR = 77; +CAQLLexer.ERROR_RECONGNIGION = 78; + +CAQLLexer.ERRORCHANNEL = 2; + + + diff --git a/ui/src/suggestions/grammar/CAQLLexer.tokens b/ui/src/suggestions/grammar/CAQLLexer.tokens new file mode 100644 index 0000000..7bdaf61 --- /dev/null +++ b/ui/src/suggestions/grammar/CAQLLexer.tokens @@ -0,0 +1,103 @@ +DOT=1 +T_REGEX_MATCH=2 +T_REGEX_NON_MATCH=3 +T_EQ=4 +T_NE=5 +T_LT=6 +T_GT=7 +T_LE=8 +T_GE=9 +T_PLUS=10 +T_MINUS=11 +T_TIMES=12 +T_DIV=13 +T_MOD=14 +T_QUESTION=15 +T_COLON=16 +T_SCOPE=17 +T_RANGE=18 +T_COMMA=19 +T_OPEN=20 +T_CLOSE=21 +T_OBJECT_OPEN=22 +T_OBJECT_CLOSE=23 +T_ARRAY_OPEN=24 +T_ARRAY_CLOSE=25 +T_AGGREGATE=26 +T_ALL=27 +T_AND=28 +T_ANY=29 +T_ASC=30 +T_COLLECT=31 +T_DESC=32 +T_DISTINCT=33 +T_FALSE=34 +T_FILTER=35 +T_FOR=36 +T_GRAPH=37 +T_IN=38 +T_INBOUND=39 +T_INSERT=40 +T_INTO=41 +T_K_SHORTEST_PATHS=42 +T_LET=43 +T_LIKE=44 +T_LIMIT=45 +T_NONE=46 +T_NOT=47 +T_NULL=48 +T_OR=49 +T_OUTBOUND=50 +T_REMOVE=51 +T_REPLACE=52 +T_RETURN=53 +T_SHORTEST_PATH=54 +T_SORT=55 +T_TRUE=56 +T_UPDATE=57 +T_UPSERT=58 +T_WITH=59 +T_KEEP=60 +T_COUNT=61 +T_OPTIONS=62 +T_PRUNE=63 +T_SEARCH=64 +T_TO=65 +T_CURRENT=66 +T_NEW=67 +T_OLD=68 +T_STRING=69 +T_INT=70 +T_FLOAT=71 +T_PARAMETER=72 +T_QUOTED_STRING=73 +SINGLE_LINE_COMMENT=74 +MULTILINE_COMMENT=75 +SPACES=76 +UNEXPECTED_CHAR=77 +ERROR_RECONGNIGION=78 +'.'=1 +'=~'=2 +'!~'=3 +'=='=4 +'!='=5 +'<'=6 +'>'=7 +'<='=8 +'>='=9 +'+'=10 +'-'=11 +'*'=12 +'/'=13 +'%'=14 +'?'=15 +':'=16 +'::'=17 +'..'=18 +','=19 +'('=20 +')'=21 +'{'=22 +'}'=23 +'['=24 +']'=25 diff --git a/ui/src/suggestions/grammar/CAQLParser.interp b/ui/src/suggestions/grammar/CAQLParser.interp new file mode 100644 index 0000000..8abde5b --- /dev/null +++ b/ui/src/suggestions/grammar/CAQLParser.interp @@ -0,0 +1,178 @@ +token literal names: +null +'.' +'=~' +'!~' +'==' +'!=' +'<' +'>' +'<=' +'>=' +'+' +'-' +'*' +'/' +'%' +'?' +':' +'::' +'..' +',' +'(' +')' +'{' +'}' +'[' +']' +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null + +token symbolic names: +null +DOT +T_REGEX_MATCH +T_REGEX_NON_MATCH +T_EQ +T_NE +T_LT +T_GT +T_LE +T_GE +T_PLUS +T_MINUS +T_TIMES +T_DIV +T_MOD +T_QUESTION +T_COLON +T_SCOPE +T_RANGE +T_COMMA +T_OPEN +T_CLOSE +T_OBJECT_OPEN +T_OBJECT_CLOSE +T_ARRAY_OPEN +T_ARRAY_CLOSE +T_AGGREGATE +T_ALL +T_AND +T_ANY +T_ASC +T_COLLECT +T_DESC +T_DISTINCT +T_FALSE +T_FILTER +T_FOR +T_GRAPH +T_IN +T_INBOUND +T_INSERT +T_INTO +T_K_SHORTEST_PATHS +T_LET +T_LIKE +T_LIMIT +T_NONE +T_NOT +T_NULL +T_OR +T_OUTBOUND +T_REMOVE +T_REPLACE +T_RETURN +T_SHORTEST_PATH +T_SORT +T_TRUE +T_UPDATE +T_UPSERT +T_WITH +T_KEEP +T_COUNT +T_OPTIONS +T_PRUNE +T_SEARCH +T_TO +T_CURRENT +T_NEW +T_OLD +T_STRING +T_INT +T_FLOAT +T_PARAMETER +T_QUOTED_STRING +SINGLE_LINE_COMMENT +MULTILINE_COMMENT +SPACES +UNEXPECTED_CHAR +ERROR_RECONGNIGION + +rule names: +parse +expression +operator_unary +reference +compound_value +function_call +value_literal +array +object +object_element +object_element_name + + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 80, 192, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 32, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 48, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 66, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 86, 10, 3, 12, 3, 14, 3, 89, 11, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 5, 4, 97, 10, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 107, 10, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 7, 5, 117, 10, 5, 12, 5, 14, 5, 120, 11, 5, 3, 6, 3, 6, 5, 6, 124, 10, 6, 3, 7, 3, 7, 3, 7, 5, 7, 129, 10, 7, 3, 7, 3, 7, 7, 7, 133, 10, 7, 12, 7, 14, 7, 136, 11, 7, 3, 7, 5, 7, 139, 10, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 5, 9, 147, 10, 9, 3, 9, 3, 9, 7, 9, 151, 10, 9, 12, 9, 14, 9, 154, 11, 9, 3, 9, 5, 9, 157, 10, 9, 3, 9, 3, 9, 3, 10, 3, 10, 5, 10, 163, 10, 10, 3, 10, 3, 10, 7, 10, 167, 10, 10, 12, 10, 14, 10, 170, 11, 10, 3, 10, 5, 10, 173, 10, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 5, 11, 188, 10, 11, 3, 12, 3, 12, 3, 12, 4, 134, 152, 4, 4, 8, 13, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 2, 11, 3, 2, 12, 13, 3, 2, 14, 16, 3, 2, 8, 11, 3, 2, 6, 7, 5, 2, 29, 29, 31, 31, 48, 48, 4, 2, 6, 11, 40, 40, 4, 2, 4, 5, 46, 46, 7, 2, 36, 36, 50, 50, 58, 58, 72, 73, 75, 75, 4, 2, 71, 71, 75, 75, 2, 216, 2, 24, 3, 2, 2, 2, 4, 31, 3, 2, 2, 2, 6, 96, 3, 2, 2, 2, 8, 106, 3, 2, 2, 2, 10, 123, 3, 2, 2, 2, 12, 125, 3, 2, 2, 2, 14, 142, 3, 2, 2, 2, 16, 144, 3, 2, 2, 2, 18, 160, 3, 2, 2, 2, 20, 187, 3, 2, 2, 2, 22, 189, 3, 2, 2, 2, 24, 25, 5, 4, 3, 2, 25, 26, 7, 2, 2, 3, 26, 3, 3, 2, 2, 2, 27, 28, 8, 3, 1, 2, 28, 32, 5, 14, 8, 2, 29, 32, 5, 8, 5, 2, 30, 32, 5, 6, 4, 2, 31, 27, 3, 2, 2, 2, 31, 29, 3, 2, 2, 2, 31, 30, 3, 2, 2, 2, 32, 87, 3, 2, 2, 2, 33, 34, 12, 15, 2, 2, 34, 35, 9, 2, 2, 2, 35, 86, 5, 4, 3, 16, 36, 37, 12, 14, 2, 2, 37, 38, 9, 3, 2, 2, 38, 86, 5, 4, 3, 15, 39, 40, 12, 13, 2, 2, 40, 41, 7, 20, 2, 2, 41, 86, 5, 4, 3, 14, 42, 43, 12, 12, 2, 2, 43, 44, 9, 4, 2, 2, 44, 86, 5, 4, 3, 13, 45, 47, 12, 11, 2, 2, 46, 48, 7, 49, 2, 2, 47, 46, 3, 2, 2, 2, 47, 48, 3, 2, 2, 2, 48, 49, 3, 2, 2, 2, 49, 50, 7, 40, 2, 2, 50, 86, 5, 4, 3, 12, 51, 52, 12, 10, 2, 2, 52, 53, 9, 5, 2, 2, 53, 86, 5, 4, 3, 11, 54, 55, 12, 9, 2, 2, 55, 56, 9, 6, 2, 2, 56, 57, 9, 7, 2, 2, 57, 86, 5, 4, 3, 10, 58, 59, 12, 8, 2, 2, 59, 60, 9, 6, 2, 2, 60, 61, 7, 49, 2, 2, 61, 62, 7, 40, 2, 2, 62, 86, 5, 4, 3, 9, 63, 65, 12, 7, 2, 2, 64, 66, 7, 49, 2, 2, 65, 64, 3, 2, 2, 2, 65, 66, 3, 2, 2, 2, 66, 67, 3, 2, 2, 2, 67, 68, 9, 8, 2, 2, 68, 86, 5, 4, 3, 8, 69, 70, 12, 6, 2, 2, 70, 71, 7, 30, 2, 2, 71, 86, 5, 4, 3, 7, 72, 73, 12, 5, 2, 2, 73, 74, 7, 51, 2, 2, 74, 86, 5, 4, 3, 6, 75, 76, 12, 4, 2, 2, 76, 77, 7, 17, 2, 2, 77, 78, 5, 4, 3, 2, 78, 79, 7, 18, 2, 2, 79, 80, 5, 4, 3, 5, 80, 86, 3, 2, 2, 2, 81, 82, 12, 3, 2, 2, 82, 83, 7, 17, 2, 2, 83, 84, 7, 18, 2, 2, 84, 86, 5, 4, 3, 4, 85, 33, 3, 2, 2, 2, 85, 36, 3, 2, 2, 2, 85, 39, 3, 2, 2, 2, 85, 42, 3, 2, 2, 2, 85, 45, 3, 2, 2, 2, 85, 51, 3, 2, 2, 2, 85, 54, 3, 2, 2, 2, 85, 58, 3, 2, 2, 2, 85, 63, 3, 2, 2, 2, 85, 69, 3, 2, 2, 2, 85, 72, 3, 2, 2, 2, 85, 75, 3, 2, 2, 2, 85, 81, 3, 2, 2, 2, 86, 89, 3, 2, 2, 2, 87, 85, 3, 2, 2, 2, 87, 88, 3, 2, 2, 2, 88, 5, 3, 2, 2, 2, 89, 87, 3, 2, 2, 2, 90, 91, 7, 12, 2, 2, 91, 97, 5, 4, 3, 2, 92, 93, 7, 13, 2, 2, 93, 97, 5, 4, 3, 2, 94, 95, 7, 49, 2, 2, 95, 97, 5, 4, 3, 2, 96, 90, 3, 2, 2, 2, 96, 92, 3, 2, 2, 2, 96, 94, 3, 2, 2, 2, 97, 7, 3, 2, 2, 2, 98, 99, 8, 5, 1, 2, 99, 107, 7, 71, 2, 2, 100, 107, 5, 10, 6, 2, 101, 107, 5, 12, 7, 2, 102, 103, 7, 22, 2, 2, 103, 104, 5, 4, 3, 2, 104, 105, 7, 23, 2, 2, 105, 107, 3, 2, 2, 2, 106, 98, 3, 2, 2, 2, 106, 100, 3, 2, 2, 2, 106, 101, 3, 2, 2, 2, 106, 102, 3, 2, 2, 2, 107, 118, 3, 2, 2, 2, 108, 109, 12, 4, 2, 2, 109, 110, 7, 3, 2, 2, 110, 117, 7, 71, 2, 2, 111, 112, 12, 3, 2, 2, 112, 113, 7, 26, 2, 2, 113, 114, 5, 4, 3, 2, 114, 115, 7, 27, 2, 2, 115, 117, 3, 2, 2, 2, 116, 108, 3, 2, 2, 2, 116, 111, 3, 2, 2, 2, 117, 120, 3, 2, 2, 2, 118, 116, 3, 2, 2, 2, 118, 119, 3, 2, 2, 2, 119, 9, 3, 2, 2, 2, 120, 118, 3, 2, 2, 2, 121, 124, 5, 16, 9, 2, 122, 124, 5, 18, 10, 2, 123, 121, 3, 2, 2, 2, 123, 122, 3, 2, 2, 2, 124, 11, 3, 2, 2, 2, 125, 126, 7, 71, 2, 2, 126, 128, 7, 22, 2, 2, 127, 129, 5, 4, 3, 2, 128, 127, 3, 2, 2, 2, 128, 129, 3, 2, 2, 2, 129, 134, 3, 2, 2, 2, 130, 131, 7, 21, 2, 2, 131, 133, 5, 4, 3, 2, 132, 130, 3, 2, 2, 2, 133, 136, 3, 2, 2, 2, 134, 135, 3, 2, 2, 2, 134, 132, 3, 2, 2, 2, 135, 138, 3, 2, 2, 2, 136, 134, 3, 2, 2, 2, 137, 139, 7, 21, 2, 2, 138, 137, 3, 2, 2, 2, 138, 139, 3, 2, 2, 2, 139, 140, 3, 2, 2, 2, 140, 141, 7, 23, 2, 2, 141, 13, 3, 2, 2, 2, 142, 143, 9, 9, 2, 2, 143, 15, 3, 2, 2, 2, 144, 146, 7, 26, 2, 2, 145, 147, 5, 4, 3, 2, 146, 145, 3, 2, 2, 2, 146, 147, 3, 2, 2, 2, 147, 152, 3, 2, 2, 2, 148, 149, 7, 21, 2, 2, 149, 151, 5, 4, 3, 2, 150, 148, 3, 2, 2, 2, 151, 154, 3, 2, 2, 2, 152, 153, 3, 2, 2, 2, 152, 150, 3, 2, 2, 2, 153, 156, 3, 2, 2, 2, 154, 152, 3, 2, 2, 2, 155, 157, 7, 21, 2, 2, 156, 155, 3, 2, 2, 2, 156, 157, 3, 2, 2, 2, 157, 158, 3, 2, 2, 2, 158, 159, 7, 27, 2, 2, 159, 17, 3, 2, 2, 2, 160, 162, 7, 24, 2, 2, 161, 163, 5, 20, 11, 2, 162, 161, 3, 2, 2, 2, 162, 163, 3, 2, 2, 2, 163, 168, 3, 2, 2, 2, 164, 165, 7, 21, 2, 2, 165, 167, 5, 20, 11, 2, 166, 164, 3, 2, 2, 2, 167, 170, 3, 2, 2, 2, 168, 166, 3, 2, 2, 2, 168, 169, 3, 2, 2, 2, 169, 172, 3, 2, 2, 2, 170, 168, 3, 2, 2, 2, 171, 173, 7, 21, 2, 2, 172, 171, 3, 2, 2, 2, 172, 173, 3, 2, 2, 2, 173, 174, 3, 2, 2, 2, 174, 175, 7, 25, 2, 2, 175, 19, 3, 2, 2, 2, 176, 188, 7, 71, 2, 2, 177, 178, 5, 22, 12, 2, 178, 179, 7, 18, 2, 2, 179, 180, 5, 4, 3, 2, 180, 188, 3, 2, 2, 2, 181, 182, 7, 26, 2, 2, 182, 183, 5, 4, 3, 2, 183, 184, 7, 27, 2, 2, 184, 185, 7, 18, 2, 2, 185, 186, 5, 4, 3, 2, 186, 188, 3, 2, 2, 2, 187, 176, 3, 2, 2, 2, 187, 177, 3, 2, 2, 2, 187, 181, 3, 2, 2, 2, 188, 21, 3, 2, 2, 2, 189, 190, 9, 10, 2, 2, 190, 23, 3, 2, 2, 2, 22, 31, 47, 65, 85, 87, 96, 106, 116, 118, 123, 128, 134, 138, 146, 152, 156, 162, 168, 172, 187] \ No newline at end of file diff --git a/ui/src/suggestions/grammar/CAQLParser.js b/ui/src/suggestions/grammar/CAQLParser.js new file mode 100644 index 0000000..fc295fe --- /dev/null +++ b/ui/src/suggestions/grammar/CAQLParser.js @@ -0,0 +1,1866 @@ +// Generated from CAQLParser.g4 by ANTLR 4.9.2 +// jshint ignore: start +import antlr4 from 'antlr4'; +import CAQLParserListener from './CAQLParserListener.js'; + +const serializedATN = ["\u0003\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786", + "\u5964\u0003P\u00c0\u0004\u0002\t\u0002\u0004\u0003\t\u0003\u0004\u0004", + "\t\u0004\u0004\u0005\t\u0005\u0004\u0006\t\u0006\u0004\u0007\t\u0007", + "\u0004\b\t\b\u0004\t\t\t\u0004\n\t\n\u0004\u000b\t\u000b\u0004\f\t\f", + "\u0003\u0002\u0003\u0002\u0003\u0002\u0003\u0003\u0003\u0003\u0003\u0003", + "\u0003\u0003\u0005\u0003 \n\u0003\u0003\u0003\u0003\u0003\u0003\u0003", + "\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003", + "\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0005\u0003", + "0\n\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003", + "\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003", + "\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0005\u0003", + "B\n\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003", + "\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003", + "\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003", + "\u0003\u0003\u0007\u0003V\n\u0003\f\u0003\u000e\u0003Y\u000b\u0003\u0003", + "\u0004\u0003\u0004\u0003\u0004\u0003\u0004\u0003\u0004\u0003\u0004\u0005", + "\u0004a\n\u0004\u0003\u0005\u0003\u0005\u0003\u0005\u0003\u0005\u0003", + "\u0005\u0003\u0005\u0003\u0005\u0003\u0005\u0005\u0005k\n\u0005\u0003", + "\u0005\u0003\u0005\u0003\u0005\u0003\u0005\u0003\u0005\u0003\u0005\u0003", + "\u0005\u0003\u0005\u0007\u0005u\n\u0005\f\u0005\u000e\u0005x\u000b\u0005", + "\u0003\u0006\u0003\u0006\u0005\u0006|\n\u0006\u0003\u0007\u0003\u0007", + "\u0003\u0007\u0005\u0007\u0081\n\u0007\u0003\u0007\u0003\u0007\u0007", + "\u0007\u0085\n\u0007\f\u0007\u000e\u0007\u0088\u000b\u0007\u0003\u0007", + "\u0005\u0007\u008b\n\u0007\u0003\u0007\u0003\u0007\u0003\b\u0003\b\u0003", + "\t\u0003\t\u0005\t\u0093\n\t\u0003\t\u0003\t\u0007\t\u0097\n\t\f\t\u000e", + "\t\u009a\u000b\t\u0003\t\u0005\t\u009d\n\t\u0003\t\u0003\t\u0003\n\u0003", + "\n\u0005\n\u00a3\n\n\u0003\n\u0003\n\u0007\n\u00a7\n\n\f\n\u000e\n\u00aa", + "\u000b\n\u0003\n\u0005\n\u00ad\n\n\u0003\n\u0003\n\u0003\u000b\u0003", + "\u000b\u0003\u000b\u0003\u000b\u0003\u000b\u0003\u000b\u0003\u000b\u0003", + "\u000b\u0003\u000b\u0003\u000b\u0003\u000b\u0005\u000b\u00bc\n\u000b", + "\u0003\f\u0003\f\u0003\f\u0004\u0086\u0098\u0004\u0004\b\r\u0002\u0004", + "\u0006\b\n\f\u000e\u0010\u0012\u0014\u0016\u0002\u000b\u0003\u0002\f", + "\r\u0003\u0002\u000e\u0010\u0003\u0002\b\u000b\u0003\u0002\u0006\u0007", + "\u0005\u0002\u001d\u001d\u001f\u001f00\u0004\u0002\u0006\u000b((\u0004", + "\u0002\u0004\u0005..\u0007\u0002$$22::HIKK\u0004\u0002GGKK\u0002\u00d8", + "\u0002\u0018\u0003\u0002\u0002\u0002\u0004\u001f\u0003\u0002\u0002\u0002", + "\u0006`\u0003\u0002\u0002\u0002\bj\u0003\u0002\u0002\u0002\n{\u0003", + "\u0002\u0002\u0002\f}\u0003\u0002\u0002\u0002\u000e\u008e\u0003\u0002", + "\u0002\u0002\u0010\u0090\u0003\u0002\u0002\u0002\u0012\u00a0\u0003\u0002", + "\u0002\u0002\u0014\u00bb\u0003\u0002\u0002\u0002\u0016\u00bd\u0003\u0002", + "\u0002\u0002\u0018\u0019\u0005\u0004\u0003\u0002\u0019\u001a\u0007\u0002", + "\u0002\u0003\u001a\u0003\u0003\u0002\u0002\u0002\u001b\u001c\b\u0003", + "\u0001\u0002\u001c \u0005\u000e\b\u0002\u001d \u0005\b\u0005\u0002\u001e", + " \u0005\u0006\u0004\u0002\u001f\u001b\u0003\u0002\u0002\u0002\u001f", + "\u001d\u0003\u0002\u0002\u0002\u001f\u001e\u0003\u0002\u0002\u0002 ", + "W\u0003\u0002\u0002\u0002!\"\f\u000f\u0002\u0002\"#\t\u0002\u0002\u0002", + "#V\u0005\u0004\u0003\u0010$%\f\u000e\u0002\u0002%&\t\u0003\u0002\u0002", + "&V\u0005\u0004\u0003\u000f\'(\f\r\u0002\u0002()\u0007\u0014\u0002\u0002", + ")V\u0005\u0004\u0003\u000e*+\f\f\u0002\u0002+,\t\u0004\u0002\u0002,", + "V\u0005\u0004\u0003\r-/\f\u000b\u0002\u0002.0\u00071\u0002\u0002/.\u0003", + "\u0002\u0002\u0002/0\u0003\u0002\u0002\u000201\u0003\u0002\u0002\u0002", + "12\u0007(\u0002\u00022V\u0005\u0004\u0003\f34\f\n\u0002\u000245\t\u0005", + "\u0002\u00025V\u0005\u0004\u0003\u000b67\f\t\u0002\u000278\t\u0006\u0002", + "\u000289\t\u0007\u0002\u00029V\u0005\u0004\u0003\n:;\f\b\u0002\u0002", + ";<\t\u0006\u0002\u0002<=\u00071\u0002\u0002=>\u0007(\u0002\u0002>V\u0005", + "\u0004\u0003\t?A\f\u0007\u0002\u0002@B\u00071\u0002\u0002A@\u0003\u0002", + "\u0002\u0002AB\u0003\u0002\u0002\u0002BC\u0003\u0002\u0002\u0002CD\t", + "\b\u0002\u0002DV\u0005\u0004\u0003\bEF\f\u0006\u0002\u0002FG\u0007\u001e", + "\u0002\u0002GV\u0005\u0004\u0003\u0007HI\f\u0005\u0002\u0002IJ\u0007", + "3\u0002\u0002JV\u0005\u0004\u0003\u0006KL\f\u0004\u0002\u0002LM\u0007", + "\u0011\u0002\u0002MN\u0005\u0004\u0003\u0002NO\u0007\u0012\u0002\u0002", + "OP\u0005\u0004\u0003\u0005PV\u0003\u0002\u0002\u0002QR\f\u0003\u0002", + "\u0002RS\u0007\u0011\u0002\u0002ST\u0007\u0012\u0002\u0002TV\u0005\u0004", + "\u0003\u0004U!\u0003\u0002\u0002\u0002U$\u0003\u0002\u0002\u0002U\'", + "\u0003\u0002\u0002\u0002U*\u0003\u0002\u0002\u0002U-\u0003\u0002\u0002", + "\u0002U3\u0003\u0002\u0002\u0002U6\u0003\u0002\u0002\u0002U:\u0003\u0002", + "\u0002\u0002U?\u0003\u0002\u0002\u0002UE\u0003\u0002\u0002\u0002UH\u0003", + "\u0002\u0002\u0002UK\u0003\u0002\u0002\u0002UQ\u0003\u0002\u0002\u0002", + "VY\u0003\u0002\u0002\u0002WU\u0003\u0002\u0002\u0002WX\u0003\u0002\u0002", + "\u0002X\u0005\u0003\u0002\u0002\u0002YW\u0003\u0002\u0002\u0002Z[\u0007", + "\f\u0002\u0002[a\u0005\u0004\u0003\u0002\\]\u0007\r\u0002\u0002]a\u0005", + "\u0004\u0003\u0002^_\u00071\u0002\u0002_a\u0005\u0004\u0003\u0002`Z", + "\u0003\u0002\u0002\u0002`\\\u0003\u0002\u0002\u0002`^\u0003\u0002\u0002", + "\u0002a\u0007\u0003\u0002\u0002\u0002bc\b\u0005\u0001\u0002ck\u0007", + "G\u0002\u0002dk\u0005\n\u0006\u0002ek\u0005\f\u0007\u0002fg\u0007\u0016", + "\u0002\u0002gh\u0005\u0004\u0003\u0002hi\u0007\u0017\u0002\u0002ik\u0003", + "\u0002\u0002\u0002jb\u0003\u0002\u0002\u0002jd\u0003\u0002\u0002\u0002", + "je\u0003\u0002\u0002\u0002jf\u0003\u0002\u0002\u0002kv\u0003\u0002\u0002", + "\u0002lm\f\u0004\u0002\u0002mn\u0007\u0003\u0002\u0002nu\u0007G\u0002", + "\u0002op\f\u0003\u0002\u0002pq\u0007\u001a\u0002\u0002qr\u0005\u0004", + "\u0003\u0002rs\u0007\u001b\u0002\u0002su\u0003\u0002\u0002\u0002tl\u0003", + "\u0002\u0002\u0002to\u0003\u0002\u0002\u0002ux\u0003\u0002\u0002\u0002", + "vt\u0003\u0002\u0002\u0002vw\u0003\u0002\u0002\u0002w\t\u0003\u0002", + "\u0002\u0002xv\u0003\u0002\u0002\u0002y|\u0005\u0010\t\u0002z|\u0005", + "\u0012\n\u0002{y\u0003\u0002\u0002\u0002{z\u0003\u0002\u0002\u0002|", + "\u000b\u0003\u0002\u0002\u0002}~\u0007G\u0002\u0002~\u0080\u0007\u0016", + "\u0002\u0002\u007f\u0081\u0005\u0004\u0003\u0002\u0080\u007f\u0003\u0002", + "\u0002\u0002\u0080\u0081\u0003\u0002\u0002\u0002\u0081\u0086\u0003\u0002", + "\u0002\u0002\u0082\u0083\u0007\u0015\u0002\u0002\u0083\u0085\u0005\u0004", + "\u0003\u0002\u0084\u0082\u0003\u0002\u0002\u0002\u0085\u0088\u0003\u0002", + "\u0002\u0002\u0086\u0087\u0003\u0002\u0002\u0002\u0086\u0084\u0003\u0002", + "\u0002\u0002\u0087\u008a\u0003\u0002\u0002\u0002\u0088\u0086\u0003\u0002", + "\u0002\u0002\u0089\u008b\u0007\u0015\u0002\u0002\u008a\u0089\u0003\u0002", + "\u0002\u0002\u008a\u008b\u0003\u0002\u0002\u0002\u008b\u008c\u0003\u0002", + "\u0002\u0002\u008c\u008d\u0007\u0017\u0002\u0002\u008d\r\u0003\u0002", + "\u0002\u0002\u008e\u008f\t\t\u0002\u0002\u008f\u000f\u0003\u0002\u0002", + "\u0002\u0090\u0092\u0007\u001a\u0002\u0002\u0091\u0093\u0005\u0004\u0003", + "\u0002\u0092\u0091\u0003\u0002\u0002\u0002\u0092\u0093\u0003\u0002\u0002", + "\u0002\u0093\u0098\u0003\u0002\u0002\u0002\u0094\u0095\u0007\u0015\u0002", + "\u0002\u0095\u0097\u0005\u0004\u0003\u0002\u0096\u0094\u0003\u0002\u0002", + "\u0002\u0097\u009a\u0003\u0002\u0002\u0002\u0098\u0099\u0003\u0002\u0002", + "\u0002\u0098\u0096\u0003\u0002\u0002\u0002\u0099\u009c\u0003\u0002\u0002", + "\u0002\u009a\u0098\u0003\u0002\u0002\u0002\u009b\u009d\u0007\u0015\u0002", + "\u0002\u009c\u009b\u0003\u0002\u0002\u0002\u009c\u009d\u0003\u0002\u0002", + "\u0002\u009d\u009e\u0003\u0002\u0002\u0002\u009e\u009f\u0007\u001b\u0002", + "\u0002\u009f\u0011\u0003\u0002\u0002\u0002\u00a0\u00a2\u0007\u0018\u0002", + "\u0002\u00a1\u00a3\u0005\u0014\u000b\u0002\u00a2\u00a1\u0003\u0002\u0002", + "\u0002\u00a2\u00a3\u0003\u0002\u0002\u0002\u00a3\u00a8\u0003\u0002\u0002", + "\u0002\u00a4\u00a5\u0007\u0015\u0002\u0002\u00a5\u00a7\u0005\u0014\u000b", + "\u0002\u00a6\u00a4\u0003\u0002\u0002\u0002\u00a7\u00aa\u0003\u0002\u0002", + "\u0002\u00a8\u00a6\u0003\u0002\u0002\u0002\u00a8\u00a9\u0003\u0002\u0002", + "\u0002\u00a9\u00ac\u0003\u0002\u0002\u0002\u00aa\u00a8\u0003\u0002\u0002", + "\u0002\u00ab\u00ad\u0007\u0015\u0002\u0002\u00ac\u00ab\u0003\u0002\u0002", + "\u0002\u00ac\u00ad\u0003\u0002\u0002\u0002\u00ad\u00ae\u0003\u0002\u0002", + "\u0002\u00ae\u00af\u0007\u0019\u0002\u0002\u00af\u0013\u0003\u0002\u0002", + "\u0002\u00b0\u00bc\u0007G\u0002\u0002\u00b1\u00b2\u0005\u0016\f\u0002", + "\u00b2\u00b3\u0007\u0012\u0002\u0002\u00b3\u00b4\u0005\u0004\u0003\u0002", + "\u00b4\u00bc\u0003\u0002\u0002\u0002\u00b5\u00b6\u0007\u001a\u0002\u0002", + "\u00b6\u00b7\u0005\u0004\u0003\u0002\u00b7\u00b8\u0007\u001b\u0002\u0002", + "\u00b8\u00b9\u0007\u0012\u0002\u0002\u00b9\u00ba\u0005\u0004\u0003\u0002", + "\u00ba\u00bc\u0003\u0002\u0002\u0002\u00bb\u00b0\u0003\u0002\u0002\u0002", + "\u00bb\u00b1\u0003\u0002\u0002\u0002\u00bb\u00b5\u0003\u0002\u0002\u0002", + "\u00bc\u0015\u0003\u0002\u0002\u0002\u00bd\u00be\t\n\u0002\u0002\u00be", + "\u0017\u0003\u0002\u0002\u0002\u0016\u001f/AUW`jtv{\u0080\u0086\u008a", + "\u0092\u0098\u009c\u00a2\u00a8\u00ac\u00bb"].join(""); + + +const atn = new antlr4.atn.ATNDeserializer().deserialize(serializedATN); + +const decisionsToDFA = atn.decisionToState.map( (ds, index) => new antlr4.dfa.DFA(ds, index) ); + +const sharedContextCache = new antlr4.PredictionContextCache(); + +export default class CAQLParser extends antlr4.Parser { + + static grammarFileName = "CAQLParser.g4"; + static literalNames = [ null, "'.'", "'=~'", "'!~'", "'=='", "'!='", + "'<'", "'>'", "'<='", "'>='", "'+'", "'-'", + "'*'", "'/'", "'%'", "'?'", "':'", "'::'", "'..'", + "','", "'('", "')'", "'{'", "'}'", "'['", "']'" ]; + static symbolicNames = [ null, "DOT", "T_REGEX_MATCH", "T_REGEX_NON_MATCH", + "T_EQ", "T_NE", "T_LT", "T_GT", "T_LE", "T_GE", + "T_PLUS", "T_MINUS", "T_TIMES", "T_DIV", "T_MOD", + "T_QUESTION", "T_COLON", "T_SCOPE", "T_RANGE", + "T_COMMA", "T_OPEN", "T_CLOSE", "T_OBJECT_OPEN", + "T_OBJECT_CLOSE", "T_ARRAY_OPEN", "T_ARRAY_CLOSE", + "T_AGGREGATE", "T_ALL", "T_AND", "T_ANY", "T_ASC", + "T_COLLECT", "T_DESC", "T_DISTINCT", "T_FALSE", + "T_FILTER", "T_FOR", "T_GRAPH", "T_IN", "T_INBOUND", + "T_INSERT", "T_INTO", "T_K_SHORTEST_PATHS", + "T_LET", "T_LIKE", "T_LIMIT", "T_NONE", "T_NOT", + "T_NULL", "T_OR", "T_OUTBOUND", "T_REMOVE", + "T_REPLACE", "T_RETURN", "T_SHORTEST_PATH", + "T_SORT", "T_TRUE", "T_UPDATE", "T_UPSERT", + "T_WITH", "T_KEEP", "T_COUNT", "T_OPTIONS", + "T_PRUNE", "T_SEARCH", "T_TO", "T_CURRENT", + "T_NEW", "T_OLD", "T_STRING", "T_INT", "T_FLOAT", + "T_PARAMETER", "T_QUOTED_STRING", "SINGLE_LINE_COMMENT", + "MULTILINE_COMMENT", "SPACES", "UNEXPECTED_CHAR", + "ERROR_RECONGNIGION" ]; + static ruleNames = [ "parse", "expression", "operator_unary", "reference", + "compound_value", "function_call", "value_literal", + "array", "object", "object_element", "object_element_name" ]; + + constructor(input) { + super(input); + this._interp = new antlr4.atn.ParserATNSimulator(this, atn, decisionsToDFA, sharedContextCache); + this.ruleNames = CAQLParser.ruleNames; + this.literalNames = CAQLParser.literalNames; + this.symbolicNames = CAQLParser.symbolicNames; + } + + get atn() { + return atn; + } + + sempred(localctx, ruleIndex, predIndex) { + switch(ruleIndex) { + case 1: + return this.expression_sempred(localctx, predIndex); + case 3: + return this.reference_sempred(localctx, predIndex); + default: + throw "No predicate with index:" + ruleIndex; + } + } + + expression_sempred(localctx, predIndex) { + switch(predIndex) { + case 0: + return this.precpred(this._ctx, 13); + case 1: + return this.precpred(this._ctx, 12); + case 2: + return this.precpred(this._ctx, 11); + case 3: + return this.precpred(this._ctx, 10); + case 4: + return this.precpred(this._ctx, 9); + case 5: + return this.precpred(this._ctx, 8); + case 6: + return this.precpred(this._ctx, 7); + case 7: + return this.precpred(this._ctx, 6); + case 8: + return this.precpred(this._ctx, 5); + case 9: + return this.precpred(this._ctx, 4); + case 10: + return this.precpred(this._ctx, 3); + case 11: + return this.precpred(this._ctx, 2); + case 12: + return this.precpred(this._ctx, 1); + default: + throw "No predicate with index:" + predIndex; + } + }; + + reference_sempred(localctx, predIndex) { + switch(predIndex) { + case 13: + return this.precpred(this._ctx, 2); + case 14: + return this.precpred(this._ctx, 1); + default: + throw "No predicate with index:" + predIndex; + } + }; + + + + + parse() { + let localctx = new ParseContext(this, this._ctx, this.state); + this.enterRule(localctx, 0, CAQLParser.RULE_parse); + try { + this.enterOuterAlt(localctx, 1); + this.state = 22; + this.expression(0); + this.state = 23; + this.match(CAQLParser.EOF); + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; + } + + + expression(_p) { + if(_p===undefined) { + _p = 0; + } + const _parentctx = this._ctx; + const _parentState = this.state; + let localctx = new ExpressionContext(this, this._ctx, _parentState); + let _prevctx = localctx; + const _startState = 2; + this.enterRecursionRule(localctx, 2, CAQLParser.RULE_expression, _p); + var _la = 0; // Token type + try { + this.enterOuterAlt(localctx, 1); + this.state = 29; + this._errHandler.sync(this); + switch(this._input.LA(1)) { + case CAQLParser.T_FALSE: + case CAQLParser.T_NULL: + case CAQLParser.T_TRUE: + case CAQLParser.T_INT: + case CAQLParser.T_FLOAT: + case CAQLParser.T_QUOTED_STRING: + this.state = 26; + this.value_literal(); + break; + case CAQLParser.T_OPEN: + case CAQLParser.T_OBJECT_OPEN: + case CAQLParser.T_ARRAY_OPEN: + case CAQLParser.T_STRING: + this.state = 27; + this.reference(0); + break; + case CAQLParser.T_PLUS: + case CAQLParser.T_MINUS: + case CAQLParser.T_NOT: + this.state = 28; + this.operator_unary(); + break; + default: + throw new antlr4.error.NoViableAltException(this); + } + this._ctx.stop = this._input.LT(-1); + this.state = 85; + this._errHandler.sync(this); + var _alt = this._interp.adaptivePredict(this._input,4,this._ctx) + while(_alt!=2 && _alt!=antlr4.atn.ATN.INVALID_ALT_NUMBER) { + if(_alt===1) { + if(this._parseListeners!==null) { + this.triggerExitRuleEvent(); + } + _prevctx = localctx; + this.state = 83; + this._errHandler.sync(this); + var la_ = this._interp.adaptivePredict(this._input,3,this._ctx); + switch(la_) { + case 1: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 31; + if (!( this.precpred(this._ctx, 13))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 13)"); + } + this.state = 32; + _la = this._input.LA(1); + if(!(_la===CAQLParser.T_PLUS || _la===CAQLParser.T_MINUS)) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + this.state = 33; + this.expression(14); + break; + + case 2: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 34; + if (!( this.precpred(this._ctx, 12))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 12)"); + } + this.state = 35; + _la = this._input.LA(1); + if(!((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << CAQLParser.T_TIMES) | (1 << CAQLParser.T_DIV) | (1 << CAQLParser.T_MOD))) !== 0))) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + this.state = 36; + this.expression(13); + break; + + case 3: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 37; + if (!( this.precpred(this._ctx, 11))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 11)"); + } + this.state = 38; + this.match(CAQLParser.T_RANGE); + this.state = 39; + this.expression(12); + break; + + case 4: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 40; + if (!( this.precpred(this._ctx, 10))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 10)"); + } + this.state = 41; + _la = this._input.LA(1); + if(!((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << CAQLParser.T_LT) | (1 << CAQLParser.T_GT) | (1 << CAQLParser.T_LE) | (1 << CAQLParser.T_GE))) !== 0))) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + this.state = 42; + this.expression(11); + break; + + case 5: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 43; + if (!( this.precpred(this._ctx, 9))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 9)"); + } + this.state = 45; + this._errHandler.sync(this); + _la = this._input.LA(1); + if(_la===CAQLParser.T_NOT) { + this.state = 44; + this.match(CAQLParser.T_NOT); + } + + this.state = 47; + this.match(CAQLParser.T_IN); + this.state = 48; + this.expression(10); + break; + + case 6: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 49; + if (!( this.precpred(this._ctx, 8))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 8)"); + } + this.state = 50; + _la = this._input.LA(1); + if(!(_la===CAQLParser.T_EQ || _la===CAQLParser.T_NE)) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + this.state = 51; + this.expression(9); + break; + + case 7: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 52; + if (!( this.precpred(this._ctx, 7))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 7)"); + } + this.state = 53; + _la = this._input.LA(1); + if(!(((((_la - 27)) & ~0x1f) == 0 && ((1 << (_la - 27)) & ((1 << (CAQLParser.T_ALL - 27)) | (1 << (CAQLParser.T_ANY - 27)) | (1 << (CAQLParser.T_NONE - 27)))) !== 0))) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + this.state = 54; + localctx.eq_op = this._input.LT(1); + _la = this._input.LA(1); + if(!((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << CAQLParser.T_EQ) | (1 << CAQLParser.T_NE) | (1 << CAQLParser.T_LT) | (1 << CAQLParser.T_GT) | (1 << CAQLParser.T_LE) | (1 << CAQLParser.T_GE))) !== 0) || _la===CAQLParser.T_IN)) { + localctx.eq_op = this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + this.state = 55; + this.expression(8); + break; + + case 8: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 56; + if (!( this.precpred(this._ctx, 6))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 6)"); + } + this.state = 57; + _la = this._input.LA(1); + if(!(((((_la - 27)) & ~0x1f) == 0 && ((1 << (_la - 27)) & ((1 << (CAQLParser.T_ALL - 27)) | (1 << (CAQLParser.T_ANY - 27)) | (1 << (CAQLParser.T_NONE - 27)))) !== 0))) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + this.state = 58; + this.match(CAQLParser.T_NOT); + this.state = 59; + this.match(CAQLParser.T_IN); + this.state = 60; + this.expression(7); + break; + + case 9: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 61; + if (!( this.precpred(this._ctx, 5))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 5)"); + } + this.state = 63; + this._errHandler.sync(this); + _la = this._input.LA(1); + if(_la===CAQLParser.T_NOT) { + this.state = 62; + this.match(CAQLParser.T_NOT); + } + + this.state = 65; + _la = this._input.LA(1); + if(!(_la===CAQLParser.T_REGEX_MATCH || _la===CAQLParser.T_REGEX_NON_MATCH || _la===CAQLParser.T_LIKE)) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + this.state = 66; + this.expression(6); + break; + + case 10: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 67; + if (!( this.precpred(this._ctx, 4))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 4)"); + } + this.state = 68; + this.match(CAQLParser.T_AND); + this.state = 69; + this.expression(5); + break; + + case 11: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 70; + if (!( this.precpred(this._ctx, 3))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 3)"); + } + this.state = 71; + this.match(CAQLParser.T_OR); + this.state = 72; + this.expression(4); + break; + + case 12: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 73; + if (!( this.precpred(this._ctx, 2))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 2)"); + } + this.state = 74; + this.match(CAQLParser.T_QUESTION); + this.state = 75; + this.expression(0); + this.state = 76; + this.match(CAQLParser.T_COLON); + this.state = 77; + this.expression(3); + break; + + case 13: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 79; + if (!( this.precpred(this._ctx, 1))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 1)"); + } + this.state = 80; + this.match(CAQLParser.T_QUESTION); + this.state = 81; + this.match(CAQLParser.T_COLON); + this.state = 82; + this.expression(2); + break; + + } + } + this.state = 87; + this._errHandler.sync(this); + _alt = this._interp.adaptivePredict(this._input,4,this._ctx); + } + + } catch( error) { + if(error instanceof antlr4.error.RecognitionException) { + localctx.exception = error; + this._errHandler.reportError(this, error); + this._errHandler.recover(this, error); + } else { + throw error; + } + } finally { + this.unrollRecursionContexts(_parentctx) + } + return localctx; + } + + + + operator_unary() { + let localctx = new Operator_unaryContext(this, this._ctx, this.state); + this.enterRule(localctx, 4, CAQLParser.RULE_operator_unary); + try { + this.enterOuterAlt(localctx, 1); + this.state = 94; + this._errHandler.sync(this); + switch(this._input.LA(1)) { + case CAQLParser.T_PLUS: + this.state = 88; + this.match(CAQLParser.T_PLUS); + this.state = 89; + this.expression(0); + break; + case CAQLParser.T_MINUS: + this.state = 90; + this.match(CAQLParser.T_MINUS); + this.state = 91; + this.expression(0); + break; + case CAQLParser.T_NOT: + this.state = 92; + this.match(CAQLParser.T_NOT); + this.state = 93; + this.expression(0); + break; + default: + throw new antlr4.error.NoViableAltException(this); + } + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; + } + + + reference(_p) { + if(_p===undefined) { + _p = 0; + } + const _parentctx = this._ctx; + const _parentState = this.state; + let localctx = new ReferenceContext(this, this._ctx, _parentState); + let _prevctx = localctx; + const _startState = 6; + this.enterRecursionRule(localctx, 6, CAQLParser.RULE_reference, _p); + try { + this.enterOuterAlt(localctx, 1); + this.state = 104; + this._errHandler.sync(this); + var la_ = this._interp.adaptivePredict(this._input,6,this._ctx); + switch(la_) { + case 1: + this.state = 97; + this.match(CAQLParser.T_STRING); + break; + + case 2: + this.state = 98; + this.compound_value(); + break; + + case 3: + this.state = 99; + this.function_call(); + break; + + case 4: + this.state = 100; + this.match(CAQLParser.T_OPEN); + this.state = 101; + this.expression(0); + this.state = 102; + this.match(CAQLParser.T_CLOSE); + break; + + } + this._ctx.stop = this._input.LT(-1); + this.state = 116; + this._errHandler.sync(this); + var _alt = this._interp.adaptivePredict(this._input,8,this._ctx) + while(_alt!=2 && _alt!=antlr4.atn.ATN.INVALID_ALT_NUMBER) { + if(_alt===1) { + if(this._parseListeners!==null) { + this.triggerExitRuleEvent(); + } + _prevctx = localctx; + this.state = 114; + this._errHandler.sync(this); + var la_ = this._interp.adaptivePredict(this._input,7,this._ctx); + switch(la_) { + case 1: + localctx = new ReferenceContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_reference); + this.state = 106; + if (!( this.precpred(this._ctx, 2))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 2)"); + } + this.state = 107; + this.match(CAQLParser.DOT); + this.state = 108; + this.match(CAQLParser.T_STRING); + break; + + case 2: + localctx = new ReferenceContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_reference); + this.state = 109; + if (!( this.precpred(this._ctx, 1))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 1)"); + } + this.state = 110; + this.match(CAQLParser.T_ARRAY_OPEN); + this.state = 111; + this.expression(0); + this.state = 112; + this.match(CAQLParser.T_ARRAY_CLOSE); + break; + + } + } + this.state = 118; + this._errHandler.sync(this); + _alt = this._interp.adaptivePredict(this._input,8,this._ctx); + } + + } catch( error) { + if(error instanceof antlr4.error.RecognitionException) { + localctx.exception = error; + this._errHandler.reportError(this, error); + this._errHandler.recover(this, error); + } else { + throw error; + } + } finally { + this.unrollRecursionContexts(_parentctx) + } + return localctx; + } + + + + compound_value() { + let localctx = new Compound_valueContext(this, this._ctx, this.state); + this.enterRule(localctx, 8, CAQLParser.RULE_compound_value); + try { + this.enterOuterAlt(localctx, 1); + this.state = 121; + this._errHandler.sync(this); + switch(this._input.LA(1)) { + case CAQLParser.T_ARRAY_OPEN: + this.state = 119; + this.array(); + break; + case CAQLParser.T_OBJECT_OPEN: + this.state = 120; + this.object(); + break; + default: + throw new antlr4.error.NoViableAltException(this); + } + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; + } + + + + function_call() { + let localctx = new Function_callContext(this, this._ctx, this.state); + this.enterRule(localctx, 10, CAQLParser.RULE_function_call); + var _la = 0; // Token type + try { + this.enterOuterAlt(localctx, 1); + this.state = 123; + this.match(CAQLParser.T_STRING); + this.state = 124; + this.match(CAQLParser.T_OPEN); + this.state = 126; + this._errHandler.sync(this); + _la = this._input.LA(1); + if(((((_la - 10)) & ~0x1f) == 0 && ((1 << (_la - 10)) & ((1 << (CAQLParser.T_PLUS - 10)) | (1 << (CAQLParser.T_MINUS - 10)) | (1 << (CAQLParser.T_OPEN - 10)) | (1 << (CAQLParser.T_OBJECT_OPEN - 10)) | (1 << (CAQLParser.T_ARRAY_OPEN - 10)) | (1 << (CAQLParser.T_FALSE - 10)))) !== 0) || ((((_la - 47)) & ~0x1f) == 0 && ((1 << (_la - 47)) & ((1 << (CAQLParser.T_NOT - 47)) | (1 << (CAQLParser.T_NULL - 47)) | (1 << (CAQLParser.T_TRUE - 47)) | (1 << (CAQLParser.T_STRING - 47)) | (1 << (CAQLParser.T_INT - 47)) | (1 << (CAQLParser.T_FLOAT - 47)) | (1 << (CAQLParser.T_QUOTED_STRING - 47)))) !== 0)) { + this.state = 125; + this.expression(0); + } + + this.state = 132; + this._errHandler.sync(this); + var _alt = this._interp.adaptivePredict(this._input,11,this._ctx) + while(_alt!=1 && _alt!=antlr4.atn.ATN.INVALID_ALT_NUMBER) { + if(_alt===1+1) { + this.state = 128; + this.match(CAQLParser.T_COMMA); + this.state = 129; + this.expression(0); + } + this.state = 134; + this._errHandler.sync(this); + _alt = this._interp.adaptivePredict(this._input,11,this._ctx); + } + + this.state = 136; + this._errHandler.sync(this); + _la = this._input.LA(1); + if(_la===CAQLParser.T_COMMA) { + this.state = 135; + this.match(CAQLParser.T_COMMA); + } + + this.state = 138; + this.match(CAQLParser.T_CLOSE); + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; + } + + + + value_literal() { + let localctx = new Value_literalContext(this, this._ctx, this.state); + this.enterRule(localctx, 12, CAQLParser.RULE_value_literal); + var _la = 0; // Token type + try { + this.enterOuterAlt(localctx, 1); + this.state = 140; + _la = this._input.LA(1); + if(!(((((_la - 34)) & ~0x1f) == 0 && ((1 << (_la - 34)) & ((1 << (CAQLParser.T_FALSE - 34)) | (1 << (CAQLParser.T_NULL - 34)) | (1 << (CAQLParser.T_TRUE - 34)))) !== 0) || ((((_la - 70)) & ~0x1f) == 0 && ((1 << (_la - 70)) & ((1 << (CAQLParser.T_INT - 70)) | (1 << (CAQLParser.T_FLOAT - 70)) | (1 << (CAQLParser.T_QUOTED_STRING - 70)))) !== 0))) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; + } + + + + array() { + let localctx = new ArrayContext(this, this._ctx, this.state); + this.enterRule(localctx, 14, CAQLParser.RULE_array); + var _la = 0; // Token type + try { + this.enterOuterAlt(localctx, 1); + this.state = 142; + this.match(CAQLParser.T_ARRAY_OPEN); + this.state = 144; + this._errHandler.sync(this); + _la = this._input.LA(1); + if(((((_la - 10)) & ~0x1f) == 0 && ((1 << (_la - 10)) & ((1 << (CAQLParser.T_PLUS - 10)) | (1 << (CAQLParser.T_MINUS - 10)) | (1 << (CAQLParser.T_OPEN - 10)) | (1 << (CAQLParser.T_OBJECT_OPEN - 10)) | (1 << (CAQLParser.T_ARRAY_OPEN - 10)) | (1 << (CAQLParser.T_FALSE - 10)))) !== 0) || ((((_la - 47)) & ~0x1f) == 0 && ((1 << (_la - 47)) & ((1 << (CAQLParser.T_NOT - 47)) | (1 << (CAQLParser.T_NULL - 47)) | (1 << (CAQLParser.T_TRUE - 47)) | (1 << (CAQLParser.T_STRING - 47)) | (1 << (CAQLParser.T_INT - 47)) | (1 << (CAQLParser.T_FLOAT - 47)) | (1 << (CAQLParser.T_QUOTED_STRING - 47)))) !== 0)) { + this.state = 143; + this.expression(0); + } + + this.state = 150; + this._errHandler.sync(this); + var _alt = this._interp.adaptivePredict(this._input,14,this._ctx) + while(_alt!=1 && _alt!=antlr4.atn.ATN.INVALID_ALT_NUMBER) { + if(_alt===1+1) { + this.state = 146; + this.match(CAQLParser.T_COMMA); + this.state = 147; + this.expression(0); + } + this.state = 152; + this._errHandler.sync(this); + _alt = this._interp.adaptivePredict(this._input,14,this._ctx); + } + + this.state = 154; + this._errHandler.sync(this); + _la = this._input.LA(1); + if(_la===CAQLParser.T_COMMA) { + this.state = 153; + this.match(CAQLParser.T_COMMA); + } + + this.state = 156; + this.match(CAQLParser.T_ARRAY_CLOSE); + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; + } + + + + object() { + let localctx = new ObjectContext(this, this._ctx, this.state); + this.enterRule(localctx, 16, CAQLParser.RULE_object); + var _la = 0; // Token type + try { + this.enterOuterAlt(localctx, 1); + this.state = 158; + this.match(CAQLParser.T_OBJECT_OPEN); + this.state = 160; + this._errHandler.sync(this); + _la = this._input.LA(1); + if(_la===CAQLParser.T_ARRAY_OPEN || _la===CAQLParser.T_STRING || _la===CAQLParser.T_QUOTED_STRING) { + this.state = 159; + this.object_element(); + } + + this.state = 166; + this._errHandler.sync(this); + var _alt = this._interp.adaptivePredict(this._input,17,this._ctx) + while(_alt!=2 && _alt!=antlr4.atn.ATN.INVALID_ALT_NUMBER) { + if(_alt===1) { + this.state = 162; + this.match(CAQLParser.T_COMMA); + this.state = 163; + this.object_element(); + } + this.state = 168; + this._errHandler.sync(this); + _alt = this._interp.adaptivePredict(this._input,17,this._ctx); + } + + this.state = 170; + this._errHandler.sync(this); + _la = this._input.LA(1); + if(_la===CAQLParser.T_COMMA) { + this.state = 169; + this.match(CAQLParser.T_COMMA); + } + + this.state = 172; + this.match(CAQLParser.T_OBJECT_CLOSE); + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; + } + + + + object_element() { + let localctx = new Object_elementContext(this, this._ctx, this.state); + this.enterRule(localctx, 18, CAQLParser.RULE_object_element); + try { + this.enterOuterAlt(localctx, 1); + this.state = 185; + this._errHandler.sync(this); + var la_ = this._interp.adaptivePredict(this._input,19,this._ctx); + switch(la_) { + case 1: + this.state = 174; + this.match(CAQLParser.T_STRING); + break; + + case 2: + this.state = 175; + this.object_element_name(); + this.state = 176; + this.match(CAQLParser.T_COLON); + this.state = 177; + this.expression(0); + break; + + case 3: + this.state = 179; + this.match(CAQLParser.T_ARRAY_OPEN); + this.state = 180; + this.expression(0); + this.state = 181; + this.match(CAQLParser.T_ARRAY_CLOSE); + this.state = 182; + this.match(CAQLParser.T_COLON); + this.state = 183; + this.expression(0); + break; + + } + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; + } + + + + object_element_name() { + let localctx = new Object_element_nameContext(this, this._ctx, this.state); + this.enterRule(localctx, 20, CAQLParser.RULE_object_element_name); + var _la = 0; // Token type + try { + this.enterOuterAlt(localctx, 1); + this.state = 187; + _la = this._input.LA(1); + if(!(_la===CAQLParser.T_STRING || _la===CAQLParser.T_QUOTED_STRING)) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; + } + + +} + +CAQLParser.EOF = antlr4.Token.EOF; +CAQLParser.DOT = 1; +CAQLParser.T_REGEX_MATCH = 2; +CAQLParser.T_REGEX_NON_MATCH = 3; +CAQLParser.T_EQ = 4; +CAQLParser.T_NE = 5; +CAQLParser.T_LT = 6; +CAQLParser.T_GT = 7; +CAQLParser.T_LE = 8; +CAQLParser.T_GE = 9; +CAQLParser.T_PLUS = 10; +CAQLParser.T_MINUS = 11; +CAQLParser.T_TIMES = 12; +CAQLParser.T_DIV = 13; +CAQLParser.T_MOD = 14; +CAQLParser.T_QUESTION = 15; +CAQLParser.T_COLON = 16; +CAQLParser.T_SCOPE = 17; +CAQLParser.T_RANGE = 18; +CAQLParser.T_COMMA = 19; +CAQLParser.T_OPEN = 20; +CAQLParser.T_CLOSE = 21; +CAQLParser.T_OBJECT_OPEN = 22; +CAQLParser.T_OBJECT_CLOSE = 23; +CAQLParser.T_ARRAY_OPEN = 24; +CAQLParser.T_ARRAY_CLOSE = 25; +CAQLParser.T_AGGREGATE = 26; +CAQLParser.T_ALL = 27; +CAQLParser.T_AND = 28; +CAQLParser.T_ANY = 29; +CAQLParser.T_ASC = 30; +CAQLParser.T_COLLECT = 31; +CAQLParser.T_DESC = 32; +CAQLParser.T_DISTINCT = 33; +CAQLParser.T_FALSE = 34; +CAQLParser.T_FILTER = 35; +CAQLParser.T_FOR = 36; +CAQLParser.T_GRAPH = 37; +CAQLParser.T_IN = 38; +CAQLParser.T_INBOUND = 39; +CAQLParser.T_INSERT = 40; +CAQLParser.T_INTO = 41; +CAQLParser.T_K_SHORTEST_PATHS = 42; +CAQLParser.T_LET = 43; +CAQLParser.T_LIKE = 44; +CAQLParser.T_LIMIT = 45; +CAQLParser.T_NONE = 46; +CAQLParser.T_NOT = 47; +CAQLParser.T_NULL = 48; +CAQLParser.T_OR = 49; +CAQLParser.T_OUTBOUND = 50; +CAQLParser.T_REMOVE = 51; +CAQLParser.T_REPLACE = 52; +CAQLParser.T_RETURN = 53; +CAQLParser.T_SHORTEST_PATH = 54; +CAQLParser.T_SORT = 55; +CAQLParser.T_TRUE = 56; +CAQLParser.T_UPDATE = 57; +CAQLParser.T_UPSERT = 58; +CAQLParser.T_WITH = 59; +CAQLParser.T_KEEP = 60; +CAQLParser.T_COUNT = 61; +CAQLParser.T_OPTIONS = 62; +CAQLParser.T_PRUNE = 63; +CAQLParser.T_SEARCH = 64; +CAQLParser.T_TO = 65; +CAQLParser.T_CURRENT = 66; +CAQLParser.T_NEW = 67; +CAQLParser.T_OLD = 68; +CAQLParser.T_STRING = 69; +CAQLParser.T_INT = 70; +CAQLParser.T_FLOAT = 71; +CAQLParser.T_PARAMETER = 72; +CAQLParser.T_QUOTED_STRING = 73; +CAQLParser.SINGLE_LINE_COMMENT = 74; +CAQLParser.MULTILINE_COMMENT = 75; +CAQLParser.SPACES = 76; +CAQLParser.UNEXPECTED_CHAR = 77; +CAQLParser.ERROR_RECONGNIGION = 78; + +CAQLParser.RULE_parse = 0; +CAQLParser.RULE_expression = 1; +CAQLParser.RULE_operator_unary = 2; +CAQLParser.RULE_reference = 3; +CAQLParser.RULE_compound_value = 4; +CAQLParser.RULE_function_call = 5; +CAQLParser.RULE_value_literal = 6; +CAQLParser.RULE_array = 7; +CAQLParser.RULE_object = 8; +CAQLParser.RULE_object_element = 9; +CAQLParser.RULE_object_element_name = 10; + +class ParseContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_parse; + } + + expression() { + return this.getTypedRuleContext(ExpressionContext,0); + }; + + EOF() { + return this.getToken(CAQLParser.EOF, 0); + }; + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterParse(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitParse(this); + } + } + + +} + + + +class ExpressionContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_expression; + this.eq_op = null; // Token + } + + value_literal() { + return this.getTypedRuleContext(Value_literalContext,0); + }; + + reference() { + return this.getTypedRuleContext(ReferenceContext,0); + }; + + operator_unary() { + return this.getTypedRuleContext(Operator_unaryContext,0); + }; + + expression = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTypedRuleContexts(ExpressionContext); + } else { + return this.getTypedRuleContext(ExpressionContext,i); + } + }; + + T_PLUS() { + return this.getToken(CAQLParser.T_PLUS, 0); + }; + + T_MINUS() { + return this.getToken(CAQLParser.T_MINUS, 0); + }; + + T_TIMES() { + return this.getToken(CAQLParser.T_TIMES, 0); + }; + + T_DIV() { + return this.getToken(CAQLParser.T_DIV, 0); + }; + + T_MOD() { + return this.getToken(CAQLParser.T_MOD, 0); + }; + + T_RANGE() { + return this.getToken(CAQLParser.T_RANGE, 0); + }; + + T_LT() { + return this.getToken(CAQLParser.T_LT, 0); + }; + + T_GT() { + return this.getToken(CAQLParser.T_GT, 0); + }; + + T_LE() { + return this.getToken(CAQLParser.T_LE, 0); + }; + + T_GE() { + return this.getToken(CAQLParser.T_GE, 0); + }; + + T_IN() { + return this.getToken(CAQLParser.T_IN, 0); + }; + + T_NOT() { + return this.getToken(CAQLParser.T_NOT, 0); + }; + + T_EQ() { + return this.getToken(CAQLParser.T_EQ, 0); + }; + + T_NE() { + return this.getToken(CAQLParser.T_NE, 0); + }; + + T_ALL() { + return this.getToken(CAQLParser.T_ALL, 0); + }; + + T_ANY() { + return this.getToken(CAQLParser.T_ANY, 0); + }; + + T_NONE() { + return this.getToken(CAQLParser.T_NONE, 0); + }; + + T_LIKE() { + return this.getToken(CAQLParser.T_LIKE, 0); + }; + + T_REGEX_MATCH() { + return this.getToken(CAQLParser.T_REGEX_MATCH, 0); + }; + + T_REGEX_NON_MATCH() { + return this.getToken(CAQLParser.T_REGEX_NON_MATCH, 0); + }; + + T_AND() { + return this.getToken(CAQLParser.T_AND, 0); + }; + + T_OR() { + return this.getToken(CAQLParser.T_OR, 0); + }; + + T_QUESTION() { + return this.getToken(CAQLParser.T_QUESTION, 0); + }; + + T_COLON() { + return this.getToken(CAQLParser.T_COLON, 0); + }; + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterExpression(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitExpression(this); + } + } + + +} + + + +class Operator_unaryContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_operator_unary; + } + + T_PLUS() { + return this.getToken(CAQLParser.T_PLUS, 0); + }; + + expression() { + return this.getTypedRuleContext(ExpressionContext,0); + }; + + T_MINUS() { + return this.getToken(CAQLParser.T_MINUS, 0); + }; + + T_NOT() { + return this.getToken(CAQLParser.T_NOT, 0); + }; + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterOperator_unary(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitOperator_unary(this); + } + } + + +} + + + +class ReferenceContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_reference; + } + + T_STRING() { + return this.getToken(CAQLParser.T_STRING, 0); + }; + + compound_value() { + return this.getTypedRuleContext(Compound_valueContext,0); + }; + + function_call() { + return this.getTypedRuleContext(Function_callContext,0); + }; + + T_OPEN() { + return this.getToken(CAQLParser.T_OPEN, 0); + }; + + expression() { + return this.getTypedRuleContext(ExpressionContext,0); + }; + + T_CLOSE() { + return this.getToken(CAQLParser.T_CLOSE, 0); + }; + + reference() { + return this.getTypedRuleContext(ReferenceContext,0); + }; + + DOT() { + return this.getToken(CAQLParser.DOT, 0); + }; + + T_ARRAY_OPEN() { + return this.getToken(CAQLParser.T_ARRAY_OPEN, 0); + }; + + T_ARRAY_CLOSE() { + return this.getToken(CAQLParser.T_ARRAY_CLOSE, 0); + }; + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterReference(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitReference(this); + } + } + + +} + + + +class Compound_valueContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_compound_value; + } + + array() { + return this.getTypedRuleContext(ArrayContext,0); + }; + + object() { + return this.getTypedRuleContext(ObjectContext,0); + }; + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterCompound_value(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitCompound_value(this); + } + } + + +} + + + +class Function_callContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_function_call; + } + + T_STRING() { + return this.getToken(CAQLParser.T_STRING, 0); + }; + + T_OPEN() { + return this.getToken(CAQLParser.T_OPEN, 0); + }; + + T_CLOSE() { + return this.getToken(CAQLParser.T_CLOSE, 0); + }; + + expression = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTypedRuleContexts(ExpressionContext); + } else { + return this.getTypedRuleContext(ExpressionContext,i); + } + }; + + T_COMMA = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTokens(CAQLParser.T_COMMA); + } else { + return this.getToken(CAQLParser.T_COMMA, i); + } + }; + + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterFunction_call(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitFunction_call(this); + } + } + + +} + + + +class Value_literalContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_value_literal; + } + + T_QUOTED_STRING() { + return this.getToken(CAQLParser.T_QUOTED_STRING, 0); + }; + + T_INT() { + return this.getToken(CAQLParser.T_INT, 0); + }; + + T_FLOAT() { + return this.getToken(CAQLParser.T_FLOAT, 0); + }; + + T_NULL() { + return this.getToken(CAQLParser.T_NULL, 0); + }; + + T_TRUE() { + return this.getToken(CAQLParser.T_TRUE, 0); + }; + + T_FALSE() { + return this.getToken(CAQLParser.T_FALSE, 0); + }; + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterValue_literal(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitValue_literal(this); + } + } + + +} + + + +class ArrayContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_array; + } + + T_ARRAY_OPEN() { + return this.getToken(CAQLParser.T_ARRAY_OPEN, 0); + }; + + T_ARRAY_CLOSE() { + return this.getToken(CAQLParser.T_ARRAY_CLOSE, 0); + }; + + expression = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTypedRuleContexts(ExpressionContext); + } else { + return this.getTypedRuleContext(ExpressionContext,i); + } + }; + + T_COMMA = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTokens(CAQLParser.T_COMMA); + } else { + return this.getToken(CAQLParser.T_COMMA, i); + } + }; + + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterArray(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitArray(this); + } + } + + +} + + + +class ObjectContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_object; + } + + T_OBJECT_OPEN() { + return this.getToken(CAQLParser.T_OBJECT_OPEN, 0); + }; + + T_OBJECT_CLOSE() { + return this.getToken(CAQLParser.T_OBJECT_CLOSE, 0); + }; + + object_element = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTypedRuleContexts(Object_elementContext); + } else { + return this.getTypedRuleContext(Object_elementContext,i); + } + }; + + T_COMMA = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTokens(CAQLParser.T_COMMA); + } else { + return this.getToken(CAQLParser.T_COMMA, i); + } + }; + + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterObject(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitObject(this); + } + } + + +} + + + +class Object_elementContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_object_element; + } + + T_STRING() { + return this.getToken(CAQLParser.T_STRING, 0); + }; + + object_element_name() { + return this.getTypedRuleContext(Object_element_nameContext,0); + }; + + T_COLON() { + return this.getToken(CAQLParser.T_COLON, 0); + }; + + expression = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTypedRuleContexts(ExpressionContext); + } else { + return this.getTypedRuleContext(ExpressionContext,i); + } + }; + + T_ARRAY_OPEN() { + return this.getToken(CAQLParser.T_ARRAY_OPEN, 0); + }; + + T_ARRAY_CLOSE() { + return this.getToken(CAQLParser.T_ARRAY_CLOSE, 0); + }; + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterObject_element(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitObject_element(this); + } + } + + +} + + + +class Object_element_nameContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_object_element_name; + } + + T_STRING() { + return this.getToken(CAQLParser.T_STRING, 0); + }; + + T_QUOTED_STRING() { + return this.getToken(CAQLParser.T_QUOTED_STRING, 0); + }; + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterObject_element_name(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitObject_element_name(this); + } + } + + +} + + + + +CAQLParser.ParseContext = ParseContext; +CAQLParser.ExpressionContext = ExpressionContext; +CAQLParser.Operator_unaryContext = Operator_unaryContext; +CAQLParser.ReferenceContext = ReferenceContext; +CAQLParser.Compound_valueContext = Compound_valueContext; +CAQLParser.Function_callContext = Function_callContext; +CAQLParser.Value_literalContext = Value_literalContext; +CAQLParser.ArrayContext = ArrayContext; +CAQLParser.ObjectContext = ObjectContext; +CAQLParser.Object_elementContext = Object_elementContext; +CAQLParser.Object_element_nameContext = Object_element_nameContext; diff --git a/ui/src/suggestions/grammar/CAQLParser.tokens b/ui/src/suggestions/grammar/CAQLParser.tokens new file mode 100644 index 0000000..7bdaf61 --- /dev/null +++ b/ui/src/suggestions/grammar/CAQLParser.tokens @@ -0,0 +1,103 @@ +DOT=1 +T_REGEX_MATCH=2 +T_REGEX_NON_MATCH=3 +T_EQ=4 +T_NE=5 +T_LT=6 +T_GT=7 +T_LE=8 +T_GE=9 +T_PLUS=10 +T_MINUS=11 +T_TIMES=12 +T_DIV=13 +T_MOD=14 +T_QUESTION=15 +T_COLON=16 +T_SCOPE=17 +T_RANGE=18 +T_COMMA=19 +T_OPEN=20 +T_CLOSE=21 +T_OBJECT_OPEN=22 +T_OBJECT_CLOSE=23 +T_ARRAY_OPEN=24 +T_ARRAY_CLOSE=25 +T_AGGREGATE=26 +T_ALL=27 +T_AND=28 +T_ANY=29 +T_ASC=30 +T_COLLECT=31 +T_DESC=32 +T_DISTINCT=33 +T_FALSE=34 +T_FILTER=35 +T_FOR=36 +T_GRAPH=37 +T_IN=38 +T_INBOUND=39 +T_INSERT=40 +T_INTO=41 +T_K_SHORTEST_PATHS=42 +T_LET=43 +T_LIKE=44 +T_LIMIT=45 +T_NONE=46 +T_NOT=47 +T_NULL=48 +T_OR=49 +T_OUTBOUND=50 +T_REMOVE=51 +T_REPLACE=52 +T_RETURN=53 +T_SHORTEST_PATH=54 +T_SORT=55 +T_TRUE=56 +T_UPDATE=57 +T_UPSERT=58 +T_WITH=59 +T_KEEP=60 +T_COUNT=61 +T_OPTIONS=62 +T_PRUNE=63 +T_SEARCH=64 +T_TO=65 +T_CURRENT=66 +T_NEW=67 +T_OLD=68 +T_STRING=69 +T_INT=70 +T_FLOAT=71 +T_PARAMETER=72 +T_QUOTED_STRING=73 +SINGLE_LINE_COMMENT=74 +MULTILINE_COMMENT=75 +SPACES=76 +UNEXPECTED_CHAR=77 +ERROR_RECONGNIGION=78 +'.'=1 +'=~'=2 +'!~'=3 +'=='=4 +'!='=5 +'<'=6 +'>'=7 +'<='=8 +'>='=9 +'+'=10 +'-'=11 +'*'=12 +'/'=13 +'%'=14 +'?'=15 +':'=16 +'::'=17 +'..'=18 +','=19 +'('=20 +')'=21 +'{'=22 +'}'=23 +'['=24 +']'=25 diff --git a/ui/src/suggestions/grammar/CAQLParserListener.js b/ui/src/suggestions/grammar/CAQLParserListener.js new file mode 100644 index 0000000..36af753 --- /dev/null +++ b/ui/src/suggestions/grammar/CAQLParserListener.js @@ -0,0 +1,108 @@ +// Generated from CAQLParser.g4 by ANTLR 4.9.2 +// jshint ignore: start +import antlr4 from 'antlr4'; + +// This class defines a complete listener for a parse tree produced by CAQLParser. +export default class CAQLParserListener extends antlr4.tree.ParseTreeListener { + + // Enter a parse tree produced by CAQLParser#parse. + enterParse(ctx) { + } + + // Exit a parse tree produced by CAQLParser#parse. + exitParse(ctx) { + } + + + // Enter a parse tree produced by CAQLParser#expression. + enterExpression(ctx) { + } + + // Exit a parse tree produced by CAQLParser#expression. + exitExpression(ctx) { + } + + + // Enter a parse tree produced by CAQLParser#operator_unary. + enterOperator_unary(ctx) { + } + + // Exit a parse tree produced by CAQLParser#operator_unary. + exitOperator_unary(ctx) { + } + + + // Enter a parse tree produced by CAQLParser#reference. + enterReference(ctx) { + } + + // Exit a parse tree produced by CAQLParser#reference. + exitReference(ctx) { + } + + + // Enter a parse tree produced by CAQLParser#compound_value. + enterCompound_value(ctx) { + } + + // Exit a parse tree produced by CAQLParser#compound_value. + exitCompound_value(ctx) { + } + + + // Enter a parse tree produced by CAQLParser#function_call. + enterFunction_call(ctx) { + } + + // Exit a parse tree produced by CAQLParser#function_call. + exitFunction_call(ctx) { + } + + + // Enter a parse tree produced by CAQLParser#value_literal. + enterValue_literal(ctx) { + } + + // Exit a parse tree produced by CAQLParser#value_literal. + exitValue_literal(ctx) { + } + + + // Enter a parse tree produced by CAQLParser#array. + enterArray(ctx) { + } + + // Exit a parse tree produced by CAQLParser#array. + exitArray(ctx) { + } + + + // Enter a parse tree produced by CAQLParser#object. + enterObject(ctx) { + } + + // Exit a parse tree produced by CAQLParser#object. + exitObject(ctx) { + } + + + // Enter a parse tree produced by CAQLParser#object_element. + enterObject_element(ctx) { + } + + // Exit a parse tree produced by CAQLParser#object_element. + exitObject_element(ctx) { + } + + + // Enter a parse tree produced by CAQLParser#object_element_name. + enterObject_element_name(ctx) { + } + + // Exit a parse tree produced by CAQLParser#object_element_name. + exitObject_element_name(ctx) { + } + + + +} \ No newline at end of file diff --git a/ui/src/suggestions/grammar/RQLLexer.interp b/ui/src/suggestions/grammar/RQLLexer.interp new file mode 100644 index 0000000..7633444 --- /dev/null +++ b/ui/src/suggestions/grammar/RQLLexer.interp @@ -0,0 +1,282 @@ +token literal names: +null +'.' +'=~' +'!~' +'==' +'!=' +'<' +'>' +'<=' +'>=' +'+' +'-' +'*' +'/' +'%' +'?' +':' +'::' +'..' +',' +'(' +')' +'{' +'}' +'[' +']' +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null + +token symbolic names: +null +DOT +T_REGEX_MATCH +T_REGEX_NON_MATCH +T_EQ +T_NE +T_LT +T_GT +T_LE +T_GE +T_PLUS +T_MINUS +T_TIMES +T_DIV +T_MOD +T_QUESTION +T_COLON +T_SCOPE +T_RANGE +T_COMMA +T_OPEN +T_CLOSE +T_OBJECT_OPEN +T_OBJECT_CLOSE +T_ARRAY_OPEN +T_ARRAY_CLOSE +T_AGGREGATE +T_ALL +T_AND +T_ANY +T_ASC +T_COLLECT +T_DESC +T_DISTINCT +T_FALSE +T_FILTER +T_FOR +T_GRAPH +T_IN +T_INBOUND +T_INSERT +T_INTO +T_K_SHORTEST_PATHS +T_LET +T_LIKE +T_LIMIT +T_NONE +T_NOT +T_NULL +T_OR +T_OUTBOUND +T_REMOVE +T_REPLACE +T_RETURN +T_SHORTEST_PATH +T_SORT +T_TRUE +T_UPDATE +T_UPSERT +T_WITH +T_KEEP +T_COUNT +T_OPTIONS +T_PRUNE +T_SEARCH +T_TO +T_CURRENT +T_NEW +T_OLD +T_STRING +T_INT +T_FLOAT +T_PARAMETER +T_QUOTED_STRING +SINGLE_LINE_COMMENT +MULTILINE_COMMENT +SPACES +UNEXPECTED_CHAR +ERROR_RECONGNIGION + +rule names: +DOT +T_REGEX_MATCH +T_REGEX_NON_MATCH +T_EQ +T_NE +T_LT +T_GT +T_LE +T_GE +T_PLUS +T_MINUS +T_TIMES +T_DIV +T_MOD +T_QUESTION +T_COLON +T_SCOPE +T_RANGE +T_COMMA +T_OPEN +T_CLOSE +T_OBJECT_OPEN +T_OBJECT_CLOSE +T_ARRAY_OPEN +T_ARRAY_CLOSE +T_AGGREGATE +T_ALL +T_AND +T_ANY +T_ASC +T_COLLECT +T_DESC +T_DISTINCT +T_FALSE +T_FILTER +T_FOR +T_GRAPH +T_IN +T_INBOUND +T_INSERT +T_INTO +T_K_SHORTEST_PATHS +T_LET +T_LIKE +T_LIMIT +T_NONE +T_NOT +T_NULL +T_OR +T_OUTBOUND +T_REMOVE +T_REPLACE +T_RETURN +T_SHORTEST_PATH +T_SORT +T_TRUE +T_UPDATE +T_UPSERT +T_WITH +T_KEEP +T_COUNT +T_OPTIONS +T_PRUNE +T_SEARCH +T_TO +T_CURRENT +T_NEW +T_OLD +T_STRING +T_INT +T_FLOAT +T_PARAMETER +T_QUOTED_STRING +SINGLE_LINE_COMMENT +MULTILINE_COMMENT +SPACES +UNEXPECTED_CHAR +HEX_DIGIT +DIGIT +A +B +C +D +E +F +G +H +I +J +K +L +M +N +O +P +Q +R +S +T +U +V +W +X +Y +Z +ERROR_RECONGNIGION + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN +null +null +ERRORCHANNEL + +mode names: +DEFAULT_MODE + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 80, 739, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, 9, 106, 4, 107, 9, 107, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 5, 29, 294, 10, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 5, 48, 414, 10, 48, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 5, 50, 426, 10, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 54, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 3, 70, 3, 70, 7, 70, 555, 10, 70, 12, 70, 14, 70, 558, 11, 70, 3, 71, 3, 71, 7, 71, 562, 10, 71, 12, 71, 14, 71, 565, 11, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 6, 71, 572, 10, 71, 13, 71, 14, 71, 573, 3, 71, 3, 71, 3, 71, 3, 71, 6, 71, 580, 10, 71, 13, 71, 14, 71, 581, 5, 71, 584, 10, 71, 3, 72, 3, 72, 7, 72, 588, 10, 72, 12, 72, 14, 72, 591, 11, 72, 3, 72, 5, 72, 594, 10, 72, 3, 72, 3, 72, 6, 72, 598, 10, 72, 13, 72, 14, 72, 599, 3, 72, 3, 72, 5, 72, 604, 10, 72, 3, 72, 6, 72, 607, 10, 72, 13, 72, 14, 72, 608, 5, 72, 611, 10, 72, 3, 73, 3, 73, 3, 73, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 7, 74, 622, 10, 74, 12, 74, 14, 74, 625, 11, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 7, 74, 634, 10, 74, 12, 74, 14, 74, 637, 11, 74, 3, 74, 5, 74, 640, 10, 74, 3, 75, 3, 75, 3, 75, 3, 75, 7, 75, 646, 10, 75, 12, 75, 14, 75, 649, 11, 75, 3, 75, 5, 75, 652, 10, 75, 3, 75, 3, 75, 5, 75, 656, 10, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 7, 76, 664, 10, 76, 12, 76, 14, 76, 667, 11, 76, 3, 76, 3, 76, 3, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 3, 79, 3, 79, 3, 80, 3, 80, 3, 81, 3, 81, 3, 82, 3, 82, 3, 83, 3, 83, 3, 84, 3, 84, 3, 85, 3, 85, 3, 86, 3, 86, 3, 87, 3, 87, 3, 88, 3, 88, 3, 89, 3, 89, 3, 90, 3, 90, 3, 91, 3, 91, 3, 92, 3, 92, 3, 93, 3, 93, 3, 94, 3, 94, 3, 95, 3, 95, 3, 96, 3, 96, 3, 97, 3, 97, 3, 98, 3, 98, 3, 99, 3, 99, 3, 100, 3, 100, 3, 101, 3, 101, 3, 102, 3, 102, 3, 103, 3, 103, 3, 104, 3, 104, 3, 105, 3, 105, 3, 106, 3, 106, 3, 107, 3, 107, 3, 107, 3, 107, 3, 665, 2, 108, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 41, 22, 43, 23, 45, 24, 47, 25, 49, 26, 51, 27, 53, 28, 55, 29, 57, 30, 59, 31, 61, 32, 63, 33, 65, 34, 67, 35, 69, 36, 71, 37, 73, 38, 75, 39, 77, 40, 79, 41, 81, 42, 83, 43, 85, 44, 87, 45, 89, 46, 91, 47, 93, 48, 95, 49, 97, 50, 99, 51, 101, 52, 103, 53, 105, 54, 107, 55, 109, 56, 111, 57, 113, 58, 115, 59, 117, 60, 119, 61, 121, 62, 123, 63, 125, 64, 127, 65, 129, 66, 131, 67, 133, 68, 135, 69, 137, 70, 139, 71, 141, 72, 143, 73, 145, 74, 147, 75, 149, 76, 151, 77, 153, 78, 155, 79, 157, 2, 159, 2, 161, 2, 163, 2, 165, 2, 167, 2, 169, 2, 171, 2, 173, 2, 175, 2, 177, 2, 179, 2, 181, 2, 183, 2, 185, 2, 187, 2, 189, 2, 191, 2, 193, 2, 195, 2, 197, 2, 199, 2, 201, 2, 203, 2, 205, 2, 207, 2, 209, 2, 211, 2, 213, 80, 3, 2, 39, 5, 2, 67, 92, 97, 97, 99, 124, 6, 2, 50, 59, 67, 92, 97, 97, 99, 124, 3, 2, 51, 59, 3, 2, 50, 51, 4, 2, 45, 45, 47, 47, 4, 2, 41, 41, 94, 94, 4, 2, 36, 36, 94, 94, 4, 2, 12, 12, 15, 15, 5, 2, 11, 13, 15, 15, 34, 34, 5, 2, 50, 59, 67, 72, 99, 104, 3, 2, 50, 59, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 71, 71, 103, 103, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 77, 77, 109, 109, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 91, 91, 123, 123, 4, 2, 92, 92, 124, 124, 2, 738, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 49, 3, 2, 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2, 97, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2, 2, 2, 105, 3, 2, 2, 2, 2, 107, 3, 2, 2, 2, 2, 109, 3, 2, 2, 2, 2, 111, 3, 2, 2, 2, 2, 113, 3, 2, 2, 2, 2, 115, 3, 2, 2, 2, 2, 117, 3, 2, 2, 2, 2, 119, 3, 2, 2, 2, 2, 121, 3, 2, 2, 2, 2, 123, 3, 2, 2, 2, 2, 125, 3, 2, 2, 2, 2, 127, 3, 2, 2, 2, 2, 129, 3, 2, 2, 2, 2, 131, 3, 2, 2, 2, 2, 133, 3, 2, 2, 2, 2, 135, 3, 2, 2, 2, 2, 137, 3, 2, 2, 2, 2, 139, 3, 2, 2, 2, 2, 141, 3, 2, 2, 2, 2, 143, 3, 2, 2, 2, 2, 145, 3, 2, 2, 2, 2, 147, 3, 2, 2, 2, 2, 149, 3, 2, 2, 2, 2, 151, 3, 2, 2, 2, 2, 153, 3, 2, 2, 2, 2, 155, 3, 2, 2, 2, 2, 213, 3, 2, 2, 2, 3, 215, 3, 2, 2, 2, 5, 217, 3, 2, 2, 2, 7, 220, 3, 2, 2, 2, 9, 223, 3, 2, 2, 2, 11, 226, 3, 2, 2, 2, 13, 229, 3, 2, 2, 2, 15, 231, 3, 2, 2, 2, 17, 233, 3, 2, 2, 2, 19, 236, 3, 2, 2, 2, 21, 239, 3, 2, 2, 2, 23, 241, 3, 2, 2, 2, 25, 243, 3, 2, 2, 2, 27, 245, 3, 2, 2, 2, 29, 247, 3, 2, 2, 2, 31, 249, 3, 2, 2, 2, 33, 251, 3, 2, 2, 2, 35, 253, 3, 2, 2, 2, 37, 256, 3, 2, 2, 2, 39, 259, 3, 2, 2, 2, 41, 261, 3, 2, 2, 2, 43, 263, 3, 2, 2, 2, 45, 265, 3, 2, 2, 2, 47, 267, 3, 2, 2, 2, 49, 269, 3, 2, 2, 2, 51, 271, 3, 2, 2, 2, 53, 273, 3, 2, 2, 2, 55, 283, 3, 2, 2, 2, 57, 293, 3, 2, 2, 2, 59, 295, 3, 2, 2, 2, 61, 299, 3, 2, 2, 2, 63, 303, 3, 2, 2, 2, 65, 311, 3, 2, 2, 2, 67, 316, 3, 2, 2, 2, 69, 325, 3, 2, 2, 2, 71, 331, 3, 2, 2, 2, 73, 338, 3, 2, 2, 2, 75, 342, 3, 2, 2, 2, 77, 348, 3, 2, 2, 2, 79, 351, 3, 2, 2, 2, 81, 359, 3, 2, 2, 2, 83, 366, 3, 2, 2, 2, 85, 371, 3, 2, 2, 2, 87, 388, 3, 2, 2, 2, 89, 392, 3, 2, 2, 2, 91, 397, 3, 2, 2, 2, 93, 403, 3, 2, 2, 2, 95, 413, 3, 2, 2, 2, 97, 415, 3, 2, 2, 2, 99, 425, 3, 2, 2, 2, 101, 427, 3, 2, 2, 2, 103, 436, 3, 2, 2, 2, 105, 443, 3, 2, 2, 2, 107, 451, 3, 2, 2, 2, 109, 458, 3, 2, 2, 2, 111, 472, 3, 2, 2, 2, 113, 477, 3, 2, 2, 2, 115, 482, 3, 2, 2, 2, 117, 489, 3, 2, 2, 2, 119, 496, 3, 2, 2, 2, 121, 501, 3, 2, 2, 2, 123, 506, 3, 2, 2, 2, 125, 512, 3, 2, 2, 2, 127, 520, 3, 2, 2, 2, 129, 526, 3, 2, 2, 2, 131, 533, 3, 2, 2, 2, 133, 536, 3, 2, 2, 2, 135, 544, 3, 2, 2, 2, 137, 548, 3, 2, 2, 2, 139, 552, 3, 2, 2, 2, 141, 583, 3, 2, 2, 2, 143, 593, 3, 2, 2, 2, 145, 612, 3, 2, 2, 2, 147, 639, 3, 2, 2, 2, 149, 641, 3, 2, 2, 2, 151, 659, 3, 2, 2, 2, 153, 673, 3, 2, 2, 2, 155, 677, 3, 2, 2, 2, 157, 679, 3, 2, 2, 2, 159, 681, 3, 2, 2, 2, 161, 683, 3, 2, 2, 2, 163, 685, 3, 2, 2, 2, 165, 687, 3, 2, 2, 2, 167, 689, 3, 2, 2, 2, 169, 691, 3, 2, 2, 2, 171, 693, 3, 2, 2, 2, 173, 695, 3, 2, 2, 2, 175, 697, 3, 2, 2, 2, 177, 699, 3, 2, 2, 2, 179, 701, 3, 2, 2, 2, 181, 703, 3, 2, 2, 2, 183, 705, 3, 2, 2, 2, 185, 707, 3, 2, 2, 2, 187, 709, 3, 2, 2, 2, 189, 711, 3, 2, 2, 2, 191, 713, 3, 2, 2, 2, 193, 715, 3, 2, 2, 2, 195, 717, 3, 2, 2, 2, 197, 719, 3, 2, 2, 2, 199, 721, 3, 2, 2, 2, 201, 723, 3, 2, 2, 2, 203, 725, 3, 2, 2, 2, 205, 727, 3, 2, 2, 2, 207, 729, 3, 2, 2, 2, 209, 731, 3, 2, 2, 2, 211, 733, 3, 2, 2, 2, 213, 735, 3, 2, 2, 2, 215, 216, 7, 48, 2, 2, 216, 4, 3, 2, 2, 2, 217, 218, 7, 63, 2, 2, 218, 219, 7, 128, 2, 2, 219, 6, 3, 2, 2, 2, 220, 221, 7, 35, 2, 2, 221, 222, 7, 128, 2, 2, 222, 8, 3, 2, 2, 2, 223, 224, 7, 63, 2, 2, 224, 225, 7, 63, 2, 2, 225, 10, 3, 2, 2, 2, 226, 227, 7, 35, 2, 2, 227, 228, 7, 63, 2, 2, 228, 12, 3, 2, 2, 2, 229, 230, 7, 62, 2, 2, 230, 14, 3, 2, 2, 2, 231, 232, 7, 64, 2, 2, 232, 16, 3, 2, 2, 2, 233, 234, 7, 62, 2, 2, 234, 235, 7, 63, 2, 2, 235, 18, 3, 2, 2, 2, 236, 237, 7, 64, 2, 2, 237, 238, 7, 63, 2, 2, 238, 20, 3, 2, 2, 2, 239, 240, 7, 45, 2, 2, 240, 22, 3, 2, 2, 2, 241, 242, 7, 47, 2, 2, 242, 24, 3, 2, 2, 2, 243, 244, 7, 44, 2, 2, 244, 26, 3, 2, 2, 2, 245, 246, 7, 49, 2, 2, 246, 28, 3, 2, 2, 2, 247, 248, 7, 39, 2, 2, 248, 30, 3, 2, 2, 2, 249, 250, 7, 65, 2, 2, 250, 32, 3, 2, 2, 2, 251, 252, 7, 60, 2, 2, 252, 34, 3, 2, 2, 2, 253, 254, 7, 60, 2, 2, 254, 255, 7, 60, 2, 2, 255, 36, 3, 2, 2, 2, 256, 257, 7, 48, 2, 2, 257, 258, 7, 48, 2, 2, 258, 38, 3, 2, 2, 2, 259, 260, 7, 46, 2, 2, 260, 40, 3, 2, 2, 2, 261, 262, 7, 42, 2, 2, 262, 42, 3, 2, 2, 2, 263, 264, 7, 43, 2, 2, 264, 44, 3, 2, 2, 2, 265, 266, 7, 125, 2, 2, 266, 46, 3, 2, 2, 2, 267, 268, 7, 127, 2, 2, 268, 48, 3, 2, 2, 2, 269, 270, 7, 93, 2, 2, 270, 50, 3, 2, 2, 2, 271, 272, 7, 95, 2, 2, 272, 52, 3, 2, 2, 2, 273, 274, 5, 161, 81, 2, 274, 275, 5, 173, 87, 2, 275, 276, 5, 173, 87, 2, 276, 277, 5, 195, 98, 2, 277, 278, 5, 169, 85, 2, 278, 279, 5, 173, 87, 2, 279, 280, 5, 161, 81, 2, 280, 281, 5, 199, 100, 2, 281, 282, 5, 169, 85, 2, 282, 54, 3, 2, 2, 2, 283, 284, 5, 161, 81, 2, 284, 285, 5, 183, 92, 2, 285, 286, 5, 183, 92, 2, 286, 56, 3, 2, 2, 2, 287, 288, 5, 161, 81, 2, 288, 289, 5, 187, 94, 2, 289, 290, 5, 167, 84, 2, 290, 294, 3, 2, 2, 2, 291, 292, 7, 40, 2, 2, 292, 294, 7, 40, 2, 2, 293, 287, 3, 2, 2, 2, 293, 291, 3, 2, 2, 2, 294, 58, 3, 2, 2, 2, 295, 296, 5, 161, 81, 2, 296, 297, 5, 187, 94, 2, 297, 298, 5, 209, 105, 2, 298, 60, 3, 2, 2, 2, 299, 300, 5, 161, 81, 2, 300, 301, 5, 197, 99, 2, 301, 302, 5, 165, 83, 2, 302, 62, 3, 2, 2, 2, 303, 304, 5, 165, 83, 2, 304, 305, 5, 189, 95, 2, 305, 306, 5, 183, 92, 2, 306, 307, 5, 183, 92, 2, 307, 308, 5, 169, 85, 2, 308, 309, 5, 165, 83, 2, 309, 310, 5, 199, 100, 2, 310, 64, 3, 2, 2, 2, 311, 312, 5, 167, 84, 2, 312, 313, 5, 169, 85, 2, 313, 314, 5, 197, 99, 2, 314, 315, 5, 165, 83, 2, 315, 66, 3, 2, 2, 2, 316, 317, 5, 167, 84, 2, 317, 318, 5, 177, 89, 2, 318, 319, 5, 197, 99, 2, 319, 320, 5, 199, 100, 2, 320, 321, 5, 177, 89, 2, 321, 322, 5, 187, 94, 2, 322, 323, 5, 165, 83, 2, 323, 324, 5, 199, 100, 2, 324, 68, 3, 2, 2, 2, 325, 326, 5, 171, 86, 2, 326, 327, 5, 161, 81, 2, 327, 328, 5, 183, 92, 2, 328, 329, 5, 197, 99, 2, 329, 330, 5, 169, 85, 2, 330, 70, 3, 2, 2, 2, 331, 332, 5, 171, 86, 2, 332, 333, 5, 177, 89, 2, 333, 334, 5, 183, 92, 2, 334, 335, 5, 199, 100, 2, 335, 336, 5, 169, 85, 2, 336, 337, 5, 195, 98, 2, 337, 72, 3, 2, 2, 2, 338, 339, 5, 171, 86, 2, 339, 340, 5, 189, 95, 2, 340, 341, 5, 195, 98, 2, 341, 74, 3, 2, 2, 2, 342, 343, 5, 173, 87, 2, 343, 344, 5, 195, 98, 2, 344, 345, 5, 161, 81, 2, 345, 346, 5, 191, 96, 2, 346, 347, 5, 175, 88, 2, 347, 76, 3, 2, 2, 2, 348, 349, 5, 177, 89, 2, 349, 350, 5, 187, 94, 2, 350, 78, 3, 2, 2, 2, 351, 352, 5, 177, 89, 2, 352, 353, 5, 187, 94, 2, 353, 354, 5, 163, 82, 2, 354, 355, 5, 189, 95, 2, 355, 356, 5, 201, 101, 2, 356, 357, 5, 187, 94, 2, 357, 358, 5, 167, 84, 2, 358, 80, 3, 2, 2, 2, 359, 360, 5, 177, 89, 2, 360, 361, 5, 187, 94, 2, 361, 362, 5, 197, 99, 2, 362, 363, 5, 169, 85, 2, 363, 364, 5, 195, 98, 2, 364, 365, 5, 199, 100, 2, 365, 82, 3, 2, 2, 2, 366, 367, 5, 177, 89, 2, 367, 368, 5, 187, 94, 2, 368, 369, 5, 199, 100, 2, 369, 370, 5, 189, 95, 2, 370, 84, 3, 2, 2, 2, 371, 372, 5, 181, 91, 2, 372, 373, 7, 97, 2, 2, 373, 374, 5, 197, 99, 2, 374, 375, 5, 175, 88, 2, 375, 376, 5, 189, 95, 2, 376, 377, 5, 195, 98, 2, 377, 378, 5, 199, 100, 2, 378, 379, 5, 169, 85, 2, 379, 380, 5, 197, 99, 2, 380, 381, 5, 199, 100, 2, 381, 382, 7, 97, 2, 2, 382, 383, 5, 191, 96, 2, 383, 384, 5, 161, 81, 2, 384, 385, 5, 199, 100, 2, 385, 386, 5, 175, 88, 2, 386, 387, 5, 197, 99, 2, 387, 86, 3, 2, 2, 2, 388, 389, 5, 183, 92, 2, 389, 390, 5, 169, 85, 2, 390, 391, 5, 199, 100, 2, 391, 88, 3, 2, 2, 2, 392, 393, 5, 183, 92, 2, 393, 394, 5, 177, 89, 2, 394, 395, 5, 181, 91, 2, 395, 396, 5, 169, 85, 2, 396, 90, 3, 2, 2, 2, 397, 398, 5, 183, 92, 2, 398, 399, 5, 177, 89, 2, 399, 400, 5, 185, 93, 2, 400, 401, 5, 177, 89, 2, 401, 402, 5, 199, 100, 2, 402, 92, 3, 2, 2, 2, 403, 404, 5, 187, 94, 2, 404, 405, 5, 189, 95, 2, 405, 406, 5, 187, 94, 2, 406, 407, 5, 169, 85, 2, 407, 94, 3, 2, 2, 2, 408, 409, 5, 187, 94, 2, 409, 410, 5, 189, 95, 2, 410, 411, 5, 199, 100, 2, 411, 414, 3, 2, 2, 2, 412, 414, 7, 35, 2, 2, 413, 408, 3, 2, 2, 2, 413, 412, 3, 2, 2, 2, 414, 96, 3, 2, 2, 2, 415, 416, 5, 187, 94, 2, 416, 417, 5, 201, 101, 2, 417, 418, 5, 183, 92, 2, 418, 419, 5, 183, 92, 2, 419, 98, 3, 2, 2, 2, 420, 421, 5, 189, 95, 2, 421, 422, 5, 195, 98, 2, 422, 426, 3, 2, 2, 2, 423, 424, 7, 126, 2, 2, 424, 426, 7, 126, 2, 2, 425, 420, 3, 2, 2, 2, 425, 423, 3, 2, 2, 2, 426, 100, 3, 2, 2, 2, 427, 428, 5, 189, 95, 2, 428, 429, 5, 201, 101, 2, 429, 430, 5, 199, 100, 2, 430, 431, 5, 163, 82, 2, 431, 432, 5, 189, 95, 2, 432, 433, 5, 201, 101, 2, 433, 434, 5, 187, 94, 2, 434, 435, 5, 167, 84, 2, 435, 102, 3, 2, 2, 2, 436, 437, 5, 195, 98, 2, 437, 438, 5, 169, 85, 2, 438, 439, 5, 185, 93, 2, 439, 440, 5, 189, 95, 2, 440, 441, 5, 203, 102, 2, 441, 442, 5, 169, 85, 2, 442, 104, 3, 2, 2, 2, 443, 444, 5, 195, 98, 2, 444, 445, 5, 169, 85, 2, 445, 446, 5, 191, 96, 2, 446, 447, 5, 183, 92, 2, 447, 448, 5, 161, 81, 2, 448, 449, 5, 165, 83, 2, 449, 450, 5, 169, 85, 2, 450, 106, 3, 2, 2, 2, 451, 452, 5, 195, 98, 2, 452, 453, 5, 169, 85, 2, 453, 454, 5, 199, 100, 2, 454, 455, 5, 201, 101, 2, 455, 456, 5, 195, 98, 2, 456, 457, 5, 187, 94, 2, 457, 108, 3, 2, 2, 2, 458, 459, 5, 197, 99, 2, 459, 460, 5, 175, 88, 2, 460, 461, 5, 189, 95, 2, 461, 462, 5, 195, 98, 2, 462, 463, 5, 199, 100, 2, 463, 464, 5, 169, 85, 2, 464, 465, 5, 197, 99, 2, 465, 466, 5, 199, 100, 2, 466, 467, 7, 97, 2, 2, 467, 468, 5, 191, 96, 2, 468, 469, 5, 161, 81, 2, 469, 470, 5, 199, 100, 2, 470, 471, 5, 175, 88, 2, 471, 110, 3, 2, 2, 2, 472, 473, 5, 197, 99, 2, 473, 474, 5, 189, 95, 2, 474, 475, 5, 195, 98, 2, 475, 476, 5, 199, 100, 2, 476, 112, 3, 2, 2, 2, 477, 478, 5, 199, 100, 2, 478, 479, 5, 195, 98, 2, 479, 480, 5, 201, 101, 2, 480, 481, 5, 169, 85, 2, 481, 114, 3, 2, 2, 2, 482, 483, 5, 201, 101, 2, 483, 484, 5, 191, 96, 2, 484, 485, 5, 167, 84, 2, 485, 486, 5, 161, 81, 2, 486, 487, 5, 199, 100, 2, 487, 488, 5, 169, 85, 2, 488, 116, 3, 2, 2, 2, 489, 490, 5, 201, 101, 2, 490, 491, 5, 191, 96, 2, 491, 492, 5, 197, 99, 2, 492, 493, 5, 169, 85, 2, 493, 494, 5, 195, 98, 2, 494, 495, 5, 199, 100, 2, 495, 118, 3, 2, 2, 2, 496, 497, 5, 205, 103, 2, 497, 498, 5, 177, 89, 2, 498, 499, 5, 199, 100, 2, 499, 500, 5, 175, 88, 2, 500, 120, 3, 2, 2, 2, 501, 502, 5, 181, 91, 2, 502, 503, 5, 169, 85, 2, 503, 504, 5, 169, 85, 2, 504, 505, 5, 191, 96, 2, 505, 122, 3, 2, 2, 2, 506, 507, 5, 165, 83, 2, 507, 508, 5, 189, 95, 2, 508, 509, 5, 201, 101, 2, 509, 510, 5, 187, 94, 2, 510, 511, 5, 199, 100, 2, 511, 124, 3, 2, 2, 2, 512, 513, 5, 189, 95, 2, 513, 514, 5, 191, 96, 2, 514, 515, 5, 199, 100, 2, 515, 516, 5, 177, 89, 2, 516, 517, 5, 189, 95, 2, 517, 518, 5, 187, 94, 2, 518, 519, 5, 197, 99, 2, 519, 126, 3, 2, 2, 2, 520, 521, 5, 191, 96, 2, 521, 522, 5, 195, 98, 2, 522, 523, 5, 201, 101, 2, 523, 524, 5, 187, 94, 2, 524, 525, 5, 169, 85, 2, 525, 128, 3, 2, 2, 2, 526, 527, 5, 197, 99, 2, 527, 528, 5, 169, 85, 2, 528, 529, 5, 161, 81, 2, 529, 530, 5, 195, 98, 2, 530, 531, 5, 165, 83, 2, 531, 532, 5, 175, 88, 2, 532, 130, 3, 2, 2, 2, 533, 534, 5, 199, 100, 2, 534, 535, 5, 189, 95, 2, 535, 132, 3, 2, 2, 2, 536, 537, 5, 165, 83, 2, 537, 538, 5, 201, 101, 2, 538, 539, 5, 195, 98, 2, 539, 540, 5, 195, 98, 2, 540, 541, 5, 169, 85, 2, 541, 542, 5, 187, 94, 2, 542, 543, 5, 199, 100, 2, 543, 134, 3, 2, 2, 2, 544, 545, 5, 187, 94, 2, 545, 546, 5, 169, 85, 2, 546, 547, 5, 205, 103, 2, 547, 136, 3, 2, 2, 2, 548, 549, 5, 189, 95, 2, 549, 550, 5, 183, 92, 2, 550, 551, 5, 167, 84, 2, 551, 138, 3, 2, 2, 2, 552, 556, 9, 2, 2, 2, 553, 555, 9, 3, 2, 2, 554, 553, 3, 2, 2, 2, 555, 558, 3, 2, 2, 2, 556, 554, 3, 2, 2, 2, 556, 557, 3, 2, 2, 2, 557, 140, 3, 2, 2, 2, 558, 556, 3, 2, 2, 2, 559, 563, 9, 4, 2, 2, 560, 562, 5, 159, 80, 2, 561, 560, 3, 2, 2, 2, 562, 565, 3, 2, 2, 2, 563, 561, 3, 2, 2, 2, 563, 564, 3, 2, 2, 2, 564, 584, 3, 2, 2, 2, 565, 563, 3, 2, 2, 2, 566, 584, 7, 50, 2, 2, 567, 568, 7, 50, 2, 2, 568, 569, 7, 122, 2, 2, 569, 571, 3, 2, 2, 2, 570, 572, 5, 157, 79, 2, 571, 570, 3, 2, 2, 2, 572, 573, 3, 2, 2, 2, 573, 571, 3, 2, 2, 2, 573, 574, 3, 2, 2, 2, 574, 584, 3, 2, 2, 2, 575, 576, 7, 50, 2, 2, 576, 577, 7, 100, 2, 2, 577, 579, 3, 2, 2, 2, 578, 580, 9, 5, 2, 2, 579, 578, 3, 2, 2, 2, 580, 581, 3, 2, 2, 2, 581, 579, 3, 2, 2, 2, 581, 582, 3, 2, 2, 2, 582, 584, 3, 2, 2, 2, 583, 559, 3, 2, 2, 2, 583, 566, 3, 2, 2, 2, 583, 567, 3, 2, 2, 2, 583, 575, 3, 2, 2, 2, 584, 142, 3, 2, 2, 2, 585, 589, 9, 4, 2, 2, 586, 588, 5, 159, 80, 2, 587, 586, 3, 2, 2, 2, 588, 591, 3, 2, 2, 2, 589, 587, 3, 2, 2, 2, 589, 590, 3, 2, 2, 2, 590, 594, 3, 2, 2, 2, 591, 589, 3, 2, 2, 2, 592, 594, 7, 50, 2, 2, 593, 585, 3, 2, 2, 2, 593, 592, 3, 2, 2, 2, 593, 594, 3, 2, 2, 2, 594, 595, 3, 2, 2, 2, 595, 597, 7, 48, 2, 2, 596, 598, 5, 159, 80, 2, 597, 596, 3, 2, 2, 2, 598, 599, 3, 2, 2, 2, 599, 597, 3, 2, 2, 2, 599, 600, 3, 2, 2, 2, 600, 610, 3, 2, 2, 2, 601, 603, 5, 169, 85, 2, 602, 604, 9, 6, 2, 2, 603, 602, 3, 2, 2, 2, 603, 604, 3, 2, 2, 2, 604, 606, 3, 2, 2, 2, 605, 607, 5, 159, 80, 2, 606, 605, 3, 2, 2, 2, 607, 608, 3, 2, 2, 2, 608, 606, 3, 2, 2, 2, 608, 609, 3, 2, 2, 2, 609, 611, 3, 2, 2, 2, 610, 601, 3, 2, 2, 2, 610, 611, 3, 2, 2, 2, 611, 144, 3, 2, 2, 2, 612, 613, 7, 66, 2, 2, 613, 614, 5, 139, 70, 2, 614, 146, 3, 2, 2, 2, 615, 623, 7, 41, 2, 2, 616, 617, 7, 94, 2, 2, 617, 622, 11, 2, 2, 2, 618, 619, 7, 41, 2, 2, 619, 622, 7, 41, 2, 2, 620, 622, 10, 7, 2, 2, 621, 616, 3, 2, 2, 2, 621, 618, 3, 2, 2, 2, 621, 620, 3, 2, 2, 2, 622, 625, 3, 2, 2, 2, 623, 621, 3, 2, 2, 2, 623, 624, 3, 2, 2, 2, 624, 626, 3, 2, 2, 2, 625, 623, 3, 2, 2, 2, 626, 640, 7, 41, 2, 2, 627, 635, 7, 36, 2, 2, 628, 629, 7, 94, 2, 2, 629, 634, 11, 2, 2, 2, 630, 631, 7, 36, 2, 2, 631, 634, 7, 36, 2, 2, 632, 634, 10, 8, 2, 2, 633, 628, 3, 2, 2, 2, 633, 630, 3, 2, 2, 2, 633, 632, 3, 2, 2, 2, 634, 637, 3, 2, 2, 2, 635, 633, 3, 2, 2, 2, 635, 636, 3, 2, 2, 2, 636, 638, 3, 2, 2, 2, 637, 635, 3, 2, 2, 2, 638, 640, 7, 36, 2, 2, 639, 615, 3, 2, 2, 2, 639, 627, 3, 2, 2, 2, 640, 148, 3, 2, 2, 2, 641, 642, 7, 49, 2, 2, 642, 643, 7, 49, 2, 2, 643, 647, 3, 2, 2, 2, 644, 646, 10, 9, 2, 2, 645, 644, 3, 2, 2, 2, 646, 649, 3, 2, 2, 2, 647, 645, 3, 2, 2, 2, 647, 648, 3, 2, 2, 2, 648, 655, 3, 2, 2, 2, 649, 647, 3, 2, 2, 2, 650, 652, 7, 15, 2, 2, 651, 650, 3, 2, 2, 2, 651, 652, 3, 2, 2, 2, 652, 653, 3, 2, 2, 2, 653, 656, 7, 12, 2, 2, 654, 656, 7, 2, 2, 3, 655, 651, 3, 2, 2, 2, 655, 654, 3, 2, 2, 2, 656, 657, 3, 2, 2, 2, 657, 658, 8, 75, 2, 2, 658, 150, 3, 2, 2, 2, 659, 660, 7, 49, 2, 2, 660, 661, 7, 44, 2, 2, 661, 665, 3, 2, 2, 2, 662, 664, 11, 2, 2, 2, 663, 662, 3, 2, 2, 2, 664, 667, 3, 2, 2, 2, 665, 666, 3, 2, 2, 2, 665, 663, 3, 2, 2, 2, 666, 668, 3, 2, 2, 2, 667, 665, 3, 2, 2, 2, 668, 669, 7, 44, 2, 2, 669, 670, 7, 49, 2, 2, 670, 671, 3, 2, 2, 2, 671, 672, 8, 76, 2, 2, 672, 152, 3, 2, 2, 2, 673, 674, 9, 10, 2, 2, 674, 675, 3, 2, 2, 2, 675, 676, 8, 77, 2, 2, 676, 154, 3, 2, 2, 2, 677, 678, 11, 2, 2, 2, 678, 156, 3, 2, 2, 2, 679, 680, 9, 11, 2, 2, 680, 158, 3, 2, 2, 2, 681, 682, 9, 12, 2, 2, 682, 160, 3, 2, 2, 2, 683, 684, 9, 13, 2, 2, 684, 162, 3, 2, 2, 2, 685, 686, 9, 14, 2, 2, 686, 164, 3, 2, 2, 2, 687, 688, 9, 15, 2, 2, 688, 166, 3, 2, 2, 2, 689, 690, 9, 16, 2, 2, 690, 168, 3, 2, 2, 2, 691, 692, 9, 17, 2, 2, 692, 170, 3, 2, 2, 2, 693, 694, 9, 18, 2, 2, 694, 172, 3, 2, 2, 2, 695, 696, 9, 19, 2, 2, 696, 174, 3, 2, 2, 2, 697, 698, 9, 20, 2, 2, 698, 176, 3, 2, 2, 2, 699, 700, 9, 21, 2, 2, 700, 178, 3, 2, 2, 2, 701, 702, 9, 22, 2, 2, 702, 180, 3, 2, 2, 2, 703, 704, 9, 23, 2, 2, 704, 182, 3, 2, 2, 2, 705, 706, 9, 24, 2, 2, 706, 184, 3, 2, 2, 2, 707, 708, 9, 25, 2, 2, 708, 186, 3, 2, 2, 2, 709, 710, 9, 26, 2, 2, 710, 188, 3, 2, 2, 2, 711, 712, 9, 27, 2, 2, 712, 190, 3, 2, 2, 2, 713, 714, 9, 28, 2, 2, 714, 192, 3, 2, 2, 2, 715, 716, 9, 29, 2, 2, 716, 194, 3, 2, 2, 2, 717, 718, 9, 30, 2, 2, 718, 196, 3, 2, 2, 2, 719, 720, 9, 31, 2, 2, 720, 198, 3, 2, 2, 2, 721, 722, 9, 32, 2, 2, 722, 200, 3, 2, 2, 2, 723, 724, 9, 33, 2, 2, 724, 202, 3, 2, 2, 2, 725, 726, 9, 34, 2, 2, 726, 204, 3, 2, 2, 2, 727, 728, 9, 35, 2, 2, 728, 206, 3, 2, 2, 2, 729, 730, 9, 36, 2, 2, 730, 208, 3, 2, 2, 2, 731, 732, 9, 37, 2, 2, 732, 210, 3, 2, 2, 2, 733, 734, 9, 38, 2, 2, 734, 212, 3, 2, 2, 2, 735, 736, 11, 2, 2, 2, 736, 737, 3, 2, 2, 2, 737, 738, 8, 107, 3, 2, 738, 214, 3, 2, 2, 2, 26, 2, 293, 413, 425, 556, 563, 573, 581, 583, 589, 593, 599, 603, 608, 610, 621, 623, 633, 635, 639, 647, 651, 655, 665, 4, 2, 3, 2, 2, 4, 2] \ No newline at end of file diff --git a/ui/src/suggestions/grammar/RQLLexer.js b/ui/src/suggestions/grammar/RQLLexer.js new file mode 100644 index 0000000..3a65707 --- /dev/null +++ b/ui/src/suggestions/grammar/RQLLexer.js @@ -0,0 +1,607 @@ +// Generated from CAQLLexer.g4 by ANTLR 4.9.2 +// jshint ignore: start +import antlr4 from 'antlr4'; + + + +const serializedATN = ["\u0003\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786", + "\u5964\u0002P\u02e3\b\u0001\u0004\u0002\t\u0002\u0004\u0003\t\u0003", + "\u0004\u0004\t\u0004\u0004\u0005\t\u0005\u0004\u0006\t\u0006\u0004\u0007", + "\t\u0007\u0004\b\t\b\u0004\t\t\t\u0004\n\t\n\u0004\u000b\t\u000b\u0004", + "\f\t\f\u0004\r\t\r\u0004\u000e\t\u000e\u0004\u000f\t\u000f\u0004\u0010", + "\t\u0010\u0004\u0011\t\u0011\u0004\u0012\t\u0012\u0004\u0013\t\u0013", + "\u0004\u0014\t\u0014\u0004\u0015\t\u0015\u0004\u0016\t\u0016\u0004\u0017", + "\t\u0017\u0004\u0018\t\u0018\u0004\u0019\t\u0019\u0004\u001a\t\u001a", + "\u0004\u001b\t\u001b\u0004\u001c\t\u001c\u0004\u001d\t\u001d\u0004\u001e", + "\t\u001e\u0004\u001f\t\u001f\u0004 \t \u0004!\t!\u0004\"\t\"\u0004#", + "\t#\u0004$\t$\u0004%\t%\u0004&\t&\u0004\'\t\'\u0004(\t(\u0004)\t)\u0004", + "*\t*\u0004+\t+\u0004,\t,\u0004-\t-\u0004.\t.\u0004/\t/\u00040\t0\u0004", + "1\t1\u00042\t2\u00043\t3\u00044\t4\u00045\t5\u00046\t6\u00047\t7\u0004", + "8\t8\u00049\t9\u0004:\t:\u0004;\t;\u0004<\t<\u0004=\t=\u0004>\t>\u0004", + "?\t?\u0004@\t@\u0004A\tA\u0004B\tB\u0004C\tC\u0004D\tD\u0004E\tE\u0004", + "F\tF\u0004G\tG\u0004H\tH\u0004I\tI\u0004J\tJ\u0004K\tK\u0004L\tL\u0004", + "M\tM\u0004N\tN\u0004O\tO\u0004P\tP\u0004Q\tQ\u0004R\tR\u0004S\tS\u0004", + "T\tT\u0004U\tU\u0004V\tV\u0004W\tW\u0004X\tX\u0004Y\tY\u0004Z\tZ\u0004", + "[\t[\u0004\\\t\\\u0004]\t]\u0004^\t^\u0004_\t_\u0004`\t`\u0004a\ta\u0004", + "b\tb\u0004c\tc\u0004d\td\u0004e\te\u0004f\tf\u0004g\tg\u0004h\th\u0004", + "i\ti\u0004j\tj\u0004k\tk\u0003\u0002\u0003\u0002\u0003\u0003\u0003\u0003", + "\u0003\u0003\u0003\u0004\u0003\u0004\u0003\u0004\u0003\u0005\u0003\u0005", + "\u0003\u0005\u0003\u0006\u0003\u0006\u0003\u0006\u0003\u0007\u0003\u0007", + "\u0003\b\u0003\b\u0003\t\u0003\t\u0003\t\u0003\n\u0003\n\u0003\n\u0003", + "\u000b\u0003\u000b\u0003\f\u0003\f\u0003\r\u0003\r\u0003\u000e\u0003", + "\u000e\u0003\u000f\u0003\u000f\u0003\u0010\u0003\u0010\u0003\u0011\u0003", + "\u0011\u0003\u0012\u0003\u0012\u0003\u0012\u0003\u0013\u0003\u0013\u0003", + "\u0013\u0003\u0014\u0003\u0014\u0003\u0015\u0003\u0015\u0003\u0016\u0003", + "\u0016\u0003\u0017\u0003\u0017\u0003\u0018\u0003\u0018\u0003\u0019\u0003", + "\u0019\u0003\u001a\u0003\u001a\u0003\u001b\u0003\u001b\u0003\u001b\u0003", + "\u001b\u0003\u001b\u0003\u001b\u0003\u001b\u0003\u001b\u0003\u001b\u0003", + "\u001b\u0003\u001c\u0003\u001c\u0003\u001c\u0003\u001c\u0003\u001d\u0003", + "\u001d\u0003\u001d\u0003\u001d\u0003\u001d\u0003\u001d\u0005\u001d\u0126", + "\n\u001d\u0003\u001e\u0003\u001e\u0003\u001e\u0003\u001e\u0003\u001f", + "\u0003\u001f\u0003\u001f\u0003\u001f\u0003 \u0003 \u0003 \u0003 \u0003", + " \u0003 \u0003 \u0003 \u0003!\u0003!\u0003!\u0003!\u0003!\u0003\"\u0003", + "\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003\"\u0003#\u0003", + "#\u0003#\u0003#\u0003#\u0003#\u0003$\u0003$\u0003$\u0003$\u0003$\u0003", + "$\u0003$\u0003%\u0003%\u0003%\u0003%\u0003&\u0003&\u0003&\u0003&\u0003", + "&\u0003&\u0003\'\u0003\'\u0003\'\u0003(\u0003(\u0003(\u0003(\u0003(", + "\u0003(\u0003(\u0003(\u0003)\u0003)\u0003)\u0003)\u0003)\u0003)\u0003", + ")\u0003*\u0003*\u0003*\u0003*\u0003*\u0003+\u0003+\u0003+\u0003+\u0003", + "+\u0003+\u0003+\u0003+\u0003+\u0003+\u0003+\u0003+\u0003+\u0003+\u0003", + "+\u0003+\u0003+\u0003,\u0003,\u0003,\u0003,\u0003-\u0003-\u0003-\u0003", + "-\u0003-\u0003.\u0003.\u0003.\u0003.\u0003.\u0003.\u0003/\u0003/\u0003", + "/\u0003/\u0003/\u00030\u00030\u00030\u00030\u00030\u00050\u019e\n0\u0003", + "1\u00031\u00031\u00031\u00031\u00032\u00032\u00032\u00032\u00032\u0005", + "2\u01aa\n2\u00033\u00033\u00033\u00033\u00033\u00033\u00033\u00033\u0003", + "3\u00034\u00034\u00034\u00034\u00034\u00034\u00034\u00035\u00035\u0003", + "5\u00035\u00035\u00035\u00035\u00035\u00036\u00036\u00036\u00036\u0003", + "6\u00036\u00036\u00037\u00037\u00037\u00037\u00037\u00037\u00037\u0003", + "7\u00037\u00037\u00037\u00037\u00037\u00037\u00038\u00038\u00038\u0003", + "8\u00038\u00039\u00039\u00039\u00039\u00039\u0003:\u0003:\u0003:\u0003", + ":\u0003:\u0003:\u0003:\u0003;\u0003;\u0003;\u0003;\u0003;\u0003;\u0003", + ";\u0003<\u0003<\u0003<\u0003<\u0003<\u0003=\u0003=\u0003=\u0003=\u0003", + "=\u0003>\u0003>\u0003>\u0003>\u0003>\u0003>\u0003?\u0003?\u0003?\u0003", + "?\u0003?\u0003?\u0003?\u0003?\u0003@\u0003@\u0003@\u0003@\u0003@\u0003", + "@\u0003A\u0003A\u0003A\u0003A\u0003A\u0003A\u0003A\u0003B\u0003B\u0003", + "B\u0003C\u0003C\u0003C\u0003C\u0003C\u0003C\u0003C\u0003C\u0003D\u0003", + "D\u0003D\u0003D\u0003E\u0003E\u0003E\u0003E\u0003F\u0003F\u0007F\u022b", + "\nF\fF\u000eF\u022e\u000bF\u0003G\u0003G\u0007G\u0232\nG\fG\u000eG\u0235", + "\u000bG\u0003G\u0003G\u0003G\u0003G\u0003G\u0006G\u023c\nG\rG\u000e", + "G\u023d\u0003G\u0003G\u0003G\u0003G\u0006G\u0244\nG\rG\u000eG\u0245", + "\u0005G\u0248\nG\u0003H\u0003H\u0007H\u024c\nH\fH\u000eH\u024f\u000b", + "H\u0003H\u0005H\u0252\nH\u0003H\u0003H\u0006H\u0256\nH\rH\u000eH\u0257", + "\u0003H\u0003H\u0005H\u025c\nH\u0003H\u0006H\u025f\nH\rH\u000eH\u0260", + "\u0005H\u0263\nH\u0003I\u0003I\u0003I\u0003J\u0003J\u0003J\u0003J\u0003", + "J\u0003J\u0007J\u026e\nJ\fJ\u000eJ\u0271\u000bJ\u0003J\u0003J\u0003", + "J\u0003J\u0003J\u0003J\u0003J\u0007J\u027a\nJ\fJ\u000eJ\u027d\u000b", + "J\u0003J\u0005J\u0280\nJ\u0003K\u0003K\u0003K\u0003K\u0007K\u0286\n", + "K\fK\u000eK\u0289\u000bK\u0003K\u0005K\u028c\nK\u0003K\u0003K\u0005", + "K\u0290\nK\u0003K\u0003K\u0003L\u0003L\u0003L\u0003L\u0007L\u0298\n", + "L\fL\u000eL\u029b\u000bL\u0003L\u0003L\u0003L\u0003L\u0003L\u0003M\u0003", + "M\u0003M\u0003M\u0003N\u0003N\u0003O\u0003O\u0003P\u0003P\u0003Q\u0003", + "Q\u0003R\u0003R\u0003S\u0003S\u0003T\u0003T\u0003U\u0003U\u0003V\u0003", + "V\u0003W\u0003W\u0003X\u0003X\u0003Y\u0003Y\u0003Z\u0003Z\u0003[\u0003", + "[\u0003\\\u0003\\\u0003]\u0003]\u0003^\u0003^\u0003_\u0003_\u0003`\u0003", + "`\u0003a\u0003a\u0003b\u0003b\u0003c\u0003c\u0003d\u0003d\u0003e\u0003", + "e\u0003f\u0003f\u0003g\u0003g\u0003h\u0003h\u0003i\u0003i\u0003j\u0003", + "j\u0003k\u0003k\u0003k\u0003k\u0003\u0299\u0002l\u0003\u0003\u0005\u0004", + "\u0007\u0005\t\u0006\u000b\u0007\r\b\u000f\t\u0011\n\u0013\u000b\u0015", + "\f\u0017\r\u0019\u000e\u001b\u000f\u001d\u0010\u001f\u0011!\u0012#\u0013", + "%\u0014\'\u0015)\u0016+\u0017-\u0018/\u00191\u001a3\u001b5\u001c7\u001d", + "9\u001e;\u001f= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]0_1a2c3e4g5i6k7m8o", + "9q:s;u{?}@\u007fA\u0081B\u0083C\u0085D\u0087E\u0089F\u008bG\u008d", + "H\u008fI\u0091J\u0093K\u0095L\u0097M\u0099N\u009bO\u009d\u0002\u009f", + "\u0002\u00a1\u0002\u00a3\u0002\u00a5\u0002\u00a7\u0002\u00a9\u0002\u00ab", + "\u0002\u00ad\u0002\u00af\u0002\u00b1\u0002\u00b3\u0002\u00b5\u0002\u00b7", + "\u0002\u00b9\u0002\u00bb\u0002\u00bd\u0002\u00bf\u0002\u00c1\u0002\u00c3", + "\u0002\u00c5\u0002\u00c7\u0002\u00c9\u0002\u00cb\u0002\u00cd\u0002\u00cf", + "\u0002\u00d1\u0002\u00d3\u0002\u00d5P\u0003\u0002\'\u0005\u0002C\\a", + "ac|\u0006\u00022;C\\aac|\u0003\u00023;\u0003\u000223\u0004\u0002--/", + "/\u0004\u0002))^^\u0004\u0002$$^^\u0004\u0002\f\f\u000f\u000f\u0005", + "\u0002\u000b\r\u000f\u000f\"\"\u0005\u00022;CHch\u0003\u00022;\u0004", + "\u0002CCcc\u0004\u0002DDdd\u0004\u0002EEee\u0004\u0002FFff\u0004\u0002", + "GGgg\u0004\u0002HHhh\u0004\u0002IIii\u0004\u0002JJjj\u0004\u0002KKk", + "k\u0004\u0002LLll\u0004\u0002MMmm\u0004\u0002NNnn\u0004\u0002OOoo\u0004", + "\u0002PPpp\u0004\u0002QQqq\u0004\u0002RRrr\u0004\u0002SSss\u0004\u0002", + "TTtt\u0004\u0002UUuu\u0004\u0002VVvv\u0004\u0002WWww\u0004\u0002XXx", + "x\u0004\u0002YYyy\u0004\u0002ZZzz\u0004\u0002[[{{\u0004\u0002\\\\||", + "\u0002\u02e2\u0002\u0003\u0003\u0002\u0002\u0002\u0002\u0005\u0003\u0002", + "\u0002\u0002\u0002\u0007\u0003\u0002\u0002\u0002\u0002\t\u0003\u0002", + "\u0002\u0002\u0002\u000b\u0003\u0002\u0002\u0002\u0002\r\u0003\u0002", + "\u0002\u0002\u0002\u000f\u0003\u0002\u0002\u0002\u0002\u0011\u0003\u0002", + "\u0002\u0002\u0002\u0013\u0003\u0002\u0002\u0002\u0002\u0015\u0003\u0002", + "\u0002\u0002\u0002\u0017\u0003\u0002\u0002\u0002\u0002\u0019\u0003\u0002", + "\u0002\u0002\u0002\u001b\u0003\u0002\u0002\u0002\u0002\u001d\u0003\u0002", + "\u0002\u0002\u0002\u001f\u0003\u0002\u0002\u0002\u0002!\u0003\u0002", + "\u0002\u0002\u0002#\u0003\u0002\u0002\u0002\u0002%\u0003\u0002\u0002", + "\u0002\u0002\'\u0003\u0002\u0002\u0002\u0002)\u0003\u0002\u0002\u0002", + "\u0002+\u0003\u0002\u0002\u0002\u0002-\u0003\u0002\u0002\u0002\u0002", + "/\u0003\u0002\u0002\u0002\u00021\u0003\u0002\u0002\u0002\u00023\u0003", + "\u0002\u0002\u0002\u00025\u0003\u0002\u0002\u0002\u00027\u0003\u0002", + "\u0002\u0002\u00029\u0003\u0002\u0002\u0002\u0002;\u0003\u0002\u0002", + "\u0002\u0002=\u0003\u0002\u0002\u0002\u0002?\u0003\u0002\u0002\u0002", + "\u0002A\u0003\u0002\u0002\u0002\u0002C\u0003\u0002\u0002\u0002\u0002", + "E\u0003\u0002\u0002\u0002\u0002G\u0003\u0002\u0002\u0002\u0002I\u0003", + "\u0002\u0002\u0002\u0002K\u0003\u0002\u0002\u0002\u0002M\u0003\u0002", + "\u0002\u0002\u0002O\u0003\u0002\u0002\u0002\u0002Q\u0003\u0002\u0002", + "\u0002\u0002S\u0003\u0002\u0002\u0002\u0002U\u0003\u0002\u0002\u0002", + "\u0002W\u0003\u0002\u0002\u0002\u0002Y\u0003\u0002\u0002\u0002\u0002", + "[\u0003\u0002\u0002\u0002\u0002]\u0003\u0002\u0002\u0002\u0002_\u0003", + "\u0002\u0002\u0002\u0002a\u0003\u0002\u0002\u0002\u0002c\u0003\u0002", + "\u0002\u0002\u0002e\u0003\u0002\u0002\u0002\u0002g\u0003\u0002\u0002", + "\u0002\u0002i\u0003\u0002\u0002\u0002\u0002k\u0003\u0002\u0002\u0002", + "\u0002m\u0003\u0002\u0002\u0002\u0002o\u0003\u0002\u0002\u0002\u0002", + "q\u0003\u0002\u0002\u0002\u0002s\u0003\u0002\u0002\u0002\u0002u\u0003", + "\u0002\u0002\u0002\u0002w\u0003\u0002\u0002\u0002\u0002y\u0003\u0002", + "\u0002\u0002\u0002{\u0003\u0002\u0002\u0002\u0002}\u0003\u0002\u0002", + "\u0002\u0002\u007f\u0003\u0002\u0002\u0002\u0002\u0081\u0003\u0002\u0002", + "\u0002\u0002\u0083\u0003\u0002\u0002\u0002\u0002\u0085\u0003\u0002\u0002", + "\u0002\u0002\u0087\u0003\u0002\u0002\u0002\u0002\u0089\u0003\u0002\u0002", + "\u0002\u0002\u008b\u0003\u0002\u0002\u0002\u0002\u008d\u0003\u0002\u0002", + "\u0002\u0002\u008f\u0003\u0002\u0002\u0002\u0002\u0091\u0003\u0002\u0002", + "\u0002\u0002\u0093\u0003\u0002\u0002\u0002\u0002\u0095\u0003\u0002\u0002", + "\u0002\u0002\u0097\u0003\u0002\u0002\u0002\u0002\u0099\u0003\u0002\u0002", + "\u0002\u0002\u009b\u0003\u0002\u0002\u0002\u0002\u00d5\u0003\u0002\u0002", + "\u0002\u0003\u00d7\u0003\u0002\u0002\u0002\u0005\u00d9\u0003\u0002\u0002", + "\u0002\u0007\u00dc\u0003\u0002\u0002\u0002\t\u00df\u0003\u0002\u0002", + "\u0002\u000b\u00e2\u0003\u0002\u0002\u0002\r\u00e5\u0003\u0002\u0002", + "\u0002\u000f\u00e7\u0003\u0002\u0002\u0002\u0011\u00e9\u0003\u0002\u0002", + "\u0002\u0013\u00ec\u0003\u0002\u0002\u0002\u0015\u00ef\u0003\u0002\u0002", + "\u0002\u0017\u00f1\u0003\u0002\u0002\u0002\u0019\u00f3\u0003\u0002\u0002", + "\u0002\u001b\u00f5\u0003\u0002\u0002\u0002\u001d\u00f7\u0003\u0002\u0002", + "\u0002\u001f\u00f9\u0003\u0002\u0002\u0002!\u00fb\u0003\u0002\u0002", + "\u0002#\u00fd\u0003\u0002\u0002\u0002%\u0100\u0003\u0002\u0002\u0002", + "\'\u0103\u0003\u0002\u0002\u0002)\u0105\u0003\u0002\u0002\u0002+\u0107", + "\u0003\u0002\u0002\u0002-\u0109\u0003\u0002\u0002\u0002/\u010b\u0003", + "\u0002\u0002\u00021\u010d\u0003\u0002\u0002\u00023\u010f\u0003\u0002", + "\u0002\u00025\u0111\u0003\u0002\u0002\u00027\u011b\u0003\u0002\u0002", + "\u00029\u0125\u0003\u0002\u0002\u0002;\u0127\u0003\u0002\u0002\u0002", + "=\u012b\u0003\u0002\u0002\u0002?\u012f\u0003\u0002\u0002\u0002A\u0137", + "\u0003\u0002\u0002\u0002C\u013c\u0003\u0002\u0002\u0002E\u0145\u0003", + "\u0002\u0002\u0002G\u014b\u0003\u0002\u0002\u0002I\u0152\u0003\u0002", + "\u0002\u0002K\u0156\u0003\u0002\u0002\u0002M\u015c\u0003\u0002\u0002", + "\u0002O\u015f\u0003\u0002\u0002\u0002Q\u0167\u0003\u0002\u0002\u0002", + "S\u016e\u0003\u0002\u0002\u0002U\u0173\u0003\u0002\u0002\u0002W\u0184", + "\u0003\u0002\u0002\u0002Y\u0188\u0003\u0002\u0002\u0002[\u018d\u0003", + "\u0002\u0002\u0002]\u0193\u0003\u0002\u0002\u0002_\u019d\u0003\u0002", + "\u0002\u0002a\u019f\u0003\u0002\u0002\u0002c\u01a9\u0003\u0002\u0002", + "\u0002e\u01ab\u0003\u0002\u0002\u0002g\u01b4\u0003\u0002\u0002\u0002", + "i\u01bb\u0003\u0002\u0002\u0002k\u01c3\u0003\u0002\u0002\u0002m\u01ca", + "\u0003\u0002\u0002\u0002o\u01d8\u0003\u0002\u0002\u0002q\u01dd\u0003", + "\u0002\u0002\u0002s\u01e2\u0003\u0002\u0002\u0002u\u01e9\u0003\u0002", + "\u0002\u0002w\u01f0\u0003\u0002\u0002\u0002y\u01f5\u0003\u0002\u0002", + "\u0002{\u01fa\u0003\u0002\u0002\u0002}\u0200\u0003\u0002\u0002\u0002", + "\u007f\u0208\u0003\u0002\u0002\u0002\u0081\u020e\u0003\u0002\u0002\u0002", + "\u0083\u0215\u0003\u0002\u0002\u0002\u0085\u0218\u0003\u0002\u0002\u0002", + "\u0087\u0220\u0003\u0002\u0002\u0002\u0089\u0224\u0003\u0002\u0002\u0002", + "\u008b\u0228\u0003\u0002\u0002\u0002\u008d\u0247\u0003\u0002\u0002\u0002", + "\u008f\u0251\u0003\u0002\u0002\u0002\u0091\u0264\u0003\u0002\u0002\u0002", + "\u0093\u027f\u0003\u0002\u0002\u0002\u0095\u0281\u0003\u0002\u0002\u0002", + "\u0097\u0293\u0003\u0002\u0002\u0002\u0099\u02a1\u0003\u0002\u0002\u0002", + "\u009b\u02a5\u0003\u0002\u0002\u0002\u009d\u02a7\u0003\u0002\u0002\u0002", + "\u009f\u02a9\u0003\u0002\u0002\u0002\u00a1\u02ab\u0003\u0002\u0002\u0002", + "\u00a3\u02ad\u0003\u0002\u0002\u0002\u00a5\u02af\u0003\u0002\u0002\u0002", + "\u00a7\u02b1\u0003\u0002\u0002\u0002\u00a9\u02b3\u0003\u0002\u0002\u0002", + "\u00ab\u02b5\u0003\u0002\u0002\u0002\u00ad\u02b7\u0003\u0002\u0002\u0002", + "\u00af\u02b9\u0003\u0002\u0002\u0002\u00b1\u02bb\u0003\u0002\u0002\u0002", + "\u00b3\u02bd\u0003\u0002\u0002\u0002\u00b5\u02bf\u0003\u0002\u0002\u0002", + "\u00b7\u02c1\u0003\u0002\u0002\u0002\u00b9\u02c3\u0003\u0002\u0002\u0002", + "\u00bb\u02c5\u0003\u0002\u0002\u0002\u00bd\u02c7\u0003\u0002\u0002\u0002", + "\u00bf\u02c9\u0003\u0002\u0002\u0002\u00c1\u02cb\u0003\u0002\u0002\u0002", + "\u00c3\u02cd\u0003\u0002\u0002\u0002\u00c5\u02cf\u0003\u0002\u0002\u0002", + "\u00c7\u02d1\u0003\u0002\u0002\u0002\u00c9\u02d3\u0003\u0002\u0002\u0002", + "\u00cb\u02d5\u0003\u0002\u0002\u0002\u00cd\u02d7\u0003\u0002\u0002\u0002", + "\u00cf\u02d9\u0003\u0002\u0002\u0002\u00d1\u02db\u0003\u0002\u0002\u0002", + "\u00d3\u02dd\u0003\u0002\u0002\u0002\u00d5\u02df\u0003\u0002\u0002\u0002", + "\u00d7\u00d8\u00070\u0002\u0002\u00d8\u0004\u0003\u0002\u0002\u0002", + "\u00d9\u00da\u0007?\u0002\u0002\u00da\u00db\u0007\u0080\u0002\u0002", + "\u00db\u0006\u0003\u0002\u0002\u0002\u00dc\u00dd\u0007#\u0002\u0002", + "\u00dd\u00de\u0007\u0080\u0002\u0002\u00de\b\u0003\u0002\u0002\u0002", + "\u00df\u00e0\u0007?\u0002\u0002\u00e0\u00e1\u0007?\u0002\u0002\u00e1", + "\n\u0003\u0002\u0002\u0002\u00e2\u00e3\u0007#\u0002\u0002\u00e3\u00e4", + "\u0007?\u0002\u0002\u00e4\f\u0003\u0002\u0002\u0002\u00e5\u00e6\u0007", + ">\u0002\u0002\u00e6\u000e\u0003\u0002\u0002\u0002\u00e7\u00e8\u0007", + "@\u0002\u0002\u00e8\u0010\u0003\u0002\u0002\u0002\u00e9\u00ea\u0007", + ">\u0002\u0002\u00ea\u00eb\u0007?\u0002\u0002\u00eb\u0012\u0003\u0002", + "\u0002\u0002\u00ec\u00ed\u0007@\u0002\u0002\u00ed\u00ee\u0007?\u0002", + "\u0002\u00ee\u0014\u0003\u0002\u0002\u0002\u00ef\u00f0\u0007-\u0002", + "\u0002\u00f0\u0016\u0003\u0002\u0002\u0002\u00f1\u00f2\u0007/\u0002", + "\u0002\u00f2\u0018\u0003\u0002\u0002\u0002\u00f3\u00f4\u0007,\u0002", + "\u0002\u00f4\u001a\u0003\u0002\u0002\u0002\u00f5\u00f6\u00071\u0002", + "\u0002\u00f6\u001c\u0003\u0002\u0002\u0002\u00f7\u00f8\u0007\'\u0002", + "\u0002\u00f8\u001e\u0003\u0002\u0002\u0002\u00f9\u00fa\u0007A\u0002", + "\u0002\u00fa \u0003\u0002\u0002\u0002\u00fb\u00fc\u0007<\u0002\u0002", + "\u00fc\"\u0003\u0002\u0002\u0002\u00fd\u00fe\u0007<\u0002\u0002\u00fe", + "\u00ff\u0007<\u0002\u0002\u00ff$\u0003\u0002\u0002\u0002\u0100\u0101", + "\u00070\u0002\u0002\u0101\u0102\u00070\u0002\u0002\u0102&\u0003\u0002", + "\u0002\u0002\u0103\u0104\u0007.\u0002\u0002\u0104(\u0003\u0002\u0002", + "\u0002\u0105\u0106\u0007*\u0002\u0002\u0106*\u0003\u0002\u0002\u0002", + "\u0107\u0108\u0007+\u0002\u0002\u0108,\u0003\u0002\u0002\u0002\u0109", + "\u010a\u0007}\u0002\u0002\u010a.\u0003\u0002\u0002\u0002\u010b\u010c", + "\u0007\u007f\u0002\u0002\u010c0\u0003\u0002\u0002\u0002\u010d\u010e", + "\u0007]\u0002\u0002\u010e2\u0003\u0002\u0002\u0002\u010f\u0110\u0007", + "_\u0002\u0002\u01104\u0003\u0002\u0002\u0002\u0111\u0112\u0005\u00a1", + "Q\u0002\u0112\u0113\u0005\u00adW\u0002\u0113\u0114\u0005\u00adW\u0002", + "\u0114\u0115\u0005\u00c3b\u0002\u0115\u0116\u0005\u00a9U\u0002\u0116", + "\u0117\u0005\u00adW\u0002\u0117\u0118\u0005\u00a1Q\u0002\u0118\u0119", + "\u0005\u00c7d\u0002\u0119\u011a\u0005\u00a9U\u0002\u011a6\u0003\u0002", + "\u0002\u0002\u011b\u011c\u0005\u00a1Q\u0002\u011c\u011d\u0005\u00b7", + "\\\u0002\u011d\u011e\u0005\u00b7\\\u0002\u011e8\u0003\u0002\u0002\u0002", + "\u011f\u0120\u0005\u00a1Q\u0002\u0120\u0121\u0005\u00bb^\u0002\u0121", + "\u0122\u0005\u00a7T\u0002\u0122\u0126\u0003\u0002\u0002\u0002\u0123", + "\u0124\u0007(\u0002\u0002\u0124\u0126\u0007(\u0002\u0002\u0125\u011f", + "\u0003\u0002\u0002\u0002\u0125\u0123\u0003\u0002\u0002\u0002\u0126:", + "\u0003\u0002\u0002\u0002\u0127\u0128\u0005\u00a1Q\u0002\u0128\u0129", + "\u0005\u00bb^\u0002\u0129\u012a\u0005\u00d1i\u0002\u012a<\u0003\u0002", + "\u0002\u0002\u012b\u012c\u0005\u00a1Q\u0002\u012c\u012d\u0005\u00c5", + "c\u0002\u012d\u012e\u0005\u00a5S\u0002\u012e>\u0003\u0002\u0002\u0002", + "\u012f\u0130\u0005\u00a5S\u0002\u0130\u0131\u0005\u00bd_\u0002\u0131", + "\u0132\u0005\u00b7\\\u0002\u0132\u0133\u0005\u00b7\\\u0002\u0133\u0134", + "\u0005\u00a9U\u0002\u0134\u0135\u0005\u00a5S\u0002\u0135\u0136\u0005", + "\u00c7d\u0002\u0136@\u0003\u0002\u0002\u0002\u0137\u0138\u0005\u00a7", + "T\u0002\u0138\u0139\u0005\u00a9U\u0002\u0139\u013a\u0005\u00c5c\u0002", + "\u013a\u013b\u0005\u00a5S\u0002\u013bB\u0003\u0002\u0002\u0002\u013c", + "\u013d\u0005\u00a7T\u0002\u013d\u013e\u0005\u00b1Y\u0002\u013e\u013f", + "\u0005\u00c5c\u0002\u013f\u0140\u0005\u00c7d\u0002\u0140\u0141\u0005", + "\u00b1Y\u0002\u0141\u0142\u0005\u00bb^\u0002\u0142\u0143\u0005\u00a5", + "S\u0002\u0143\u0144\u0005\u00c7d\u0002\u0144D\u0003\u0002\u0002\u0002", + "\u0145\u0146\u0005\u00abV\u0002\u0146\u0147\u0005\u00a1Q\u0002\u0147", + "\u0148\u0005\u00b7\\\u0002\u0148\u0149\u0005\u00c5c\u0002\u0149\u014a", + "\u0005\u00a9U\u0002\u014aF\u0003\u0002\u0002\u0002\u014b\u014c\u0005", + "\u00abV\u0002\u014c\u014d\u0005\u00b1Y\u0002\u014d\u014e\u0005\u00b7", + "\\\u0002\u014e\u014f\u0005\u00c7d\u0002\u014f\u0150\u0005\u00a9U\u0002", + "\u0150\u0151\u0005\u00c3b\u0002\u0151H\u0003\u0002\u0002\u0002\u0152", + "\u0153\u0005\u00abV\u0002\u0153\u0154\u0005\u00bd_\u0002\u0154\u0155", + "\u0005\u00c3b\u0002\u0155J\u0003\u0002\u0002\u0002\u0156\u0157\u0005", + "\u00adW\u0002\u0157\u0158\u0005\u00c3b\u0002\u0158\u0159\u0005\u00a1", + "Q\u0002\u0159\u015a\u0005\u00bf`\u0002\u015a\u015b\u0005\u00afX\u0002", + "\u015bL\u0003\u0002\u0002\u0002\u015c\u015d\u0005\u00b1Y\u0002\u015d", + "\u015e\u0005\u00bb^\u0002\u015eN\u0003\u0002\u0002\u0002\u015f\u0160", + "\u0005\u00b1Y\u0002\u0160\u0161\u0005\u00bb^\u0002\u0161\u0162\u0005", + "\u00a3R\u0002\u0162\u0163\u0005\u00bd_\u0002\u0163\u0164\u0005\u00c9", + "e\u0002\u0164\u0165\u0005\u00bb^\u0002\u0165\u0166\u0005\u00a7T\u0002", + "\u0166P\u0003\u0002\u0002\u0002\u0167\u0168\u0005\u00b1Y\u0002\u0168", + "\u0169\u0005\u00bb^\u0002\u0169\u016a\u0005\u00c5c\u0002\u016a\u016b", + "\u0005\u00a9U\u0002\u016b\u016c\u0005\u00c3b\u0002\u016c\u016d\u0005", + "\u00c7d\u0002\u016dR\u0003\u0002\u0002\u0002\u016e\u016f\u0005\u00b1", + "Y\u0002\u016f\u0170\u0005\u00bb^\u0002\u0170\u0171\u0005\u00c7d\u0002", + "\u0171\u0172\u0005\u00bd_\u0002\u0172T\u0003\u0002\u0002\u0002\u0173", + "\u0174\u0005\u00b5[\u0002\u0174\u0175\u0007a\u0002\u0002\u0175\u0176", + "\u0005\u00c5c\u0002\u0176\u0177\u0005\u00afX\u0002\u0177\u0178\u0005", + "\u00bd_\u0002\u0178\u0179\u0005\u00c3b\u0002\u0179\u017a\u0005\u00c7", + "d\u0002\u017a\u017b\u0005\u00a9U\u0002\u017b\u017c\u0005\u00c5c\u0002", + "\u017c\u017d\u0005\u00c7d\u0002\u017d\u017e\u0007a\u0002\u0002\u017e", + "\u017f\u0005\u00bf`\u0002\u017f\u0180\u0005\u00a1Q\u0002\u0180\u0181", + "\u0005\u00c7d\u0002\u0181\u0182\u0005\u00afX\u0002\u0182\u0183\u0005", + "\u00c5c\u0002\u0183V\u0003\u0002\u0002\u0002\u0184\u0185\u0005\u00b7", + "\\\u0002\u0185\u0186\u0005\u00a9U\u0002\u0186\u0187\u0005\u00c7d\u0002", + "\u0187X\u0003\u0002\u0002\u0002\u0188\u0189\u0005\u00b7\\\u0002\u0189", + "\u018a\u0005\u00b1Y\u0002\u018a\u018b\u0005\u00b5[\u0002\u018b\u018c", + "\u0005\u00a9U\u0002\u018cZ\u0003\u0002\u0002\u0002\u018d\u018e\u0005", + "\u00b7\\\u0002\u018e\u018f\u0005\u00b1Y\u0002\u018f\u0190\u0005\u00b9", + "]\u0002\u0190\u0191\u0005\u00b1Y\u0002\u0191\u0192\u0005\u00c7d\u0002", + "\u0192\\\u0003\u0002\u0002\u0002\u0193\u0194\u0005\u00bb^\u0002\u0194", + "\u0195\u0005\u00bd_\u0002\u0195\u0196\u0005\u00bb^\u0002\u0196\u0197", + "\u0005\u00a9U\u0002\u0197^\u0003\u0002\u0002\u0002\u0198\u0199\u0005", + "\u00bb^\u0002\u0199\u019a\u0005\u00bd_\u0002\u019a\u019b\u0005\u00c7", + "d\u0002\u019b\u019e\u0003\u0002\u0002\u0002\u019c\u019e\u0007#\u0002", + "\u0002\u019d\u0198\u0003\u0002\u0002\u0002\u019d\u019c\u0003\u0002\u0002", + "\u0002\u019e`\u0003\u0002\u0002\u0002\u019f\u01a0\u0005\u00bb^\u0002", + "\u01a0\u01a1\u0005\u00c9e\u0002\u01a1\u01a2\u0005\u00b7\\\u0002\u01a2", + "\u01a3\u0005\u00b7\\\u0002\u01a3b\u0003\u0002\u0002\u0002\u01a4\u01a5", + "\u0005\u00bd_\u0002\u01a5\u01a6\u0005\u00c3b\u0002\u01a6\u01aa\u0003", + "\u0002\u0002\u0002\u01a7\u01a8\u0007~\u0002\u0002\u01a8\u01aa\u0007", + "~\u0002\u0002\u01a9\u01a4\u0003\u0002\u0002\u0002\u01a9\u01a7\u0003", + "\u0002\u0002\u0002\u01aad\u0003\u0002\u0002\u0002\u01ab\u01ac\u0005", + "\u00bd_\u0002\u01ac\u01ad\u0005\u00c9e\u0002\u01ad\u01ae\u0005\u00c7", + "d\u0002\u01ae\u01af\u0005\u00a3R\u0002\u01af\u01b0\u0005\u00bd_\u0002", + "\u01b0\u01b1\u0005\u00c9e\u0002\u01b1\u01b2\u0005\u00bb^\u0002\u01b2", + "\u01b3\u0005\u00a7T\u0002\u01b3f\u0003\u0002\u0002\u0002\u01b4\u01b5", + "\u0005\u00c3b\u0002\u01b5\u01b6\u0005\u00a9U\u0002\u01b6\u01b7\u0005", + "\u00b9]\u0002\u01b7\u01b8\u0005\u00bd_\u0002\u01b8\u01b9\u0005\u00cb", + "f\u0002\u01b9\u01ba\u0005\u00a9U\u0002\u01bah\u0003\u0002\u0002\u0002", + "\u01bb\u01bc\u0005\u00c3b\u0002\u01bc\u01bd\u0005\u00a9U\u0002\u01bd", + "\u01be\u0005\u00bf`\u0002\u01be\u01bf\u0005\u00b7\\\u0002\u01bf\u01c0", + "\u0005\u00a1Q\u0002\u01c0\u01c1\u0005\u00a5S\u0002\u01c1\u01c2\u0005", + "\u00a9U\u0002\u01c2j\u0003\u0002\u0002\u0002\u01c3\u01c4\u0005\u00c3", + "b\u0002\u01c4\u01c5\u0005\u00a9U\u0002\u01c5\u01c6\u0005\u00c7d\u0002", + "\u01c6\u01c7\u0005\u00c9e\u0002\u01c7\u01c8\u0005\u00c3b\u0002\u01c8", + "\u01c9\u0005\u00bb^\u0002\u01c9l\u0003\u0002\u0002\u0002\u01ca\u01cb", + "\u0005\u00c5c\u0002\u01cb\u01cc\u0005\u00afX\u0002\u01cc\u01cd\u0005", + "\u00bd_\u0002\u01cd\u01ce\u0005\u00c3b\u0002\u01ce\u01cf\u0005\u00c7", + "d\u0002\u01cf\u01d0\u0005\u00a9U\u0002\u01d0\u01d1\u0005\u00c5c\u0002", + "\u01d1\u01d2\u0005\u00c7d\u0002\u01d2\u01d3\u0007a\u0002\u0002\u01d3", + "\u01d4\u0005\u00bf`\u0002\u01d4\u01d5\u0005\u00a1Q\u0002\u01d5\u01d6", + "\u0005\u00c7d\u0002\u01d6\u01d7\u0005\u00afX\u0002\u01d7n\u0003\u0002", + "\u0002\u0002\u01d8\u01d9\u0005\u00c5c\u0002\u01d9\u01da\u0005\u00bd", + "_\u0002\u01da\u01db\u0005\u00c3b\u0002\u01db\u01dc\u0005\u00c7d\u0002", + "\u01dcp\u0003\u0002\u0002\u0002\u01dd\u01de\u0005\u00c7d\u0002\u01de", + "\u01df\u0005\u00c3b\u0002\u01df\u01e0\u0005\u00c9e\u0002\u01e0\u01e1", + "\u0005\u00a9U\u0002\u01e1r\u0003\u0002\u0002\u0002\u01e2\u01e3\u0005", + "\u00c9e\u0002\u01e3\u01e4\u0005\u00bf`\u0002\u01e4\u01e5\u0005\u00a7", + "T\u0002\u01e5\u01e6\u0005\u00a1Q\u0002\u01e6\u01e7\u0005\u00c7d\u0002", + "\u01e7\u01e8\u0005\u00a9U\u0002\u01e8t\u0003\u0002\u0002\u0002\u01e9", + "\u01ea\u0005\u00c9e\u0002\u01ea\u01eb\u0005\u00bf`\u0002\u01eb\u01ec", + "\u0005\u00c5c\u0002\u01ec\u01ed\u0005\u00a9U\u0002\u01ed\u01ee\u0005", + "\u00c3b\u0002\u01ee\u01ef\u0005\u00c7d\u0002\u01efv\u0003\u0002\u0002", + "\u0002\u01f0\u01f1\u0005\u00cdg\u0002\u01f1\u01f2\u0005\u00b1Y\u0002", + "\u01f2\u01f3\u0005\u00c7d\u0002\u01f3\u01f4\u0005\u00afX\u0002\u01f4", + "x\u0003\u0002\u0002\u0002\u01f5\u01f6\u0005\u00b5[\u0002\u01f6\u01f7", + "\u0005\u00a9U\u0002\u01f7\u01f8\u0005\u00a9U\u0002\u01f8\u01f9\u0005", + "\u00bf`\u0002\u01f9z\u0003\u0002\u0002\u0002\u01fa\u01fb\u0005\u00a5", + "S\u0002\u01fb\u01fc\u0005\u00bd_\u0002\u01fc\u01fd\u0005\u00c9e\u0002", + "\u01fd\u01fe\u0005\u00bb^\u0002\u01fe\u01ff\u0005\u00c7d\u0002\u01ff", + "|\u0003\u0002\u0002\u0002\u0200\u0201\u0005\u00bd_\u0002\u0201\u0202", + "\u0005\u00bf`\u0002\u0202\u0203\u0005\u00c7d\u0002\u0203\u0204\u0005", + "\u00b1Y\u0002\u0204\u0205\u0005\u00bd_\u0002\u0205\u0206\u0005\u00bb", + "^\u0002\u0206\u0207\u0005\u00c5c\u0002\u0207~\u0003\u0002\u0002\u0002", + "\u0208\u0209\u0005\u00bf`\u0002\u0209\u020a\u0005\u00c3b\u0002\u020a", + "\u020b\u0005\u00c9e\u0002\u020b\u020c\u0005\u00bb^\u0002\u020c\u020d", + "\u0005\u00a9U\u0002\u020d\u0080\u0003\u0002\u0002\u0002\u020e\u020f", + "\u0005\u00c5c\u0002\u020f\u0210\u0005\u00a9U\u0002\u0210\u0211\u0005", + "\u00a1Q\u0002\u0211\u0212\u0005\u00c3b\u0002\u0212\u0213\u0005\u00a5", + "S\u0002\u0213\u0214\u0005\u00afX\u0002\u0214\u0082\u0003\u0002\u0002", + "\u0002\u0215\u0216\u0005\u00c7d\u0002\u0216\u0217\u0005\u00bd_\u0002", + "\u0217\u0084\u0003\u0002\u0002\u0002\u0218\u0219\u0005\u00a5S\u0002", + "\u0219\u021a\u0005\u00c9e\u0002\u021a\u021b\u0005\u00c3b\u0002\u021b", + "\u021c\u0005\u00c3b\u0002\u021c\u021d\u0005\u00a9U\u0002\u021d\u021e", + "\u0005\u00bb^\u0002\u021e\u021f\u0005\u00c7d\u0002\u021f\u0086\u0003", + "\u0002\u0002\u0002\u0220\u0221\u0005\u00bb^\u0002\u0221\u0222\u0005", + "\u00a9U\u0002\u0222\u0223\u0005\u00cdg\u0002\u0223\u0088\u0003\u0002", + "\u0002\u0002\u0224\u0225\u0005\u00bd_\u0002\u0225\u0226\u0005\u00b7", + "\\\u0002\u0226\u0227\u0005\u00a7T\u0002\u0227\u008a\u0003\u0002\u0002", + "\u0002\u0228\u022c\t\u0002\u0002\u0002\u0229\u022b\t\u0003\u0002\u0002", + "\u022a\u0229\u0003\u0002\u0002\u0002\u022b\u022e\u0003\u0002\u0002\u0002", + "\u022c\u022a\u0003\u0002\u0002\u0002\u022c\u022d\u0003\u0002\u0002\u0002", + "\u022d\u008c\u0003\u0002\u0002\u0002\u022e\u022c\u0003\u0002\u0002\u0002", + "\u022f\u0233\t\u0004\u0002\u0002\u0230\u0232\u0005\u009fP\u0002\u0231", + "\u0230\u0003\u0002\u0002\u0002\u0232\u0235\u0003\u0002\u0002\u0002\u0233", + "\u0231\u0003\u0002\u0002\u0002\u0233\u0234\u0003\u0002\u0002\u0002\u0234", + "\u0248\u0003\u0002\u0002\u0002\u0235\u0233\u0003\u0002\u0002\u0002\u0236", + "\u0248\u00072\u0002\u0002\u0237\u0238\u00072\u0002\u0002\u0238\u0239", + "\u0007z\u0002\u0002\u0239\u023b\u0003\u0002\u0002\u0002\u023a\u023c", + "\u0005\u009dO\u0002\u023b\u023a\u0003\u0002\u0002\u0002\u023c\u023d", + "\u0003\u0002\u0002\u0002\u023d\u023b\u0003\u0002\u0002\u0002\u023d\u023e", + "\u0003\u0002\u0002\u0002\u023e\u0248\u0003\u0002\u0002\u0002\u023f\u0240", + "\u00072\u0002\u0002\u0240\u0241\u0007d\u0002\u0002\u0241\u0243\u0003", + "\u0002\u0002\u0002\u0242\u0244\t\u0005\u0002\u0002\u0243\u0242\u0003", + "\u0002\u0002\u0002\u0244\u0245\u0003\u0002\u0002\u0002\u0245\u0243\u0003", + "\u0002\u0002\u0002\u0245\u0246\u0003\u0002\u0002\u0002\u0246\u0248\u0003", + "\u0002\u0002\u0002\u0247\u022f\u0003\u0002\u0002\u0002\u0247\u0236\u0003", + "\u0002\u0002\u0002\u0247\u0237\u0003\u0002\u0002\u0002\u0247\u023f\u0003", + "\u0002\u0002\u0002\u0248\u008e\u0003\u0002\u0002\u0002\u0249\u024d\t", + "\u0004\u0002\u0002\u024a\u024c\u0005\u009fP\u0002\u024b\u024a\u0003", + "\u0002\u0002\u0002\u024c\u024f\u0003\u0002\u0002\u0002\u024d\u024b\u0003", + "\u0002\u0002\u0002\u024d\u024e\u0003\u0002\u0002\u0002\u024e\u0252\u0003", + "\u0002\u0002\u0002\u024f\u024d\u0003\u0002\u0002\u0002\u0250\u0252\u0007", + "2\u0002\u0002\u0251\u0249\u0003\u0002\u0002\u0002\u0251\u0250\u0003", + "\u0002\u0002\u0002\u0251\u0252\u0003\u0002\u0002\u0002\u0252\u0253\u0003", + "\u0002\u0002\u0002\u0253\u0255\u00070\u0002\u0002\u0254\u0256\u0005", + "\u009fP\u0002\u0255\u0254\u0003\u0002\u0002\u0002\u0256\u0257\u0003", + "\u0002\u0002\u0002\u0257\u0255\u0003\u0002\u0002\u0002\u0257\u0258\u0003", + "\u0002\u0002\u0002\u0258\u0262\u0003\u0002\u0002\u0002\u0259\u025b\u0005", + "\u00a9U\u0002\u025a\u025c\t\u0006\u0002\u0002\u025b\u025a\u0003\u0002", + "\u0002\u0002\u025b\u025c\u0003\u0002\u0002\u0002\u025c\u025e\u0003\u0002", + "\u0002\u0002\u025d\u025f\u0005\u009fP\u0002\u025e\u025d\u0003\u0002", + "\u0002\u0002\u025f\u0260\u0003\u0002\u0002\u0002\u0260\u025e\u0003\u0002", + "\u0002\u0002\u0260\u0261\u0003\u0002\u0002\u0002\u0261\u0263\u0003\u0002", + "\u0002\u0002\u0262\u0259\u0003\u0002\u0002\u0002\u0262\u0263\u0003\u0002", + "\u0002\u0002\u0263\u0090\u0003\u0002\u0002\u0002\u0264\u0265\u0007B", + "\u0002\u0002\u0265\u0266\u0005\u008bF\u0002\u0266\u0092\u0003\u0002", + "\u0002\u0002\u0267\u026f\u0007)\u0002\u0002\u0268\u0269\u0007^\u0002", + "\u0002\u0269\u026e\u000b\u0002\u0002\u0002\u026a\u026b\u0007)\u0002", + "\u0002\u026b\u026e\u0007)\u0002\u0002\u026c\u026e\n\u0007\u0002\u0002", + "\u026d\u0268\u0003\u0002\u0002\u0002\u026d\u026a\u0003\u0002\u0002\u0002", + "\u026d\u026c\u0003\u0002\u0002\u0002\u026e\u0271\u0003\u0002\u0002\u0002", + "\u026f\u026d\u0003\u0002\u0002\u0002\u026f\u0270\u0003\u0002\u0002\u0002", + "\u0270\u0272\u0003\u0002\u0002\u0002\u0271\u026f\u0003\u0002\u0002\u0002", + "\u0272\u0280\u0007)\u0002\u0002\u0273\u027b\u0007$\u0002\u0002\u0274", + "\u0275\u0007^\u0002\u0002\u0275\u027a\u000b\u0002\u0002\u0002\u0276", + "\u0277\u0007$\u0002\u0002\u0277\u027a\u0007$\u0002\u0002\u0278\u027a", + "\n\b\u0002\u0002\u0279\u0274\u0003\u0002\u0002\u0002\u0279\u0276\u0003", + "\u0002\u0002\u0002\u0279\u0278\u0003\u0002\u0002\u0002\u027a\u027d\u0003", + "\u0002\u0002\u0002\u027b\u0279\u0003\u0002\u0002\u0002\u027b\u027c\u0003", + "\u0002\u0002\u0002\u027c\u027e\u0003\u0002\u0002\u0002\u027d\u027b\u0003", + "\u0002\u0002\u0002\u027e\u0280\u0007$\u0002\u0002\u027f\u0267\u0003", + "\u0002\u0002\u0002\u027f\u0273\u0003\u0002\u0002\u0002\u0280\u0094\u0003", + "\u0002\u0002\u0002\u0281\u0282\u00071\u0002\u0002\u0282\u0283\u0007", + "1\u0002\u0002\u0283\u0287\u0003\u0002\u0002\u0002\u0284\u0286\n\t\u0002", + "\u0002\u0285\u0284\u0003\u0002\u0002\u0002\u0286\u0289\u0003\u0002\u0002", + "\u0002\u0287\u0285\u0003\u0002\u0002\u0002\u0287\u0288\u0003\u0002\u0002", + "\u0002\u0288\u028f\u0003\u0002\u0002\u0002\u0289\u0287\u0003\u0002\u0002", + "\u0002\u028a\u028c\u0007\u000f\u0002\u0002\u028b\u028a\u0003\u0002\u0002", + "\u0002\u028b\u028c\u0003\u0002\u0002\u0002\u028c\u028d\u0003\u0002\u0002", + "\u0002\u028d\u0290\u0007\f\u0002\u0002\u028e\u0290\u0007\u0002\u0002", + "\u0003\u028f\u028b\u0003\u0002\u0002\u0002\u028f\u028e\u0003\u0002\u0002", + "\u0002\u0290\u0291\u0003\u0002\u0002\u0002\u0291\u0292\bK\u0002\u0002", + "\u0292\u0096\u0003\u0002\u0002\u0002\u0293\u0294\u00071\u0002\u0002", + "\u0294\u0295\u0007,\u0002\u0002\u0295\u0299\u0003\u0002\u0002\u0002", + "\u0296\u0298\u000b\u0002\u0002\u0002\u0297\u0296\u0003\u0002\u0002\u0002", + "\u0298\u029b\u0003\u0002\u0002\u0002\u0299\u029a\u0003\u0002\u0002\u0002", + "\u0299\u0297\u0003\u0002\u0002\u0002\u029a\u029c\u0003\u0002\u0002\u0002", + "\u029b\u0299\u0003\u0002\u0002\u0002\u029c\u029d\u0007,\u0002\u0002", + "\u029d\u029e\u00071\u0002\u0002\u029e\u029f\u0003\u0002\u0002\u0002", + "\u029f\u02a0\bL\u0002\u0002\u02a0\u0098\u0003\u0002\u0002\u0002\u02a1", + "\u02a2\t\n\u0002\u0002\u02a2\u02a3\u0003\u0002\u0002\u0002\u02a3\u02a4", + "\bM\u0002\u0002\u02a4\u009a\u0003\u0002\u0002\u0002\u02a5\u02a6\u000b", + "\u0002\u0002\u0002\u02a6\u009c\u0003\u0002\u0002\u0002\u02a7\u02a8\t", + "\u000b\u0002\u0002\u02a8\u009e\u0003\u0002\u0002\u0002\u02a9\u02aa\t", + "\f\u0002\u0002\u02aa\u00a0\u0003\u0002\u0002\u0002\u02ab\u02ac\t\r\u0002", + "\u0002\u02ac\u00a2\u0003\u0002\u0002\u0002\u02ad\u02ae\t\u000e\u0002", + "\u0002\u02ae\u00a4\u0003\u0002\u0002\u0002\u02af\u02b0\t\u000f\u0002", + "\u0002\u02b0\u00a6\u0003\u0002\u0002\u0002\u02b1\u02b2\t\u0010\u0002", + "\u0002\u02b2\u00a8\u0003\u0002\u0002\u0002\u02b3\u02b4\t\u0011\u0002", + "\u0002\u02b4\u00aa\u0003\u0002\u0002\u0002\u02b5\u02b6\t\u0012\u0002", + "\u0002\u02b6\u00ac\u0003\u0002\u0002\u0002\u02b7\u02b8\t\u0013\u0002", + "\u0002\u02b8\u00ae\u0003\u0002\u0002\u0002\u02b9\u02ba\t\u0014\u0002", + "\u0002\u02ba\u00b0\u0003\u0002\u0002\u0002\u02bb\u02bc\t\u0015\u0002", + "\u0002\u02bc\u00b2\u0003\u0002\u0002\u0002\u02bd\u02be\t\u0016\u0002", + "\u0002\u02be\u00b4\u0003\u0002\u0002\u0002\u02bf\u02c0\t\u0017\u0002", + "\u0002\u02c0\u00b6\u0003\u0002\u0002\u0002\u02c1\u02c2\t\u0018\u0002", + "\u0002\u02c2\u00b8\u0003\u0002\u0002\u0002\u02c3\u02c4\t\u0019\u0002", + "\u0002\u02c4\u00ba\u0003\u0002\u0002\u0002\u02c5\u02c6\t\u001a\u0002", + "\u0002\u02c6\u00bc\u0003\u0002\u0002\u0002\u02c7\u02c8\t\u001b\u0002", + "\u0002\u02c8\u00be\u0003\u0002\u0002\u0002\u02c9\u02ca\t\u001c\u0002", + "\u0002\u02ca\u00c0\u0003\u0002\u0002\u0002\u02cb\u02cc\t\u001d\u0002", + "\u0002\u02cc\u00c2\u0003\u0002\u0002\u0002\u02cd\u02ce\t\u001e\u0002", + "\u0002\u02ce\u00c4\u0003\u0002\u0002\u0002\u02cf\u02d0\t\u001f\u0002", + "\u0002\u02d0\u00c6\u0003\u0002\u0002\u0002\u02d1\u02d2\t \u0002\u0002", + "\u02d2\u00c8\u0003\u0002\u0002\u0002\u02d3\u02d4\t!\u0002\u0002\u02d4", + "\u00ca\u0003\u0002\u0002\u0002\u02d5\u02d6\t\"\u0002\u0002\u02d6\u00cc", + "\u0003\u0002\u0002\u0002\u02d7\u02d8\t#\u0002\u0002\u02d8\u00ce\u0003", + "\u0002\u0002\u0002\u02d9\u02da\t$\u0002\u0002\u02da\u00d0\u0003\u0002", + "\u0002\u0002\u02db\u02dc\t%\u0002\u0002\u02dc\u00d2\u0003\u0002\u0002", + "\u0002\u02dd\u02de\t&\u0002\u0002\u02de\u00d4\u0003\u0002\u0002\u0002", + "\u02df\u02e0\u000b\u0002\u0002\u0002\u02e0\u02e1\u0003\u0002\u0002\u0002", + "\u02e1\u02e2\bk\u0003\u0002\u02e2\u00d6\u0003\u0002\u0002\u0002\u001a", + "\u0002\u0125\u019d\u01a9\u022c\u0233\u023d\u0245\u0247\u024d\u0251\u0257", + "\u025b\u0260\u0262\u026d\u026f\u0279\u027b\u027f\u0287\u028b\u028f\u0299", + "\u0004\u0002\u0003\u0002\u0002\u0004\u0002"].join(""); + + +const atn = new antlr4.atn.ATNDeserializer().deserialize(serializedATN); + +const decisionsToDFA = atn.decisionToState.map( (ds, index) => new antlr4.dfa.DFA(ds, index) ); + +export default class CAQLLexer extends antlr4.Lexer { + + static grammarFileName = "CAQLLexer.g4"; + static channelNames = [ "DEFAULT_TOKEN_CHANNEL", "HIDDEN", "ERRORCHANNEL" ]; + static modeNames = [ "DEFAULT_MODE" ]; + static literalNames = [ null, "'.'", "'=~'", "'!~'", "'=='", "'!='", "'<'", + "'>'", "'<='", "'>='", "'+'", "'-'", "'*'", "'/'", + "'%'", "'?'", "':'", "'::'", "'..'", "','", "'('", + "')'", "'{'", "'}'", "'['", "']'" ]; + static symbolicNames = [ null, "DOT", "T_REGEX_MATCH", "T_REGEX_NON_MATCH", + "T_EQ", "T_NE", "T_LT", "T_GT", "T_LE", "T_GE", + "T_PLUS", "T_MINUS", "T_TIMES", "T_DIV", "T_MOD", + "T_QUESTION", "T_COLON", "T_SCOPE", "T_RANGE", + "T_COMMA", "T_OPEN", "T_CLOSE", "T_OBJECT_OPEN", + "T_OBJECT_CLOSE", "T_ARRAY_OPEN", "T_ARRAY_CLOSE", + "T_AGGREGATE", "T_ALL", "T_AND", "T_ANY", "T_ASC", + "T_COLLECT", "T_DESC", "T_DISTINCT", "T_FALSE", + "T_FILTER", "T_FOR", "T_GRAPH", "T_IN", "T_INBOUND", + "T_INSERT", "T_INTO", "T_K_SHORTEST_PATHS", "T_LET", + "T_LIKE", "T_LIMIT", "T_NONE", "T_NOT", "T_NULL", + "T_OR", "T_OUTBOUND", "T_REMOVE", "T_REPLACE", + "T_RETURN", "T_SHORTEST_PATH", "T_SORT", "T_TRUE", + "T_UPDATE", "T_UPSERT", "T_WITH", "T_KEEP", "T_COUNT", + "T_OPTIONS", "T_PRUNE", "T_SEARCH", "T_TO", "T_CURRENT", + "T_NEW", "T_OLD", "T_STRING", "T_INT", "T_FLOAT", + "T_PARAMETER", "T_QUOTED_STRING", "SINGLE_LINE_COMMENT", + "MULTILINE_COMMENT", "SPACES", "UNEXPECTED_CHAR", + "ERROR_RECONGNIGION" ]; + static ruleNames = [ "DOT", "T_REGEX_MATCH", "T_REGEX_NON_MATCH", "T_EQ", + "T_NE", "T_LT", "T_GT", "T_LE", "T_GE", "T_PLUS", + "T_MINUS", "T_TIMES", "T_DIV", "T_MOD", "T_QUESTION", + "T_COLON", "T_SCOPE", "T_RANGE", "T_COMMA", "T_OPEN", + "T_CLOSE", "T_OBJECT_OPEN", "T_OBJECT_CLOSE", "T_ARRAY_OPEN", + "T_ARRAY_CLOSE", "T_AGGREGATE", "T_ALL", "T_AND", + "T_ANY", "T_ASC", "T_COLLECT", "T_DESC", "T_DISTINCT", + "T_FALSE", "T_FILTER", "T_FOR", "T_GRAPH", "T_IN", + "T_INBOUND", "T_INSERT", "T_INTO", "T_K_SHORTEST_PATHS", + "T_LET", "T_LIKE", "T_LIMIT", "T_NONE", "T_NOT", "T_NULL", + "T_OR", "T_OUTBOUND", "T_REMOVE", "T_REPLACE", "T_RETURN", + "T_SHORTEST_PATH", "T_SORT", "T_TRUE", "T_UPDATE", + "T_UPSERT", "T_WITH", "T_KEEP", "T_COUNT", "T_OPTIONS", + "T_PRUNE", "T_SEARCH", "T_TO", "T_CURRENT", "T_NEW", + "T_OLD", "T_STRING", "T_INT", "T_FLOAT", "T_PARAMETER", + "T_QUOTED_STRING", "SINGLE_LINE_COMMENT", "MULTILINE_COMMENT", + "SPACES", "UNEXPECTED_CHAR", "HEX_DIGIT", "DIGIT", + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", + "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", + "U", "V", "W", "X", "Y", "Z", "ERROR_RECONGNIGION" ]; + + constructor(input) { + super(input) + this._interp = new antlr4.atn.LexerATNSimulator(this, atn, decisionsToDFA, new antlr4.PredictionContextCache()); + } + + get atn() { + return atn; + } +} + +CAQLLexer.EOF = antlr4.Token.EOF; +CAQLLexer.DOT = 1; +CAQLLexer.T_REGEX_MATCH = 2; +CAQLLexer.T_REGEX_NON_MATCH = 3; +CAQLLexer.T_EQ = 4; +CAQLLexer.T_NE = 5; +CAQLLexer.T_LT = 6; +CAQLLexer.T_GT = 7; +CAQLLexer.T_LE = 8; +CAQLLexer.T_GE = 9; +CAQLLexer.T_PLUS = 10; +CAQLLexer.T_MINUS = 11; +CAQLLexer.T_TIMES = 12; +CAQLLexer.T_DIV = 13; +CAQLLexer.T_MOD = 14; +CAQLLexer.T_QUESTION = 15; +CAQLLexer.T_COLON = 16; +CAQLLexer.T_SCOPE = 17; +CAQLLexer.T_RANGE = 18; +CAQLLexer.T_COMMA = 19; +CAQLLexer.T_OPEN = 20; +CAQLLexer.T_CLOSE = 21; +CAQLLexer.T_OBJECT_OPEN = 22; +CAQLLexer.T_OBJECT_CLOSE = 23; +CAQLLexer.T_ARRAY_OPEN = 24; +CAQLLexer.T_ARRAY_CLOSE = 25; +CAQLLexer.T_AGGREGATE = 26; +CAQLLexer.T_ALL = 27; +CAQLLexer.T_AND = 28; +CAQLLexer.T_ANY = 29; +CAQLLexer.T_ASC = 30; +CAQLLexer.T_COLLECT = 31; +CAQLLexer.T_DESC = 32; +CAQLLexer.T_DISTINCT = 33; +CAQLLexer.T_FALSE = 34; +CAQLLexer.T_FILTER = 35; +CAQLLexer.T_FOR = 36; +CAQLLexer.T_GRAPH = 37; +CAQLLexer.T_IN = 38; +CAQLLexer.T_INBOUND = 39; +CAQLLexer.T_INSERT = 40; +CAQLLexer.T_INTO = 41; +CAQLLexer.T_K_SHORTEST_PATHS = 42; +CAQLLexer.T_LET = 43; +CAQLLexer.T_LIKE = 44; +CAQLLexer.T_LIMIT = 45; +CAQLLexer.T_NONE = 46; +CAQLLexer.T_NOT = 47; +CAQLLexer.T_NULL = 48; +CAQLLexer.T_OR = 49; +CAQLLexer.T_OUTBOUND = 50; +CAQLLexer.T_REMOVE = 51; +CAQLLexer.T_REPLACE = 52; +CAQLLexer.T_RETURN = 53; +CAQLLexer.T_SHORTEST_PATH = 54; +CAQLLexer.T_SORT = 55; +CAQLLexer.T_TRUE = 56; +CAQLLexer.T_UPDATE = 57; +CAQLLexer.T_UPSERT = 58; +CAQLLexer.T_WITH = 59; +CAQLLexer.T_KEEP = 60; +CAQLLexer.T_COUNT = 61; +CAQLLexer.T_OPTIONS = 62; +CAQLLexer.T_PRUNE = 63; +CAQLLexer.T_SEARCH = 64; +CAQLLexer.T_TO = 65; +CAQLLexer.T_CURRENT = 66; +CAQLLexer.T_NEW = 67; +CAQLLexer.T_OLD = 68; +CAQLLexer.T_STRING = 69; +CAQLLexer.T_INT = 70; +CAQLLexer.T_FLOAT = 71; +CAQLLexer.T_PARAMETER = 72; +CAQLLexer.T_QUOTED_STRING = 73; +CAQLLexer.SINGLE_LINE_COMMENT = 74; +CAQLLexer.MULTILINE_COMMENT = 75; +CAQLLexer.SPACES = 76; +CAQLLexer.UNEXPECTED_CHAR = 77; +CAQLLexer.ERROR_RECONGNIGION = 78; + +CAQLLexer.ERRORCHANNEL = 2; + + + diff --git a/ui/src/suggestions/grammar/RQLLexer.tokens b/ui/src/suggestions/grammar/RQLLexer.tokens new file mode 100644 index 0000000..7bdaf61 --- /dev/null +++ b/ui/src/suggestions/grammar/RQLLexer.tokens @@ -0,0 +1,103 @@ +DOT=1 +T_REGEX_MATCH=2 +T_REGEX_NON_MATCH=3 +T_EQ=4 +T_NE=5 +T_LT=6 +T_GT=7 +T_LE=8 +T_GE=9 +T_PLUS=10 +T_MINUS=11 +T_TIMES=12 +T_DIV=13 +T_MOD=14 +T_QUESTION=15 +T_COLON=16 +T_SCOPE=17 +T_RANGE=18 +T_COMMA=19 +T_OPEN=20 +T_CLOSE=21 +T_OBJECT_OPEN=22 +T_OBJECT_CLOSE=23 +T_ARRAY_OPEN=24 +T_ARRAY_CLOSE=25 +T_AGGREGATE=26 +T_ALL=27 +T_AND=28 +T_ANY=29 +T_ASC=30 +T_COLLECT=31 +T_DESC=32 +T_DISTINCT=33 +T_FALSE=34 +T_FILTER=35 +T_FOR=36 +T_GRAPH=37 +T_IN=38 +T_INBOUND=39 +T_INSERT=40 +T_INTO=41 +T_K_SHORTEST_PATHS=42 +T_LET=43 +T_LIKE=44 +T_LIMIT=45 +T_NONE=46 +T_NOT=47 +T_NULL=48 +T_OR=49 +T_OUTBOUND=50 +T_REMOVE=51 +T_REPLACE=52 +T_RETURN=53 +T_SHORTEST_PATH=54 +T_SORT=55 +T_TRUE=56 +T_UPDATE=57 +T_UPSERT=58 +T_WITH=59 +T_KEEP=60 +T_COUNT=61 +T_OPTIONS=62 +T_PRUNE=63 +T_SEARCH=64 +T_TO=65 +T_CURRENT=66 +T_NEW=67 +T_OLD=68 +T_STRING=69 +T_INT=70 +T_FLOAT=71 +T_PARAMETER=72 +T_QUOTED_STRING=73 +SINGLE_LINE_COMMENT=74 +MULTILINE_COMMENT=75 +SPACES=76 +UNEXPECTED_CHAR=77 +ERROR_RECONGNIGION=78 +'.'=1 +'=~'=2 +'!~'=3 +'=='=4 +'!='=5 +'<'=6 +'>'=7 +'<='=8 +'>='=9 +'+'=10 +'-'=11 +'*'=12 +'/'=13 +'%'=14 +'?'=15 +':'=16 +'::'=17 +'..'=18 +','=19 +'('=20 +')'=21 +'{'=22 +'}'=23 +'['=24 +']'=25 diff --git a/ui/src/suggestions/grammar/RQLParser.interp b/ui/src/suggestions/grammar/RQLParser.interp new file mode 100644 index 0000000..8abde5b --- /dev/null +++ b/ui/src/suggestions/grammar/RQLParser.interp @@ -0,0 +1,178 @@ +token literal names: +null +'.' +'=~' +'!~' +'==' +'!=' +'<' +'>' +'<=' +'>=' +'+' +'-' +'*' +'/' +'%' +'?' +':' +'::' +'..' +',' +'(' +')' +'{' +'}' +'[' +']' +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null + +token symbolic names: +null +DOT +T_REGEX_MATCH +T_REGEX_NON_MATCH +T_EQ +T_NE +T_LT +T_GT +T_LE +T_GE +T_PLUS +T_MINUS +T_TIMES +T_DIV +T_MOD +T_QUESTION +T_COLON +T_SCOPE +T_RANGE +T_COMMA +T_OPEN +T_CLOSE +T_OBJECT_OPEN +T_OBJECT_CLOSE +T_ARRAY_OPEN +T_ARRAY_CLOSE +T_AGGREGATE +T_ALL +T_AND +T_ANY +T_ASC +T_COLLECT +T_DESC +T_DISTINCT +T_FALSE +T_FILTER +T_FOR +T_GRAPH +T_IN +T_INBOUND +T_INSERT +T_INTO +T_K_SHORTEST_PATHS +T_LET +T_LIKE +T_LIMIT +T_NONE +T_NOT +T_NULL +T_OR +T_OUTBOUND +T_REMOVE +T_REPLACE +T_RETURN +T_SHORTEST_PATH +T_SORT +T_TRUE +T_UPDATE +T_UPSERT +T_WITH +T_KEEP +T_COUNT +T_OPTIONS +T_PRUNE +T_SEARCH +T_TO +T_CURRENT +T_NEW +T_OLD +T_STRING +T_INT +T_FLOAT +T_PARAMETER +T_QUOTED_STRING +SINGLE_LINE_COMMENT +MULTILINE_COMMENT +SPACES +UNEXPECTED_CHAR +ERROR_RECONGNIGION + +rule names: +parse +expression +operator_unary +reference +compound_value +function_call +value_literal +array +object +object_element +object_element_name + + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 80, 192, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 32, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 48, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 66, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 86, 10, 3, 12, 3, 14, 3, 89, 11, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 5, 4, 97, 10, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 107, 10, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 7, 5, 117, 10, 5, 12, 5, 14, 5, 120, 11, 5, 3, 6, 3, 6, 5, 6, 124, 10, 6, 3, 7, 3, 7, 3, 7, 5, 7, 129, 10, 7, 3, 7, 3, 7, 7, 7, 133, 10, 7, 12, 7, 14, 7, 136, 11, 7, 3, 7, 5, 7, 139, 10, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 5, 9, 147, 10, 9, 3, 9, 3, 9, 7, 9, 151, 10, 9, 12, 9, 14, 9, 154, 11, 9, 3, 9, 5, 9, 157, 10, 9, 3, 9, 3, 9, 3, 10, 3, 10, 5, 10, 163, 10, 10, 3, 10, 3, 10, 7, 10, 167, 10, 10, 12, 10, 14, 10, 170, 11, 10, 3, 10, 5, 10, 173, 10, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 5, 11, 188, 10, 11, 3, 12, 3, 12, 3, 12, 4, 134, 152, 4, 4, 8, 13, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 2, 11, 3, 2, 12, 13, 3, 2, 14, 16, 3, 2, 8, 11, 3, 2, 6, 7, 5, 2, 29, 29, 31, 31, 48, 48, 4, 2, 6, 11, 40, 40, 4, 2, 4, 5, 46, 46, 7, 2, 36, 36, 50, 50, 58, 58, 72, 73, 75, 75, 4, 2, 71, 71, 75, 75, 2, 216, 2, 24, 3, 2, 2, 2, 4, 31, 3, 2, 2, 2, 6, 96, 3, 2, 2, 2, 8, 106, 3, 2, 2, 2, 10, 123, 3, 2, 2, 2, 12, 125, 3, 2, 2, 2, 14, 142, 3, 2, 2, 2, 16, 144, 3, 2, 2, 2, 18, 160, 3, 2, 2, 2, 20, 187, 3, 2, 2, 2, 22, 189, 3, 2, 2, 2, 24, 25, 5, 4, 3, 2, 25, 26, 7, 2, 2, 3, 26, 3, 3, 2, 2, 2, 27, 28, 8, 3, 1, 2, 28, 32, 5, 14, 8, 2, 29, 32, 5, 8, 5, 2, 30, 32, 5, 6, 4, 2, 31, 27, 3, 2, 2, 2, 31, 29, 3, 2, 2, 2, 31, 30, 3, 2, 2, 2, 32, 87, 3, 2, 2, 2, 33, 34, 12, 15, 2, 2, 34, 35, 9, 2, 2, 2, 35, 86, 5, 4, 3, 16, 36, 37, 12, 14, 2, 2, 37, 38, 9, 3, 2, 2, 38, 86, 5, 4, 3, 15, 39, 40, 12, 13, 2, 2, 40, 41, 7, 20, 2, 2, 41, 86, 5, 4, 3, 14, 42, 43, 12, 12, 2, 2, 43, 44, 9, 4, 2, 2, 44, 86, 5, 4, 3, 13, 45, 47, 12, 11, 2, 2, 46, 48, 7, 49, 2, 2, 47, 46, 3, 2, 2, 2, 47, 48, 3, 2, 2, 2, 48, 49, 3, 2, 2, 2, 49, 50, 7, 40, 2, 2, 50, 86, 5, 4, 3, 12, 51, 52, 12, 10, 2, 2, 52, 53, 9, 5, 2, 2, 53, 86, 5, 4, 3, 11, 54, 55, 12, 9, 2, 2, 55, 56, 9, 6, 2, 2, 56, 57, 9, 7, 2, 2, 57, 86, 5, 4, 3, 10, 58, 59, 12, 8, 2, 2, 59, 60, 9, 6, 2, 2, 60, 61, 7, 49, 2, 2, 61, 62, 7, 40, 2, 2, 62, 86, 5, 4, 3, 9, 63, 65, 12, 7, 2, 2, 64, 66, 7, 49, 2, 2, 65, 64, 3, 2, 2, 2, 65, 66, 3, 2, 2, 2, 66, 67, 3, 2, 2, 2, 67, 68, 9, 8, 2, 2, 68, 86, 5, 4, 3, 8, 69, 70, 12, 6, 2, 2, 70, 71, 7, 30, 2, 2, 71, 86, 5, 4, 3, 7, 72, 73, 12, 5, 2, 2, 73, 74, 7, 51, 2, 2, 74, 86, 5, 4, 3, 6, 75, 76, 12, 4, 2, 2, 76, 77, 7, 17, 2, 2, 77, 78, 5, 4, 3, 2, 78, 79, 7, 18, 2, 2, 79, 80, 5, 4, 3, 5, 80, 86, 3, 2, 2, 2, 81, 82, 12, 3, 2, 2, 82, 83, 7, 17, 2, 2, 83, 84, 7, 18, 2, 2, 84, 86, 5, 4, 3, 4, 85, 33, 3, 2, 2, 2, 85, 36, 3, 2, 2, 2, 85, 39, 3, 2, 2, 2, 85, 42, 3, 2, 2, 2, 85, 45, 3, 2, 2, 2, 85, 51, 3, 2, 2, 2, 85, 54, 3, 2, 2, 2, 85, 58, 3, 2, 2, 2, 85, 63, 3, 2, 2, 2, 85, 69, 3, 2, 2, 2, 85, 72, 3, 2, 2, 2, 85, 75, 3, 2, 2, 2, 85, 81, 3, 2, 2, 2, 86, 89, 3, 2, 2, 2, 87, 85, 3, 2, 2, 2, 87, 88, 3, 2, 2, 2, 88, 5, 3, 2, 2, 2, 89, 87, 3, 2, 2, 2, 90, 91, 7, 12, 2, 2, 91, 97, 5, 4, 3, 2, 92, 93, 7, 13, 2, 2, 93, 97, 5, 4, 3, 2, 94, 95, 7, 49, 2, 2, 95, 97, 5, 4, 3, 2, 96, 90, 3, 2, 2, 2, 96, 92, 3, 2, 2, 2, 96, 94, 3, 2, 2, 2, 97, 7, 3, 2, 2, 2, 98, 99, 8, 5, 1, 2, 99, 107, 7, 71, 2, 2, 100, 107, 5, 10, 6, 2, 101, 107, 5, 12, 7, 2, 102, 103, 7, 22, 2, 2, 103, 104, 5, 4, 3, 2, 104, 105, 7, 23, 2, 2, 105, 107, 3, 2, 2, 2, 106, 98, 3, 2, 2, 2, 106, 100, 3, 2, 2, 2, 106, 101, 3, 2, 2, 2, 106, 102, 3, 2, 2, 2, 107, 118, 3, 2, 2, 2, 108, 109, 12, 4, 2, 2, 109, 110, 7, 3, 2, 2, 110, 117, 7, 71, 2, 2, 111, 112, 12, 3, 2, 2, 112, 113, 7, 26, 2, 2, 113, 114, 5, 4, 3, 2, 114, 115, 7, 27, 2, 2, 115, 117, 3, 2, 2, 2, 116, 108, 3, 2, 2, 2, 116, 111, 3, 2, 2, 2, 117, 120, 3, 2, 2, 2, 118, 116, 3, 2, 2, 2, 118, 119, 3, 2, 2, 2, 119, 9, 3, 2, 2, 2, 120, 118, 3, 2, 2, 2, 121, 124, 5, 16, 9, 2, 122, 124, 5, 18, 10, 2, 123, 121, 3, 2, 2, 2, 123, 122, 3, 2, 2, 2, 124, 11, 3, 2, 2, 2, 125, 126, 7, 71, 2, 2, 126, 128, 7, 22, 2, 2, 127, 129, 5, 4, 3, 2, 128, 127, 3, 2, 2, 2, 128, 129, 3, 2, 2, 2, 129, 134, 3, 2, 2, 2, 130, 131, 7, 21, 2, 2, 131, 133, 5, 4, 3, 2, 132, 130, 3, 2, 2, 2, 133, 136, 3, 2, 2, 2, 134, 135, 3, 2, 2, 2, 134, 132, 3, 2, 2, 2, 135, 138, 3, 2, 2, 2, 136, 134, 3, 2, 2, 2, 137, 139, 7, 21, 2, 2, 138, 137, 3, 2, 2, 2, 138, 139, 3, 2, 2, 2, 139, 140, 3, 2, 2, 2, 140, 141, 7, 23, 2, 2, 141, 13, 3, 2, 2, 2, 142, 143, 9, 9, 2, 2, 143, 15, 3, 2, 2, 2, 144, 146, 7, 26, 2, 2, 145, 147, 5, 4, 3, 2, 146, 145, 3, 2, 2, 2, 146, 147, 3, 2, 2, 2, 147, 152, 3, 2, 2, 2, 148, 149, 7, 21, 2, 2, 149, 151, 5, 4, 3, 2, 150, 148, 3, 2, 2, 2, 151, 154, 3, 2, 2, 2, 152, 153, 3, 2, 2, 2, 152, 150, 3, 2, 2, 2, 153, 156, 3, 2, 2, 2, 154, 152, 3, 2, 2, 2, 155, 157, 7, 21, 2, 2, 156, 155, 3, 2, 2, 2, 156, 157, 3, 2, 2, 2, 157, 158, 3, 2, 2, 2, 158, 159, 7, 27, 2, 2, 159, 17, 3, 2, 2, 2, 160, 162, 7, 24, 2, 2, 161, 163, 5, 20, 11, 2, 162, 161, 3, 2, 2, 2, 162, 163, 3, 2, 2, 2, 163, 168, 3, 2, 2, 2, 164, 165, 7, 21, 2, 2, 165, 167, 5, 20, 11, 2, 166, 164, 3, 2, 2, 2, 167, 170, 3, 2, 2, 2, 168, 166, 3, 2, 2, 2, 168, 169, 3, 2, 2, 2, 169, 172, 3, 2, 2, 2, 170, 168, 3, 2, 2, 2, 171, 173, 7, 21, 2, 2, 172, 171, 3, 2, 2, 2, 172, 173, 3, 2, 2, 2, 173, 174, 3, 2, 2, 2, 174, 175, 7, 25, 2, 2, 175, 19, 3, 2, 2, 2, 176, 188, 7, 71, 2, 2, 177, 178, 5, 22, 12, 2, 178, 179, 7, 18, 2, 2, 179, 180, 5, 4, 3, 2, 180, 188, 3, 2, 2, 2, 181, 182, 7, 26, 2, 2, 182, 183, 5, 4, 3, 2, 183, 184, 7, 27, 2, 2, 184, 185, 7, 18, 2, 2, 185, 186, 5, 4, 3, 2, 186, 188, 3, 2, 2, 2, 187, 176, 3, 2, 2, 2, 187, 177, 3, 2, 2, 2, 187, 181, 3, 2, 2, 2, 188, 21, 3, 2, 2, 2, 189, 190, 9, 10, 2, 2, 190, 23, 3, 2, 2, 2, 22, 31, 47, 65, 85, 87, 96, 106, 116, 118, 123, 128, 134, 138, 146, 152, 156, 162, 168, 172, 187] \ No newline at end of file diff --git a/ui/src/suggestions/grammar/RQLParser.js b/ui/src/suggestions/grammar/RQLParser.js new file mode 100644 index 0000000..fc295fe --- /dev/null +++ b/ui/src/suggestions/grammar/RQLParser.js @@ -0,0 +1,1866 @@ +// Generated from CAQLParser.g4 by ANTLR 4.9.2 +// jshint ignore: start +import antlr4 from 'antlr4'; +import CAQLParserListener from './CAQLParserListener.js'; + +const serializedATN = ["\u0003\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786", + "\u5964\u0003P\u00c0\u0004\u0002\t\u0002\u0004\u0003\t\u0003\u0004\u0004", + "\t\u0004\u0004\u0005\t\u0005\u0004\u0006\t\u0006\u0004\u0007\t\u0007", + "\u0004\b\t\b\u0004\t\t\t\u0004\n\t\n\u0004\u000b\t\u000b\u0004\f\t\f", + "\u0003\u0002\u0003\u0002\u0003\u0002\u0003\u0003\u0003\u0003\u0003\u0003", + "\u0003\u0003\u0005\u0003 \n\u0003\u0003\u0003\u0003\u0003\u0003\u0003", + "\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003", + "\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0005\u0003", + "0\n\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003", + "\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003", + "\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0005\u0003", + "B\n\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003", + "\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003", + "\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003", + "\u0003\u0003\u0007\u0003V\n\u0003\f\u0003\u000e\u0003Y\u000b\u0003\u0003", + "\u0004\u0003\u0004\u0003\u0004\u0003\u0004\u0003\u0004\u0003\u0004\u0005", + "\u0004a\n\u0004\u0003\u0005\u0003\u0005\u0003\u0005\u0003\u0005\u0003", + "\u0005\u0003\u0005\u0003\u0005\u0003\u0005\u0005\u0005k\n\u0005\u0003", + "\u0005\u0003\u0005\u0003\u0005\u0003\u0005\u0003\u0005\u0003\u0005\u0003", + "\u0005\u0003\u0005\u0007\u0005u\n\u0005\f\u0005\u000e\u0005x\u000b\u0005", + "\u0003\u0006\u0003\u0006\u0005\u0006|\n\u0006\u0003\u0007\u0003\u0007", + "\u0003\u0007\u0005\u0007\u0081\n\u0007\u0003\u0007\u0003\u0007\u0007", + "\u0007\u0085\n\u0007\f\u0007\u000e\u0007\u0088\u000b\u0007\u0003\u0007", + "\u0005\u0007\u008b\n\u0007\u0003\u0007\u0003\u0007\u0003\b\u0003\b\u0003", + "\t\u0003\t\u0005\t\u0093\n\t\u0003\t\u0003\t\u0007\t\u0097\n\t\f\t\u000e", + "\t\u009a\u000b\t\u0003\t\u0005\t\u009d\n\t\u0003\t\u0003\t\u0003\n\u0003", + "\n\u0005\n\u00a3\n\n\u0003\n\u0003\n\u0007\n\u00a7\n\n\f\n\u000e\n\u00aa", + "\u000b\n\u0003\n\u0005\n\u00ad\n\n\u0003\n\u0003\n\u0003\u000b\u0003", + "\u000b\u0003\u000b\u0003\u000b\u0003\u000b\u0003\u000b\u0003\u000b\u0003", + "\u000b\u0003\u000b\u0003\u000b\u0003\u000b\u0005\u000b\u00bc\n\u000b", + "\u0003\f\u0003\f\u0003\f\u0004\u0086\u0098\u0004\u0004\b\r\u0002\u0004", + "\u0006\b\n\f\u000e\u0010\u0012\u0014\u0016\u0002\u000b\u0003\u0002\f", + "\r\u0003\u0002\u000e\u0010\u0003\u0002\b\u000b\u0003\u0002\u0006\u0007", + "\u0005\u0002\u001d\u001d\u001f\u001f00\u0004\u0002\u0006\u000b((\u0004", + "\u0002\u0004\u0005..\u0007\u0002$$22::HIKK\u0004\u0002GGKK\u0002\u00d8", + "\u0002\u0018\u0003\u0002\u0002\u0002\u0004\u001f\u0003\u0002\u0002\u0002", + "\u0006`\u0003\u0002\u0002\u0002\bj\u0003\u0002\u0002\u0002\n{\u0003", + "\u0002\u0002\u0002\f}\u0003\u0002\u0002\u0002\u000e\u008e\u0003\u0002", + "\u0002\u0002\u0010\u0090\u0003\u0002\u0002\u0002\u0012\u00a0\u0003\u0002", + "\u0002\u0002\u0014\u00bb\u0003\u0002\u0002\u0002\u0016\u00bd\u0003\u0002", + "\u0002\u0002\u0018\u0019\u0005\u0004\u0003\u0002\u0019\u001a\u0007\u0002", + "\u0002\u0003\u001a\u0003\u0003\u0002\u0002\u0002\u001b\u001c\b\u0003", + "\u0001\u0002\u001c \u0005\u000e\b\u0002\u001d \u0005\b\u0005\u0002\u001e", + " \u0005\u0006\u0004\u0002\u001f\u001b\u0003\u0002\u0002\u0002\u001f", + "\u001d\u0003\u0002\u0002\u0002\u001f\u001e\u0003\u0002\u0002\u0002 ", + "W\u0003\u0002\u0002\u0002!\"\f\u000f\u0002\u0002\"#\t\u0002\u0002\u0002", + "#V\u0005\u0004\u0003\u0010$%\f\u000e\u0002\u0002%&\t\u0003\u0002\u0002", + "&V\u0005\u0004\u0003\u000f\'(\f\r\u0002\u0002()\u0007\u0014\u0002\u0002", + ")V\u0005\u0004\u0003\u000e*+\f\f\u0002\u0002+,\t\u0004\u0002\u0002,", + "V\u0005\u0004\u0003\r-/\f\u000b\u0002\u0002.0\u00071\u0002\u0002/.\u0003", + "\u0002\u0002\u0002/0\u0003\u0002\u0002\u000201\u0003\u0002\u0002\u0002", + "12\u0007(\u0002\u00022V\u0005\u0004\u0003\f34\f\n\u0002\u000245\t\u0005", + "\u0002\u00025V\u0005\u0004\u0003\u000b67\f\t\u0002\u000278\t\u0006\u0002", + "\u000289\t\u0007\u0002\u00029V\u0005\u0004\u0003\n:;\f\b\u0002\u0002", + ";<\t\u0006\u0002\u0002<=\u00071\u0002\u0002=>\u0007(\u0002\u0002>V\u0005", + "\u0004\u0003\t?A\f\u0007\u0002\u0002@B\u00071\u0002\u0002A@\u0003\u0002", + "\u0002\u0002AB\u0003\u0002\u0002\u0002BC\u0003\u0002\u0002\u0002CD\t", + "\b\u0002\u0002DV\u0005\u0004\u0003\bEF\f\u0006\u0002\u0002FG\u0007\u001e", + "\u0002\u0002GV\u0005\u0004\u0003\u0007HI\f\u0005\u0002\u0002IJ\u0007", + "3\u0002\u0002JV\u0005\u0004\u0003\u0006KL\f\u0004\u0002\u0002LM\u0007", + "\u0011\u0002\u0002MN\u0005\u0004\u0003\u0002NO\u0007\u0012\u0002\u0002", + "OP\u0005\u0004\u0003\u0005PV\u0003\u0002\u0002\u0002QR\f\u0003\u0002", + "\u0002RS\u0007\u0011\u0002\u0002ST\u0007\u0012\u0002\u0002TV\u0005\u0004", + "\u0003\u0004U!\u0003\u0002\u0002\u0002U$\u0003\u0002\u0002\u0002U\'", + "\u0003\u0002\u0002\u0002U*\u0003\u0002\u0002\u0002U-\u0003\u0002\u0002", + "\u0002U3\u0003\u0002\u0002\u0002U6\u0003\u0002\u0002\u0002U:\u0003\u0002", + "\u0002\u0002U?\u0003\u0002\u0002\u0002UE\u0003\u0002\u0002\u0002UH\u0003", + "\u0002\u0002\u0002UK\u0003\u0002\u0002\u0002UQ\u0003\u0002\u0002\u0002", + "VY\u0003\u0002\u0002\u0002WU\u0003\u0002\u0002\u0002WX\u0003\u0002\u0002", + "\u0002X\u0005\u0003\u0002\u0002\u0002YW\u0003\u0002\u0002\u0002Z[\u0007", + "\f\u0002\u0002[a\u0005\u0004\u0003\u0002\\]\u0007\r\u0002\u0002]a\u0005", + "\u0004\u0003\u0002^_\u00071\u0002\u0002_a\u0005\u0004\u0003\u0002`Z", + "\u0003\u0002\u0002\u0002`\\\u0003\u0002\u0002\u0002`^\u0003\u0002\u0002", + "\u0002a\u0007\u0003\u0002\u0002\u0002bc\b\u0005\u0001\u0002ck\u0007", + "G\u0002\u0002dk\u0005\n\u0006\u0002ek\u0005\f\u0007\u0002fg\u0007\u0016", + "\u0002\u0002gh\u0005\u0004\u0003\u0002hi\u0007\u0017\u0002\u0002ik\u0003", + "\u0002\u0002\u0002jb\u0003\u0002\u0002\u0002jd\u0003\u0002\u0002\u0002", + "je\u0003\u0002\u0002\u0002jf\u0003\u0002\u0002\u0002kv\u0003\u0002\u0002", + "\u0002lm\f\u0004\u0002\u0002mn\u0007\u0003\u0002\u0002nu\u0007G\u0002", + "\u0002op\f\u0003\u0002\u0002pq\u0007\u001a\u0002\u0002qr\u0005\u0004", + "\u0003\u0002rs\u0007\u001b\u0002\u0002su\u0003\u0002\u0002\u0002tl\u0003", + "\u0002\u0002\u0002to\u0003\u0002\u0002\u0002ux\u0003\u0002\u0002\u0002", + "vt\u0003\u0002\u0002\u0002vw\u0003\u0002\u0002\u0002w\t\u0003\u0002", + "\u0002\u0002xv\u0003\u0002\u0002\u0002y|\u0005\u0010\t\u0002z|\u0005", + "\u0012\n\u0002{y\u0003\u0002\u0002\u0002{z\u0003\u0002\u0002\u0002|", + "\u000b\u0003\u0002\u0002\u0002}~\u0007G\u0002\u0002~\u0080\u0007\u0016", + "\u0002\u0002\u007f\u0081\u0005\u0004\u0003\u0002\u0080\u007f\u0003\u0002", + "\u0002\u0002\u0080\u0081\u0003\u0002\u0002\u0002\u0081\u0086\u0003\u0002", + "\u0002\u0002\u0082\u0083\u0007\u0015\u0002\u0002\u0083\u0085\u0005\u0004", + "\u0003\u0002\u0084\u0082\u0003\u0002\u0002\u0002\u0085\u0088\u0003\u0002", + "\u0002\u0002\u0086\u0087\u0003\u0002\u0002\u0002\u0086\u0084\u0003\u0002", + "\u0002\u0002\u0087\u008a\u0003\u0002\u0002\u0002\u0088\u0086\u0003\u0002", + "\u0002\u0002\u0089\u008b\u0007\u0015\u0002\u0002\u008a\u0089\u0003\u0002", + "\u0002\u0002\u008a\u008b\u0003\u0002\u0002\u0002\u008b\u008c\u0003\u0002", + "\u0002\u0002\u008c\u008d\u0007\u0017\u0002\u0002\u008d\r\u0003\u0002", + "\u0002\u0002\u008e\u008f\t\t\u0002\u0002\u008f\u000f\u0003\u0002\u0002", + "\u0002\u0090\u0092\u0007\u001a\u0002\u0002\u0091\u0093\u0005\u0004\u0003", + "\u0002\u0092\u0091\u0003\u0002\u0002\u0002\u0092\u0093\u0003\u0002\u0002", + "\u0002\u0093\u0098\u0003\u0002\u0002\u0002\u0094\u0095\u0007\u0015\u0002", + "\u0002\u0095\u0097\u0005\u0004\u0003\u0002\u0096\u0094\u0003\u0002\u0002", + "\u0002\u0097\u009a\u0003\u0002\u0002\u0002\u0098\u0099\u0003\u0002\u0002", + "\u0002\u0098\u0096\u0003\u0002\u0002\u0002\u0099\u009c\u0003\u0002\u0002", + "\u0002\u009a\u0098\u0003\u0002\u0002\u0002\u009b\u009d\u0007\u0015\u0002", + "\u0002\u009c\u009b\u0003\u0002\u0002\u0002\u009c\u009d\u0003\u0002\u0002", + "\u0002\u009d\u009e\u0003\u0002\u0002\u0002\u009e\u009f\u0007\u001b\u0002", + "\u0002\u009f\u0011\u0003\u0002\u0002\u0002\u00a0\u00a2\u0007\u0018\u0002", + "\u0002\u00a1\u00a3\u0005\u0014\u000b\u0002\u00a2\u00a1\u0003\u0002\u0002", + "\u0002\u00a2\u00a3\u0003\u0002\u0002\u0002\u00a3\u00a8\u0003\u0002\u0002", + "\u0002\u00a4\u00a5\u0007\u0015\u0002\u0002\u00a5\u00a7\u0005\u0014\u000b", + "\u0002\u00a6\u00a4\u0003\u0002\u0002\u0002\u00a7\u00aa\u0003\u0002\u0002", + "\u0002\u00a8\u00a6\u0003\u0002\u0002\u0002\u00a8\u00a9\u0003\u0002\u0002", + "\u0002\u00a9\u00ac\u0003\u0002\u0002\u0002\u00aa\u00a8\u0003\u0002\u0002", + "\u0002\u00ab\u00ad\u0007\u0015\u0002\u0002\u00ac\u00ab\u0003\u0002\u0002", + "\u0002\u00ac\u00ad\u0003\u0002\u0002\u0002\u00ad\u00ae\u0003\u0002\u0002", + "\u0002\u00ae\u00af\u0007\u0019\u0002\u0002\u00af\u0013\u0003\u0002\u0002", + "\u0002\u00b0\u00bc\u0007G\u0002\u0002\u00b1\u00b2\u0005\u0016\f\u0002", + "\u00b2\u00b3\u0007\u0012\u0002\u0002\u00b3\u00b4\u0005\u0004\u0003\u0002", + "\u00b4\u00bc\u0003\u0002\u0002\u0002\u00b5\u00b6\u0007\u001a\u0002\u0002", + "\u00b6\u00b7\u0005\u0004\u0003\u0002\u00b7\u00b8\u0007\u001b\u0002\u0002", + "\u00b8\u00b9\u0007\u0012\u0002\u0002\u00b9\u00ba\u0005\u0004\u0003\u0002", + "\u00ba\u00bc\u0003\u0002\u0002\u0002\u00bb\u00b0\u0003\u0002\u0002\u0002", + "\u00bb\u00b1\u0003\u0002\u0002\u0002\u00bb\u00b5\u0003\u0002\u0002\u0002", + "\u00bc\u0015\u0003\u0002\u0002\u0002\u00bd\u00be\t\n\u0002\u0002\u00be", + "\u0017\u0003\u0002\u0002\u0002\u0016\u001f/AUW`jtv{\u0080\u0086\u008a", + "\u0092\u0098\u009c\u00a2\u00a8\u00ac\u00bb"].join(""); + + +const atn = new antlr4.atn.ATNDeserializer().deserialize(serializedATN); + +const decisionsToDFA = atn.decisionToState.map( (ds, index) => new antlr4.dfa.DFA(ds, index) ); + +const sharedContextCache = new antlr4.PredictionContextCache(); + +export default class CAQLParser extends antlr4.Parser { + + static grammarFileName = "CAQLParser.g4"; + static literalNames = [ null, "'.'", "'=~'", "'!~'", "'=='", "'!='", + "'<'", "'>'", "'<='", "'>='", "'+'", "'-'", + "'*'", "'/'", "'%'", "'?'", "':'", "'::'", "'..'", + "','", "'('", "')'", "'{'", "'}'", "'['", "']'" ]; + static symbolicNames = [ null, "DOT", "T_REGEX_MATCH", "T_REGEX_NON_MATCH", + "T_EQ", "T_NE", "T_LT", "T_GT", "T_LE", "T_GE", + "T_PLUS", "T_MINUS", "T_TIMES", "T_DIV", "T_MOD", + "T_QUESTION", "T_COLON", "T_SCOPE", "T_RANGE", + "T_COMMA", "T_OPEN", "T_CLOSE", "T_OBJECT_OPEN", + "T_OBJECT_CLOSE", "T_ARRAY_OPEN", "T_ARRAY_CLOSE", + "T_AGGREGATE", "T_ALL", "T_AND", "T_ANY", "T_ASC", + "T_COLLECT", "T_DESC", "T_DISTINCT", "T_FALSE", + "T_FILTER", "T_FOR", "T_GRAPH", "T_IN", "T_INBOUND", + "T_INSERT", "T_INTO", "T_K_SHORTEST_PATHS", + "T_LET", "T_LIKE", "T_LIMIT", "T_NONE", "T_NOT", + "T_NULL", "T_OR", "T_OUTBOUND", "T_REMOVE", + "T_REPLACE", "T_RETURN", "T_SHORTEST_PATH", + "T_SORT", "T_TRUE", "T_UPDATE", "T_UPSERT", + "T_WITH", "T_KEEP", "T_COUNT", "T_OPTIONS", + "T_PRUNE", "T_SEARCH", "T_TO", "T_CURRENT", + "T_NEW", "T_OLD", "T_STRING", "T_INT", "T_FLOAT", + "T_PARAMETER", "T_QUOTED_STRING", "SINGLE_LINE_COMMENT", + "MULTILINE_COMMENT", "SPACES", "UNEXPECTED_CHAR", + "ERROR_RECONGNIGION" ]; + static ruleNames = [ "parse", "expression", "operator_unary", "reference", + "compound_value", "function_call", "value_literal", + "array", "object", "object_element", "object_element_name" ]; + + constructor(input) { + super(input); + this._interp = new antlr4.atn.ParserATNSimulator(this, atn, decisionsToDFA, sharedContextCache); + this.ruleNames = CAQLParser.ruleNames; + this.literalNames = CAQLParser.literalNames; + this.symbolicNames = CAQLParser.symbolicNames; + } + + get atn() { + return atn; + } + + sempred(localctx, ruleIndex, predIndex) { + switch(ruleIndex) { + case 1: + return this.expression_sempred(localctx, predIndex); + case 3: + return this.reference_sempred(localctx, predIndex); + default: + throw "No predicate with index:" + ruleIndex; + } + } + + expression_sempred(localctx, predIndex) { + switch(predIndex) { + case 0: + return this.precpred(this._ctx, 13); + case 1: + return this.precpred(this._ctx, 12); + case 2: + return this.precpred(this._ctx, 11); + case 3: + return this.precpred(this._ctx, 10); + case 4: + return this.precpred(this._ctx, 9); + case 5: + return this.precpred(this._ctx, 8); + case 6: + return this.precpred(this._ctx, 7); + case 7: + return this.precpred(this._ctx, 6); + case 8: + return this.precpred(this._ctx, 5); + case 9: + return this.precpred(this._ctx, 4); + case 10: + return this.precpred(this._ctx, 3); + case 11: + return this.precpred(this._ctx, 2); + case 12: + return this.precpred(this._ctx, 1); + default: + throw "No predicate with index:" + predIndex; + } + }; + + reference_sempred(localctx, predIndex) { + switch(predIndex) { + case 13: + return this.precpred(this._ctx, 2); + case 14: + return this.precpred(this._ctx, 1); + default: + throw "No predicate with index:" + predIndex; + } + }; + + + + + parse() { + let localctx = new ParseContext(this, this._ctx, this.state); + this.enterRule(localctx, 0, CAQLParser.RULE_parse); + try { + this.enterOuterAlt(localctx, 1); + this.state = 22; + this.expression(0); + this.state = 23; + this.match(CAQLParser.EOF); + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; + } + + + expression(_p) { + if(_p===undefined) { + _p = 0; + } + const _parentctx = this._ctx; + const _parentState = this.state; + let localctx = new ExpressionContext(this, this._ctx, _parentState); + let _prevctx = localctx; + const _startState = 2; + this.enterRecursionRule(localctx, 2, CAQLParser.RULE_expression, _p); + var _la = 0; // Token type + try { + this.enterOuterAlt(localctx, 1); + this.state = 29; + this._errHandler.sync(this); + switch(this._input.LA(1)) { + case CAQLParser.T_FALSE: + case CAQLParser.T_NULL: + case CAQLParser.T_TRUE: + case CAQLParser.T_INT: + case CAQLParser.T_FLOAT: + case CAQLParser.T_QUOTED_STRING: + this.state = 26; + this.value_literal(); + break; + case CAQLParser.T_OPEN: + case CAQLParser.T_OBJECT_OPEN: + case CAQLParser.T_ARRAY_OPEN: + case CAQLParser.T_STRING: + this.state = 27; + this.reference(0); + break; + case CAQLParser.T_PLUS: + case CAQLParser.T_MINUS: + case CAQLParser.T_NOT: + this.state = 28; + this.operator_unary(); + break; + default: + throw new antlr4.error.NoViableAltException(this); + } + this._ctx.stop = this._input.LT(-1); + this.state = 85; + this._errHandler.sync(this); + var _alt = this._interp.adaptivePredict(this._input,4,this._ctx) + while(_alt!=2 && _alt!=antlr4.atn.ATN.INVALID_ALT_NUMBER) { + if(_alt===1) { + if(this._parseListeners!==null) { + this.triggerExitRuleEvent(); + } + _prevctx = localctx; + this.state = 83; + this._errHandler.sync(this); + var la_ = this._interp.adaptivePredict(this._input,3,this._ctx); + switch(la_) { + case 1: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 31; + if (!( this.precpred(this._ctx, 13))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 13)"); + } + this.state = 32; + _la = this._input.LA(1); + if(!(_la===CAQLParser.T_PLUS || _la===CAQLParser.T_MINUS)) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + this.state = 33; + this.expression(14); + break; + + case 2: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 34; + if (!( this.precpred(this._ctx, 12))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 12)"); + } + this.state = 35; + _la = this._input.LA(1); + if(!((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << CAQLParser.T_TIMES) | (1 << CAQLParser.T_DIV) | (1 << CAQLParser.T_MOD))) !== 0))) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + this.state = 36; + this.expression(13); + break; + + case 3: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 37; + if (!( this.precpred(this._ctx, 11))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 11)"); + } + this.state = 38; + this.match(CAQLParser.T_RANGE); + this.state = 39; + this.expression(12); + break; + + case 4: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 40; + if (!( this.precpred(this._ctx, 10))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 10)"); + } + this.state = 41; + _la = this._input.LA(1); + if(!((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << CAQLParser.T_LT) | (1 << CAQLParser.T_GT) | (1 << CAQLParser.T_LE) | (1 << CAQLParser.T_GE))) !== 0))) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + this.state = 42; + this.expression(11); + break; + + case 5: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 43; + if (!( this.precpred(this._ctx, 9))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 9)"); + } + this.state = 45; + this._errHandler.sync(this); + _la = this._input.LA(1); + if(_la===CAQLParser.T_NOT) { + this.state = 44; + this.match(CAQLParser.T_NOT); + } + + this.state = 47; + this.match(CAQLParser.T_IN); + this.state = 48; + this.expression(10); + break; + + case 6: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 49; + if (!( this.precpred(this._ctx, 8))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 8)"); + } + this.state = 50; + _la = this._input.LA(1); + if(!(_la===CAQLParser.T_EQ || _la===CAQLParser.T_NE)) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + this.state = 51; + this.expression(9); + break; + + case 7: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 52; + if (!( this.precpred(this._ctx, 7))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 7)"); + } + this.state = 53; + _la = this._input.LA(1); + if(!(((((_la - 27)) & ~0x1f) == 0 && ((1 << (_la - 27)) & ((1 << (CAQLParser.T_ALL - 27)) | (1 << (CAQLParser.T_ANY - 27)) | (1 << (CAQLParser.T_NONE - 27)))) !== 0))) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + this.state = 54; + localctx.eq_op = this._input.LT(1); + _la = this._input.LA(1); + if(!((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << CAQLParser.T_EQ) | (1 << CAQLParser.T_NE) | (1 << CAQLParser.T_LT) | (1 << CAQLParser.T_GT) | (1 << CAQLParser.T_LE) | (1 << CAQLParser.T_GE))) !== 0) || _la===CAQLParser.T_IN)) { + localctx.eq_op = this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + this.state = 55; + this.expression(8); + break; + + case 8: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 56; + if (!( this.precpred(this._ctx, 6))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 6)"); + } + this.state = 57; + _la = this._input.LA(1); + if(!(((((_la - 27)) & ~0x1f) == 0 && ((1 << (_la - 27)) & ((1 << (CAQLParser.T_ALL - 27)) | (1 << (CAQLParser.T_ANY - 27)) | (1 << (CAQLParser.T_NONE - 27)))) !== 0))) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + this.state = 58; + this.match(CAQLParser.T_NOT); + this.state = 59; + this.match(CAQLParser.T_IN); + this.state = 60; + this.expression(7); + break; + + case 9: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 61; + if (!( this.precpred(this._ctx, 5))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 5)"); + } + this.state = 63; + this._errHandler.sync(this); + _la = this._input.LA(1); + if(_la===CAQLParser.T_NOT) { + this.state = 62; + this.match(CAQLParser.T_NOT); + } + + this.state = 65; + _la = this._input.LA(1); + if(!(_la===CAQLParser.T_REGEX_MATCH || _la===CAQLParser.T_REGEX_NON_MATCH || _la===CAQLParser.T_LIKE)) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + this.state = 66; + this.expression(6); + break; + + case 10: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 67; + if (!( this.precpred(this._ctx, 4))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 4)"); + } + this.state = 68; + this.match(CAQLParser.T_AND); + this.state = 69; + this.expression(5); + break; + + case 11: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 70; + if (!( this.precpred(this._ctx, 3))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 3)"); + } + this.state = 71; + this.match(CAQLParser.T_OR); + this.state = 72; + this.expression(4); + break; + + case 12: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 73; + if (!( this.precpred(this._ctx, 2))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 2)"); + } + this.state = 74; + this.match(CAQLParser.T_QUESTION); + this.state = 75; + this.expression(0); + this.state = 76; + this.match(CAQLParser.T_COLON); + this.state = 77; + this.expression(3); + break; + + case 13: + localctx = new ExpressionContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_expression); + this.state = 79; + if (!( this.precpred(this._ctx, 1))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 1)"); + } + this.state = 80; + this.match(CAQLParser.T_QUESTION); + this.state = 81; + this.match(CAQLParser.T_COLON); + this.state = 82; + this.expression(2); + break; + + } + } + this.state = 87; + this._errHandler.sync(this); + _alt = this._interp.adaptivePredict(this._input,4,this._ctx); + } + + } catch( error) { + if(error instanceof antlr4.error.RecognitionException) { + localctx.exception = error; + this._errHandler.reportError(this, error); + this._errHandler.recover(this, error); + } else { + throw error; + } + } finally { + this.unrollRecursionContexts(_parentctx) + } + return localctx; + } + + + + operator_unary() { + let localctx = new Operator_unaryContext(this, this._ctx, this.state); + this.enterRule(localctx, 4, CAQLParser.RULE_operator_unary); + try { + this.enterOuterAlt(localctx, 1); + this.state = 94; + this._errHandler.sync(this); + switch(this._input.LA(1)) { + case CAQLParser.T_PLUS: + this.state = 88; + this.match(CAQLParser.T_PLUS); + this.state = 89; + this.expression(0); + break; + case CAQLParser.T_MINUS: + this.state = 90; + this.match(CAQLParser.T_MINUS); + this.state = 91; + this.expression(0); + break; + case CAQLParser.T_NOT: + this.state = 92; + this.match(CAQLParser.T_NOT); + this.state = 93; + this.expression(0); + break; + default: + throw new antlr4.error.NoViableAltException(this); + } + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; + } + + + reference(_p) { + if(_p===undefined) { + _p = 0; + } + const _parentctx = this._ctx; + const _parentState = this.state; + let localctx = new ReferenceContext(this, this._ctx, _parentState); + let _prevctx = localctx; + const _startState = 6; + this.enterRecursionRule(localctx, 6, CAQLParser.RULE_reference, _p); + try { + this.enterOuterAlt(localctx, 1); + this.state = 104; + this._errHandler.sync(this); + var la_ = this._interp.adaptivePredict(this._input,6,this._ctx); + switch(la_) { + case 1: + this.state = 97; + this.match(CAQLParser.T_STRING); + break; + + case 2: + this.state = 98; + this.compound_value(); + break; + + case 3: + this.state = 99; + this.function_call(); + break; + + case 4: + this.state = 100; + this.match(CAQLParser.T_OPEN); + this.state = 101; + this.expression(0); + this.state = 102; + this.match(CAQLParser.T_CLOSE); + break; + + } + this._ctx.stop = this._input.LT(-1); + this.state = 116; + this._errHandler.sync(this); + var _alt = this._interp.adaptivePredict(this._input,8,this._ctx) + while(_alt!=2 && _alt!=antlr4.atn.ATN.INVALID_ALT_NUMBER) { + if(_alt===1) { + if(this._parseListeners!==null) { + this.triggerExitRuleEvent(); + } + _prevctx = localctx; + this.state = 114; + this._errHandler.sync(this); + var la_ = this._interp.adaptivePredict(this._input,7,this._ctx); + switch(la_) { + case 1: + localctx = new ReferenceContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_reference); + this.state = 106; + if (!( this.precpred(this._ctx, 2))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 2)"); + } + this.state = 107; + this.match(CAQLParser.DOT); + this.state = 108; + this.match(CAQLParser.T_STRING); + break; + + case 2: + localctx = new ReferenceContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, CAQLParser.RULE_reference); + this.state = 109; + if (!( this.precpred(this._ctx, 1))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 1)"); + } + this.state = 110; + this.match(CAQLParser.T_ARRAY_OPEN); + this.state = 111; + this.expression(0); + this.state = 112; + this.match(CAQLParser.T_ARRAY_CLOSE); + break; + + } + } + this.state = 118; + this._errHandler.sync(this); + _alt = this._interp.adaptivePredict(this._input,8,this._ctx); + } + + } catch( error) { + if(error instanceof antlr4.error.RecognitionException) { + localctx.exception = error; + this._errHandler.reportError(this, error); + this._errHandler.recover(this, error); + } else { + throw error; + } + } finally { + this.unrollRecursionContexts(_parentctx) + } + return localctx; + } + + + + compound_value() { + let localctx = new Compound_valueContext(this, this._ctx, this.state); + this.enterRule(localctx, 8, CAQLParser.RULE_compound_value); + try { + this.enterOuterAlt(localctx, 1); + this.state = 121; + this._errHandler.sync(this); + switch(this._input.LA(1)) { + case CAQLParser.T_ARRAY_OPEN: + this.state = 119; + this.array(); + break; + case CAQLParser.T_OBJECT_OPEN: + this.state = 120; + this.object(); + break; + default: + throw new antlr4.error.NoViableAltException(this); + } + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; + } + + + + function_call() { + let localctx = new Function_callContext(this, this._ctx, this.state); + this.enterRule(localctx, 10, CAQLParser.RULE_function_call); + var _la = 0; // Token type + try { + this.enterOuterAlt(localctx, 1); + this.state = 123; + this.match(CAQLParser.T_STRING); + this.state = 124; + this.match(CAQLParser.T_OPEN); + this.state = 126; + this._errHandler.sync(this); + _la = this._input.LA(1); + if(((((_la - 10)) & ~0x1f) == 0 && ((1 << (_la - 10)) & ((1 << (CAQLParser.T_PLUS - 10)) | (1 << (CAQLParser.T_MINUS - 10)) | (1 << (CAQLParser.T_OPEN - 10)) | (1 << (CAQLParser.T_OBJECT_OPEN - 10)) | (1 << (CAQLParser.T_ARRAY_OPEN - 10)) | (1 << (CAQLParser.T_FALSE - 10)))) !== 0) || ((((_la - 47)) & ~0x1f) == 0 && ((1 << (_la - 47)) & ((1 << (CAQLParser.T_NOT - 47)) | (1 << (CAQLParser.T_NULL - 47)) | (1 << (CAQLParser.T_TRUE - 47)) | (1 << (CAQLParser.T_STRING - 47)) | (1 << (CAQLParser.T_INT - 47)) | (1 << (CAQLParser.T_FLOAT - 47)) | (1 << (CAQLParser.T_QUOTED_STRING - 47)))) !== 0)) { + this.state = 125; + this.expression(0); + } + + this.state = 132; + this._errHandler.sync(this); + var _alt = this._interp.adaptivePredict(this._input,11,this._ctx) + while(_alt!=1 && _alt!=antlr4.atn.ATN.INVALID_ALT_NUMBER) { + if(_alt===1+1) { + this.state = 128; + this.match(CAQLParser.T_COMMA); + this.state = 129; + this.expression(0); + } + this.state = 134; + this._errHandler.sync(this); + _alt = this._interp.adaptivePredict(this._input,11,this._ctx); + } + + this.state = 136; + this._errHandler.sync(this); + _la = this._input.LA(1); + if(_la===CAQLParser.T_COMMA) { + this.state = 135; + this.match(CAQLParser.T_COMMA); + } + + this.state = 138; + this.match(CAQLParser.T_CLOSE); + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; + } + + + + value_literal() { + let localctx = new Value_literalContext(this, this._ctx, this.state); + this.enterRule(localctx, 12, CAQLParser.RULE_value_literal); + var _la = 0; // Token type + try { + this.enterOuterAlt(localctx, 1); + this.state = 140; + _la = this._input.LA(1); + if(!(((((_la - 34)) & ~0x1f) == 0 && ((1 << (_la - 34)) & ((1 << (CAQLParser.T_FALSE - 34)) | (1 << (CAQLParser.T_NULL - 34)) | (1 << (CAQLParser.T_TRUE - 34)))) !== 0) || ((((_la - 70)) & ~0x1f) == 0 && ((1 << (_la - 70)) & ((1 << (CAQLParser.T_INT - 70)) | (1 << (CAQLParser.T_FLOAT - 70)) | (1 << (CAQLParser.T_QUOTED_STRING - 70)))) !== 0))) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; + } + + + + array() { + let localctx = new ArrayContext(this, this._ctx, this.state); + this.enterRule(localctx, 14, CAQLParser.RULE_array); + var _la = 0; // Token type + try { + this.enterOuterAlt(localctx, 1); + this.state = 142; + this.match(CAQLParser.T_ARRAY_OPEN); + this.state = 144; + this._errHandler.sync(this); + _la = this._input.LA(1); + if(((((_la - 10)) & ~0x1f) == 0 && ((1 << (_la - 10)) & ((1 << (CAQLParser.T_PLUS - 10)) | (1 << (CAQLParser.T_MINUS - 10)) | (1 << (CAQLParser.T_OPEN - 10)) | (1 << (CAQLParser.T_OBJECT_OPEN - 10)) | (1 << (CAQLParser.T_ARRAY_OPEN - 10)) | (1 << (CAQLParser.T_FALSE - 10)))) !== 0) || ((((_la - 47)) & ~0x1f) == 0 && ((1 << (_la - 47)) & ((1 << (CAQLParser.T_NOT - 47)) | (1 << (CAQLParser.T_NULL - 47)) | (1 << (CAQLParser.T_TRUE - 47)) | (1 << (CAQLParser.T_STRING - 47)) | (1 << (CAQLParser.T_INT - 47)) | (1 << (CAQLParser.T_FLOAT - 47)) | (1 << (CAQLParser.T_QUOTED_STRING - 47)))) !== 0)) { + this.state = 143; + this.expression(0); + } + + this.state = 150; + this._errHandler.sync(this); + var _alt = this._interp.adaptivePredict(this._input,14,this._ctx) + while(_alt!=1 && _alt!=antlr4.atn.ATN.INVALID_ALT_NUMBER) { + if(_alt===1+1) { + this.state = 146; + this.match(CAQLParser.T_COMMA); + this.state = 147; + this.expression(0); + } + this.state = 152; + this._errHandler.sync(this); + _alt = this._interp.adaptivePredict(this._input,14,this._ctx); + } + + this.state = 154; + this._errHandler.sync(this); + _la = this._input.LA(1); + if(_la===CAQLParser.T_COMMA) { + this.state = 153; + this.match(CAQLParser.T_COMMA); + } + + this.state = 156; + this.match(CAQLParser.T_ARRAY_CLOSE); + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; + } + + + + object() { + let localctx = new ObjectContext(this, this._ctx, this.state); + this.enterRule(localctx, 16, CAQLParser.RULE_object); + var _la = 0; // Token type + try { + this.enterOuterAlt(localctx, 1); + this.state = 158; + this.match(CAQLParser.T_OBJECT_OPEN); + this.state = 160; + this._errHandler.sync(this); + _la = this._input.LA(1); + if(_la===CAQLParser.T_ARRAY_OPEN || _la===CAQLParser.T_STRING || _la===CAQLParser.T_QUOTED_STRING) { + this.state = 159; + this.object_element(); + } + + this.state = 166; + this._errHandler.sync(this); + var _alt = this._interp.adaptivePredict(this._input,17,this._ctx) + while(_alt!=2 && _alt!=antlr4.atn.ATN.INVALID_ALT_NUMBER) { + if(_alt===1) { + this.state = 162; + this.match(CAQLParser.T_COMMA); + this.state = 163; + this.object_element(); + } + this.state = 168; + this._errHandler.sync(this); + _alt = this._interp.adaptivePredict(this._input,17,this._ctx); + } + + this.state = 170; + this._errHandler.sync(this); + _la = this._input.LA(1); + if(_la===CAQLParser.T_COMMA) { + this.state = 169; + this.match(CAQLParser.T_COMMA); + } + + this.state = 172; + this.match(CAQLParser.T_OBJECT_CLOSE); + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; + } + + + + object_element() { + let localctx = new Object_elementContext(this, this._ctx, this.state); + this.enterRule(localctx, 18, CAQLParser.RULE_object_element); + try { + this.enterOuterAlt(localctx, 1); + this.state = 185; + this._errHandler.sync(this); + var la_ = this._interp.adaptivePredict(this._input,19,this._ctx); + switch(la_) { + case 1: + this.state = 174; + this.match(CAQLParser.T_STRING); + break; + + case 2: + this.state = 175; + this.object_element_name(); + this.state = 176; + this.match(CAQLParser.T_COLON); + this.state = 177; + this.expression(0); + break; + + case 3: + this.state = 179; + this.match(CAQLParser.T_ARRAY_OPEN); + this.state = 180; + this.expression(0); + this.state = 181; + this.match(CAQLParser.T_ARRAY_CLOSE); + this.state = 182; + this.match(CAQLParser.T_COLON); + this.state = 183; + this.expression(0); + break; + + } + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; + } + + + + object_element_name() { + let localctx = new Object_element_nameContext(this, this._ctx, this.state); + this.enterRule(localctx, 20, CAQLParser.RULE_object_element_name); + var _la = 0; // Token type + try { + this.enterOuterAlt(localctx, 1); + this.state = 187; + _la = this._input.LA(1); + if(!(_la===CAQLParser.T_STRING || _la===CAQLParser.T_QUOTED_STRING)) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; + } + + +} + +CAQLParser.EOF = antlr4.Token.EOF; +CAQLParser.DOT = 1; +CAQLParser.T_REGEX_MATCH = 2; +CAQLParser.T_REGEX_NON_MATCH = 3; +CAQLParser.T_EQ = 4; +CAQLParser.T_NE = 5; +CAQLParser.T_LT = 6; +CAQLParser.T_GT = 7; +CAQLParser.T_LE = 8; +CAQLParser.T_GE = 9; +CAQLParser.T_PLUS = 10; +CAQLParser.T_MINUS = 11; +CAQLParser.T_TIMES = 12; +CAQLParser.T_DIV = 13; +CAQLParser.T_MOD = 14; +CAQLParser.T_QUESTION = 15; +CAQLParser.T_COLON = 16; +CAQLParser.T_SCOPE = 17; +CAQLParser.T_RANGE = 18; +CAQLParser.T_COMMA = 19; +CAQLParser.T_OPEN = 20; +CAQLParser.T_CLOSE = 21; +CAQLParser.T_OBJECT_OPEN = 22; +CAQLParser.T_OBJECT_CLOSE = 23; +CAQLParser.T_ARRAY_OPEN = 24; +CAQLParser.T_ARRAY_CLOSE = 25; +CAQLParser.T_AGGREGATE = 26; +CAQLParser.T_ALL = 27; +CAQLParser.T_AND = 28; +CAQLParser.T_ANY = 29; +CAQLParser.T_ASC = 30; +CAQLParser.T_COLLECT = 31; +CAQLParser.T_DESC = 32; +CAQLParser.T_DISTINCT = 33; +CAQLParser.T_FALSE = 34; +CAQLParser.T_FILTER = 35; +CAQLParser.T_FOR = 36; +CAQLParser.T_GRAPH = 37; +CAQLParser.T_IN = 38; +CAQLParser.T_INBOUND = 39; +CAQLParser.T_INSERT = 40; +CAQLParser.T_INTO = 41; +CAQLParser.T_K_SHORTEST_PATHS = 42; +CAQLParser.T_LET = 43; +CAQLParser.T_LIKE = 44; +CAQLParser.T_LIMIT = 45; +CAQLParser.T_NONE = 46; +CAQLParser.T_NOT = 47; +CAQLParser.T_NULL = 48; +CAQLParser.T_OR = 49; +CAQLParser.T_OUTBOUND = 50; +CAQLParser.T_REMOVE = 51; +CAQLParser.T_REPLACE = 52; +CAQLParser.T_RETURN = 53; +CAQLParser.T_SHORTEST_PATH = 54; +CAQLParser.T_SORT = 55; +CAQLParser.T_TRUE = 56; +CAQLParser.T_UPDATE = 57; +CAQLParser.T_UPSERT = 58; +CAQLParser.T_WITH = 59; +CAQLParser.T_KEEP = 60; +CAQLParser.T_COUNT = 61; +CAQLParser.T_OPTIONS = 62; +CAQLParser.T_PRUNE = 63; +CAQLParser.T_SEARCH = 64; +CAQLParser.T_TO = 65; +CAQLParser.T_CURRENT = 66; +CAQLParser.T_NEW = 67; +CAQLParser.T_OLD = 68; +CAQLParser.T_STRING = 69; +CAQLParser.T_INT = 70; +CAQLParser.T_FLOAT = 71; +CAQLParser.T_PARAMETER = 72; +CAQLParser.T_QUOTED_STRING = 73; +CAQLParser.SINGLE_LINE_COMMENT = 74; +CAQLParser.MULTILINE_COMMENT = 75; +CAQLParser.SPACES = 76; +CAQLParser.UNEXPECTED_CHAR = 77; +CAQLParser.ERROR_RECONGNIGION = 78; + +CAQLParser.RULE_parse = 0; +CAQLParser.RULE_expression = 1; +CAQLParser.RULE_operator_unary = 2; +CAQLParser.RULE_reference = 3; +CAQLParser.RULE_compound_value = 4; +CAQLParser.RULE_function_call = 5; +CAQLParser.RULE_value_literal = 6; +CAQLParser.RULE_array = 7; +CAQLParser.RULE_object = 8; +CAQLParser.RULE_object_element = 9; +CAQLParser.RULE_object_element_name = 10; + +class ParseContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_parse; + } + + expression() { + return this.getTypedRuleContext(ExpressionContext,0); + }; + + EOF() { + return this.getToken(CAQLParser.EOF, 0); + }; + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterParse(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitParse(this); + } + } + + +} + + + +class ExpressionContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_expression; + this.eq_op = null; // Token + } + + value_literal() { + return this.getTypedRuleContext(Value_literalContext,0); + }; + + reference() { + return this.getTypedRuleContext(ReferenceContext,0); + }; + + operator_unary() { + return this.getTypedRuleContext(Operator_unaryContext,0); + }; + + expression = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTypedRuleContexts(ExpressionContext); + } else { + return this.getTypedRuleContext(ExpressionContext,i); + } + }; + + T_PLUS() { + return this.getToken(CAQLParser.T_PLUS, 0); + }; + + T_MINUS() { + return this.getToken(CAQLParser.T_MINUS, 0); + }; + + T_TIMES() { + return this.getToken(CAQLParser.T_TIMES, 0); + }; + + T_DIV() { + return this.getToken(CAQLParser.T_DIV, 0); + }; + + T_MOD() { + return this.getToken(CAQLParser.T_MOD, 0); + }; + + T_RANGE() { + return this.getToken(CAQLParser.T_RANGE, 0); + }; + + T_LT() { + return this.getToken(CAQLParser.T_LT, 0); + }; + + T_GT() { + return this.getToken(CAQLParser.T_GT, 0); + }; + + T_LE() { + return this.getToken(CAQLParser.T_LE, 0); + }; + + T_GE() { + return this.getToken(CAQLParser.T_GE, 0); + }; + + T_IN() { + return this.getToken(CAQLParser.T_IN, 0); + }; + + T_NOT() { + return this.getToken(CAQLParser.T_NOT, 0); + }; + + T_EQ() { + return this.getToken(CAQLParser.T_EQ, 0); + }; + + T_NE() { + return this.getToken(CAQLParser.T_NE, 0); + }; + + T_ALL() { + return this.getToken(CAQLParser.T_ALL, 0); + }; + + T_ANY() { + return this.getToken(CAQLParser.T_ANY, 0); + }; + + T_NONE() { + return this.getToken(CAQLParser.T_NONE, 0); + }; + + T_LIKE() { + return this.getToken(CAQLParser.T_LIKE, 0); + }; + + T_REGEX_MATCH() { + return this.getToken(CAQLParser.T_REGEX_MATCH, 0); + }; + + T_REGEX_NON_MATCH() { + return this.getToken(CAQLParser.T_REGEX_NON_MATCH, 0); + }; + + T_AND() { + return this.getToken(CAQLParser.T_AND, 0); + }; + + T_OR() { + return this.getToken(CAQLParser.T_OR, 0); + }; + + T_QUESTION() { + return this.getToken(CAQLParser.T_QUESTION, 0); + }; + + T_COLON() { + return this.getToken(CAQLParser.T_COLON, 0); + }; + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterExpression(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitExpression(this); + } + } + + +} + + + +class Operator_unaryContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_operator_unary; + } + + T_PLUS() { + return this.getToken(CAQLParser.T_PLUS, 0); + }; + + expression() { + return this.getTypedRuleContext(ExpressionContext,0); + }; + + T_MINUS() { + return this.getToken(CAQLParser.T_MINUS, 0); + }; + + T_NOT() { + return this.getToken(CAQLParser.T_NOT, 0); + }; + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterOperator_unary(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitOperator_unary(this); + } + } + + +} + + + +class ReferenceContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_reference; + } + + T_STRING() { + return this.getToken(CAQLParser.T_STRING, 0); + }; + + compound_value() { + return this.getTypedRuleContext(Compound_valueContext,0); + }; + + function_call() { + return this.getTypedRuleContext(Function_callContext,0); + }; + + T_OPEN() { + return this.getToken(CAQLParser.T_OPEN, 0); + }; + + expression() { + return this.getTypedRuleContext(ExpressionContext,0); + }; + + T_CLOSE() { + return this.getToken(CAQLParser.T_CLOSE, 0); + }; + + reference() { + return this.getTypedRuleContext(ReferenceContext,0); + }; + + DOT() { + return this.getToken(CAQLParser.DOT, 0); + }; + + T_ARRAY_OPEN() { + return this.getToken(CAQLParser.T_ARRAY_OPEN, 0); + }; + + T_ARRAY_CLOSE() { + return this.getToken(CAQLParser.T_ARRAY_CLOSE, 0); + }; + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterReference(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitReference(this); + } + } + + +} + + + +class Compound_valueContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_compound_value; + } + + array() { + return this.getTypedRuleContext(ArrayContext,0); + }; + + object() { + return this.getTypedRuleContext(ObjectContext,0); + }; + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterCompound_value(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitCompound_value(this); + } + } + + +} + + + +class Function_callContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_function_call; + } + + T_STRING() { + return this.getToken(CAQLParser.T_STRING, 0); + }; + + T_OPEN() { + return this.getToken(CAQLParser.T_OPEN, 0); + }; + + T_CLOSE() { + return this.getToken(CAQLParser.T_CLOSE, 0); + }; + + expression = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTypedRuleContexts(ExpressionContext); + } else { + return this.getTypedRuleContext(ExpressionContext,i); + } + }; + + T_COMMA = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTokens(CAQLParser.T_COMMA); + } else { + return this.getToken(CAQLParser.T_COMMA, i); + } + }; + + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterFunction_call(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitFunction_call(this); + } + } + + +} + + + +class Value_literalContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_value_literal; + } + + T_QUOTED_STRING() { + return this.getToken(CAQLParser.T_QUOTED_STRING, 0); + }; + + T_INT() { + return this.getToken(CAQLParser.T_INT, 0); + }; + + T_FLOAT() { + return this.getToken(CAQLParser.T_FLOAT, 0); + }; + + T_NULL() { + return this.getToken(CAQLParser.T_NULL, 0); + }; + + T_TRUE() { + return this.getToken(CAQLParser.T_TRUE, 0); + }; + + T_FALSE() { + return this.getToken(CAQLParser.T_FALSE, 0); + }; + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterValue_literal(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitValue_literal(this); + } + } + + +} + + + +class ArrayContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_array; + } + + T_ARRAY_OPEN() { + return this.getToken(CAQLParser.T_ARRAY_OPEN, 0); + }; + + T_ARRAY_CLOSE() { + return this.getToken(CAQLParser.T_ARRAY_CLOSE, 0); + }; + + expression = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTypedRuleContexts(ExpressionContext); + } else { + return this.getTypedRuleContext(ExpressionContext,i); + } + }; + + T_COMMA = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTokens(CAQLParser.T_COMMA); + } else { + return this.getToken(CAQLParser.T_COMMA, i); + } + }; + + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterArray(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitArray(this); + } + } + + +} + + + +class ObjectContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_object; + } + + T_OBJECT_OPEN() { + return this.getToken(CAQLParser.T_OBJECT_OPEN, 0); + }; + + T_OBJECT_CLOSE() { + return this.getToken(CAQLParser.T_OBJECT_CLOSE, 0); + }; + + object_element = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTypedRuleContexts(Object_elementContext); + } else { + return this.getTypedRuleContext(Object_elementContext,i); + } + }; + + T_COMMA = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTokens(CAQLParser.T_COMMA); + } else { + return this.getToken(CAQLParser.T_COMMA, i); + } + }; + + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterObject(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitObject(this); + } + } + + +} + + + +class Object_elementContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_object_element; + } + + T_STRING() { + return this.getToken(CAQLParser.T_STRING, 0); + }; + + object_element_name() { + return this.getTypedRuleContext(Object_element_nameContext,0); + }; + + T_COLON() { + return this.getToken(CAQLParser.T_COLON, 0); + }; + + expression = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTypedRuleContexts(ExpressionContext); + } else { + return this.getTypedRuleContext(ExpressionContext,i); + } + }; + + T_ARRAY_OPEN() { + return this.getToken(CAQLParser.T_ARRAY_OPEN, 0); + }; + + T_ARRAY_CLOSE() { + return this.getToken(CAQLParser.T_ARRAY_CLOSE, 0); + }; + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterObject_element(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitObject_element(this); + } + } + + +} + + + +class Object_element_nameContext extends antlr4.ParserRuleContext { + + constructor(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + super(parent, invokingState); + this.parser = parser; + this.ruleIndex = CAQLParser.RULE_object_element_name; + } + + T_STRING() { + return this.getToken(CAQLParser.T_STRING, 0); + }; + + T_QUOTED_STRING() { + return this.getToken(CAQLParser.T_QUOTED_STRING, 0); + }; + + enterRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.enterObject_element_name(this); + } + } + + exitRule(listener) { + if(listener instanceof CAQLParserListener ) { + listener.exitObject_element_name(this); + } + } + + +} + + + + +CAQLParser.ParseContext = ParseContext; +CAQLParser.ExpressionContext = ExpressionContext; +CAQLParser.Operator_unaryContext = Operator_unaryContext; +CAQLParser.ReferenceContext = ReferenceContext; +CAQLParser.Compound_valueContext = Compound_valueContext; +CAQLParser.Function_callContext = Function_callContext; +CAQLParser.Value_literalContext = Value_literalContext; +CAQLParser.ArrayContext = ArrayContext; +CAQLParser.ObjectContext = ObjectContext; +CAQLParser.Object_elementContext = Object_elementContext; +CAQLParser.Object_element_nameContext = Object_element_nameContext; diff --git a/ui/src/suggestions/grammar/RQLParser.tokens b/ui/src/suggestions/grammar/RQLParser.tokens new file mode 100644 index 0000000..7bdaf61 --- /dev/null +++ b/ui/src/suggestions/grammar/RQLParser.tokens @@ -0,0 +1,103 @@ +DOT=1 +T_REGEX_MATCH=2 +T_REGEX_NON_MATCH=3 +T_EQ=4 +T_NE=5 +T_LT=6 +T_GT=7 +T_LE=8 +T_GE=9 +T_PLUS=10 +T_MINUS=11 +T_TIMES=12 +T_DIV=13 +T_MOD=14 +T_QUESTION=15 +T_COLON=16 +T_SCOPE=17 +T_RANGE=18 +T_COMMA=19 +T_OPEN=20 +T_CLOSE=21 +T_OBJECT_OPEN=22 +T_OBJECT_CLOSE=23 +T_ARRAY_OPEN=24 +T_ARRAY_CLOSE=25 +T_AGGREGATE=26 +T_ALL=27 +T_AND=28 +T_ANY=29 +T_ASC=30 +T_COLLECT=31 +T_DESC=32 +T_DISTINCT=33 +T_FALSE=34 +T_FILTER=35 +T_FOR=36 +T_GRAPH=37 +T_IN=38 +T_INBOUND=39 +T_INSERT=40 +T_INTO=41 +T_K_SHORTEST_PATHS=42 +T_LET=43 +T_LIKE=44 +T_LIMIT=45 +T_NONE=46 +T_NOT=47 +T_NULL=48 +T_OR=49 +T_OUTBOUND=50 +T_REMOVE=51 +T_REPLACE=52 +T_RETURN=53 +T_SHORTEST_PATH=54 +T_SORT=55 +T_TRUE=56 +T_UPDATE=57 +T_UPSERT=58 +T_WITH=59 +T_KEEP=60 +T_COUNT=61 +T_OPTIONS=62 +T_PRUNE=63 +T_SEARCH=64 +T_TO=65 +T_CURRENT=66 +T_NEW=67 +T_OLD=68 +T_STRING=69 +T_INT=70 +T_FLOAT=71 +T_PARAMETER=72 +T_QUOTED_STRING=73 +SINGLE_LINE_COMMENT=74 +MULTILINE_COMMENT=75 +SPACES=76 +UNEXPECTED_CHAR=77 +ERROR_RECONGNIGION=78 +'.'=1 +'=~'=2 +'!~'=3 +'=='=4 +'!='=5 +'<'=6 +'>'=7 +'<='=8 +'>='=9 +'+'=10 +'-'=11 +'*'=12 +'/'=13 +'%'=14 +'?'=15 +':'=16 +'::'=17 +'..'=18 +','=19 +'('=20 +')'=21 +'{'=22 +'}'=23 +'['=24 +']'=25 diff --git a/ui/src/suggestions/grammar/RQLParserListener.js b/ui/src/suggestions/grammar/RQLParserListener.js new file mode 100644 index 0000000..869d319 --- /dev/null +++ b/ui/src/suggestions/grammar/RQLParserListener.js @@ -0,0 +1,108 @@ +// Generated from CAQLParser.g4 by ANTLR 4.9.2 +// jshint ignore: start +import antlr4 from 'antlr4'; + +// This class defines a complete listener for a parse tree produced by CAQLParser. +export default class CAQLParserListener extends antlr4.tree.ParseTreeListener { + + // Enter a parse tree produced by CAQLParser#parse. + enterParse(ctx) { + } + + // Exit a parse tree produced by CAQLParser#parse. + exitParse(ctx) { + } + + + // Enter a parse tree produced by CAQLParser#expression. + enterExpression(ctx) { + } + + // Exit a parse tree produced by CAQLParser#expression. + exitExpression(ctx) { + } + + + // Enter a parse tree produced by CAQLParser#operator_unary. + enterOperator_unary(ctx) { + } + + // Exit a parse tree produced by CAQLParser#operator_unary. + exitOperator_unary(ctx) { + } + + + // Enter a parse tree produced by CAQLParser#reference. + enterReference(ctx) { + } + + // Exit a parse tree produced by CAQLParser#reference. + exitReference(ctx) { + } + + + // Enter a parse tree produced by CAQLParser#compound_value. + enterCompound_value(ctx) { + } + + // Exit a parse tree produced by CAQLParser#compound_value. + exitCompound_value(ctx) { + } + + + // Enter a parse tree produced by CAQLParser#function_call. + enterFunction_call(ctx) { + } + + // Exit a parse tree produced by CAQLParser#function_call. + exitFunction_call(ctx) { + } + + + // Enter a parse tree produced by CAQLParser#value_literal. + enterValue_literal(ctx) { + } + + // Exit a parse tree produced by CAQLParser#value_literal. + exitValue_literal(ctx) { + } + + + // Enter a parse tree produced by CAQLParser#array. + enterArray(ctx) { + } + + // Exit a parse tree produced by CAQLParser#array. + exitArray(ctx) { + } + + + // Enter a parse tree produced by CAQLParser#object. + enterObject(ctx) { + } + + // Exit a parse tree produced by CAQLParser#object. + exitObject(ctx) { + } + + + // Enter a parse tree produced by CAQLParser#object_element. + enterObject_element(ctx) { + } + + // Exit a parse tree produced by CAQLParser#object_element. + exitObject_element(ctx) { + } + + + // Enter a parse tree produced by CAQLParser#object_element_name. + enterObject_element_name(ctx) { + } + + // Exit a parse tree produced by CAQLParser#object_element_name. + exitObject_element_name(ctx) { + } + + + +} diff --git a/ui/src/suggestions/suggestions.ts b/ui/src/suggestions/suggestions.ts new file mode 100644 index 0000000..41dce63 --- /dev/null +++ b/ui/src/suggestions/suggestions.ts @@ -0,0 +1,46 @@ +import lexerModule from "./grammar/CAQLLexer.js"; +import parserModule from "./grammar/CAQLParser.js"; + +import antlr4 from "antlr4"; + +class ErrorListener extends antlr4.error.ErrorListener { + /** + * Checks syntax error + * + * @param {object} recognizer The parsing support code essentially. Most of it is error recovery stuff + * @param {object} symbol Offending symbol + * @param {int} line Line of offending symbol + * @param {int} column Position in line of offending symbol + * @param {string} message Error message + * @param {string} payload Stack trace + */ + syntaxError( + recognizer: any, + symbol: any, + line: number, + column: number, + message: string, + payload: string + ) { + throw {symbol, line, column, message, payload}; + } +} + +export function validateCAQL(term: string): any { + const chars = new antlr4.InputStream(term); + const lexer = new lexerModule(chars); + + const tokens = new antlr4.CommonTokenStream(lexer); + const parser = new parserModule(tokens); + + const listener = new ErrorListener(); + + parser.removeErrorListeners(); + parser.addErrorListener(listener); + try { + parser.parse() + return null; + } catch (error) { + return error; + } +} diff --git a/ui/src/types/types.ts b/ui/src/types/types.ts new file mode 100644 index 0000000..00936b8 --- /dev/null +++ b/ui/src/types/types.ts @@ -0,0 +1,17 @@ +export interface Problem { + title: string; + detail: string; +} + +enum AlertType { + success = "success", + info = "info", + warning = "warning", + error = "error", +} + +export interface Alert { + name: string; + detail: string; + type: AlertType; +} diff --git a/ui/src/views/API.vue b/ui/src/views/API.vue new file mode 100644 index 0000000..57e5667 --- /dev/null +++ b/ui/src/views/API.vue @@ -0,0 +1,48 @@ + + + + + diff --git a/ui/src/views/ArtifactPopup.vue b/ui/src/views/ArtifactPopup.vue new file mode 100644 index 0000000..89d924e --- /dev/null +++ b/ui/src/views/ArtifactPopup.vue @@ -0,0 +1,264 @@ + + + + + diff --git a/ui/src/views/Automation.vue b/ui/src/views/Automation.vue new file mode 100644 index 0000000..a15e277 --- /dev/null +++ b/ui/src/views/Automation.vue @@ -0,0 +1,131 @@ + + + diff --git a/ui/src/views/AutomationList.vue b/ui/src/views/AutomationList.vue new file mode 100644 index 0000000..ad81ca4 --- /dev/null +++ b/ui/src/views/AutomationList.vue @@ -0,0 +1,64 @@ + + + diff --git a/ui/src/views/Dashboard.vue b/ui/src/views/Dashboard.vue new file mode 100644 index 0000000..8088637 --- /dev/null +++ b/ui/src/views/Dashboard.vue @@ -0,0 +1,219 @@ + + + + + diff --git a/ui/src/views/Graph.vue b/ui/src/views/Graph.vue new file mode 100644 index 0000000..8383dfa --- /dev/null +++ b/ui/src/views/Graph.vue @@ -0,0 +1,217 @@ + + + + + + diff --git a/ui/src/views/Group.vue b/ui/src/views/Group.vue new file mode 100644 index 0000000..013c909 --- /dev/null +++ b/ui/src/views/Group.vue @@ -0,0 +1,13 @@ + + + + + diff --git a/ui/src/views/GroupList.vue b/ui/src/views/GroupList.vue new file mode 100644 index 0000000..72ef79d --- /dev/null +++ b/ui/src/views/GroupList.vue @@ -0,0 +1,62 @@ + + + diff --git a/ui/src/views/Job.vue b/ui/src/views/Job.vue new file mode 100644 index 0000000..1cdeb64 --- /dev/null +++ b/ui/src/views/Job.vue @@ -0,0 +1,186 @@ + + + diff --git a/ui/src/views/JobList.vue b/ui/src/views/JobList.vue new file mode 100644 index 0000000..dd9d8c4 --- /dev/null +++ b/ui/src/views/JobList.vue @@ -0,0 +1,61 @@ + + + diff --git a/ui/src/views/Playbook.vue b/ui/src/views/Playbook.vue new file mode 100644 index 0000000..053a0bb --- /dev/null +++ b/ui/src/views/Playbook.vue @@ -0,0 +1,311 @@ + + + + + diff --git a/ui/src/views/PlaybookList.vue b/ui/src/views/PlaybookList.vue new file mode 100644 index 0000000..d6e394a --- /dev/null +++ b/ui/src/views/PlaybookList.vue @@ -0,0 +1,66 @@ + + + diff --git a/ui/src/views/Profile.vue b/ui/src/views/Profile.vue new file mode 100644 index 0000000..16aacec --- /dev/null +++ b/ui/src/views/Profile.vue @@ -0,0 +1,47 @@ + + + + diff --git a/ui/src/views/Rule.vue b/ui/src/views/Rule.vue new file mode 100644 index 0000000..574d656 --- /dev/null +++ b/ui/src/views/Rule.vue @@ -0,0 +1,89 @@ + + + diff --git a/ui/src/views/RuleList.vue b/ui/src/views/RuleList.vue new file mode 100644 index 0000000..347d4a4 --- /dev/null +++ b/ui/src/views/RuleList.vue @@ -0,0 +1,63 @@ + + + diff --git a/ui/src/views/TaskList.vue b/ui/src/views/TaskList.vue new file mode 100644 index 0000000..75dacc0 --- /dev/null +++ b/ui/src/views/TaskList.vue @@ -0,0 +1,85 @@ + + + diff --git a/ui/src/views/Template.vue b/ui/src/views/Template.vue new file mode 100644 index 0000000..9f076d4 --- /dev/null +++ b/ui/src/views/Template.vue @@ -0,0 +1,87 @@ + + + diff --git a/ui/src/views/TemplateList.vue b/ui/src/views/TemplateList.vue new file mode 100644 index 0000000..fe46cd6 --- /dev/null +++ b/ui/src/views/TemplateList.vue @@ -0,0 +1,50 @@ + + + diff --git a/ui/src/views/Ticket.vue b/ui/src/views/Ticket.vue new file mode 100644 index 0000000..7e37471 --- /dev/null +++ b/ui/src/views/Ticket.vue @@ -0,0 +1,1626 @@ + + + + + diff --git a/ui/src/views/TicketList.vue b/ui/src/views/TicketList.vue new file mode 100644 index 0000000..b924bb9 --- /dev/null +++ b/ui/src/views/TicketList.vue @@ -0,0 +1,30 @@ + + + diff --git a/ui/src/views/TicketNew.vue b/ui/src/views/TicketNew.vue new file mode 100644 index 0000000..550f878 --- /dev/null +++ b/ui/src/views/TicketNew.vue @@ -0,0 +1,170 @@ + + + + + diff --git a/ui/src/views/TicketType.vue b/ui/src/views/TicketType.vue new file mode 100644 index 0000000..d861a80 --- /dev/null +++ b/ui/src/views/TicketType.vue @@ -0,0 +1,126 @@ + + + diff --git a/ui/src/views/TicketTypeList.vue b/ui/src/views/TicketTypeList.vue new file mode 100644 index 0000000..d01f23a --- /dev/null +++ b/ui/src/views/TicketTypeList.vue @@ -0,0 +1,64 @@ + + + diff --git a/ui/src/views/User.vue b/ui/src/views/User.vue new file mode 100644 index 0000000..a533045 --- /dev/null +++ b/ui/src/views/User.vue @@ -0,0 +1,105 @@ + + + diff --git a/ui/src/views/UserData.vue b/ui/src/views/UserData.vue new file mode 100644 index 0000000..5375d4d --- /dev/null +++ b/ui/src/views/UserData.vue @@ -0,0 +1,44 @@ + + + diff --git a/ui/src/views/UserDataList.vue b/ui/src/views/UserDataList.vue new file mode 100644 index 0000000..c04d4aa --- /dev/null +++ b/ui/src/views/UserDataList.vue @@ -0,0 +1,60 @@ + + + diff --git a/ui/src/views/UserList.vue b/ui/src/views/UserList.vue new file mode 100644 index 0000000..72a30df --- /dev/null +++ b/ui/src/views/UserList.vue @@ -0,0 +1,66 @@ + + + diff --git a/ui/src/views/embed/Arango.vue b/ui/src/views/embed/Arango.vue new file mode 100644 index 0000000..391515a --- /dev/null +++ b/ui/src/views/embed/Arango.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/ui/src/views/embed/Emitter.vue b/ui/src/views/embed/Emitter.vue new file mode 100644 index 0000000..8414679 --- /dev/null +++ b/ui/src/views/embed/Emitter.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/ui/src/views/embed/Minio.vue b/ui/src/views/embed/Minio.vue new file mode 100644 index 0000000..80fb53d --- /dev/null +++ b/ui/src/views/embed/Minio.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/ui/src/views/embed/Nodered.vue b/ui/src/views/embed/Nodered.vue new file mode 100644 index 0000000..633b764 --- /dev/null +++ b/ui/src/views/embed/Nodered.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/ui/tsconfig.json b/ui/tsconfig.json new file mode 100644 index 0000000..a00b252 --- /dev/null +++ b/ui/tsconfig.json @@ -0,0 +1,49 @@ +{ + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "strict": true, + "jsx": "preserve", + "importHelpers": true, + "moduleResolution": "node", + "experimentalDecorators": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, + "sourceMap": true, + "noImplicitAny": false, + "baseUrl": ".", + "types": [ + "webpack-env", + "jest", + "vuetify" + ], + "paths": { + "@/*": [ + "src/*" + ] + }, + "lib": [ + "esnext", + "dom", + "dom.iterable", + "scripthost" + ], + "typeRoots": [ + "./node_modules/@types", + "./node_modules/vuetify/types" + ] + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx", + "src/**/*.vue", + "tests/**/*.ts", + "tests/**/*.tsx" + ], + "exclude": [ + "node_modules", + "src/suggestions/suggestions.ts" + ] +} diff --git a/ui/ui.go b/ui/ui.go new file mode 100644 index 0000000..07c646b --- /dev/null +++ b/ui/ui.go @@ -0,0 +1,6 @@ +package ui + +import "embed" + +//go:embed dist/* +var UI embed.FS diff --git a/ui/ui_test.go b/ui/ui_test.go new file mode 100644 index 0000000..fd21fbc --- /dev/null +++ b/ui/ui_test.go @@ -0,0 +1,21 @@ +package ui + +import "testing" + +func TestUI(t *testing.T) { + requiredFiles := []string{ + "dist/index.html", + "dist/favicon.ico", + "dist/manifest.json", + "dist/img", + } + for _, requiredFile := range requiredFiles { + t.Run("Require "+requiredFile, func(t *testing.T) { + f, err := UI.Open(requiredFile) + if err != nil { + t.Fatal(err) + } + defer f.Close() + }) + } +} diff --git a/ui/vue.config.js b/ui/vue.config.js new file mode 100644 index 0000000..8312135 --- /dev/null +++ b/ui/vue.config.js @@ -0,0 +1,29 @@ +module.exports = { + transpileDependencies: ["vuetify", "@koumoul/vjsf"], + pwa: { + name: "Catalyst", + themeColor: "#FFC107", + msTileColor: "#000000", + appleMobileWebAppCapable: "yes", + appleMobileWebAppStatusBarStyle: "black", + + // configure the workbox plugin + // workboxPluginMode: "InjectManifest", + // workboxOptions: { + // // swSrc is required in InjectManifest mode. + // swSrc: "dev/sw.js", + // // ...other Workbox options... + // }, + iconPaths: { + favicon32: "img/icons/favicon-32x32.png", + favicon16: "img/icons/favicon-16x16.png", + appleTouchIcon: "img/icons/apple-touch-icon-152x152.png", + maskIcon: "img/icons/safari-pinned-tab.svg", + msTileImage: "img/icons/msapplication-icon-144x144.png", + }, + manifestCrossorigin: 'use-credentials' + }, + devServer: { + disableHostCheck: true + } +}; diff --git a/ui/yarn.lock b/ui/yarn.lock new file mode 100644 index 0000000..5659160 --- /dev/null +++ b/ui/yarn.lock @@ -0,0 +1,13107 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ant-design/colors@^3.1.0": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@ant-design/colors/-/colors-3.2.2.tgz#5ad43d619e911f3488ebac303d606e66a8423903" + integrity "sha1-WtQ9YZ6RHzSI66wwPWBuZqhCOQM= sha512-YKgNbG2dlzqMhA9NtI3/pbY16m3Yl/EeWBRa+lB1X1YaYxHrxNexiQYCLTWO/uDvAjLFMEDU+zR901waBtMtjQ==" + dependencies: + tinycolor2 "^1.4.1" + +"@ant-design/icons-vue@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@ant-design/icons-vue/-/icons-vue-2.0.0.tgz#0357f5010a404e9f34a87a4b41b2a08df691dbce" + integrity "sha1-A1f1AQpATp80qHpLQbKgjfaR284= sha512-2c0QQE5hL4N48k5NkPG5sdpMl9YnvyNhf0U7YkdZYDlLnspoRU7vIA0UK9eHBs6OpFLcJB6o8eJrIl2ajBskPg==" + dependencies: + "@ant-design/colors" "^3.1.0" + babel-runtime "^6.26.0" + +"@ant-design/icons@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@ant-design/icons/-/icons-2.1.1.tgz#7b9c08dffd4f5d41db667d9dbe5e0107d0bd9a4a" + integrity "sha1-e5wI3/1PXUHbZn2dvl4BB9C9mko= sha512-jCH+k2Vjlno4YWl6g535nHR09PwCEmTBKAG6VqF+rhkrSPRLfgpU2maagwbZPLjaHuU5Jd1DFQ2KJpQuI6uG8w==" + +"@babel/code-frame@7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity "sha1-9K1DWqJj25NbjxDyxVLSP7cWpj8= sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==" + dependencies: + "@babel/highlight" "^7.10.4" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.8.3": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431" + integrity "sha1-DfyAMJvuyEEeZecGRhxAiwu5tDE= sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==" + dependencies: + "@babel/highlight" "^7.16.0" + +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.0.tgz#ea269d7f78deb3a7826c39a4048eecda541ebdaa" + integrity "sha1-6iadf3jes6eCbDmkBI7s2lQevao= sha512-DGjt2QZse5SGd9nfOSqO4WLJ8NN/oHkijbXbPrxuoJO3oIPJL3TciZs9FX+cOHNiY9E9l0opL8g7BmLe3T+9ew==" + +"@babel/core@^7.1.0", "@babel/core@^7.11.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.0.tgz#c4ff44046f5fe310525cc9eb4ef5147f0c5374d4" + integrity "sha1-xP9EBG9f4xBSXMnrTvUUfwxTdNQ= sha512-mYZEvshBRHGsIAiyH5PzCFTCfbWfoYbO/jcSdXQSUQu1/pW0xDZAUP7KEc32heqWTAfAHhV9j1vH8Sav7l+JNQ==" + dependencies: + "@babel/code-frame" "^7.16.0" + "@babel/generator" "^7.16.0" + "@babel/helper-compilation-targets" "^7.16.0" + "@babel/helper-module-transforms" "^7.16.0" + "@babel/helpers" "^7.16.0" + "@babel/parser" "^7.16.0" + "@babel/template" "^7.16.0" + "@babel/traverse" "^7.16.0" + "@babel/types" "^7.16.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.1.2" + semver "^6.3.0" + source-map "^0.5.0" + +"@babel/generator@^7.16.0", "@babel/generator@^7.4.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.0.tgz#d40f3d1d5075e62d3500bccb67f3daa8a95265b2" + integrity "sha1-1A89HVB15i01ALzLZ/PaqKlSZbI= sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew==" + dependencies: + "@babel/types" "^7.16.0" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/helper-annotate-as-pure@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz#9a1f0ebcda53d9a2d00108c4ceace6a5d5f1f08d" + integrity "sha1-mh8OvNpT2aLQAQjEzqzmpdXx8I0= sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==" + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.0.tgz#f1a686b92da794020c26582eb852e9accd0d7882" + integrity "sha1-8aaGuS2nlAIMJlguuFLprM0NeII= sha512-9KuleLT0e77wFUku6TUkqZzCEymBdtuQQ27MhEKzf9UOOJu3cYj98kyaDAzxpC7lV6DGiZFuC8XqDsq8/Kl6aQ==" + dependencies: + "@babel/helper-explode-assignable-expression" "^7.16.0" + "@babel/types" "^7.16.0" + +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.16.0", "@babel/helper-compilation-targets@^7.9.6": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.0.tgz#01d615762e796c17952c29e3ede9d6de07d235a8" + integrity "sha1-AdYVdi55bBeVLCnj7enW3gfSNag= sha512-S7iaOT1SYlqK0sQaCi21RX4+13hmdmnxIEAnQUB/eh7GeAnRjOUgTYpLkUOiRXzD+yog1JxP0qyAQZ7ZxVxLVg==" + dependencies: + "@babel/compat-data" "^7.16.0" + "@babel/helper-validator-option" "^7.14.5" + browserslist "^4.16.6" + semver "^6.3.0" + +"@babel/helper-create-class-features-plugin@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.0.tgz#090d4d166b342a03a9fec37ef4fd5aeb9c7c6a4b" + integrity "sha1-CQ1NFms0KgOp/sN+9P1a65x8aks= sha512-XLwWvqEaq19zFlF5PTgOod4bUA+XbkR4WLQBct1bkzmxJGB0ZEJaoKF4c8cgH9oBtCDuYJ8BP5NB9uFiEgO5QA==" + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.0" + "@babel/helper-function-name" "^7.16.0" + "@babel/helper-member-expression-to-functions" "^7.16.0" + "@babel/helper-optimise-call-expression" "^7.16.0" + "@babel/helper-replace-supers" "^7.16.0" + "@babel/helper-split-export-declaration" "^7.16.0" + +"@babel/helper-create-regexp-features-plugin@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.0.tgz#06b2348ce37fccc4f5e18dcd8d75053f2a7c44ff" + integrity "sha1-BrI0jON/zMT14Y3NjXUFPyp8RP8= sha512-3DyG0zAFAZKcOp7aVr33ddwkxJ0Z0Jr5V99y3I690eYLpukJsJvAbzTy1ewoCqsML8SbIrjH14Jc/nSQ4TvNPA==" + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.0" + regexpu-core "^4.7.1" + +"@babel/helper-define-polyfill-provider@^0.2.4": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.4.tgz#8867aed79d3ea6cade40f801efb7ac5c66916b10" + integrity "sha1-iGeu150+psreQPgB77esXGaRaxA= sha512-OrpPZ97s+aPi6h2n1OXzdhVis1SGSsMU2aMHgLcOKfsp4/v1NWpx3CWT3lBj5eeBq9cDkPkh+YCfdF7O12uNDQ==" + dependencies: + "@babel/helper-compilation-targets" "^7.13.0" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/traverse" "^7.13.0" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + semver "^6.1.2" + +"@babel/helper-explode-assignable-expression@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.0.tgz#753017337a15f46f9c09f674cff10cee9b9d7778" + integrity "sha1-dTAXM3oV9G+cCfZ0z/EM7pudd3g= sha512-Hk2SLxC9ZbcOhLpg/yMznzJ11W++lg5GMbxt1ev6TXUiJB0N42KPC+7w8a+eWGuqDnUYuwStJoZHM7RgmIOaGQ==" + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-function-name@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz#b7dd0797d00bbfee4f07e9c4ea5b0e30c8bb1481" + integrity "sha1-t90Hl9ALv+5PB+nE6lsOMMi7FIE= sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==" + dependencies: + "@babel/helper-get-function-arity" "^7.16.0" + "@babel/template" "^7.16.0" + "@babel/types" "^7.16.0" + +"@babel/helper-get-function-arity@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz#0088c7486b29a9cb5d948b1a1de46db66e089cfa" + integrity "sha1-AIjHSGspqctdlIsaHeRttm4InPo= sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==" + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-hoist-variables@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz#4c9023c2f1def7e28ff46fc1dbcd36a39beaa81a" + integrity "sha1-TJAjwvHe9+KP9G/B2802o5vqqBo= sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==" + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-member-expression-to-functions@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.0.tgz#29287040efd197c77636ef75188e81da8bccd5a4" + integrity "sha1-KShwQO/Rl8d2Nu91GI6B2ovM1aQ= sha512-bsjlBFPuWT6IWhl28EdrQ+gTvSvj5tqVP5Xeftp07SEuz5pLnsXZuDkDD3Rfcxy0IsHmbZ+7B2/9SHzxO0T+sQ==" + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.0", "@babel/helper-module-imports@^7.8.3": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz#90538e60b672ecf1b448f5f4f5433d37e79a3ec3" + integrity "sha1-kFOOYLZy7PG0SPX09UM9N+eaPsM= sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==" + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-module-transforms@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.0.tgz#1c82a8dd4cb34577502ebd2909699b194c3e9bb5" + integrity "sha1-HIKo3UyzRXdQLr0pCWmbGUw+m7U= sha512-My4cr9ATcaBbmaEa8M0dZNA74cfI6gitvUAskgDtAFmAqyFKDSHQo5YstxPbN+lzHl2D9l/YOEFqb2mtUh4gfA==" + dependencies: + "@babel/helper-module-imports" "^7.16.0" + "@babel/helper-replace-supers" "^7.16.0" + "@babel/helper-simple-access" "^7.16.0" + "@babel/helper-split-export-declaration" "^7.16.0" + "@babel/helper-validator-identifier" "^7.15.7" + "@babel/template" "^7.16.0" + "@babel/traverse" "^7.16.0" + "@babel/types" "^7.16.0" + +"@babel/helper-optimise-call-expression@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz#cecdb145d70c54096b1564f8e9f10cd7d193b338" + integrity "sha1-zs2xRdcMVAlrFWT46fEM19GTszg= sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==" + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" + integrity "sha1-WsgizpfuxGdBq3ClF5ceRDpwxak= sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==" + +"@babel/helper-remap-async-to-generator@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.0.tgz#d5aa3b086e13a5fe05238ff40c3a5a0c2dab3ead" + integrity "sha1-1ao7CG4Tpf4FI4/0DDpaDC2rPq0= sha512-MLM1IOMe9aQBqMWxcRw8dcb9jlM86NIw7KA0Wri91Xkfied+dE0QuBFSBjMNvqzmS0OSIDsMNC24dBEkPUi7ew==" + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.0" + "@babel/helper-wrap-function" "^7.16.0" + "@babel/types" "^7.16.0" + +"@babel/helper-replace-supers@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.0.tgz#73055e8d3cf9bcba8ddb55cad93fedc860f68f17" + integrity "sha1-cwVejTz5vLqN21XK2T/tyGD2jxc= sha512-TQxuQfSCdoha7cpRNJvfaYxxxzmbxXw/+6cS7V02eeDYyhxderSoMVALvwupA54/pZcOTtVeJ0xccp1nGWladA==" + dependencies: + "@babel/helper-member-expression-to-functions" "^7.16.0" + "@babel/helper-optimise-call-expression" "^7.16.0" + "@babel/traverse" "^7.16.0" + "@babel/types" "^7.16.0" + +"@babel/helper-simple-access@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz#21d6a27620e383e37534cf6c10bba019a6f90517" + integrity "sha1-IdaidiDjg+N1NM9sELugGab5BRc= sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==" + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-skip-transparent-expression-wrappers@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09" + integrity "sha1-DuM4gHAUfDrgUeSH7KPrsOLouwk= sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==" + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-split-export-declaration@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz#29672f43663e936df370aaeb22beddb3baec7438" + integrity "sha1-KWcvQ2Y+k23zcKrrIr7ds7rsdDg= sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==" + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-validator-identifier@^7.15.7": + version "7.15.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" + integrity "sha1-Ig35k7/pBKSmsCq08zhaXr9uI4k= sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==" + +"@babel/helper-validator-option@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" + integrity "sha1-bnKh//GNXfy4eOHmLxoCHEty1aM= sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==" + +"@babel/helper-wrap-function@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.16.0.tgz#b3cf318afce774dfe75b86767cd6d68f3482e57c" + integrity "sha1-s88xivzndN/nW4Z2fNbWjzSC5Xw= sha512-VVMGzYY3vkWgCJML+qVLvGIam902mJW0FvT7Avj1zEe0Gn7D93aWdLblYARTxEw+6DhZmtzhBM2zv0ekE5zg1g==" + dependencies: + "@babel/helper-function-name" "^7.16.0" + "@babel/template" "^7.16.0" + "@babel/traverse" "^7.16.0" + "@babel/types" "^7.16.0" + +"@babel/helpers@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.0.tgz#875519c979c232f41adfbd43a3b0398c2e388183" + integrity "sha1-h1UZyXnCMvQa371Do7A5jC44gYM= sha512-dVRM0StFMdKlkt7cVcGgwD8UMaBfWJHl3A83Yfs8GQ3MO0LHIIIMvK7Fa0RGOGUQ10qikLaX6D7o5htcQWgTMQ==" + dependencies: + "@babel/template" "^7.16.0" + "@babel/traverse" "^7.16.0" + "@babel/types" "^7.16.0" + +"@babel/highlight@^7.10.4", "@babel/highlight@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a" + integrity "sha1-bOsysspLj182H7f9gh4/3fShclo= sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==" + dependencies: + "@babel/helper-validator-identifier" "^7.15.7" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.15.0", "@babel/parser@^7.16.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0": + version "7.16.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.2.tgz#3723cd5c8d8773eef96ce57ea1d9b7faaccd12ac" + integrity "sha1-NyPNXI2Hc+75bOV+odm3+qzNEqw= sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw==" + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.0": + version "7.16.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.2.tgz#2977fca9b212db153c195674e57cfab807733183" + integrity "sha1-KXf8qbIS2xU8GVZ05Xz6uAdzMYM= sha512-h37CvpLSf8gb2lIJ2CgC3t+EjFbi0t8qS7LCS1xcJIlEXE4czlofwaW7W1HA8zpgOCzI9C1nmoqNR1zWkk0pQg==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.0.tgz#358972eaab006f5eb0826183b0c93cbcaf13e1e2" + integrity "sha1-NYly6qsAb16wgmGDsMk8vK8T4eI= sha512-4tcFwwicpWTrpl9qjf7UsoosaArgImF85AxqCRZlgc3IQDvkUHjJpruXAL58Wmj+T6fypWTC/BakfEkwIL/pwA==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/plugin-proposal-optional-chaining" "^7.16.0" + +"@babel/plugin-proposal-async-generator-functions@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.0.tgz#11425d47a60364352f668ad5fbc1d6596b2c5caf" + integrity "sha1-EUJdR6YDZDUvZorV+8HWWWssXK8= sha512-nyYmIo7ZqKsY6P4lnVmBlxp9B3a96CscbLotlsNuktMHahkDwoPYEjXrZHU0Tj844Z9f1IthVxQln57mhkcExw==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-remap-async-to-generator" "^7.16.0" + "@babel/plugin-syntax-async-generators" "^7.8.4" + +"@babel/plugin-proposal-class-properties@^7.16.0", "@babel/plugin-proposal-class-properties@^7.8.3": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.0.tgz#c029618267ddebc7280fa286e0f8ca2a278a2d1a" + integrity "sha1-wClhgmfd68coD6KG4PjKKieKLRo= sha512-mCF3HcuZSY9Fcx56Lbn+CGdT44ioBMMvjNVldpKtj8tpniETdLjnxdHI1+sDWXIM1nNt+EanJOZ3IG9lzVjs7A==" + dependencies: + "@babel/helper-create-class-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-proposal-class-static-block@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.0.tgz#5296942c564d8144c83eea347d0aa8a0b89170e7" + integrity "sha1-UpaULFZNgUTIPuo0fQqooLiRcOc= sha512-mAy3sdcY9sKAkf3lQbDiv3olOfiLqI51c9DR9b19uMoR2Z6r5pmGl7dfNFqEvqOyqbf1ta4lknK4gc5PJn3mfA==" + dependencies: + "@babel/helper-create-class-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + +"@babel/plugin-proposal-decorators@^7.8.3": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.16.0.tgz#515db5f6891611c0d176b63ede0844fbd9be797b" + integrity "sha1-UV219okWEcDRdrY+3ghE+9m+eXs= sha512-ttvhKuVnQwoNQrcTd1oe6o49ahaZ1kns1fsJKzTVOaS/FJDJoK4qzgVS68xzJhYUMgTnbXW6z/T6rlP3lL7tJw==" + dependencies: + "@babel/helper-create-class-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-decorators" "^7.16.0" + +"@babel/plugin-proposal-dynamic-import@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.0.tgz#783eca61d50526202f9b296095453977e88659f1" + integrity "sha1-eD7KYdUFJiAvmylglUU5d+iGWfE= sha512-QGSA6ExWk95jFQgwz5GQ2Dr95cf7eI7TKutIXXTb7B1gCLTCz5hTjFTQGfLFBBiC5WSNi7udNwWsqbbMh1c4yQ==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + +"@babel/plugin-proposal-export-namespace-from@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.0.tgz#9c01dee40b9d6b847b656aaf4a3976a71740f222" + integrity "sha1-nAHe5Auda4R7ZWqvSjl2pxdA8iI= sha512-CjI4nxM/D+5wCnhD11MHB1AwRSAYeDT+h8gCdcVJZ/OK7+wRzFsf7PFPWVpVpNRkHMmMkQWAHpTq+15IXQ1diA==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-proposal-json-strings@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.0.tgz#cae35a95ed1d2a7fa29c4dc41540b84a72e9ab25" + integrity "sha1-yuNale0dKn+inE3EFUC4SnLpqyU= sha512-kouIPuiv8mSi5JkEhzApg5Gn6hFyKPnlkO0a9YSzqRurH8wYzSlf6RJdzluAsbqecdW5pBvDJDfyDIUR/vLxvg==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-json-strings" "^7.8.3" + +"@babel/plugin-proposal-logical-assignment-operators@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.0.tgz#a711b8ceb3ffddd3ef88d3a49e86dbd3cc7db3fd" + integrity "sha1-pxG4zrP/3dPviNOknobb08x9s/0= sha512-pbW0fE30sVTYXXm9lpVQQ/Vc+iTeQKiXlaNRZPPN2A2VdlWyAtsUrsQ3xydSlDW00TFMK7a8m3cDTkBF5WnV3Q==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.0.tgz#44e1cce08fe2427482cf446a91bb451528ed0596" + integrity "sha1-ROHM4I/iQnSCz0RqkbtFFSjtBZY= sha512-3bnHA8CAFm7cG93v8loghDYyQ8r97Qydf63BeYiGgYbjKKB/XP53W15wfRC7dvKfoiJ34f6Rbyyx2btExc8XsQ==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-proposal-numeric-separator@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.0.tgz#5d418e4fbbf8b9b7d03125d3a52730433a373734" + integrity "sha1-XUGOT7v4ubfQMSXTpScwQzo3NzQ= sha512-FAhE2I6mjispy+vwwd6xWPyEx3NYFS13pikDBWUAFGZvq6POGs5eNchw8+1CYoEgBl9n11I3NkzD7ghn25PQ9Q==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-proposal-object-rest-spread@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.0.tgz#5fb32f6d924d6e6712810362a60e12a2609872e6" + integrity "sha1-X7MvbZJNbmcSgQNipg4SomCYcuY= sha512-LU/+jp89efe5HuWJLmMmFG0+xbz+I2rSI7iLc1AlaeSMDMOGzWlc5yJrMN1d04osXN4sSfpo4O+azkBNBes0jg==" + dependencies: + "@babel/compat-data" "^7.16.0" + "@babel/helper-compilation-targets" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.16.0" + +"@babel/plugin-proposal-optional-catch-binding@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.0.tgz#5910085811ab4c28b00d6ebffa4ab0274d1e5f16" + integrity "sha1-WRAIWBGrTCiwDW6/+kqwJ00eXxY= sha512-kicDo0A/5J0nrsCPbn89mTG3Bm4XgYi0CZtvex9Oyw7gGZE3HXGD0zpQNH+mo+tEfbo8wbmMvJftOwpmPy7aVw==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-proposal-optional-chaining@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.0.tgz#56dbc3970825683608e9efb55ea82c2a2d6c8dc0" + integrity "sha1-VtvDlwglaDYI6e+1XqgsKi1sjcA= sha512-Y4rFpkZODfHrVo70Uaj6cC1JJOt3Pp0MdWSwIKtb8z1/lsjl9AmnB7ErRFV+QNGIfcY1Eruc2UMx5KaRnXjMyg==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-proposal-private-methods@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.0.tgz#b4dafb9c717e4301c5776b30d080d6383c89aff6" + integrity "sha1-tNr7nHF+QwHFd2sw0IDWODyJr/Y= sha512-IvHmcTHDFztQGnn6aWq4t12QaBXTKr1whF/dgp9kz84X6GUcwq9utj7z2wFCUfeOup/QKnOlt2k0zxkGFx9ubg==" + dependencies: + "@babel/helper-create-class-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-proposal-private-property-in-object@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.0.tgz#69e935b2c5c79d2488112d886f0c4e2790fee76f" + integrity "sha1-aek1ssXHnSSIES2IbwxOJ5D+528= sha512-3jQUr/HBbMVZmi72LpjQwlZ55i1queL8KcDTQEkAHihttJnAPrcvG9ZNXIfsd2ugpizZo595egYV6xy+pv4Ofw==" + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.0" + "@babel/helper-create-class-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-proposal-unicode-property-regex@^7.16.0", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.0.tgz#890482dfc5ea378e42e19a71e709728cabf18612" + integrity "sha1-iQSC38XqN45C4Zpx5wlyjKvxhhI= sha512-ti7IdM54NXv29cA4+bNNKEMS4jLMCbJgl+Drv+FgYy0erJLAxNAIXcNjNjrRZEcWq0xJHsNVwQezskMFpF8N9g==" + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity "sha1-qYP7Gusuw/btBCohD2QOkOeG/g0= sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==" + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity "sha1-tcmHJ0xKOoK4lxR5aTGmtTVErhA= sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==" + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + integrity "sha1-GV34mxRrS3izv4l/16JXyEZZ1AY= sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-decorators@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.16.0.tgz#eb8d811cdd1060f6ac3c00956bf3f6335505a32f" + integrity "sha1-642BHN0QYPasPACVa/P2M1UFoy8= sha512-nxnnngZClvlY13nHJAIDow0S7Qzhq64fQ/NlqS+VER3kjW/4F0jLhXjeL8jcwSwz6Ca3rotT5NJD2T9I7lcv7g==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity "sha1-Yr+Ysto80h1iYVT8lu5bPLaOrLM= sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==" + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity "sha1-AolkqbqA28CUyRXEh618TnpmRlo= sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==" + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity "sha1-AcohtmjNghjJ5kDLbdiMVBKyyWo= sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==" + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.2.0", "@babel/plugin-syntax-jsx@^7.8.3": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.0.tgz#f9624394317365a9a88c82358d3f8471154698f1" + integrity "sha1-+WJDlDFzZamojII1jT+EcRVGmPE= sha512-8zv2+xiPHwly31RK4RmnEYY5zziuF3O7W2kIDW+07ewWDh6Oi0dRq8kwvulRkFgt6DB97RlKs5c1y068iPlCUg==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity "sha1-ypHvRjA1MESLkGZSusLp/plB9pk= sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==" + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity "sha1-Fn7XA2iIYIH3S1w2xlqIwDtm0ak= sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==" + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity "sha1-ubBws+M1cM2f0Hun+pHA3Te5r5c= sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==" + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity "sha1-YOIl7cvZimQDMqLnLdPmbxr1WHE= sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==" + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity "sha1-YRGiZbz7Ag6579D9/X0mQCue1sE= sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==" + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity "sha1-T2nCq5UWfgGAzVM2YT+MV4j31Io= sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==" + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + integrity "sha1-DcZnHsDqIrbpShEU+FeXDNOd4a0= sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-top-level-await@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity "sha1-wc/a3DWmRiQAAfBhOCR7dBw02Uw= sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-arrow-functions@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.0.tgz#951706f8b449c834ed07bd474c0924c944b95a8e" + integrity "sha1-lRcG+LRJyDTtB71HTAkkyUS5Wo4= sha512-vIFb5250Rbh7roWARvCLvIJ/PtAU5Lhv7BtZ1u24COwpI9Ypjsh+bZcKk6rlIyalK+r0jOc1XQ8I4ovNxNrWrA==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-async-to-generator@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.0.tgz#df12637f9630ddfa0ef9d7a11bc414d629d38604" + integrity "sha1-3xJjf5Yw3foO+dehG8QU1inThgQ= sha512-PbIr7G9kR8tdH6g8Wouir5uVjklETk91GMVSUq+VaOgiinbCkBP6Q7NN/suM/QutZkMJMvcyAriogcYAdhg8Gw==" + dependencies: + "@babel/helper-module-imports" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-remap-async-to-generator" "^7.16.0" + +"@babel/plugin-transform-block-scoped-functions@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.0.tgz#c618763233ad02847805abcac4c345ce9de7145d" + integrity "sha1-xhh2MjOtAoR4BavKxMNFzp3nFF0= sha512-V14As3haUOP4ZWrLJ3VVx5rCnrYhMSHN/jX7z6FAt5hjRkLsb0snPCmJwSOML5oxkKO4FNoNv7V5hw/y2bjuvg==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-block-scoping@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.0.tgz#bcf433fb482fe8c3d3b4e8a66b1c4a8e77d37c16" + integrity "sha1-vPQz+0gv6MPTtOimaxxKjnfTfBY= sha512-27n3l67/R3UrXfizlvHGuTwsRIFyce3D/6a37GRxn28iyTPvNXaW4XvznexRh1zUNLPjbLL22Id0XQElV94ruw==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-classes@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.0.tgz#54cf5ff0b2242c6573d753cd4bfc7077a8b282f5" + integrity "sha1-VM9f8LIkLGVz11PNS/xwd6iygvU= sha512-HUxMvy6GtAdd+GKBNYDWCIA776byUQH8zjnfjxwT1P1ARv/wFu8eBDpmXQcLS/IwRtrxIReGiplOwMeyO7nsDQ==" + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.0" + "@babel/helper-function-name" "^7.16.0" + "@babel/helper-optimise-call-expression" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-replace-supers" "^7.16.0" + "@babel/helper-split-export-declaration" "^7.16.0" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.0.tgz#e0c385507d21e1b0b076d66bed6d5231b85110b7" + integrity "sha1-4MOFUH0h4bCwdtZr7W1SMbhRELc= sha512-63l1dRXday6S8V3WFY5mXJwcRAnPYxvFfTlt67bwV1rTyVTM5zrp0DBBb13Kl7+ehkCVwIZPumPpFP/4u70+Tw==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-destructuring@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.0.tgz#ad3d7e74584ad5ea4eadb1e6642146c590dee33c" + integrity "sha1-rT1+dFhK1epOrbHmZCFGxZDe4zw= sha512-Q7tBUwjxLTsHEoqktemHBMtb3NYwyJPTJdM+wDwb0g8PZ3kQUIzNvwD5lPaqW/p54TXBc/MXZu9Jr7tbUEUM8Q==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-dotall-regex@^7.16.0", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.0.tgz#50bab00c1084b6162d0a58a818031cf57798e06f" + integrity "sha1-ULqwDBCEthYtClioGAMc9XeY4G8= sha512-FXlDZfQeLILfJlC6I1qyEwcHK5UpRCFkaoVyA1nk9A1L1Yu583YO4un2KsLBsu3IJb4CUbctZks8tD9xPQubLw==" + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-duplicate-keys@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.0.tgz#8bc2e21813e3e89e5e5bf3b60aa5fc458575a176" + integrity "sha1-i8LiGBPj6J5eW/O2CqX8RYV1oXY= sha512-LIe2kcHKAZOJDNxujvmp6z3mfN6V9lJxubU4fJIGoQCkKe3Ec2OcbdlYP+vW++4MpxwG0d1wSDOJtQW5kLnkZQ==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-exponentiation-operator@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.0.tgz#a180cd2881e3533cef9d3901e48dad0fbeff4be4" + integrity "sha1-oYDNKIHjUzzvnTkB5I2tD77/S+Q= sha512-OwYEvzFI38hXklsrbNivzpO3fh87skzx8Pnqi4LoSYeav0xHlueSoCJrSgTPfnbyzopo5b3YVAJkFIcUpK2wsw==" + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-for-of@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.0.tgz#f7abaced155260e2461359bbc7c7248aca5e6bd2" + integrity "sha1-96us7RVSYOJGE1m7x8ckispea9I= sha512-5QKUw2kO+GVmKr2wMYSATCTTnHyscl6sxFRAY+rvN7h7WB0lcG0o4NoV6ZQU32OZGVsYUsfLGgPQpDFdkfjlJQ==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-function-name@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.0.tgz#02e3699c284c6262236599f751065c5d5f1f400e" + integrity "sha1-AuNpnChMYmIjZZn3UQZcXV8fQA4= sha512-lBzMle9jcOXtSOXUpc7tvvTpENu/NuekNJVova5lCCWCV9/U1ho2HH2y0p6mBg8fPm/syEAbfaaemYGOHCY3mg==" + dependencies: + "@babel/helper-function-name" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-literals@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.0.tgz#79711e670ffceb31bd298229d50f3621f7980cac" + integrity "sha1-eXEeZw/86zG9KYIp1Q82IfeYDKw= sha512-gQDlsSF1iv9RU04clgXqRjrPyyoJMTclFt3K1cjLmTKikc0s/6vE3hlDeEVC71wLTRu72Fq7650kABrdTc2wMQ==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-member-expression-literals@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.0.tgz#5251b4cce01eaf8314403d21aedb269d79f5e64b" + integrity "sha1-UlG0zOAer4MUQD0hrtsmnXn15ks= sha512-WRpw5HL4Jhnxw8QARzRvwojp9MIE7Tdk3ez6vRyUk1MwgjJN0aNpRoXainLR5SgxmoXx/vsXGZ6OthP6t/RbUg==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-modules-amd@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.0.tgz#09abd41e18dcf4fd479c598c1cef7bd39eb1337e" + integrity "sha1-CavUHhjc9P1HnFmMHO97056xM34= sha512-rWFhWbCJ9Wdmzln1NmSCqn7P0RAD+ogXG/bd9Kg5c7PKWkJtkiXmYsMBeXjDlzHpVTJ4I/hnjs45zX4dEv81xw==" + dependencies: + "@babel/helper-module-transforms" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-commonjs@^7.16.0", "@babel/plugin-transform-modules-commonjs@^7.9.6": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.0.tgz#add58e638c8ddc4875bd9a9ecb5c594613f6c922" + integrity "sha1-rdWOY4yN3Eh1vZqey1xZRhP2ySI= sha512-Dzi+NWqyEotgzk/sb7kgQPJQf7AJkQBWsVp1N6JWc1lBVo0vkElUnGdr1PzUBmfsCCN5OOFya3RtpeHk15oLKQ==" + dependencies: + "@babel/helper-module-transforms" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-simple-access" "^7.16.0" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-systemjs@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.0.tgz#a92cf240afeb605f4ca16670453024425e421ea4" + integrity "sha1-qSzyQK/rYF9MoWZwRTAkQl5CHqQ= sha512-yuGBaHS3lF1m/5R+6fjIke64ii5luRUg97N2wr+z1sF0V+sNSXPxXDdEEL/iYLszsN5VKxVB1IPfEqhzVpiqvg==" + dependencies: + "@babel/helper-hoist-variables" "^7.16.0" + "@babel/helper-module-transforms" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-validator-identifier" "^7.15.7" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-umd@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.0.tgz#195f26c2ad6d6a391b70880effce18ce625e06a7" + integrity "sha1-GV8mwq1tajkbcIgO/84YzmJeBqc= sha512-nx4f6no57himWiHhxDM5pjwhae5vLpTK2zCnDH8+wNLJy0TVER/LJRHl2bkt6w9Aad2sPD5iNNoUpY3X9sTGDg==" + dependencies: + "@babel/helper-module-transforms" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.0.tgz#d3db61cc5d5b97986559967cd5ea83e5c32096ca" + integrity "sha1-09thzF1bl5hlWZZ81eqD5cMglso= sha512-LogN88uO+7EhxWc8WZuQ8vxdSyVGxhkh8WTC3tzlT8LccMuQdA81e9SGV6zY7kY2LjDhhDOFdQVxdGwPyBCnvg==" + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.0" + +"@babel/plugin-transform-new-target@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.0.tgz#af823ab576f752215a49937779a41ca65825ab35" + integrity "sha1-r4I6tXb3UiFaSZN3eaQcplglqzU= sha512-fhjrDEYv2DBsGN/P6rlqakwRwIp7rBGLPbrKxwh7oVt5NNkIhZVOY2GRV+ULLsQri1bDqwDWnU3vhlmx5B2aCw==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-object-super@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.0.tgz#fb20d5806dc6491a06296ac14ea8e8d6fedda72b" + integrity "sha1-+yDVgG3GSRoGKWrBTqjo1v7dpys= sha512-fds+puedQHn4cPLshoHcR1DTMN0q1V9ou0mUjm8whx9pGcNvDrVVrgw+KJzzCaiTdaYhldtrUps8DWVMgrSEyg==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-replace-supers" "^7.16.0" + +"@babel/plugin-transform-parameters@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.0.tgz#1b50765fc421c229819dc4c7cdb8911660b3c2d7" + integrity "sha1-G1B2X8QhwimBncTHzbiRFmCzwtc= sha512-XgnQEm1CevKROPx+udOi/8f8TiGhrUWiHiaUCIp47tE0tpFDjzXNTZc9E5CmCwxNjXTWEVqvRfWZYOTFvMa/ZQ==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-property-literals@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.0.tgz#a95c552189a96a00059f6776dc4e00e3690c78d1" + integrity "sha1-qVxVIYmpagAFn2d23E4A42kMeNE= sha512-XLldD4V8+pOqX2hwfWhgwXzGdnDOThxaNTgqagOcpBgIxbUvpgU2FMvo5E1RyHbk756WYgdbS0T8y0Cj9FKkWQ==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-regenerator@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.0.tgz#eaee422c84b0232d03aea7db99c97deeaf6125a4" + integrity "sha1-6u5CLISwIy0Drqfbmcl97q9hJaQ= sha512-JAvGxgKuwS2PihiSFaDrp94XOzzTUeDeOQlcKzVAyaPap7BnZXK/lvMDiubkPTdotPKOIZq9xWXWnggUMYiExg==" + dependencies: + regenerator-transform "^0.14.2" + +"@babel/plugin-transform-reserved-words@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.0.tgz#fff4b9dcb19e12619394bda172d14f2d04c0379c" + integrity "sha1-//S53LGeEmGTlL2hctFPLQTAN5w= sha512-Dgs8NNCehHSvXdhEhln8u/TtJxfVwGYCgP2OOr5Z3Ar+B+zXicEOKNTyc+eca2cuEOMtjW6m9P9ijOt8QdqWkg==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-runtime@^7.11.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.0.tgz#3fe0da36c2f0834bef7c4d3e7f2b2db0ee0c8909" + integrity "sha1-P+DaNsLwg0vvfE0+fystsO4MiQk= sha512-zlPf1/XFn5+vWdve3AAhf+Sxl+MVa5VlwTwWgnLx23u4GlatSRQJ3Eoo9vllf0a9il3woQsT4SK+5Z7c06h8ag==" + dependencies: + "@babel/helper-module-imports" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + babel-plugin-polyfill-corejs2 "^0.2.3" + babel-plugin-polyfill-corejs3 "^0.3.0" + babel-plugin-polyfill-regenerator "^0.2.3" + semver "^6.3.0" + +"@babel/plugin-transform-shorthand-properties@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.0.tgz#090372e3141f7cc324ed70b3daf5379df2fa384d" + integrity "sha1-CQNy4xQffMMk7XCz2vU3nfL6OE0= sha512-iVb1mTcD8fuhSv3k99+5tlXu5N0v8/DPm2mO3WACLG6al1CGZH7v09HJyUb1TtYl/Z+KrM6pHSIJdZxP5A+xow==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-spread@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.0.tgz#d21ca099bbd53ab307a8621e019a7bd0f40cdcfb" + integrity "sha1-0hygmbvVOrMHqGIeAZp70PQM3Ps= sha512-Ao4MSYRaLAQczZVp9/7E7QHsCuK92yHRrmVNRe/SlEJjhzivq0BSn8mEraimL8wizHZ3fuaHxKH0iwzI13GyGg==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + +"@babel/plugin-transform-sticky-regex@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.0.tgz#c35ea31a02d86be485f6aa510184b677a91738fd" + integrity "sha1-w16jGgLYa+SF9qpRAYS2d6kXOP0= sha512-/ntT2NljR9foobKk4E/YyOSwcGUXtYWv5tinMK/3RkypyNBNdhHUaq6Orw5DWq9ZcNlS03BIlEALFeQgeVAo4Q==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-template-literals@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.0.tgz#a8eced3a8e7b8e2d40ec4ec4548a45912630d302" + integrity "sha1-qOztOo57ji1A7E7EVIpFkSYw0wI= sha512-Rd4Ic89hA/f7xUSJQk5PnC+4so50vBoBfxjdQAdvngwidM8jYIBVxBZ/sARxD4e0yMXRbJVDrYf7dyRtIIKT6Q==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-typeof-symbol@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.0.tgz#8b19a244c6f8c9d668dca6a6f754ad6ead1128f2" + integrity "sha1-ixmiRMb4ydZo3Kam91Stbq0RKPI= sha512-++V2L8Bdf4vcaHi2raILnptTBjGEFxn5315YU+e8+EqXIucA+q349qWngCLpUYqqv233suJ6NOienIVUpS9cqg==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-unicode-escapes@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.0.tgz#1a354064b4c45663a32334f46fa0cf6100b5b1f3" + integrity "sha1-GjVAZLTEVmOjIzT0b6DPYQC1sfM= sha512-VFi4dhgJM7Bpk8lRc5CMaRGlKZ29W9C3geZjt9beuzSUrlJxsNwX7ReLwaL6WEvsOf2EQkyIJEPtF8EXjB/g2A==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-unicode-regex@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.0.tgz#293b80950177c8c85aede87cef280259fb995402" + integrity "sha1-KTuAlQF3yMha7eh87ygCWfuZVAI= sha512-jHLK4LxhHjvCeZDWyA9c+P9XH1sOxRd1RO9xMtDVRAOND/PczPqizEtVdx4TQF/wyPaewqpT+tgQFYMnN/P94A==" + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/preset-env@^7.11.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.16.0.tgz#97228393d217560d6a1c6c56f0adb9d12bca67f5" + integrity "sha1-lyKDk9IXVg1qHGxW8K250SvKZ/U= sha512-cdTu/W0IrviamtnZiTfixPfIncr2M1VqRrkjzZWlr1B4TVYimCFK5jkyOdP4qw2MrlKHi+b3ORj6x8GoCew8Dg==" + dependencies: + "@babel/compat-data" "^7.16.0" + "@babel/helper-compilation-targets" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-validator-option" "^7.14.5" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.16.0" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.16.0" + "@babel/plugin-proposal-async-generator-functions" "^7.16.0" + "@babel/plugin-proposal-class-properties" "^7.16.0" + "@babel/plugin-proposal-class-static-block" "^7.16.0" + "@babel/plugin-proposal-dynamic-import" "^7.16.0" + "@babel/plugin-proposal-export-namespace-from" "^7.16.0" + "@babel/plugin-proposal-json-strings" "^7.16.0" + "@babel/plugin-proposal-logical-assignment-operators" "^7.16.0" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.16.0" + "@babel/plugin-proposal-numeric-separator" "^7.16.0" + "@babel/plugin-proposal-object-rest-spread" "^7.16.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.16.0" + "@babel/plugin-proposal-optional-chaining" "^7.16.0" + "@babel/plugin-proposal-private-methods" "^7.16.0" + "@babel/plugin-proposal-private-property-in-object" "^7.16.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.16.0" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-transform-arrow-functions" "^7.16.0" + "@babel/plugin-transform-async-to-generator" "^7.16.0" + "@babel/plugin-transform-block-scoped-functions" "^7.16.0" + "@babel/plugin-transform-block-scoping" "^7.16.0" + "@babel/plugin-transform-classes" "^7.16.0" + "@babel/plugin-transform-computed-properties" "^7.16.0" + "@babel/plugin-transform-destructuring" "^7.16.0" + "@babel/plugin-transform-dotall-regex" "^7.16.0" + "@babel/plugin-transform-duplicate-keys" "^7.16.0" + "@babel/plugin-transform-exponentiation-operator" "^7.16.0" + "@babel/plugin-transform-for-of" "^7.16.0" + "@babel/plugin-transform-function-name" "^7.16.0" + "@babel/plugin-transform-literals" "^7.16.0" + "@babel/plugin-transform-member-expression-literals" "^7.16.0" + "@babel/plugin-transform-modules-amd" "^7.16.0" + "@babel/plugin-transform-modules-commonjs" "^7.16.0" + "@babel/plugin-transform-modules-systemjs" "^7.16.0" + "@babel/plugin-transform-modules-umd" "^7.16.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.16.0" + "@babel/plugin-transform-new-target" "^7.16.0" + "@babel/plugin-transform-object-super" "^7.16.0" + "@babel/plugin-transform-parameters" "^7.16.0" + "@babel/plugin-transform-property-literals" "^7.16.0" + "@babel/plugin-transform-regenerator" "^7.16.0" + "@babel/plugin-transform-reserved-words" "^7.16.0" + "@babel/plugin-transform-shorthand-properties" "^7.16.0" + "@babel/plugin-transform-spread" "^7.16.0" + "@babel/plugin-transform-sticky-regex" "^7.16.0" + "@babel/plugin-transform-template-literals" "^7.16.0" + "@babel/plugin-transform-typeof-symbol" "^7.16.0" + "@babel/plugin-transform-unicode-escapes" "^7.16.0" + "@babel/plugin-transform-unicode-regex" "^7.16.0" + "@babel/preset-modules" "^0.1.5" + "@babel/types" "^7.16.0" + babel-plugin-polyfill-corejs2 "^0.2.3" + babel-plugin-polyfill-corejs3 "^0.3.0" + babel-plugin-polyfill-regenerator "^0.2.3" + core-js-compat "^3.19.0" + semver "^6.3.0" + +"@babel/preset-modules@^0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" + integrity "sha1-75Odbn8miCfhhBY43G/5VRXhFdk= sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/runtime-corejs3@^7.10.2", "@babel/runtime-corejs3@^7.11.2", "@babel/runtime-corejs3@^7.14.7": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.16.0.tgz#58a7fb00e6948508f12f53a303993e8b6e2f6c70" + integrity "sha1-WKf7AOaUhQjxL1OjA5k+i24vbHA= sha512-Oi2qwQ21X7/d9gn3WiwkDTJmq3TQtYNz89lRnoFy8VeZpWlsyXvzSwiRrRZ8cXluvSwqKxqHJ6dBd9Rv+p0ZGQ==" + dependencies: + core-js-pure "^3.19.0" + regenerator-runtime "^0.13.4" + +"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.8.4": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.0.tgz#e27b977f2e2088ba24748bf99b5e1dece64e4f0b" + integrity "sha1-4nuXfy4giLokdIv5m14d7OZOTws= sha512-Nht8L0O8YCktmsDV6FqFue7vQLRx3Hb0B37lS5y0jDRqRxlBG4wIJHnf9/bgSE2UyipKFA01YtS+npRdTWBUyw==" + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.0.0", "@babel/template@^7.16.0", "@babel/template@^7.4.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.0.tgz#d16a35ebf4cd74e202083356fab21dd89363ddd6" + integrity "sha1-0Wo16/TNdOICCDNW+rId2JNj3dY= sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==" + dependencies: + "@babel/code-frame" "^7.16.0" + "@babel/parser" "^7.16.0" + "@babel/types" "^7.16.0" + +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.16.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.7.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.0.tgz#965df6c6bfc0a958c1e739284d3c9fa4a6e3c45b" + integrity "sha1-ll32xr/AqVjB5zkoTTyfpKbjxFs= sha512-qQ84jIs1aRQxaGaxSysII9TuDaguZ5yVrEuC0BN2vcPlalwfLovVmCjbFDPECPXcYM/wLvNFfp8uDOliLxIoUQ==" + dependencies: + "@babel/code-frame" "^7.16.0" + "@babel/generator" "^7.16.0" + "@babel/helper-function-name" "^7.16.0" + "@babel/helper-hoist-variables" "^7.16.0" + "@babel/helper-split-export-declaration" "^7.16.0" + "@babel/parser" "^7.16.0" + "@babel/types" "^7.16.0" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.16.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.0.tgz#db3b313804f96aadd0b776c4823e127ad67289ba" + integrity "sha1-2zsxOAT5aq3Qt3bEgj4SetZyibo= sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==" + dependencies: + "@babel/helper-validator-identifier" "^7.15.7" + to-fast-properties "^2.0.0" + +"@braintree/sanitize-url@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-5.0.2.tgz#b23080fa35520e993a8a37a0f5bca26aa4650a48" + integrity "sha1-sjCA+jVSDpk6ijeg9byiaqRlCkg= sha512-NBEJlHWrhQucLhZGHtSxM2loSaNUMajC7KOYJLyfcdW/6goVoff2HoYI3bz8YCDN0wKGbxtUL0gx2dvHpvnWlw==" + +"@cnakazawa/watch@^1.0.3": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" + integrity "sha1-+GSuhQBND8q29QvpFBxNo2jRZWo= sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==" + dependencies: + exec-sh "^0.3.2" + minimist "^1.2.0" + +"@eslint/eslintrc@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" + integrity "sha1-nkKYHvA1vrPdSa3ResuW6P9vOUw= sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==" + dependencies: + ajv "^6.12.4" + debug "^4.1.1" + espree "^7.3.0" + globals "^13.9.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + +"@hapi/address@2.x.x": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" + integrity "sha1-XWftQ/P9QaadS5/3tW58DR0KgeU= sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==" + +"@hapi/bourne@1.x.x": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-1.3.2.tgz#0a7095adea067243ce3283e1b56b8a8f453b242a" + integrity "sha1-CnCVreoGckPOMoPhtWuKj0U7JCo= sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==" + +"@hapi/hoek@8.x.x", "@hapi/hoek@^8.3.0": + version "8.5.1" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.1.tgz#fde96064ca446dec8c55a8c2f130957b070c6e06" + integrity "sha1-/elgZMpEbeyMVajC8TCVewcMbgY= sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==" + +"@hapi/joi@^15.0.0", "@hapi/joi@^15.0.1": + version "15.1.1" + resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7" + integrity "sha1-xnW4pxKW8Cgz+NbSQ7NMV7jOGdc= sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==" + dependencies: + "@hapi/address" "2.x.x" + "@hapi/bourne" "1.x.x" + "@hapi/hoek" "8.x.x" + "@hapi/topo" "3.x.x" + +"@hapi/topo@3.x.x": + version "3.1.6" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.6.tgz#68d935fa3eae7fdd5ab0d7f953f3205d8b2bfc29" + integrity "sha1-aNk1+j6uf91asNf5U/MgXYsr/Ck= sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==" + dependencies: + "@hapi/hoek" "^8.3.0" + +"@humanwhocodes/config-array@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" + integrity "sha1-FAeWfUxu7Nc4j4Os8er00Mbljvk= sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==" + dependencies: + "@humanwhocodes/object-schema" "^1.2.0" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.0": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity "sha1-tSBSnsIdjllFoYUd/Rwy6U45/0U= sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" + +"@intervolga/optimize-cssnano-plugin@^1.0.5": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@intervolga/optimize-cssnano-plugin/-/optimize-cssnano-plugin-1.0.6.tgz#be7c7846128b88f6a9b1d1261a0ad06eb5c0fdf8" + integrity "sha1-vnx4RhKLiPapsdEmGgrQbrXA/fg= sha512-zN69TnSr0viRSU6cEDIcuPcP67QcpQ6uHACg58FiN9PDrU6SLyGW3MR4tiISbYxy1kDWAVPwD+XwQTWE5cigAA==" + dependencies: + cssnano "^4.0.0" + cssnano-preset-default "^4.0.0" + postcss "^7.0.0" + +"@jest/console@^24.7.1", "@jest/console@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" + integrity "sha1-ebG8Bvt0qM+wHL3t+UVYSxuXB/A= sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==" + dependencies: + "@jest/source-map" "^24.9.0" + chalk "^2.0.1" + slash "^2.0.0" + +"@jest/core@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.9.0.tgz#2ceccd0b93181f9c4850e74f2a9ad43d351369c4" + integrity "sha1-LOzNC5MYH5xIUOdPKprUPTUTacQ= sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A==" + dependencies: + "@jest/console" "^24.7.1" + "@jest/reporters" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + ansi-escapes "^3.0.0" + chalk "^2.0.1" + exit "^0.1.2" + graceful-fs "^4.1.15" + jest-changed-files "^24.9.0" + jest-config "^24.9.0" + jest-haste-map "^24.9.0" + jest-message-util "^24.9.0" + jest-regex-util "^24.3.0" + jest-resolve "^24.9.0" + jest-resolve-dependencies "^24.9.0" + jest-runner "^24.9.0" + jest-runtime "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + jest-watcher "^24.9.0" + micromatch "^3.1.10" + p-each-series "^1.0.0" + realpath-native "^1.1.0" + rimraf "^2.5.4" + slash "^2.0.0" + strip-ansi "^5.0.0" + +"@jest/environment@^24.3.0", "@jest/environment@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.9.0.tgz#21e3afa2d65c0586cbd6cbefe208bafade44ab18" + integrity "sha1-IeOvotZcBYbL1svv4gi6+t5Eqxg= sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==" + dependencies: + "@jest/fake-timers" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + +"@jest/fake-timers@^24.3.0", "@jest/fake-timers@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93" + integrity "sha1-uj5r8O7NCaY2BJiWQ00wZjZUDJM= sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==" + dependencies: + "@jest/types" "^24.9.0" + jest-message-util "^24.9.0" + jest-mock "^24.9.0" + +"@jest/reporters@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.9.0.tgz#86660eff8e2b9661d042a8e98a028b8d631a5b43" + integrity "sha1-hmYO/44rlmHQQqjpigKLjWMaW0M= sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw==" + dependencies: + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.2" + istanbul-lib-coverage "^2.0.2" + istanbul-lib-instrument "^3.0.1" + istanbul-lib-report "^2.0.4" + istanbul-lib-source-maps "^3.0.1" + istanbul-reports "^2.2.6" + jest-haste-map "^24.9.0" + jest-resolve "^24.9.0" + jest-runtime "^24.9.0" + jest-util "^24.9.0" + jest-worker "^24.6.0" + node-notifier "^5.4.2" + slash "^2.0.0" + source-map "^0.6.0" + string-length "^2.0.0" + +"@jest/source-map@^24.3.0", "@jest/source-map@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714" + integrity "sha1-DiY6lEML5LQdpoPMwea//ioZFxQ= sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==" + dependencies: + callsites "^3.0.0" + graceful-fs "^4.1.15" + source-map "^0.6.0" + +"@jest/test-result@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca" + integrity "sha1-EXluiqnb+I6gJXV7MVJZWtBroMo= sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==" + dependencies: + "@jest/console" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/istanbul-lib-coverage" "^2.0.0" + +"@jest/test-sequencer@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz#f8f334f35b625a4f2f355f2fe7e6036dad2e6b31" + integrity "sha1-+PM081tiWk8vNV8v5+YDba0uazE= sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==" + dependencies: + "@jest/test-result" "^24.9.0" + jest-haste-map "^24.9.0" + jest-runner "^24.9.0" + jest-runtime "^24.9.0" + +"@jest/transform@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.9.0.tgz#4ae2768b296553fadab09e9ec119543c90b16c56" + integrity "sha1-SuJ2iyllU/rasJ6ewRlUPJCxbFY= sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==" + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^24.9.0" + babel-plugin-istanbul "^5.1.0" + chalk "^2.0.1" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.1.15" + jest-haste-map "^24.9.0" + jest-regex-util "^24.9.0" + jest-util "^24.9.0" + micromatch "^3.1.10" + pirates "^4.0.1" + realpath-native "^1.1.0" + slash "^2.0.0" + source-map "^0.6.1" + write-file-atomic "2.4.1" + +"@jest/types@^24.3.0", "@jest/types@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" + integrity "sha1-Y8smy3UA0Gnlo4lEGnxqtekJ/Fk= sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==" + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^1.1.1" + "@types/yargs" "^13.0.0" + +"@jest/types@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" + integrity "sha1-vvWlMgMOHYii9abZM/hOlyJu1I4= sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==" + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" + +"@koumoul/vjsf@2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@koumoul/vjsf/-/vjsf-2.0.3.tgz#499c1e80513269b32bbf5836ebf393126242897e" + integrity "sha1-SZwegFEyabMrv1g26/OTEmJCiX4= sha512-JuQ+WBDDUuTudk2vqtsCt7CBRGVgd6wg+TvTjozo4E9irvKSK+HquAYqUTvYVJN+yJ4K2DaC/x8fagTOgR2EYQ==" + dependencies: + "@mdi/js" "^5.5.55" + ajv "^6.12.0" + debounce "^1.2.0" + fast-copy "^2.1.1" + fast-equals "^2.0.0" + markdown-it "^8.4.2" + match-all "^1.2.5" + object-hash "^2.1.1" + property-expr "^1.5.1" + vuedraggable "^2.24.3" + +"@kyleshockey/object-assign-deep@^0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@kyleshockey/object-assign-deep/-/object-assign-deep-0.4.2.tgz#84900f0eefc372798f4751b5262830b8208922ec" + integrity "sha1-hJAPDu/DcnmPR1G1JigwuCCJIuw= sha512-GWZ8omROOrXe4/T4wsKfq86E0efACDG+mghGoz0nWY/THVmt8O/vSpc1YqRBlvBnprhMcL4OrRjM7R/FyKcMJw==" + +"@kyleshockey/xml@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@kyleshockey/xml/-/xml-1.0.2.tgz#81fad3d7c33da2ba2639db095db3db24c2921f70" + integrity "sha1-gfrT18M9oromOdsJXbPbJMKSH3A= sha512-iMo32MPLcI9cPxs3YL5kmKxKgDmkSZDCFEqIT5eRk7d/Ll8r4X3SwGYSigzALd6+RHWlFEmjL1QyaQ15xDZFlw==" + dependencies: + stream "^0.0.2" + +"@mdi/font@5.9.55": + version "5.9.55" + resolved "https://registry.yarnpkg.com/@mdi/font/-/font-5.9.55.tgz#41acd50b88073ded7095fc3029d8712b6e12f38e" + integrity "sha1-QazVC4gHPe1wlfwwKdhxK24S844= sha512-jswRF6q3eq8NWpWiqct6q+6Fg/I7nUhrxYJfiEM8JJpap0wVJLQdbKtyS65GdlK7S7Ytnx3TTi/bmw+tBhkGmg==" + +"@mdi/js@^5.5.55": + version "5.9.55" + resolved "https://registry.yarnpkg.com/@mdi/js/-/js-5.9.55.tgz#8f5bc4d924c23f30dab20545ddc768e778bbc882" + integrity "sha1-j1vE2STCPzDasgVF3cdo53i7yII= sha512-BbeHMgeK2/vjdJIRnx12wvQ6s8xAYfvMmEAVsUx9b+7GiQGQ9Za8jpwp17dMKr9CgKRvemlAM4S7S3QOtEbp4A==" + +"@mdi/util@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@mdi/util/-/util-0.3.2.tgz#8964f14ad86f9a355042824553958cc01a94886f" + integrity "sha1-iWTxSthvmjVQQoJFU5WMwBqUiG8= sha512-0ICbKIcsI+OYSqz6SWsYVJA6+kM+irQQiwYGBtJlq0a0sI0JrB2bCrc4S/xVfexqwa1EG8dlSY/ohsQllEXnyQ==" + +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + integrity "sha1-UkryQNGjYFJ7cwR17PoTRKpUDd4= sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==" + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity "sha1-dhnC6yGyVIP20WdUi0z9WnSIw9U= sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==" + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity "sha1-W9Jir5Tp0lvR5xsF3u1Eh2oiLos= sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + +"@nodelib/fs.stat@^1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + integrity "sha1-K1o6s/kYzKSKjHVMCBaOPwPrphs= sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==" + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity "sha1-6Vc36LtnRt3t9pxVaVNJTxlv5po= sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==" + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@simonwep/pickr@~1.7.0": + version "1.7.4" + resolved "https://registry.yarnpkg.com/@simonwep/pickr/-/pickr-1.7.4.tgz#b14fcd945890388b870cd6db4d6c78d531f25141" + integrity "sha1-sU/NlFiQOIuHDNbbTWx41THyUUE= sha512-fq7jgKJT21uWGC1mARBHvvd1JYlEf93o7SuVOB4Lr0x/2UPuNC9Oe9n/GzVeg4oVtqMDfh1wIEJpsdOJEZb+3g==" + dependencies: + core-js "^3.6.5" + nanopop "^2.1.0" + +"@soda/friendly-errors-webpack-plugin@^1.7.1": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.0.tgz#84751d82a93019d5c92c0cf0e45ac59087cd2240" + integrity "sha1-hHUdgqkwGdXJLAzw5FrFkIfNIkA= sha512-RLotfx6k1+nfLacwNCenj7VnTMPxVwYKoGOcffMFoJDKM8tXzBiCN0hMHFJNnoAojduYAsxuiMm0EOMixgiRow==" + dependencies: + chalk "^2.4.2" + error-stack-parser "^2.0.2" + string-width "^2.0.0" + strip-ansi "^5" + +"@soda/get-current-script@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@soda/get-current-script/-/get-current-script-1.0.2.tgz#a53515db25d8038374381b73af20bb4f2e508d87" + integrity "sha1-pTUV2yXYA4N0OBtzryC7Ty5QjYc= sha512-T7VNNlYVM1SgQ+VsMYhnDkcGmWhQdL0bDyGm5TlQ3GBXnJscEClUUOKduWTmm2zCnvNLC1hc3JpuXjs/nFOc5w==" + +"@testing-library/dom@^7.26.6": + version "7.31.2" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-7.31.2.tgz#df361db38f5212b88555068ab8119f5d841a8c4a" + integrity "sha1-3zYds49SEriFVQaKuBGfXYQajEo= sha512-3UqjCpey6HiTZT92vODYLPxTBWlM8ZOOjr3LX5F37/VRipW2M1kX6I/Cm4VXzteZqfGfagg8yXywpcOgQBlNsQ==" + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/runtime" "^7.12.5" + "@types/aria-query" "^4.2.0" + aria-query "^4.2.2" + chalk "^4.1.0" + dom-accessibility-api "^0.5.6" + lz-string "^1.4.4" + pretty-format "^26.6.2" + +"@testing-library/vue@^5.6.2": + version "5.8.2" + resolved "https://registry.yarnpkg.com/@testing-library/vue/-/vue-5.8.2.tgz#976b2179dc28ceba8dd63b5437edc2749f860252" + integrity "sha1-l2shedwozrqN1jtUN+3CdJ+GAlI= sha512-evsQjLw3T/c92ZsXflZMzSN72P06VlgUZMIcrRKn5n9ZX7QgQyebB3DgdmPACf6JgNfP8Y3Lm2212FmeMnWlZw==" + dependencies: + "@babel/runtime" "^7.12.5" + "@testing-library/dom" "^7.26.6" + "@vue/test-utils" "^1.1.0" + +"@transloadit/prettier-bytes@0.0.7": + version "0.0.7" + resolved "https://registry.yarnpkg.com/@transloadit/prettier-bytes/-/prettier-bytes-0.0.7.tgz#cdb5399f445fdd606ed833872fa0cabdbc51686b" + integrity "sha1-zbU5n0Rf3WBu2DOHL6DKvbxRaGs= sha512-VeJbUb0wEKbcwaSlj5n+LscBl9IPgLPkHVGBkh00cztv6X4L/TJXK58LzFuBKX7/GAfiGhIwH67YTLTlzvIzBA==" + +"@types/aria-query@^4.2.0": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.2.tgz#ed4e0ad92306a704f9fb132a0cfcf77486dbe2bc" + integrity "sha1-7U4K2SMGpwT5+xMqDPz3dIbb4rw= sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==" + +"@types/babel__core@^7.1.0": + version "7.1.16" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.16.tgz#bc12c74b7d65e82d29876b5d0baf5c625ac58702" + integrity "sha1-vBLHS31l6C0ph2tdC69cYlrFhwI= sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==" + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.3" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.3.tgz#f456b4b2ce79137f768aa130d2423d2f0ccfaba5" + integrity "sha1-9Fa0ss55E392iqEw0kI9LwzPq6U= sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==" + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.1" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + integrity "sha1-PRpI/Z1sDt/Vby/1eNrtSPNsiWk= sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==" + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.2.tgz#ffcd470bbb3f8bf30481678fb5502278ca833a43" + integrity "sha1-/81HC7s/i/MEgWePtVAieMqDOkM= sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==" + dependencies: + "@babel/types" "^7.3.0" + +"@types/body-parser@*": + version "1.19.1" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.1.tgz#0c0174c42a7d017b818303d4b5d969cb0b75929c" + integrity "sha1-DAF0xCp9AXuBgwPUtdlpywt1kpw= sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==" + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/chart.js@^2.7.55": + version "2.9.34" + resolved "https://registry.yarnpkg.com/@types/chart.js/-/chart.js-2.9.34.tgz#d41fb6b74b72a56bac70255bb4ed087386b66ed6" + integrity "sha1-1B+2t0typWuscCVbtO0Ic4a2btY= sha512-CtZVk+kh1IN67dv+fB0CWmCLCRrDJgqOj15qPic2B1VCMovNO6B7Vhf/TgPpNscjhAL1j+qUntDMWb9A4ZmPTg==" + dependencies: + moment "^2.10.2" + +"@types/connect-history-api-fallback@*": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" + integrity "sha1-0feooJ0O1aV67lrpwYq5uAMgXa4= sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==" + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity "sha1-X89q5EXkAh0fwiGaSHPMc6O7KtE= sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==" + dependencies: + "@types/node" "*" + +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": + version "4.17.24" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.24.tgz#ea41f93bf7e0d59cd5a76665068ed6aab6815c07" + integrity "sha1-6kH5O/fg1ZzVp2ZlBo7WqraBXAc= sha512-3UJuW+Qxhzwjq3xhwXm2onQcFHn76frIYVbTu+kn24LFxI+dEhdfISDFovPB8VpEgW8oQCTpRuCe+0zJxB7NEA==" + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" + integrity "sha1-p24plXKJmbq1GjP6vOHXBaNwkDQ= sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==" + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/glob@^7.1.1": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity "sha1-vBtb86qS8lvV3TnzXFc2G9zlsus= sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==" + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + +"@types/hast@^2.0.0": + version "2.3.4" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc" + integrity "sha1-iqXvksEX0g2XSoK9+2pkiwjAuvw= sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==" + dependencies: + "@types/unist" "*" + +"@types/http-proxy@^1.17.5": + version "1.17.7" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.7.tgz#30ea85cc2c868368352a37f0d0d3581e24834c6f" + integrity "sha1-MOqFzCyGg2g1Kjfw0NNYHiSDTG8= sha512-9hdj6iXH64tHSLTY+Vt2eYOGzSogC+JQ2H7bdPWkuh7KXP5qLllWx++t+K9Wk556c3dkDdPws/SpMRi0sdCT1w==" + dependencies: + "@types/node" "*" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" + integrity "sha1-S6jdtyAiH0MuRDvV+RF/0iz9R2I= sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==" + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity "sha1-wUwk8Y6oGQwRjudWK3/5mjZVJoY= sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==" + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^1.1.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz#e875cc689e47bce549ec81f3df5e6f6f11cfaeb2" + integrity "sha1-6HXMaJ5HvOVJ7IHz315vbxHPrrI= sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==" + dependencies: + "@types/istanbul-lib-coverage" "*" + "@types/istanbul-lib-report" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity "sha1-kVP+mLuivVZaY63ZQ21vDX+EaP8= sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==" + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@^24.0.19": + version "24.9.1" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-24.9.1.tgz#02baf9573c78f1b9974a5f36778b366aa77bd534" + integrity "sha1-Arr5Vzx48bmXSl82d4s2aqd71TQ= sha512-Fb38HkXSVA4L8fGKEZ6le5bB8r6MRWlOCZbVuWZcmOMSCd2wCYOwN1ibj8daIoV9naq7aaOZjrLCoCMptKU/4Q==" + dependencies: + jest-diff "^24.3.0" + +"@types/jest@^26.0.23": + version "26.0.24" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.24.tgz#943d11976b16739185913a1936e0de0c4a7d595a" + integrity "sha1-lD0Rl2sWc5GFkToZNuDeDEp9WVo= sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w==" + dependencies: + jest-diff "^26.0.0" + pretty-format "^26.0.0" + +"@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.7", "@types/json-schema@^7.0.8": + version "7.0.9" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" + integrity "sha1-l+3JA36gw4WFMgsolk3eOznkZg0= sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==" + +"@types/lodash@^4.14.168": + version "4.14.176" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.176.tgz#641150fc1cda36fbfa329de603bbb175d7ee20c0" + integrity "sha1-ZBFQ/BzaNvv6Mp3mA7uxddfuIMA= sha512-xZmuPTa3rlZoIbtDUyJKZQimJV3bxCmzMIO2c9Pz9afyDro6kr7R79GwcB6mRhuoPmV2p1Vb66WOJH7F886WKQ==" + +"@types/luxon@^1.27.0": + version "1.27.1" + resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-1.27.1.tgz#aceeb2d5be8fccf541237e184e37ecff5faa9096" + integrity "sha1-rO6y1b6PzPVBI34YTjfs/1+qkJY= sha512-cPiXpOvPFDr2edMnOXlz3UBDApwUfR+cpizvxCy0n3vp9bz/qe8BWzHPIEFcy+ogUOyjKuCISgyq77ELZPmkkg==" + +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity "sha1-k+Jb+e51/g/YC1lLxP6w6GIRG1o= sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + +"@types/minimatch@*": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" + integrity "sha1-EAHMXmo3BLg8I2An538vWOoBD0A= sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==" + +"@types/minimist@^1.2.0": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" + integrity "sha1-7nceK6Sz3Fs3KTXVSf2WF780W4w= sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==" + +"@types/node@*": + version "16.11.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" + integrity "sha1-a+96KgrWhM9ukPz+Mc7KvZzgo64= sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==" + +"@types/normalize-package-data@^2.4.0": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" + integrity "sha1-0zV0eaD9/dWQf+Z+F+CoXJBuEwE= sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==" + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity "sha1-L4u0QUNNFjs1+4/9zNcTiSf/uMA= sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + +"@types/prismjs@^1.16.5": + version "1.16.6" + resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.16.6.tgz#377054f72f671b36dbe78c517ce2b279d83ecc40" + integrity "sha1-N3BU9y9nGzbb54xRfOKyedg+zEA= sha512-dTvnamRITNqNkqhlBd235kZl3KfVJQQoT5jkXeiWSBK7i4/TLKBNLV0S1wOt8gy4E2TY722KLtdmv2xc6+Wevg==" + +"@types/q@^1.5.1": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.5.tgz#75a2a8e7d8ab4b230414505d92335d1dcb53a6df" + integrity "sha1-daKo59irSyMEFFBdkjNdHctTpt8= sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==" + +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity "sha1-Y7t9Bn2xB8weRXwwO8JdUR/r9ss= sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity "sha1-zWZ7z90CUhOq+3ylkVqTJZCs3Nw= sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + +"@types/serve-static@*": + version "1.13.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" + integrity "sha1-9eDOh5fS18xevtpIpSyWxPpHqNk= sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==" + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/source-list-map@*": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" + integrity "sha1-AHiDYGP/rxdBI0m7o2QIfgrALsk= sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==" + +"@types/stack-utils@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" + integrity "sha1-CoUdO9lkmPolwzq3J47TvWXwbD4= sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==" + +"@types/strip-bom@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/strip-bom/-/strip-bom-3.0.0.tgz#14a8ec3956c2e81edb7520790aecf21c290aebd2" + integrity "sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I= sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==" + +"@types/strip-json-comments@0.0.30": + version "0.0.30" + resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1" + integrity "sha1-mqMMBNshKpoGSdaub9UKzMQHSKE= sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==" + +"@types/tapable@^1": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.8.tgz#b94a4391c85666c7b73299fd3ad79d4faa435310" + integrity "sha1-uUpDkchWZse3Mpn9OtedT6pDUxA= sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ==" + +"@types/uglify-js@*": + version "3.13.1" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.13.1.tgz#5e889e9e81e94245c75b6450600e1c5ea2878aea" + integrity "sha1-XoienoHpQkXHW2RQYA4cXqKHiuo= sha512-O3MmRAk6ZuAKa9CHgg0Pr0+lUOqoMLpc9AS4R8ano2auvsg7IE8syF3Xh/NPr26TWklxYcqoEEFdzLLs1fV9PQ==" + dependencies: + source-map "^0.6.1" + +"@types/unist@*": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d" + integrity "sha1-JQp7FsO5H2cqJFUuxkZ47rHToI0= sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" + +"@types/vue-markdown@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@types/vue-markdown/-/vue-markdown-2.2.1.tgz#dd302c67349e0e591d3fcb84e924eb8bf9314fea" + integrity "sha1-3TAsZzSeDlkdP8uE6STri/kxT+o= sha512-pqa1RU0GZybdtqqadOWT8rTwMSchH1PR+oYeenscTT8Nrq/gniL7hpibhH40+aZBjx3Ps0syaTSiSae4Inw7GQ==" + dependencies: + vue "^2.5.16" + +"@types/webpack-dev-server@^3.11.0": + version "3.11.6" + resolved "https://registry.yarnpkg.com/@types/webpack-dev-server/-/webpack-dev-server-3.11.6.tgz#d8888cfd2f0630203e13d3ed7833a4d11b8a34dc" + integrity "sha1-2IiM/S8GMCA+E9PteDOk0RuKNNw= sha512-XCph0RiiqFGetukCTC3KVnY1jwLcZ84illFRMbyFzCcWl90B/76ew0tSqF46oBhnLC4obNDG7dMO0JfTN0MgMQ==" + dependencies: + "@types/connect-history-api-fallback" "*" + "@types/express" "*" + "@types/serve-static" "*" + "@types/webpack" "^4" + http-proxy-middleware "^1.0.0" + +"@types/webpack-env@^1.15.2": + version "1.16.3" + resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.16.3.tgz#b776327a73e561b71e7881d0cd6d34a1424db86a" + integrity "sha1-t3YyenPlYbceeIHQzW00oUJNuGo= sha512-9gtOPPkfyNoEqCQgx4qJKkuNm/x0R2hKR7fdl7zvTJyHnIisuE/LfvXOsYWL0o3qq6uiBnKZNNNzi3l0y/X+xw==" + +"@types/webpack-sources@*": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-3.2.0.tgz#16d759ba096c289034b26553d2df1bf45248d38b" + integrity "sha1-FtdZuglsKJA0smVT0t8b9FJI04s= sha512-Ft7YH3lEVRQ6ls8k4Ff1oB4jN6oy/XmU6tQISKdhfh+1mR+viZFphS6WL0IrtDOzvefmJg5a0s7ZQoRXwqTEFg==" + dependencies: + "@types/node" "*" + "@types/source-list-map" "*" + source-map "^0.7.3" + +"@types/webpack@^4", "@types/webpack@^4.0.0": + version "4.41.31" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.31.tgz#c35f252a3559ddf9c85c0d8b0b42019025e581aa" + integrity "sha1-w18lKjVZ3fnIXA2LC0IBkCXlgao= sha512-/i0J7sepXFIp1ZT7FjUGi1eXMCg8HCCzLJEQkKsOtbJFontsJLolBcDC+3qxn5pPwiCt1G0ZdRmYRzNBtvpuGQ==" + dependencies: + "@types/node" "*" + "@types/tapable" "^1" + "@types/uglify-js" "*" + "@types/webpack-sources" "*" + anymatch "^3.0.0" + source-map "^0.6.0" + +"@types/yargs-parser@*": + version "20.2.1" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129" + integrity "sha1-O5ziSJkZ2eT+pDm3aRarw0st8Sk= sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==" + +"@types/yargs@^13.0.0": + version "13.0.12" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.12.tgz#d895a88c703b78af0465a9de88aa92c61430b092" + integrity "sha1-2JWojHA7eK8EZaneiKqSxhQwsJI= sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==" + dependencies: + "@types/yargs-parser" "*" + +"@types/yargs@^15.0.0": + version "15.0.14" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.14.tgz#26d821ddb89e70492160b66d10a0eb6df8f6fb06" + integrity "sha1-Jtgh3biecEkhYLZtEKDrbfj2+wY= sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==" + dependencies: + "@types/yargs-parser" "*" + +"@typescript-eslint/eslint-plugin@^4.22.1": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz#c24dc7c8069c7706bc40d99f6fa87edcb2005276" + integrity "sha1-wk3HyAacdwa8QNmfb6h+3LIAUnY= sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==" + dependencies: + "@typescript-eslint/experimental-utils" "4.33.0" + "@typescript-eslint/scope-manager" "4.33.0" + debug "^4.3.1" + functional-red-black-tree "^1.0.1" + ignore "^5.1.8" + regexpp "^3.1.0" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/experimental-utils@4.33.0", "@typescript-eslint/experimental-utils@^4.0.1": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz#6f2a786a4209fa2222989e9380b5331b2810f7fd" + integrity "sha1-byp4akIJ+iIimJ6TgLUzGygQ9/0= sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==" + dependencies: + "@types/json-schema" "^7.0.7" + "@typescript-eslint/scope-manager" "4.33.0" + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/typescript-estree" "4.33.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/parser@^4.22.1": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.33.0.tgz#dfe797570d9694e560528d18eecad86c8c744899" + integrity "sha1-3+eXVw2WlOVgUo0Y7srYbIx0SJk= sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==" + dependencies: + "@typescript-eslint/scope-manager" "4.33.0" + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/typescript-estree" "4.33.0" + debug "^4.3.1" + +"@typescript-eslint/scope-manager@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz#d38e49280d983e8772e29121cf8c6e9221f280a3" + integrity "sha1-045JKA2YPody4pEhz4xukiHygKM= sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==" + dependencies: + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/visitor-keys" "4.33.0" + +"@typescript-eslint/types@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.33.0.tgz#a1e59036a3b53ae8430ceebf2a919dc7f9af6d72" + integrity "sha1-oeWQNqO1OuhDDO6/KpGdx/mvbXI= sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==" + +"@typescript-eslint/typescript-estree@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz#0dfb51c2908f68c5c08d82aefeaf166a17c24609" + integrity "sha1-DftRwpCPaMXAjYKu/q8WahfCRgk= sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==" + dependencies: + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/visitor-keys" "4.33.0" + debug "^4.3.1" + globby "^11.0.3" + is-glob "^4.0.1" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/visitor-keys@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz#2a22f77a41604289b7a186586e9ec48ca92ef1dd" + integrity "sha1-KiL3ekFgQom3oYZYbp7EjKku8d0= sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==" + dependencies: + "@typescript-eslint/types" "4.33.0" + eslint-visitor-keys "^2.0.0" + +"@uppy/companion-client@^1.10.2": + version "1.10.2" + resolved "https://registry.yarnpkg.com/@uppy/companion-client/-/companion-client-1.10.2.tgz#a640b3ef90b91751c49bf4b6a7a63c2ebac294f6" + integrity "sha1-pkCz75C5F1HEm/S2p6Y8LrrClPY= sha512-5RmsNF9UBvUqmqQz48SoiLvkpGmvQTgwNM4bJX8xwVozv/6goRpFrsMJGLwqFcHS/9xj6STKOqrM582g8exVwQ==" + dependencies: + "@uppy/utils" "^3.6.2" + namespace-emitter "^2.0.1" + qs-stringify "^1.1.0" + url-parse "^1.4.7" + +"@uppy/core@^1.18.0": + version "1.20.1" + resolved "https://registry.yarnpkg.com/@uppy/core/-/core-1.20.1.tgz#23ca28d4388c29987fdc4e65a968474dcdc303c6" + integrity "sha1-I8oo1DiMKZh/3E5lqWhHTc3DA8Y= sha512-Z0yGixSNOSMgT/2aLylXQaEBB6X32RqGLQUgDJDK08jI0ZcMha5glNhD2RU1Gs9noQOAR/f7QwBssSnYJUNRfg==" + dependencies: + "@transloadit/prettier-bytes" "0.0.7" + "@uppy/store-default" "^1.2.7" + "@uppy/utils" "^3.6.2" + cuid "^2.1.1" + lodash.throttle "^4.1.1" + mime-match "^1.0.2" + namespace-emitter "^2.0.1" + preact "8.2.9" + +"@uppy/dashboard@^1.21.1": + version "1.21.1" + resolved "https://registry.yarnpkg.com/@uppy/dashboard/-/dashboard-1.21.1.tgz#c920d3af69b61413ef109608dde9b12d3c8a434b" + integrity "sha1-ySDTr2m2FBPvEJYI3emxLTyKQ0s= sha512-psMwBVxxhAZxYkRds4e//+Sx3zkFYRnYpt4jaF4hmwpL9SehlyhQKwaB/scZz/O4yshmgTN8Sri0mYK5FSh5SQ==" + dependencies: + "@transloadit/prettier-bytes" "0.0.7" + "@uppy/informer" "^1.6.6" + "@uppy/provider-views" "^1.12.3" + "@uppy/status-bar" "^1.9.6" + "@uppy/thumbnail-generator" "^1.7.11" + "@uppy/utils" "^3.6.2" + classnames "^2.2.6" + cuid "^2.1.1" + is-shallow-equal "^1.0.1" + lodash.debounce "^4.0.8" + lodash.throttle "^4.1.1" + memoize-one "^5.0.4" + preact "8.2.9" + resize-observer-polyfill "^1.5.0" + +"@uppy/drag-drop@^1.4.31": + version "1.4.31" + resolved "https://registry.yarnpkg.com/@uppy/drag-drop/-/drag-drop-1.4.31.tgz#fe342e2d653c8454c8dd9be1e95dbed5726772a6" + integrity "sha1-/jQuLWU8hFTI3Zvh6V2+1XJncqY= sha512-a9/WKOdAhz9mfFYI9JJNEGLP3TI8RQChndpFkjlxbsD82x2WHSB1TyWTslMdSCK6Ed3pV5IYyBVqDGsTqgveYg==" + dependencies: + "@uppy/utils" "^3.6.2" + preact "8.2.9" + +"@uppy/informer@^1.6.6": + version "1.6.6" + resolved "https://registry.yarnpkg.com/@uppy/informer/-/informer-1.6.6.tgz#94090ab74997f10c2a2151c04b1c75484bdfe7eb" + integrity "sha1-lAkKt0mX8QwqIVHASxx1SEvf5+s= sha512-9rZoAqNrKQN/HINnGg8rGnKEliLgc+9/tQQ0f9QcBgRIu/rnbBCTwS+qnGGdjYBdEJTSbHx+U7X9ufjrrjB+CA==" + dependencies: + "@uppy/utils" "^3.6.2" + preact "8.2.9" + +"@uppy/progress-bar@^1.3.30": + version "1.3.30" + resolved "https://registry.yarnpkg.com/@uppy/progress-bar/-/progress-bar-1.3.30.tgz#5bdbc8aab782df15def535c6be47d45ca07964da" + integrity "sha1-W9vIqreC3xXe9TXGvkfUXKB5ZNo= sha512-MAn20wBMzKc1p9M/Mot4+bV/707EO/DVgoFcvoP8rmA5oZOGMINpvFGR+rUtWQoBFMvKtvs/Wkp8mcR22rCMrw==" + dependencies: + "@uppy/utils" "^3.6.2" + preact "8.2.9" + +"@uppy/provider-views@^1.12.3": + version "1.12.3" + resolved "https://registry.yarnpkg.com/@uppy/provider-views/-/provider-views-1.12.3.tgz#aecfed615bc174abc548539a3c17b39e455aed0e" + integrity "sha1-rs/tYVvBdKvFSFOaPBeznkVa7Q4= sha512-r2kra3IftmGLeKMEgZbmQM1qXixulWUUzydgpHcZqJOpeNIjJcpspJruYRctrVqaLz/8asw87V4KxDk0U4xGzw==" + dependencies: + "@uppy/utils" "^3.6.2" + classnames "^2.2.6" + preact "8.2.9" + +"@uppy/status-bar@^1.9.6": + version "1.9.6" + resolved "https://registry.yarnpkg.com/@uppy/status-bar/-/status-bar-1.9.6.tgz#a04f699444fc7f156c260e5b7c001125e5190a5f" + integrity "sha1-oE9plET8fxVsJg5bfAARJeUZCl8= sha512-U/KPs5SwZ5d4hJFiCNAdriGHSk1Uhrl+iQmpJS8hoM+8r8rPfwScdua2/ehLuH69Ymwp6k7DpK2DU7UG2XZ+ag==" + dependencies: + "@transloadit/prettier-bytes" "0.0.7" + "@uppy/utils" "^3.6.2" + classnames "^2.2.6" + lodash.throttle "^4.1.1" + preact "8.2.9" + +"@uppy/store-default@^1.2.7": + version "1.2.7" + resolved "https://registry.yarnpkg.com/@uppy/store-default/-/store-default-1.2.7.tgz#41a0b1579f4d5b86c236e7f5e52fdc01960bb011" + integrity "sha1-QaCxV59NW4bCNuf15S/cAZYLsBE= sha512-58IG9yk/i/kYQ9uEwAwMFl1H2V3syOoODrYoFfVHlxaqv+9MkXBg2tHE2gk40iaAIxcCErcPxZkBOvkqzO1SQA==" + +"@uppy/thumbnail-generator@^1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@uppy/thumbnail-generator/-/thumbnail-generator-1.7.11.tgz#c6f49be90469f220a419ac43c129bf835cc11c41" + integrity "sha1-xvSb6QRp8iCkGaxDwSm/g1zBHEE= sha512-qo9ZD8ByDMM6gIJ4JPN0V/dWlruYMhmYifhUvDUu0qhPAOTJAqh2hLQ+dlmUXTns8RnDorCXScreICSQ09FuLQ==" + dependencies: + "@uppy/utils" "^3.6.2" + exifr "^6.0.0" + math-log2 "^1.0.1" + +"@uppy/tus@^1.8.7": + version "1.9.2" + resolved "https://registry.yarnpkg.com/@uppy/tus/-/tus-1.9.2.tgz#d6e4fa715bc386daa8e7be6e80eb93e4f2abb46e" + integrity "sha1-1uT6cVvDhtqo575ugOuT5PKrtG4= sha512-ejaczrrh6w514XGd3kiDD1PJ8tIgmnV50fuyRwsybDj8HQheKAEu6GsJjxcnctP8NcSx4HNDhazVLPj6+A4p9Q==" + dependencies: + "@uppy/companion-client" "^1.10.2" + "@uppy/utils" "^3.6.2" + tus-js-client "^2.1.1" + +"@uppy/utils@^3.6.2": + version "3.6.2" + resolved "https://registry.yarnpkg.com/@uppy/utils/-/utils-3.6.2.tgz#78b02455b9c469d927d22736be5b68cda2600826" + integrity "sha1-eLAkVbnEadkn0ic2vltozaJgCCY= sha512-wGTZma7eywIojfuE1vXlT0fxPSpmCRMkfgFWYc+6TL2FfGqWInmePoB+yal6/M2AnjeKHz6XYMhIpZkjOxFvcw==" + dependencies: + abortcontroller-polyfill "^1.4.0" + lodash.throttle "^4.1.1" + +"@uppy/vue@^0.2.1": + version "0.2.7" + resolved "https://registry.yarnpkg.com/@uppy/vue/-/vue-0.2.7.tgz#9bb1f589d9ff79994f9bc7b5a99b6a9be929736a" + integrity "sha1-m7H1idn/eZlPm8e1qZtqm+kpc2o= sha512-5sqRD7XOkq+dZUUHN6dA61swFlIMJfk4L8IaWV9CB+e3Jmaujzw0yIlNqhjra2hzzRt2AZmf0yKgHf3NeCd1UQ==" + dependencies: + "@uppy/dashboard" "^1.21.1" + "@uppy/drag-drop" "^1.4.31" + "@uppy/progress-bar" "^1.3.30" + "@uppy/status-bar" "^1.9.6" + shallow-equal "^1.2.1" + +"@vue/babel-helper-vue-jsx-merge-props@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.2.1.tgz#31624a7a505fb14da1d58023725a4c5f270e6a81" + integrity "sha1-MWJKelBfsU2h1YAjclpMXycOaoE= sha512-QOi5OW45e2R20VygMSNhyQHvpdUwQZqGPc748JLGCYEy+yp8fNFNdbNIGAgZmi9e+2JHPd6i6idRuqivyicIkA==" + +"@vue/babel-helper-vue-transform-on@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.2.tgz#9b9c691cd06fc855221a2475c3cc831d774bc7dc" + integrity "sha1-m5xpHNBvyFUiGiR1w8yDHXdLx9w= sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA==" + +"@vue/babel-plugin-jsx@^1.0.3": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.1.1.tgz#0c5bac27880d23f89894cd036a37b55ef61ddfc1" + integrity "sha1-DFusJ4gNI/iYlM0Daje1XvYd38E= sha512-j2uVfZjnB5+zkcbc/zsOc0fSNGCMMjaEXP52wdwdIfn0qjFfEYpYZBFKFg+HHnQeJCVrjOeO0YxgaL7DMrym9w==" + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.0.0" + "@babel/template" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" + "@vue/babel-helper-vue-transform-on" "^1.0.2" + camelcase "^6.0.0" + html-tags "^3.1.0" + svg-tags "^1.0.0" + +"@vue/babel-plugin-transform-vue-jsx@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.2.1.tgz#646046c652c2f0242727f34519d917b064041ed7" + integrity "sha1-ZGBGxlLC8CQnJ/NFGdkXsGQEHtc= sha512-HJuqwACYehQwh1fNT8f4kyzqlNMpBuUK4rSiSES5D4QsYncv5fxFsLyrxFPG2ksO7t5WP+Vgix6tt6yKClwPzA==" + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.2.0" + "@vue/babel-helper-vue-jsx-merge-props" "^1.2.1" + html-tags "^2.0.0" + lodash.kebabcase "^4.1.1" + svg-tags "^1.0.0" + +"@vue/babel-preset-app@^4.5.15": + version "4.5.15" + resolved "https://registry.yarnpkg.com/@vue/babel-preset-app/-/babel-preset-app-4.5.15.tgz#f6bc08f8f674e98a260004234cde18b966d72eb0" + integrity "sha1-9rwI+PZ06YomAAQjTN4YuWbXLrA= sha512-J+YttzvwRfV1BPczf8r3qCevznYk+jh531agVF+5EYlHF4Sgh/cGXTz9qkkiux3LQgvhEGXgmCteg1n38WuuKg==" + dependencies: + "@babel/core" "^7.11.0" + "@babel/helper-compilation-targets" "^7.9.6" + "@babel/helper-module-imports" "^7.8.3" + "@babel/plugin-proposal-class-properties" "^7.8.3" + "@babel/plugin-proposal-decorators" "^7.8.3" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-jsx" "^7.8.3" + "@babel/plugin-transform-runtime" "^7.11.0" + "@babel/preset-env" "^7.11.0" + "@babel/runtime" "^7.11.0" + "@vue/babel-plugin-jsx" "^1.0.3" + "@vue/babel-preset-jsx" "^1.2.4" + babel-plugin-dynamic-import-node "^2.3.3" + core-js "^3.6.5" + core-js-compat "^3.6.5" + semver "^6.1.0" + +"@vue/babel-preset-jsx@^1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@vue/babel-preset-jsx/-/babel-preset-jsx-1.2.4.tgz#92fea79db6f13b01e80d3a0099e2924bdcbe4e87" + integrity "sha1-kv6nnbbxOwHoDToAmeKSS9y+Toc= sha512-oRVnmN2a77bYDJzeGSt92AuHXbkIxbf/XXSE3klINnh9AXBmVS1DGa1f0d+dDYpLfsAKElMnqKTQfKn7obcL4w==" + dependencies: + "@vue/babel-helper-vue-jsx-merge-props" "^1.2.1" + "@vue/babel-plugin-transform-vue-jsx" "^1.2.1" + "@vue/babel-sugar-composition-api-inject-h" "^1.2.1" + "@vue/babel-sugar-composition-api-render-instance" "^1.2.4" + "@vue/babel-sugar-functional-vue" "^1.2.2" + "@vue/babel-sugar-inject-h" "^1.2.2" + "@vue/babel-sugar-v-model" "^1.2.3" + "@vue/babel-sugar-v-on" "^1.2.3" + +"@vue/babel-sugar-composition-api-inject-h@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-composition-api-inject-h/-/babel-sugar-composition-api-inject-h-1.2.1.tgz#05d6e0c432710e37582b2be9a6049b689b6f03eb" + integrity "sha1-BdbgxDJxDjdYKyvppgSbaJtvA+s= sha512-4B3L5Z2G+7s+9Bwbf+zPIifkFNcKth7fQwekVbnOA3cr3Pq71q71goWr97sk4/yyzH8phfe5ODVzEjX7HU7ItQ==" + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + +"@vue/babel-sugar-composition-api-render-instance@^1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-composition-api-render-instance/-/babel-sugar-composition-api-render-instance-1.2.4.tgz#e4cbc6997c344fac271785ad7a29325c51d68d19" + integrity "sha1-5MvGmXw0T6wnF4WteikyXFHWjRk= sha512-joha4PZznQMsxQYXtR3MnTgCASC9u3zt9KfBxIeuI5g2gscpTsSKRDzWQt4aqNIpx6cv8On7/m6zmmovlNsG7Q==" + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + +"@vue/babel-sugar-functional-vue@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.2.2.tgz#267a9ac8d787c96edbf03ce3f392c49da9bd2658" + integrity "sha1-JnqayNeHyW7b8Dzj85LEnam9Jlg= sha512-JvbgGn1bjCLByIAU1VOoepHQ1vFsroSA/QkzdiSs657V79q6OwEWLCQtQnEXD/rLTA8rRit4rMOhFpbjRFm82w==" + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + +"@vue/babel-sugar-inject-h@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.2.2.tgz#d738d3c893367ec8491dcbb669b000919293e3aa" + integrity "sha1-1zjTyJM2fshJHcu2abAAkZKT46o= sha512-y8vTo00oRkzQTgufeotjCLPAvlhnpSkcHFEp60+LJUwygGcd5Chrpn5480AQp/thrxVm8m2ifAk0LyFel9oCnw==" + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + +"@vue/babel-sugar-v-model@^1.2.3": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.2.3.tgz#fa1f29ba51ebf0aa1a6c35fa66d539bc459a18f2" + integrity "sha1-+h8pulHr8KoabDX6ZtU5vEWaGPI= sha512-A2jxx87mySr/ulAsSSyYE8un6SIH0NWHiLaCWpodPCVOlQVODCaSpiR4+IMsmBr73haG+oeCuSvMOM+ttWUqRQ==" + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + "@vue/babel-helper-vue-jsx-merge-props" "^1.2.1" + "@vue/babel-plugin-transform-vue-jsx" "^1.2.1" + camelcase "^5.0.0" + html-tags "^2.0.0" + svg-tags "^1.0.0" + +"@vue/babel-sugar-v-on@^1.2.3": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.2.3.tgz#342367178586a69f392f04bfba32021d02913ada" + integrity "sha1-NCNnF4WGpp85LwS/ujICHQKROto= sha512-kt12VJdz/37D3N3eglBywV8GStKNUhNrsxChXIV+o0MwVXORYuhDTHJRKPgLJRb/EY3vM2aRFQdxJBp9CLikjw==" + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + "@vue/babel-plugin-transform-vue-jsx" "^1.2.1" + camelcase "^5.0.0" + +"@vue/cli-overlay@^4.5.15": + version "4.5.15" + resolved "https://registry.yarnpkg.com/@vue/cli-overlay/-/cli-overlay-4.5.15.tgz#0700fd6bad39336d4189ba3ff7d25e638e818c9c" + integrity "sha1-BwD9a605M21Bibo/99JeY46BjJw= sha512-0zI0kANAVmjFO2LWGUIzdGPMeE3+9k+KeRDXsUqB30YfRF7abjfiiRPq5BU9pOzlJbVdpRkisschBrvdJqDuDg==" + +"@vue/cli-plugin-babel@^4.5.12": + version "4.5.15" + resolved "https://registry.yarnpkg.com/@vue/cli-plugin-babel/-/cli-plugin-babel-4.5.15.tgz#ae4fb2ed54255fe3d84df381dab68509641179ed" + integrity "sha1-rk+y7VQlX+PYTfOB2raFCWQRee0= sha512-hBLrwYfFkHldEe34op/YNgPhpOWI5n5DB2Qt9I/1Epeif4M4iFaayrgjvOR9AVM6WbD3Yx7WCFszYpWrQZpBzQ==" + dependencies: + "@babel/core" "^7.11.0" + "@vue/babel-preset-app" "^4.5.15" + "@vue/cli-shared-utils" "^4.5.15" + babel-loader "^8.1.0" + cache-loader "^4.1.0" + thread-loader "^2.1.3" + webpack "^4.0.0" + +"@vue/cli-plugin-eslint@^4.5.12": + version "4.5.15" + resolved "https://registry.yarnpkg.com/@vue/cli-plugin-eslint/-/cli-plugin-eslint-4.5.15.tgz#5781824a941f34c26336a67b1f6584a06c6a24ff" + integrity "sha1-V4GCSpQfNMJjNqZ7H2WEoGxqJP8= sha512-/2Fl6wY/5bz3HD035oSnFRMsKNxDxU396KqBdpCQdwdvqk4mm6JAbXqihpcBRTNPeTO6w+LwGe6FE56PVbJdbg==" + dependencies: + "@vue/cli-shared-utils" "^4.5.15" + eslint-loader "^2.2.1" + globby "^9.2.0" + inquirer "^7.1.0" + webpack "^4.0.0" + yorkie "^2.0.0" + +"@vue/cli-plugin-pwa@^4.5.12": + version "4.5.15" + resolved "https://registry.yarnpkg.com/@vue/cli-plugin-pwa/-/cli-plugin-pwa-4.5.15.tgz#eb800c418d96b496deec9d063a1798fe6e9c2db8" + integrity "sha1-64AMQY2WtJbe7J0GOheY/m6cLbg= sha512-yQzsspaIkjeQyN6btF8ATgbJFU023q1HC8uUpmiBa4QE9EyBlR8fSrKFhcJ0EmT6KnU7PMwlnOJ/OqjguFnufA==" + dependencies: + "@vue/cli-shared-utils" "^4.5.15" + webpack "^4.0.0" + workbox-webpack-plugin "^4.3.1" + +"@vue/cli-plugin-router@^4.5.12", "@vue/cli-plugin-router@^4.5.15": + version "4.5.15" + resolved "https://registry.yarnpkg.com/@vue/cli-plugin-router/-/cli-plugin-router-4.5.15.tgz#1e75c8c89df42c694f143b9f1028de3cf5d61e1e" + integrity "sha1-HnXIyJ30LGlPFDufECjePPXWHh4= sha512-q7Y6kP9b3k55Ca2j59xJ7XPA6x+iSRB+N4ac0ZbcL1TbInVQ4j5wCzyE+uqid40hLy4fUdlpl4X9fHJEwuVxPA==" + dependencies: + "@vue/cli-shared-utils" "^4.5.15" + +"@vue/cli-plugin-typescript@^4.5.12": + version "4.5.15" + resolved "https://registry.yarnpkg.com/@vue/cli-plugin-typescript/-/cli-plugin-typescript-4.5.15.tgz#14ba0ddcf3b94e73148ff84ac904fbc5346c14d1" + integrity "sha1-FLoN3PO5TnMUj/hKyQT7xTRsFNE= sha512-g2HDBwWBboTzNvVrS+w4Ctl7CCErboTlx7PyQrXgY+7uGdPVUT9PWuv4DjaZhosSk7WI3qSIpruCBIkdHX5bwQ==" + dependencies: + "@types/webpack-env" "^1.15.2" + "@vue/cli-shared-utils" "^4.5.15" + cache-loader "^4.1.0" + fork-ts-checker-webpack-plugin "^3.1.1" + globby "^9.2.0" + thread-loader "^2.1.3" + ts-loader "^6.2.2" + tslint "^5.20.1" + webpack "^4.0.0" + yorkie "^2.0.0" + optionalDependencies: + fork-ts-checker-webpack-plugin-v5 "npm:fork-ts-checker-webpack-plugin@^5.0.11" + +"@vue/cli-plugin-unit-jest@^4.5.12": + version "4.5.15" + resolved "https://registry.yarnpkg.com/@vue/cli-plugin-unit-jest/-/cli-plugin-unit-jest-4.5.15.tgz#7be914ca1507ca344487eb377ed925c9db0b772a" + integrity "sha1-e+kUyhUHyjREh+s3ftklydsLdyo= sha512-oE3RDMerb21P6ALg70Zh2zU+RYYjoe09/7ZXYUj03uTb2obqUbcINpFfeVwM0B/J6H1YmqWJpnNBxWURhrqQHg==" + dependencies: + "@babel/core" "^7.11.0" + "@babel/plugin-transform-modules-commonjs" "^7.9.6" + "@types/jest" "^24.0.19" + "@vue/cli-shared-utils" "^4.5.15" + babel-core "^7.0.0-bridge.0" + babel-jest "^24.9.0" + babel-plugin-transform-es2015-modules-commonjs "^6.26.2" + deepmerge "^4.2.2" + jest "^24.9.0" + jest-environment-jsdom-fifteen "^1.0.2" + jest-serializer-vue "^2.0.2" + jest-transform-stub "^2.0.0" + jest-watch-typeahead "^0.4.2" + ts-jest "^24.2.0" + vue-jest "^3.0.5" + +"@vue/cli-plugin-vuex@^4.5.12", "@vue/cli-plugin-vuex@^4.5.15": + version "4.5.15" + resolved "https://registry.yarnpkg.com/@vue/cli-plugin-vuex/-/cli-plugin-vuex-4.5.15.tgz#466c1f02777d02fef53a9bb49a36cc3a3bcfec4e" + integrity "sha1-RmwfAnd9Av71Opu0mjbMOjvP7E4= sha512-fqap+4HN+w+InDxlA3hZTOGE0tzBTgXhKLoDydhywqgmhQ1D9JA6Feh94ze6tG8DsWX58/ujYUqA8jAz17FJtg==" + +"@vue/cli-service@^4.5.12": + version "4.5.15" + resolved "https://registry.yarnpkg.com/@vue/cli-service/-/cli-service-4.5.15.tgz#0e9a186d51550027d0e68e95042077eb4d115b45" + integrity "sha1-DpoYbVFVACfQ5o6VBCB3600RW0U= sha512-sFWnLYVCn4zRfu45IcsIE9eXM0YpDV3S11vlM2/DVbIPAGoYo5ySpSof6aHcIvkeGsIsrHFpPHzNvDZ/efs7jA==" + dependencies: + "@intervolga/optimize-cssnano-plugin" "^1.0.5" + "@soda/friendly-errors-webpack-plugin" "^1.7.1" + "@soda/get-current-script" "^1.0.0" + "@types/minimist" "^1.2.0" + "@types/webpack" "^4.0.0" + "@types/webpack-dev-server" "^3.11.0" + "@vue/cli-overlay" "^4.5.15" + "@vue/cli-plugin-router" "^4.5.15" + "@vue/cli-plugin-vuex" "^4.5.15" + "@vue/cli-shared-utils" "^4.5.15" + "@vue/component-compiler-utils" "^3.1.2" + "@vue/preload-webpack-plugin" "^1.1.0" + "@vue/web-component-wrapper" "^1.2.0" + acorn "^7.4.0" + acorn-walk "^7.1.1" + address "^1.1.2" + autoprefixer "^9.8.6" + browserslist "^4.12.0" + cache-loader "^4.1.0" + case-sensitive-paths-webpack-plugin "^2.3.0" + cli-highlight "^2.1.4" + clipboardy "^2.3.0" + cliui "^6.0.0" + copy-webpack-plugin "^5.1.1" + css-loader "^3.5.3" + cssnano "^4.1.10" + debug "^4.1.1" + default-gateway "^5.0.5" + dotenv "^8.2.0" + dotenv-expand "^5.1.0" + file-loader "^4.2.0" + fs-extra "^7.0.1" + globby "^9.2.0" + hash-sum "^2.0.0" + html-webpack-plugin "^3.2.0" + launch-editor-middleware "^2.2.1" + lodash.defaultsdeep "^4.6.1" + lodash.mapvalues "^4.6.0" + lodash.transform "^4.6.0" + mini-css-extract-plugin "^0.9.0" + minimist "^1.2.5" + pnp-webpack-plugin "^1.6.4" + portfinder "^1.0.26" + postcss-loader "^3.0.0" + ssri "^8.0.1" + terser-webpack-plugin "^1.4.4" + thread-loader "^2.1.3" + url-loader "^2.2.0" + vue-loader "^15.9.2" + vue-style-loader "^4.1.2" + webpack "^4.0.0" + webpack-bundle-analyzer "^3.8.0" + webpack-chain "^6.4.0" + webpack-dev-server "^3.11.0" + webpack-merge "^4.2.2" + optionalDependencies: + vue-loader-v16 "npm:vue-loader@^16.1.0" + +"@vue/cli-shared-utils@^4.5.15": + version "4.5.15" + resolved "https://registry.yarnpkg.com/@vue/cli-shared-utils/-/cli-shared-utils-4.5.15.tgz#dba3858165dbe3465755f256a4890e69084532d6" + integrity "sha1-26OFgWXb40ZXVfJWpIkOaQhFMtY= sha512-SKaej9hHzzjKSOw1NlFmc6BSE0vcqUQMQiv1cxQ2DhVyy4QxZXBmzmiLBUBe+hYZZs1neXW7n//udeN9bCAY+Q==" + dependencies: + "@hapi/joi" "^15.0.1" + chalk "^2.4.2" + execa "^1.0.0" + launch-editor "^2.2.1" + lru-cache "^5.1.1" + node-ipc "^9.1.1" + open "^6.3.0" + ora "^3.4.0" + read-pkg "^5.1.1" + request "^2.88.2" + semver "^6.1.0" + strip-ansi "^6.0.0" + +"@vue/compiler-core@3.2.21": + version "3.2.21" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.21.tgz#26566c32b2ad838199d471ef5df620a83846f24e" + integrity "sha1-JlZsMrKtg4GZ1HHvXfYgqDhG8k4= sha512-NhhiQZNG71KNq1h5pMW/fAXdTF7lJRaSI7LDm2edhHXVz1ROMICo8SreUmQnSf4Fet0UPBVqJ988eF4+936iDQ==" + dependencies: + "@babel/parser" "^7.15.0" + "@vue/shared" "3.2.21" + estree-walker "^2.0.2" + source-map "^0.6.1" + +"@vue/compiler-dom@3.2.21": + version "3.2.21" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.21.tgz#d6f6c85364ef8888f9c4e9122bfba11e78fb398c" + integrity "sha1-1vbIU2TviIj5xOkSK/uhHnj7OYw= sha512-gsJD3DpYZSYquiA7UIPsMDSlAooYWDvHPq9VRsqzJEk2PZtFvLvHPb4aaMD8Ufd62xzYn32cnnkzsEOJhyGilA==" + dependencies: + "@vue/compiler-core" "3.2.21" + "@vue/shared" "3.2.21" + +"@vue/compiler-sfc@^3.1.2": + version "3.2.21" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.21.tgz#42639ee49e725afb7d8f1d1940e75dc17a56002c" + integrity "sha1-QmOe5J5yWvt9jx0ZQOddwXpWACw= sha512-+yDlUSebKpz/ovxM2vLRRx7w/gVfY767pOfYTgbIhAs+ogvIV2BsIt4fpxlThnlCNChJ+yE0ERUNoROv2kEGEQ==" + dependencies: + "@babel/parser" "^7.15.0" + "@vue/compiler-core" "3.2.21" + "@vue/compiler-dom" "3.2.21" + "@vue/compiler-ssr" "3.2.21" + "@vue/ref-transform" "3.2.21" + "@vue/shared" "3.2.21" + estree-walker "^2.0.2" + magic-string "^0.25.7" + postcss "^8.1.10" + source-map "^0.6.1" + +"@vue/compiler-ssr@3.2.21": + version "3.2.21" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.21.tgz#37d124f89e8adef9fd56b85775de4b5310a0436e" + integrity "sha1-N9Ek+J6K3vn9VrhXdd5LUxCgQ24= sha512-eU+A0iWYy+1zAo2CRIJ0zSVlv1iuGAIbNRCnllSJ31pV1lX3jypJYzGbJlSRAbB7VP6E+tYveVT1Oq8JKewa3g==" + dependencies: + "@vue/compiler-dom" "3.2.21" + "@vue/shared" "3.2.21" + +"@vue/component-compiler-utils@^3.1.0", "@vue/component-compiler-utils@^3.1.2": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-3.3.0.tgz#f9f5fb53464b0c37b2c8d2f3fbfe44df60f61dc9" + integrity "sha1-+fX7U0ZLDDeyyNLz+/5E32D2Hck= sha512-97sfH2mYNU+2PzGrmK2haqffDpVASuib9/w2/noxiFi31Z54hW+q3izKQXXQZSNhtiUpAI36uSuYepeBe4wpHQ==" + dependencies: + consolidate "^0.15.1" + hash-sum "^1.0.2" + lru-cache "^4.1.2" + merge-source-map "^1.1.0" + postcss "^7.0.36" + postcss-selector-parser "^6.0.2" + source-map "~0.6.1" + vue-template-es2015-compiler "^1.9.0" + optionalDependencies: + prettier "^1.18.2 || ^2.0.0" + +"@vue/eslint-config-typescript@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@vue/eslint-config-typescript/-/eslint-config-typescript-7.0.0.tgz#220c70c2edf7a253e739298525f4d401b8ef0038" + integrity "sha1-Igxwwu33olPnOSmFJfTUAbjvADg= sha512-UxUlvpSrFOoF8aQ+zX1leYiEBEm7CZmXYn/ZEM1zwSadUzpamx56RB4+Htdjisv1mX2tOjBegNUqH3kz2OL+Aw==" + dependencies: + vue-eslint-parser "^7.0.0" + +"@vue/preload-webpack-plugin@^1.1.0": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.2.tgz#ceb924b4ecb3b9c43871c7a429a02f8423e621ab" + integrity "sha1-zrkktOyzucQ4ccekKaAvhCPmIas= sha512-LIZMuJk38pk9U9Ur4YzHjlIyMuxPlACdBIHH9/nGYVTsaGKOSnSuELiE8vS9wa+dJpIYspYUOqk+L1Q4pgHQHQ==" + +"@vue/ref-transform@3.2.21": + version "3.2.21" + resolved "https://registry.yarnpkg.com/@vue/ref-transform/-/ref-transform-3.2.21.tgz#b0c554c9f640c3f005f77e676066aa0faba90984" + integrity "sha1-sMVUyfZAw/AF935nYGaqD6upCYQ= sha512-uiEWWBsrGeun9O7dQExYWzXO3rHm/YdtFNXDVqCSoPypzOVxWxdiL+8hHeWzxMB58fVuV2sT80aUtIVyaBVZgQ==" + dependencies: + "@babel/parser" "^7.15.0" + "@vue/compiler-core" "3.2.21" + "@vue/shared" "3.2.21" + estree-walker "^2.0.2" + magic-string "^0.25.7" + +"@vue/shared@3.2.21": + version "3.2.21" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.21.tgz#4cd80c0e62cf65a7adab2449e86b6f0cb33a130b" + integrity "sha1-TNgMDmLPZaetqyRJ6GtvDLM6Ews= sha512-5EQmIPK6gw4UVYUbM959B0uPsJ58+xoMESCZs3N89XyvJ9e+fX4pqEPrOGV8OroIk3SbEvJcC+eYc8BH9JQrHA==" + +"@vue/test-utils@^1.1.0", "@vue/test-utils@^1.2.0": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-1.2.2.tgz#0242ea4e202d4853541bb167fead3f2249140ab7" + integrity "sha1-AkLqTiAtSFNUG7Fn/q0/IkkUCrc= sha512-P+yiAsszoy8z1TqXiVUnAZaJj0WGGz5fCxm4bOSI6Cpwy1+PNYwYxDv0ROAA/SUtOPppV+aD8tp/QWwxf8ROJw==" + dependencies: + dom-event-types "^1.0.0" + lodash "^4.17.15" + pretty "^2.0.0" + +"@vue/web-component-wrapper@^1.2.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@vue/web-component-wrapper/-/web-component-wrapper-1.3.0.tgz#b6b40a7625429d2bd7c2281ddba601ed05dc7f1a" + integrity "sha1-trQKdiVCnSvXwigd26YB7QXcfxo= sha512-Iu8Tbg3f+emIIMmI2ycSI8QcEuAUgPTgHwesDU1eKMLE4YC/c/sFbGc70QgMq31ijRftV0R7vCm9co6rldCeOA==" + +"@webassemblyjs/ast@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + integrity "sha1-vYUGBLQEJFmlpBzX0zjL7Wle2WQ= sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==" + dependencies: + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + +"@webassemblyjs/floating-point-hex-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + integrity "sha1-PD07Jxvd/ITesA9xNEQ4MR1S/7Q= sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==" + +"@webassemblyjs/helper-api-error@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + integrity "sha1-ID9nbjM7lsnaLuqzzO8zxFkotqI= sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==" + +"@webassemblyjs/helper-buffer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + integrity "sha1-oUQtJpxf6yP8vJ73WdrDVH8p3gA= sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==" + +"@webassemblyjs/helper-code-frame@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + integrity "sha1-ZH+Iks0gQ6gqwMjF51w28dkVnyc= sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==" + dependencies: + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/helper-fsm@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + integrity "sha1-wFJWtxJEIUZx9LCOwQitY7cO3bg= sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==" + +"@webassemblyjs/helper-module-context@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + integrity "sha1-JdiIS3aDmHGgimxvgGw5ee9xLwc= sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==" + dependencies: + "@webassemblyjs/ast" "1.9.0" + +"@webassemblyjs/helper-wasm-bytecode@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + integrity "sha1-T+2L6sm4wU+MWLcNEk1UndH+V5A= sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==" + +"@webassemblyjs/helper-wasm-section@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + integrity "sha1-WkE41aYpK6GLBMWuSXF+QWeWU0Y= sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==" + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + +"@webassemblyjs/ieee754@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + integrity "sha1-Fceg+6roP7JhQ7us9tbfFwKtOeQ= sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==" + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + integrity "sha1-8Zygt2ptxVYjoJz/p2noOPoeHJU= sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==" + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + integrity "sha1-BNM7Y2945qaBMifoJAL3Y3tiKas= sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==" + +"@webassemblyjs/wasm-edit@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + integrity "sha1-P+bXnT8PkiGDqoYALELdJWz+6c8= sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==" + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/helper-wasm-section" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-opt" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/wasm-gen@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + integrity "sha1-ULxw7Gje2OJ2OwGhQYv0NJGnpJw= sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==" + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wasm-opt@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + integrity "sha1-IhEYHlsxMmRDzIES658LkChyGmE= sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==" + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + +"@webassemblyjs/wasm-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + integrity "sha1-nUjkSCbfSmWYKUqmyHRp1kL/9l4= sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==" + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wast-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + integrity "sha1-MDERXXmsW9JhVWzsw/qQo+9FGRQ= sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==" + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/floating-point-hex-parser" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-code-frame" "1.9.0" + "@webassemblyjs/helper-fsm" "1.9.0" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/wast-printer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + integrity "sha1-STXVTIX+9jewDOn1I3dFHQDUeJk= sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==" + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity "sha1-7vAUoxRa5Hehy8AM0eVSM23Ot5A= sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity "sha1-0pHGpOl5ibXGHZrPOWrk/hM6cY0= sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + +abab@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" + integrity "sha1-wLZ4+zLWD8EhnHhNaoJv44Wut5o= sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg= sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + +abortcontroller-polyfill@^1.4.0: + version "1.7.3" + resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.3.tgz#1b5b487bd6436b5b764fd52a612509702c3144b5" + integrity "sha1-G1tIe9ZDa1t2T9UqYSUJcCwxRLU= sha512-zetDJxd89y3X99Kvo4qFx8GKlt6GsvN3UcRZHwU6iFA/0KiOmhkTVhe8oRoTBiTVPZu09x3vCra47+w8Yz1+2Q==" + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity "sha1-UxvHJlF6OytB+FACHGzBXqq1B80= sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==" + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn-globals@^4.1.0, acorn-globals@^4.3.2: + version "4.3.4" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" + integrity "sha1-n6GSat3BHJcwjE5m163Q1Awycuc= sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==" + dependencies: + acorn "^6.0.1" + acorn-walk "^6.0.1" + +acorn-jsx@^5.2.0, acorn-jsx@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity "sha1-ftW7VZCLOy8bxVxq8WU7rafweTc= sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==" + +acorn-walk@^6.0.1: + version "6.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" + integrity "sha1-Ejy487hMIXHx9/slJhWxx4prGow= sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==" + +acorn-walk@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity "sha1-DeiJpgEgOQmw++B7iTjcIdLpZ7w= sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" + +acorn@^5.5.3: + version "5.7.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" + integrity "sha1-Po2KmUfQWZoXltECJddDL0pKz14= sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==" + +acorn@^6.0.1, acorn@^6.4.1: + version "6.4.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" + integrity "sha1-NYZv1xBSjpLeEM8GAWSY5H454eY= sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==" + +acorn@^7.1.0, acorn@^7.1.1, acorn@^7.4.0: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo= sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + +add-dom-event-listener@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/add-dom-event-listener/-/add-dom-event-listener-1.1.0.tgz#6a92db3a0dd0abc254e095c0f1dc14acbbaae310" + integrity "sha1-apLbOg3Qq8JU4JXA8dwUrLuq4xA= sha512-WCxx1ixHT0GQU9hb0KI/mhgRQhnU+U3GvwY6ZvVjYq8rsihIGoaIOUbY0yMPBxLH5MDtr0kz3fisWGNcbWW7Jw==" + dependencies: + object-assign "4.x" + +address@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" + integrity "sha1-vxEWycdYxRt6kz0pa3LCIe2UKLY= sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==" + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity "sha1-81mGrOuRr63sQQL72FAUlQzvpk0= sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==" + +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity "sha1-MfKdpatuANHC0yms97WSlhTVAU0= sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" + +ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.12.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity "sha1-uvWmLoArB9l3A0WG+MO69a3ybfQ= sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==" + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.1, ajv@^8.6.3: + version "8.6.3" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.3.tgz#11a66527761dc3e9a3845ea775d2d3c0414e8764" + integrity "sha1-EaZlJ3Ydw+mjhF6nddLTwEFOh2Q= sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==" + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +alphanum-sort@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" + integrity "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= sha512-0FcBfdcmaumGPQ0qPn7Q5qTgz/ooXgIyp1rf8ik5bGX8mpE2YHjC0P/eyQvxu1GURYQgq9ozf2mteQ5ZD9YiyQ==" + +ansi-colors@^3.0.0: + version "3.2.4" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" + integrity "sha1-46PaS/uubIapwoViXeEkojQCb78= sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==" + +ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity "sha1-y7muJWv3UK8eqzRPIpqif+lLo0g= sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" + +ansi-escapes@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity "sha1-h4C5j/nb9WOBUtHx/lwde0RCl2s= sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" + +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity "sha1-ayKR0dt9mLZSHV8e+kLQ86n+tl4= sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==" + dependencies: + type-fest "^0.21.3" + +ansi-html@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + integrity "sha1-gTWEAhliqenm/QOflA0S9WynhZ4= sha512-JoAxEa1DfP9m2xfB/y2r/aKcwXNlltr4+0QSBC4TrLfcxyvepX2Pv0t/xpgGV5bGsDzCYV8SzjWgyCW0T9yYbA==" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity "sha1-w7M6te42DYbg5ijwRorn7yfWVN8= sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==" + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= sha512-wFUFA5bg5dviipbQQ32yOQhl6gcJaJXiHE7dvR8VYPG97+J/GNC5FKGepKdEDUFeXRzDxPF1X/Btc8L+v7oqIQ==" + +ansi-regex@^4.0.0, ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc= sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + +ansi-regex@^5.0.0, ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ= sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==" + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0= sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==" + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity "sha1-7dgDYornHATIWuegkG7a00tkiTc= sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==" + dependencies: + color-convert "^2.0.1" + +ant-design-vue@^1.7.2, ant-design-vue@^1.7.8: + version "1.7.8" + resolved "https://registry.yarnpkg.com/ant-design-vue/-/ant-design-vue-1.7.8.tgz#1abbf86b68a4f5b1000bea0487b8031dc0001661" + integrity "sha1-Grv4a2ik9bEAC+oEh7gDHcAAFmE= sha512-F1hmiS9vwbyfuFvlamdW5l9bHKqRlj9wHaGDIE41NZMWXyWy8qL0UFa/+I0Wl8gQWZCqODW5pN6Yfoyn85At3A==" + dependencies: + "@ant-design/icons" "^2.1.1" + "@ant-design/icons-vue" "^2.0.0" + "@simonwep/pickr" "~1.7.0" + add-dom-event-listener "^1.0.2" + array-tree-filter "^2.1.0" + async-validator "^3.0.3" + babel-helper-vue-jsx-merge-props "^2.0.3" + babel-runtime "6.x" + classnames "^2.2.5" + component-classes "^1.2.6" + dom-align "^1.10.4" + dom-closest "^0.2.0" + dom-scroll-into-view "^2.0.0" + enquire.js "^2.1.6" + intersperse "^1.0.0" + is-mobile "^2.2.1" + is-negative-zero "^2.0.0" + ismobilejs "^1.0.0" + json2mq "^0.2.0" + lodash "^4.17.5" + moment "^2.21.0" + mutationobserver-shim "^0.3.2" + node-emoji "^1.10.0" + omit.js "^1.0.0" + raf "^3.4.0" + resize-observer-polyfill "^1.5.1" + shallow-equal "^1.0.0" + shallowequal "^1.0.2" + vue-ref "^2.0.0" + warning "^4.0.0" + +antlr4@^4.9.2: + version "4.9.2" + resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.9.2.tgz#abbc53d275954b1b6f4d8b3468b4a2cb258121fc" + integrity "sha1-q7xT0nWVSxtvTYs0aLSiyyWBIfw= sha512-UjMSlenUORL+a+6g4RNZxRh5LcFWybRi2g0ASDBpgXBY6nlavg0BRVAVEQF0dz8jH6SyX3lV7uP5y/krJzc+Hw==" + +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity "sha1-q8av7tzqUugJzcA3au0845Y10X8= sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity "sha1-vLJLTzeTTZqnrBe0ra+J58du8us= sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==" + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +anymatch@^3.0.0, anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity "sha1-wFV8CWrzLxBhmPT04qODU343hxY= sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==" + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity "sha1-aALmJk79GMeQobDVF/DyYnvyyUo= sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + +arch@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" + integrity "sha1-G8R4GPMFdk8jqzMGsL/AhsWinRE= sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==" + +argparse@^1.0.10, argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity "sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE= sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==" + dependencies: + sprintf-js "~1.0.2" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity "sha1-JG9Q88p4oyQPbJl+ipvR6sSeSzg= sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + +aria-query@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" + integrity "sha1-DSymyazrVriXfp/tau1+FbvS+Ds= sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==" + dependencies: + "@babel/runtime" "^7.10.2" + "@babel/runtime-corejs3" "^7.10.2" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==" + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE= sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==" + +array-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + integrity "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= sha512-H3LU5RLiSsGXPhN+Nipar0iR0IofH+8r89G2y1tBKxQ/agagKyAjhkAFDRBfodP2caPrNKHpAWNIM/c9yeL7uA==" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + +array-flatten@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity "sha1-JO+AoowaiTYX4hSbDG0NeIKTsJk= sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" + +array-tree-filter@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-tree-filter/-/array-tree-filter-2.1.0.tgz#873ac00fec83749f255ac8dd083814b4f6329190" + integrity "sha1-hzrAD+yDdJ8lWsjdCDgUtPYykZA= sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==" + +array-union@^1.0.1, array-union@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==" + dependencies: + array-uniq "^1.0.1" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity "sha1-t5hCCtvrHego2ErNii4j0+/oXo0= sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==" + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==" + +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + +asn1.js@^5.2.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + integrity "sha1-EamAuE67kXgc41sP3C7ilON4Pwc= sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==" + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" + +asn1@~0.2.3: + version "0.2.6" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity "sha1-DTp7tuZOAqkMAwOzHykoaOoJoI0= sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==" + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" + +assert@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity "sha1-VcEJqvbgrv2z3EtxJAxwv1dLGOs= sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==" + dependencies: + object-assign "^4.1.1" + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==" + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity "sha1-bIw/uCfdQ+45GPJ7gngqt2WKb9k= sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity "sha1-SDFDxWeu7UeFdZwIZXhtx319LjE= sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity "sha1-tyfb+H12UWAvBvTUrDh/R9kbDL8= sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity "sha1-3TeelPDbgxCwgpH51kwyCXZmF/0= sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + +async-validator@^3.0.3: + version "3.5.2" + resolved "https://registry.yarnpkg.com/async-validator/-/async-validator-3.5.2.tgz#68e866a96824e8b2694ff7a831c1a25c44d5e500" + integrity "sha1-aOhmqWgk6LJpT/eoMcGiXETV5QA= sha512-8eLCg00W9pIRZSB781UUX/H6Oskmm8xloZfr09lz5bikRpBVDlJ3hRVuxxP1SxcwsEYfJ4IU8Q19Y8/893r3rQ==" + +async@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity "sha1-1yYl4jRKNlbjo61Pp0n6gymdgv8= sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==" + dependencies: + lodash "^4.17.14" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity "sha1-x57Zf380y48robyXkLzDZkdLS3k= sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity "sha1-YCzUtG6EStTv/JKoARo8RuAjjcI= sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity "sha1-bZUX654DDSQ2ZmZR6GvZ9vE1M8k= sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + +autolinker@^3.11.0: + version "3.14.3" + resolved "https://registry.yarnpkg.com/autolinker/-/autolinker-3.14.3.tgz#c61c424bc6077bcf2fc62803803ec2f58e15a7ec" + integrity "sha1-xhxCS8YHe88vxigDgD7C9Y4Vp+w= sha512-t81i2bCpS+s+5FIhatoww9DmpjhbdiimuU9ATEuLxtZMQ7jLv9fyFn7SWNG8IkEfD4AmYyirL1ss9k1aqVWRvg==" + dependencies: + tslib "^1.9.3" + +autoprefixer@^9.8.6: + version "9.8.8" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.8.tgz#fd4bd4595385fa6f06599de749a4d5f7a474957a" + integrity "sha1-/UvUWVOF+m8GWZ3nSaTV96R0lXo= sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==" + dependencies: + browserslist "^4.12.0" + caniuse-lite "^1.0.30001109" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + picocolors "^0.2.1" + postcss "^7.0.32" + postcss-value-parser "^4.1.0" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==" + +aws4@^1.8.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + integrity "sha1-1h9G2DslGSUOJ4Ta9bCUeai0HFk= sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + +axios@^0.21.1: + version "0.21.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" + integrity "sha1-xnuQ3AVo5cHPKwuFjEO6KOLtpXU= sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==" + dependencies: + follow-redirects "^1.14.0" + +babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==" + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^7.0.0-bridge.0: + version "7.0.0-bridge.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" + integrity "sha1-laSS3dkPm06aSh2hTrM1uHtjTs4= sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==" + +babel-eslint@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232" + integrity "sha1-aWjlaKkQt4+zd5zdi2rC9HmUMjI= sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==" + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.7.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" + eslint-visitor-keys "^1.0.0" + resolve "^1.12.0" + +babel-extract-comments@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz#0a2aedf81417ed391b85e18b4614e693a0351a21" + integrity "sha1-Cirt+BQX7TkbheGLRhTmk6A1GiE= sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ==" + dependencies: + babylon "^6.18.0" + +babel-helper-vue-jsx-merge-props@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz#22aebd3b33902328e513293a8e4992b384f9f1b6" + integrity "sha1-Iq69OzOQIyjlEyk6jkmSs4T58bY= sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg==" + +babel-jest@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.9.0.tgz#3fc327cb8467b89d14d7bc70e315104a783ccd54" + integrity "sha1-P8Mny4RnuJ0U17xw4xUQSng8zVQ= sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==" + dependencies: + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/babel__core" "^7.1.0" + babel-plugin-istanbul "^5.1.0" + babel-preset-jest "^24.9.0" + chalk "^2.4.2" + slash "^2.0.0" + +babel-loader@^8.1.0: + version "8.2.3" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.3.tgz#8986b40f1a64cacfcb4b8429320085ef68b1342d" + integrity "sha1-iYa0Dxpkys/LS4QpMgCF72ixNC0= sha512-n4Zeta8NC3QAsuyiizu0GkmRcQ6clkV9WFUnUf1iXP//IeSKbWjofW3UHyZVwlOB4y039YQKefawyTn64Zwbuw==" + dependencies: + find-cache-dir "^3.3.1" + loader-utils "^1.4.0" + make-dir "^3.1.0" + schema-utils "^2.6.5" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity "sha1-hP2hnJduxcbe/vV/lCez3vZuF6M= sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==" + dependencies: + object.assign "^4.1.0" + +babel-plugin-istanbul@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz#df4ade83d897a92df069c4d9a25cf2671293c854" + integrity "sha1-30reg9iXqS3wacTZolzyZxKTyFQ= sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + find-up "^3.0.0" + istanbul-lib-instrument "^3.3.0" + test-exclude "^5.2.3" + +babel-plugin-jest-hoist@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz#4f837091eb407e01447c8843cbec546d0002d756" + integrity "sha1-T4NwketAfgFEfIhDy+xUbQAC11Y= sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==" + dependencies: + "@types/babel__traverse" "^7.0.6" + +babel-plugin-polyfill-corejs2@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.3.tgz#6ed8e30981b062f8fe6aca8873a37ebcc8cc1c0f" + integrity "sha1-btjjCYGwYvj+asqIc6N+vMjMHA8= sha512-NDZ0auNRzmAfE1oDDPW2JhzIMXUk+FFe2ICejmt5T4ocKgiQx3e0VCRx9NCAidcMtL2RUZaWtXnmjTCkx0tcbA==" + dependencies: + "@babel/compat-data" "^7.13.11" + "@babel/helper-define-polyfill-provider" "^0.2.4" + semver "^6.1.1" + +babel-plugin-polyfill-corejs3@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.3.0.tgz#fa7ca3d1ee9ddc6193600ffb632c9785d54918af" + integrity "sha1-+nyj0e6d3GGTYA/7YyyXhdVJGK8= sha512-JLwi9vloVdXLjzACL80j24bG6/T1gYxwowG44dg6HN/7aTPdyPbJJidf6ajoA3RPHHtW0j9KMrSOLpIZpAnPpg==" + dependencies: + "@babel/helper-define-polyfill-provider" "^0.2.4" + core-js-compat "^3.18.0" + +babel-plugin-polyfill-regenerator@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.3.tgz#2e9808f5027c4336c994992b48a4262580cb8d6d" + integrity "sha1-LpgI9QJ8QzbJlJkrSKQmJYDLjW0= sha512-JVE78oRZPKFIeUqFGrSORNzQnrDwZR16oiWeGM8ZyjBn2XAT5OjP+wXx5ESuo33nUsFUEJYjtklnsKbxW5L+7g==" + dependencies: + "@babel/helper-define-polyfill-provider" "^0.2.4" + +babel-plugin-syntax-object-rest-spread@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + integrity "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U= sha512-C4Aq+GaAj83pRQ0EFgTvw5YO6T3Qz2KGrNRwIj9mSoNHVvdZY4KO2uA6HNtNXCw993iSZnckY1aLW8nOi8i4+w==" + +babel-plugin-transform-es2015-modules-commonjs@^6.26.0, babel-plugin-transform-es2015-modules-commonjs@^6.26.2: + version "6.26.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" + integrity "sha1-WKeThjqefKhwvcWogRF/+sJ9tvM= sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==" + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-object-rest-spread@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" + integrity "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY= sha512-ocgA9VJvyxwt+qJB0ncxV8kb/CjfTcECUY4tQ5VT7nP6Aohzobm8CDFaQ5FHdvZQzLmf0sgDxB8iRXZXxwZcyA==" + dependencies: + babel-plugin-syntax-object-rest-spread "^6.8.0" + babel-runtime "^6.26.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + integrity "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g= sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw==" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-preset-jest@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz#192b521e2217fb1d1f67cf73f70c336650ad3cdc" + integrity "sha1-GStSHiIX+x0fZ89z9wwzZlCtPNw= sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==" + dependencies: + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + babel-plugin-jest-hoist "^24.9.0" + +babel-runtime@6.x, babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity "sha1-llxwWGaOgrVde/4E/yM3vItWR/4= sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + integrity "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==" + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + integrity "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==" + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + integrity "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==" + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity "sha1-ry87iPpvXB5MY00aD46sT1WzleM= sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity "sha1-6D46fj8wCzTLnYf2FfoMvzV2kO4= sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + +base64-js@^1.0.2, base64-js@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity "sha1-GxtEAWClv3rUC2UPCVljSBkDkwo= sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity "sha1-e95c7RRbbVUakNuH+DxVi060io8= sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==" + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==" + dependencies: + tweetnacl "^0.14.3" + +bfj@^6.1.1: + version "6.1.2" + resolved "https://registry.yarnpkg.com/bfj/-/bfj-6.1.2.tgz#325c861a822bcb358a41c78a33b8e6e2086dde7f" + integrity "sha1-MlyGGoIryzWKQceKM7jm4ght3n8= sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw==" + dependencies: + bluebird "^3.5.5" + check-types "^8.0.3" + hoopy "^0.1.4" + tryer "^1.0.1" + +big.js@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + integrity "sha1-pfwpi4G54Nyi5FiCR4S2XFK6WI4= sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==" + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity "sha1-ZfCvOC9Xi83HQr2cKB6cstd2gyg= sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity "sha1-WYr+VHVbKGilMw0q/51Ou1Mgm2U= sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity "sha1-dfUC7q+f/eQvyYgpZFvk6na9ni0= sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity "sha1-EDU8npRTNLwFEabZCzj7x8nFBN8= sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==" + dependencies: + file-uri-to-path "1.0.0" + +bluebird@^3.1.1, bluebird@^3.5.5: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity "sha1-nyKcFb4nJFT/qXOs4NvueaGww28= sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity "sha1-d1s/J477uXGO7HNh9IP7Nvu/6og= sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + +bn.js@^5.0.0, bn.js@^5.1.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" + integrity "sha1-NYhgZ0OWxpl3canQUfzBtX1K4AI= sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + +body-parser@1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity "sha1-lrJwnlfJxOCab9Zqj9l5hE9p8Io= sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==" + dependencies: + bytes "3.1.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.7.2" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.7.0" + raw-body "2.4.0" + type-is "~1.6.17" + +bonjour@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + integrity "sha1-jokKGD2O6aI5OzhExpGkK897yfU= sha512-RaVTblr+OnEli0r/ud8InrU7D+G0y6aJhlxaLa6Pwty4+xoxboF1BsUI45tujvRpbj9dQVoglChqonGAsjEBYg==" + dependencies: + array-flatten "^2.1.0" + deep-equal "^1.0.1" + dns-equal "^1.0.0" + dns-txt "^2.0.2" + multicast-dns "^6.0.1" + multicast-dns-service-types "^1.1.0" + +boolbase@^1.0.0, boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity "sha1-aN/1++YMUes3cl6p4+0xDcwed24= sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0= sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk= sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==" + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@^3.0.1, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity "sha1-NFThpGLujVmeI23zNs2epPiv4Qc= sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==" + dependencies: + fill-range "^7.0.1" + +brorand@^1.0.1, brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity "sha1-PJtLfXgsgSHlbxAQbYTA0P/JRiY= sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" + +browser-resolve@^1.11.3: + version "1.11.3" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" + integrity "sha1-m3y7PQ9RDky4a9vXlhJNKLWJCvY= sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==" + dependencies: + resolve "1.1.7" + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity "sha1-Mmc0ZC9APavDADIJhTu3CtQo70g= sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==" + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity "sha1-jWR0wbhwv9q807z8wZNKEOlPFfA= sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==" + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity "sha1-OvTx9Zg5QDVy8cZiBDdfen9wPpw= sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==" + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity "sha1-sv0Gtbda4pf3zi3GUfkY9b4VjI0= sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==" + dependencies: + bn.js "^5.0.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" + integrity "sha1-6vSt1G3VS+O7OzbAzxWrvrp5VsM= sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==" + dependencies: + bn.js "^5.1.1" + browserify-rsa "^4.0.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.3" + inherits "^2.0.4" + parse-asn1 "^5.1.5" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity "sha1-KGlFnZqjviRf6P4sofRuLn9U1z8= sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==" + dependencies: + pako "~1.0.5" + +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.16.6, browserslist@^4.17.6: + version "4.17.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.17.6.tgz#c76be33e7786b497f66cad25a73756c8b938985d" + integrity "sha1-x2vjPneGtJf2bK0lpzdWyLk4mF0= sha512-uPgz3vyRTlEiCv4ee9KlsKgo2V6qPk7Jsn0KAn2OBqbqKo3iNcPEC1Ti6J4dwnz+aIRfEEEuOzC9IBk8tXUomw==" + dependencies: + caniuse-lite "^1.0.30001274" + electron-to-chromium "^1.3.886" + escalade "^3.1.1" + node-releases "^2.0.1" + picocolors "^1.0.0" + +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity "sha1-6302UwenLPl0zGzadraDVK0za9g= sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==" + dependencies: + fast-json-stable-stringify "2.x" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity "sha1-5nh9og7OnQeZhTPP2d5vXDj0vAU= sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==" + dependencies: + node-int64 "^0.4.0" + +btoa@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73" + integrity "sha1-AamQn4ssk/a/aAuiYTHrMPf6PXM= sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==" + +buffer-from@1.x, buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity "sha1-KxRqb9cugLT1XSVfNe1Zo6mkG9U= sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + +buffer-from@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-0.1.2.tgz#15f4b9bcef012044df31142c14333caf6e0260d0" + integrity "sha1-FfS5vO8BIETfMRQsFDM8r24CYNA= sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg==" + +buffer-indexof@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + integrity "sha1-Uvq8xqYG0aADAoAmSO9o9jnaJow= sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==" + +buffer-json@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/buffer-json/-/buffer-json-2.0.0.tgz#f73e13b1e42f196fe2fd67d001c7d7107edd7c23" + integrity "sha1-9z4TseQvGW/i/WfQAcfXEH7dfCM= sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw==" + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" + +buffer@^4.3.0: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity "sha1-Iw6tNEACmIZEhBqwJEr4xEu+Pvg= sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +builtin-modules@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + integrity "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==" + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==" + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity "sha1-9s95M6Ng4FiPqf3oVlHNx/gF0fY= sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + +cacache@^12.0.2, cacache@^12.0.3: + version "12.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" + integrity "sha1-ZovL0QWutfHZL+JVcOyVJcj6pAw= sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==" + dependencies: + bluebird "^3.5.5" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.4" + graceful-fs "^4.1.15" + infer-owner "^1.0.3" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.3" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity "sha1-Cn9GQWgxyLZi7jb+TnxZ129marI= sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==" + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cache-loader@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cache-loader/-/cache-loader-4.1.0.tgz#9948cae353aec0a1fcb1eafda2300816ec85387e" + integrity "sha1-mUjK41OuwKH8ser9ojAIFuyFOH4= sha512-ftOayxve0PwKzBF/GLsZNC9fJBXl8lkZE3TOsjkboHfVHVkL39iUEs1FO07A33mizmci5Dudt38UZrrYXDtbhw==" + dependencies: + buffer-json "^2.0.0" + find-cache-dir "^3.0.0" + loader-utils "^1.2.3" + mkdirp "^0.5.1" + neo-async "^2.6.1" + schema-utils "^2.0.0" + +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity "sha1-sdTonmiBGcPJqQOtMKuy9qkZvjw= sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==" + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + integrity "sha1-JtII6onje1y95gJQoV8DHBak1ms= sha512-wCyFsDQkKPwwF8BDwOiWNx/9K45L/hvggQiDbve+viMNMQnWhrlYIuBk09offfwCRtCO9P6XwUttufzU11WCVw==" + +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==" + dependencies: + callsites "^2.0.0" + +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==" + dependencies: + caller-callsite "^2.0.0" + +callsite@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" + integrity "sha1-KAOY5dZkvXQDi28JBRU+borxvCA= sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==" + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity "sha1-s2MKvYlDQy9Us/BRkjjjPNffL3M= sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + +camel-case@3.0.x: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" + integrity "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==" + dependencies: + no-case "^2.2.0" + upper-case "^1.1.1" + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==" + +camelcase@^5.0.0, camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity "sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA= sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + +camelcase@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" + integrity "sha1-kkr4gcnVJaydh/QNlk5c6pgqGAk= sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" + +caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + integrity "sha1-Xk2Q4idJYdRikZl99Znj7QCO5MA= sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==" + dependencies: + browserslist "^4.0.0" + caniuse-lite "^1.0.0" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001274: + version "1.0.30001278" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001278.tgz#51cafc858df77d966b17f59b5839250b24417fff" + integrity "sha1-Ucr8hY33fZZrF/WbWDklCyRBf/8= sha512-mpF9KeH8u5cMoEmIic/cr7PNS+F5LWBk0t2ekGT60lFf0Wq+n9LspAj0g3P+o7DQhD3sUdlMln4YFAWhFYn9jg==" + +capture-exit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" + integrity "sha1-+5U7+uvreB9iiYI52rtCbQilCaQ= sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==" + dependencies: + rsvp "^4.8.4" + +case-sensitive-paths-webpack-plugin@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" + integrity "sha1-22QGbGQi7tLgjMFLmGykN5bbxtQ= sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + +chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ= sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==" + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0, chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity "sha1-qsTit3NKdAhnrrFr8CqtVWoeegE= sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==" + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +character-entities-legacy@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" + integrity "sha1-lLwYRdznClu50uzHSHJWYSk9j8E= sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==" + +character-entities@^1.0.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" + integrity "sha1-4Sw5Obfq9OWxXnrUxeKOHUjFsWs= sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==" + +character-reference-invalid@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" + integrity "sha1-CDMpzaDq4nKrPbvzfpo4LBOvFWA= sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity "sha1-kAlISfCTfy7twkJdDSip5fDLrZ4= sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + +chart.js@2: + version "2.9.4" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.9.4.tgz#0827f9563faffb2dc5c06562f8eb10337d5b9684" + integrity "sha1-CCf5Vj+v+y3FwGVi+OsQM31bloQ= sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==" + dependencies: + chartjs-color "^2.1.0" + moment "^2.10.2" + +chartjs-color-string@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz#1df096621c0e70720a64f4135ea171d051402f71" + integrity "sha1-HfCWYhwOcHIKZPQTXqFx0FFAL3E= sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==" + dependencies: + color-name "^1.0.0" + +chartjs-color@^2.1.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chartjs-color/-/chartjs-color-2.4.1.tgz#6118bba202fe1ea79dd7f7c0f9da93467296c3b0" + integrity "sha1-YRi7ogL+Hqed1/fA+dqTRnKWw7A= sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==" + dependencies: + chartjs-color-string "^0.6.0" + color-convert "^1.9.3" + +check-types@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/check-types/-/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552" + integrity "sha1-M1bMoZyIlUTy16le1JzlCKDs9VI= sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ==" + +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.3.0, chokidar@^3.4.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity "sha1-26OXb8rbAW9m/TZQIdkWANAcHnU= sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==" + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chokidar@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity "sha1-gEs6e2qZNYw8XGHnHYco8EHP+Rc= sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==" + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity "sha1-b8nXtC0ypYNZYzdmbn0ICE2izGs= sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity "sha1-EBXs7UdB4V0GZkqVfbv1DQQeJqw= sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" + +ci-info@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" + integrity "sha1-LKINu5zrMtRSSmgzAzE/AwSx5Jc= sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==" + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity "sha1-Z6npZL4xpR4V5QENWObxKDQAL0Y= sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity "sha1-h2Dk7MJy9MNjUy+SbYdKriwTl94= sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity "sha1-+TNprouafOAv1B+q0MqDAzGQxGM= sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==" + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +classnames@^2.2.5, classnames@^2.2.6, classnames@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" + integrity "sha1-38+jiR4wbsHa0QXQ6I9EF7hTXo4= sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" + +clean-css@4.2.x: + version "4.2.4" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.4.tgz#733bf46eba4e607c6891ea57c24a989356831178" + integrity "sha1-czv0brpOYHxokepXwkqYk1aDEXg= sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==" + dependencies: + source-map "~0.6.0" + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==" + dependencies: + restore-cursor "^2.0.0" + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity "sha1-JkMFp65JDR0Dvwybp8kl0XU68wc= sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==" + dependencies: + restore-cursor "^3.1.0" + +cli-highlight@^2.1.4: + version "2.1.11" + resolved "https://registry.yarnpkg.com/cli-highlight/-/cli-highlight-2.1.11.tgz#49736fa452f0aaf4fae580e30acb26828d2dc1bf" + integrity "sha1-SXNvpFLwqvT65YDjCssmgo0twb8= sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==" + dependencies: + chalk "^4.0.0" + highlight.js "^10.7.1" + mz "^2.4.0" + parse5 "^5.1.1" + parse5-htmlparser2-tree-adapter "^6.0.0" + yargs "^16.0.0" + +cli-spinners@^2.0.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" + integrity "sha1-rclU6+KBw3pjGb+kAebdJIj/tw0= sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==" + +cli-width@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" + integrity "sha1-ovSEN6LKqaIkNueUvwceyeYc7fY= sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==" + +clipboardy@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-2.3.0.tgz#3c2903650c68e46a91b388985bc2774287dba290" + integrity "sha1-PCkDZQxo5GqRs4iYW8J3QofbopA= sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==" + dependencies: + arch "^2.1.1" + execa "^1.0.0" + is-wsl "^2.1.1" + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity "sha1-3u/P2y6AB4SqNPRvoI4GhRx7u8U= sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==" + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity "sha1-UR1wLAxOQcoVbX0OlgIfI+EyJbE= sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==" + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity "sha1-oCZe5lVHb8gHrqnfPfjfd4OAi08= sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==" + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clone@2.x, clone@^2.1.0, clone@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==" + +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity "sha1-2jCcwmPfFZlMaIypAheco8fNfH4= sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==" + +coa@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" + integrity "sha1-Q/bCEVG07yv1cYfbDXPeIp4+fsM= sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==" + dependencies: + "@types/q" "^1.5.1" + chalk "^2.4.1" + q "^1.1.2" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==" + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0, color-convert@^1.9.3: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg= sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==" + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM= sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==" + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + +color-name@^1.0.0, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI= sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + +color-string@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.6.0.tgz#c3915f61fe267672cb7e1e064c9d692219f6c312" + integrity "sha1-w5FfYf4mdnLLfh4GTJ1pIhn2wxI= sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==" + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@^3.0.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164" + integrity "sha1-NUTcGYyvRJDD7MmnkLVP6f9F4WQ= sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==" + dependencies: + color-convert "^1.9.3" + color-string "^1.6.0" + +combine-errors@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/combine-errors/-/combine-errors-3.0.3.tgz#f4df6740083e5703a3181110c2b10551f003da86" + integrity "sha1-9N9nQAg+VwOjGBEQwrEFUfAD2oY= sha512-C8ikRNRMygCwaTx+Ek3Yr+OuZzgZjduCOfSQBjbM8V3MfgcjSTeto/GXP6PAwKvJz/v15b7GHZvx5rOlczFw/Q==" + dependencies: + custom-error-instance "2.1.1" + lodash.uniqby "4.5.0" + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity "sha1-w9RaizT9cwYxoRCoolIGgrMdWn8= sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==" + dependencies: + delayed-stream "~1.0.0" + +comma-separated-tokens@^1.0.0: + version "1.0.8" + resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" + integrity "sha1-YyuAthF4Z6FY8QgK1Jiy++fj9eo= sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==" + +commander@2.17.x: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + integrity "sha1-vXerfebelCBc6sxy8XFtKfIKd78= sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==" + +commander@^2.12.1, commander@^2.18.0, commander@^2.19.0, commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity "sha1-/UhehMA+tIgcIHIrpIA16FMa6zM= sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + +commander@~2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity "sha1-9hmKqE5bg8RgVLlN3tv+1e6f8So= sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==" + +common-tags@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" + integrity "sha1-jjFT5ULUo56bEFVENK+q+YlWqTc= sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==" + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + +component-classes@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/component-classes/-/component-classes-1.2.6.tgz#c642394c3618a4d8b0b8919efccbbd930e5cd691" + integrity "sha1-xkI5TDYYpNiwuJGe/Mu9kw5c1pE= sha512-hPFGULxdwugu1QWW3SvVOCUHLzO34+a2J6Wqy0c5ASQkfi9/8nZcBB0ZohaEbXOQlCflMAEMmEWk7u7BVs4koA==" + dependencies: + component-indexof "0.0.3" + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity "sha1-FuQHD7qK4ptnnyIVhT7hgasuq8A= sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + +component-indexof@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/component-indexof/-/component-indexof-0.0.3.tgz#11d091312239eb8f32c8f25ae9cb002ffe8d3c24" + integrity "sha1-EdCRMSI5648yyPJa6csAL/6NPCQ= sha512-puDQKvx/64HZXb4hBwIcvQLaLgux8o1CbWl39s41hrIIZDl1lJiD5jc22gj3RBeGK0ovxALDYpIbyjqDUUl0rw==" + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity "sha1-r1PMprBw1MPAdQ+9dyhqbXzEb7o= sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==" + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity "sha1-lVI+/xcMpXwpoMpB5v4TH0Hlu48= sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==" + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + +concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity "sha1-kEvfGUzTEi/Gdcd/xKw9T/D9GjQ= sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==" + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +condense-newlines@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/condense-newlines/-/condense-newlines-0.2.1.tgz#3de985553139475d32502c83b02f60684d24c55f" + integrity "sha1-PemFVTE5R10yUCyDsC9gaE0kxV8= sha512-P7X+QL9Hb9B/c8HI5BFFKmjgBu2XpQuF98WZ9XkO+dBGgk5XgwiQz7o1SmpglNWId3581UcS0SFAWfoIhMHPfg==" + dependencies: + extend-shallow "^2.0.1" + is-whitespace "^0.3.0" + kind-of "^3.0.2" + +config-chain@^1.1.12: + version "1.1.13" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" + integrity "sha1-+tB5Wqamza/57Rto6d/5Q3LCMvQ= sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==" + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + +connect-history-api-fallback@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity "sha1-izIIk1kwjRERFdgcrT/Oq4iPl7w= sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==" + +console-browserify@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity "sha1-ZwY871fOts9Jk6KrOlWECujEkzY= sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" + +consolidate@^0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.15.1.tgz#21ab043235c71a07d45d9aad98593b0dba56bab7" + integrity "sha1-IasEMjXHGgfUXZqtmFk7DbpWurc= sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==" + dependencies: + bluebird "^3.1.1" + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==" + +content-disposition@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity "sha1-4TDK9+cnkIfFYWwgB9BIVpiYT70= sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==" + dependencies: + safe-buffer "5.1.2" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity "sha1-4TjMdeBAxyexlm/l5fjJruJW/js= sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + +convert-source-map@^1.4.0, convert-source-map@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity "sha1-8zc8MtIbTXgN2ABFFGhPt5HKQ2k= sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==" + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity "sha1-4wOogrNCzD7oylE6eZmXNNqzriw= sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity "sha1-vrQ35wIrO21JAZ0IhmUwPr6cFLo= sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + +cookie@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity "sha1-r9cT/ibr0hupXOth+agRblClN9E= sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity "sha1-kilzmMrjSTf8r9bsgTnBgFHwteA= sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==" + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==" + +copy-to-clipboard@^3: + version "3.3.1" + resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz#115aa1a9998ffab6196f93076ad6da3b913662ae" + integrity "sha1-EVqhqZmP+rYZb5MHatbaO5E2Yq4= sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==" + dependencies: + toggle-selection "^1.0.6" + +copy-webpack-plugin@^5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-5.1.2.tgz#8a889e1dcafa6c91c6cd4be1ad158f1d3823bae2" + integrity "sha1-ioieHcr6bJHGzUvhrRWPHTgjuuI= sha512-Uh7crJAco3AjBvgAy9Z75CjK8IG+gxaErro71THQ+vv/bl4HaQcpkexAY8KVW/T6D2W2IRr+couF/knIRkZMIQ==" + dependencies: + cacache "^12.0.3" + find-cache-dir "^2.1.0" + glob-parent "^3.1.0" + globby "^7.1.1" + is-glob "^4.0.1" + loader-utils "^1.2.3" + minimatch "^3.0.4" + normalize-path "^3.0.0" + p-limit "^2.2.1" + schema-utils "^1.0.0" + serialize-javascript "^4.0.0" + webpack-log "^2.0.0" + +core-js-compat@^3.18.0, core-js-compat@^3.19.0, core-js-compat@^3.6.5: + version "3.19.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.19.1.tgz#fe598f1a9bf37310d77c3813968e9f7c7bb99476" + integrity "sha1-/lmPGpvzcxDXfDgTlo6ffHu5lHY= sha512-Q/VJ7jAF/y68+aUsQJ/afPOewdsGkDtcMb40J8MbuWKlK3Y+wtHq8bTHKPj2WKWLIqmS5JhHs4CzHtz6pT2W6g==" + dependencies: + browserslist "^4.17.6" + semver "7.0.0" + +core-js-pure@^3.19.0: + version "3.19.1" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.19.1.tgz#edffc1fc7634000a55ba05e95b3f0fe9587a5aa4" + integrity "sha1-7f/B/HY0AApVugXpWz8P6Vh6WqQ= sha512-Q0Knr8Es84vtv62ei6/6jXH/7izKmOrtrxH9WJTHLCMAVeU+8TF8z8Nr08CsH4Ot0oJKzBzJJL9SJBYIv7WlfQ==" + +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + integrity "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= sha512-ZiPp9pZlgxpWRu0M+YWbm6+aQ84XEfH1JRXvfOc/fILWI0VKhLC2LX13X1NYq4fULzLMq7Hfh43CSo2/aIaUPA==" + +core-js@^2.4.0: + version "2.6.12" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" + integrity "sha1-2TM9+nsGXjR8xWgiGdb2kIWcwuw= sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" + +core-js@^3.15.2, core-js@^3.6.5: + version "3.19.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.19.1.tgz#f6f173cae23e73a7d88fa23b6e9da329276c6641" + integrity "sha1-9vFzyuI+c6fYj6I7bp2jKSdsZkE= sha512-Tnc7E9iKd/b/ff7GFbhwPVzJzPztGrChB8X8GLqoYGdEOG8IpLnK1xPyo3ZoO3HsK6TodJS58VGPOxA+hLHQMg==" + +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity "sha1-pgQtNjTCsn6TKPg3uWX6yDgI24U= sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + +cosmiconfig@^5.0.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" + integrity "sha1-BA9yaAnFked6F8CjYmykW08Wixo= sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==" + dependencies: + import-fresh "^2.0.0" + is-directory "^0.3.1" + js-yaml "^3.13.1" + parse-json "^4.0.0" + +cosmiconfig@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + integrity "sha1-2k/uhTxS9rHmk19BwaL8UL1KmYI= sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==" + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.7.2" + +create-ecdh@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity "sha1-1uf0v/pmc2CFoHYv06YyaE2rzE4= sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==" + dependencies: + bn.js "^4.1.0" + elliptic "^6.5.3" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity "sha1-iJB4rxGmN1a8+1m9IhmWvjqe8ZY= sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==" + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity "sha1-aRcMeLOrlXFHsriwRXLkfq0iQ/8= sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==" + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +create-react-class@^15.5.1, create-react-class@^15.6.0: + version "15.7.0" + resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.7.0.tgz#7499d7ca2e69bb51d13faf59bd04f0c65a1d6c1e" + integrity "sha1-dJnXyi5pu1HRP69ZvQTwxlodbB4= sha512-QZv4sFWG9S5RUvkTYWbflxeZX+JG7Cz0Tn33rQBJ+WFQTqTfUTjMjiv9tnfXazjsO5r0KhPs+AqCjyrQX6h2ng==" + dependencies: + loose-envify "^1.3.1" + object-assign "^4.1.1" + +cropperjs@^1.5.6: + version "1.5.12" + resolved "https://registry.yarnpkg.com/cropperjs/-/cropperjs-1.5.12.tgz#d9c0db2bfb8c0d769d51739e8f916bbc44e10f50" + integrity "sha1-2cDbK/uMDXadUXOej5FrvEThD1A= sha512-re7UdjE5UnwdrovyhNzZ6gathI4Rs3KGCBSc8HCIjUo5hO42CtzyblmWLj6QWVw7huHyDMfpKxhiO2II77nhDw==" + +cross-fetch@^3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39" + integrity "sha1-lyPzo6JHv4uJA586OAqSROj6Lzk= sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==" + dependencies: + node-fetch "2.6.1" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^6.0.0: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity "sha1-Sl7Hxk364iw6FBJNus3uhG2Ay8Q= sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==" + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^7.0.0, cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity "sha1-9zqFudXUHQRVUcF34ogtSshXKKY= sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==" + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity "sha1-OWz58xN/A+S45TLFj2mCVOAPgOw= sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==" + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +css-color-names@0.0.4, css-color-names@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" + integrity "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= sha512-zj5D7X1U2h2zsXOAM8EyUREBnnts6H+Jm+d1M2DbiQQcUtnqgQsMrdo8JW9R80YFUmIdBZeMu5wvYM7hcgWP/Q==" + +css-declaration-sorter@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz#c198940f63a76d7e36c1e71018b001721054cb22" + integrity "sha1-wZiUD2OnbX42wecQGLABchBUyyI= sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==" + dependencies: + postcss "^7.0.1" + timsort "^0.3.0" + +css-loader@^3.5.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" + integrity "sha1-Lkssfm4tJ/jI8o9hv/zS5ske9kU= sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==" + dependencies: + camelcase "^5.3.1" + cssesc "^3.0.0" + icss-utils "^4.1.1" + loader-utils "^1.2.3" + normalize-path "^3.0.0" + postcss "^7.0.32" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^3.0.2" + postcss-modules-scope "^2.2.0" + postcss-modules-values "^3.0.0" + postcss-value-parser "^4.1.0" + schema-utils "^2.7.0" + semver "^6.3.0" + +css-select-base-adapter@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" + integrity "sha1-Oy/0lyzDYquIVhUHqVQIoUMhNdc= sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" + +css-select@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" + integrity "sha1-ajRlM1ZjWTSoG6ymjQJVQyEF2+8= sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==" + dependencies: + boolbase "^1.0.0" + css-what "^3.2.1" + domutils "^1.7.0" + nth-check "^1.0.2" + +css-select@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.1.3.tgz#a70440f70317f2669118ad74ff105e65849c7067" + integrity "sha1-pwRA9wMX8maRGK10/xBeZYSccGc= sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==" + dependencies: + boolbase "^1.0.0" + css-what "^5.0.0" + domhandler "^4.2.0" + domutils "^2.6.0" + nth-check "^2.0.0" + +css-tree@1.0.0-alpha.37: + version "1.0.0-alpha.37" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" + integrity "sha1-mL69YsTB2flg7DQM+fdSLjBwmiI= sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==" + dependencies: + mdn-data "2.0.4" + source-map "^0.6.1" + +css-tree@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" + integrity "sha1-60hw+2/XcHMn7JXC/yqwm16NuR0= sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==" + dependencies: + mdn-data "2.0.14" + source-map "^0.6.1" + +css-what@^3.2.1: + version "3.4.2" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4" + integrity "sha1-6nAm/LAXd+295SEk4h8yfnrpUOQ= sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==" + +css-what@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe" + integrity "sha1-P3tweq32M7r2LCzrhXm1RbtA9/4= sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==" + +css.escape@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" + integrity "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s= sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==" + +css@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929" + integrity "sha1-xkZ1XHOXHyu6amAeLPL9cbEpiSk= sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==" + dependencies: + inherits "^2.0.3" + source-map "^0.6.1" + source-map-resolve "^0.5.2" + urix "^0.1.0" + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity "sha1-N3QZGZA7hoVl4cCep0dEXNGJg+4= sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" + +cssnano-preset-default@^4.0.0, cssnano-preset-default@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz#920622b1fc1e95a34e8838203f1397a504f2d3ff" + integrity "sha1-kgYisfwelaNOiDggPxOXpQTy0/8= sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==" + dependencies: + css-declaration-sorter "^4.0.1" + cssnano-util-raw-cache "^4.0.1" + postcss "^7.0.0" + postcss-calc "^7.0.1" + postcss-colormin "^4.0.3" + postcss-convert-values "^4.0.1" + postcss-discard-comments "^4.0.2" + postcss-discard-duplicates "^4.0.2" + postcss-discard-empty "^4.0.1" + postcss-discard-overridden "^4.0.1" + postcss-merge-longhand "^4.0.11" + postcss-merge-rules "^4.0.3" + postcss-minify-font-values "^4.0.2" + postcss-minify-gradients "^4.0.2" + postcss-minify-params "^4.0.2" + postcss-minify-selectors "^4.0.2" + postcss-normalize-charset "^4.0.1" + postcss-normalize-display-values "^4.0.2" + postcss-normalize-positions "^4.0.2" + postcss-normalize-repeat-style "^4.0.2" + postcss-normalize-string "^4.0.2" + postcss-normalize-timing-functions "^4.0.2" + postcss-normalize-unicode "^4.0.1" + postcss-normalize-url "^4.0.1" + postcss-normalize-whitespace "^4.0.2" + postcss-ordered-values "^4.1.2" + postcss-reduce-initial "^4.0.3" + postcss-reduce-transforms "^4.0.2" + postcss-svgo "^4.0.3" + postcss-unique-selectors "^4.0.1" + +cssnano-util-get-arguments@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f" + integrity "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8= sha512-6RIcwmV3/cBMG8Aj5gucQRsJb4vv4I4rn6YjPbVWd5+Pn/fuG+YseGvXGk00XLkoZkaj31QOD7vMUpNPC4FIuw==" + +cssnano-util-get-match@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz#c0e4ca07f5386bb17ec5e52250b4f5961365156d" + integrity "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0= sha512-JPMZ1TSMRUPVIqEalIBNoBtAYbi8okvcFns4O0YIhcdGebeYZK7dMyHJiQ6GqNBA9kE0Hym4Aqym5rPdsV/4Cw==" + +cssnano-util-raw-cache@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz#b26d5fd5f72a11dfe7a7846fb4c67260f96bf282" + integrity "sha1-sm1f1fcqEd/np4RvtMZyYPlr8oI= sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==" + dependencies: + postcss "^7.0.0" + +cssnano-util-same-parent@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3" + integrity "sha1-V0CC+yhZ0ttDOFWDXZqEVuoYu/M= sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==" + +cssnano@^4.0.0, cssnano@^4.1.10: + version "4.1.11" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.11.tgz#c7b5f5b81da269cb1fd982cb960c1200910c9a99" + integrity "sha1-x7X1uB2iacsf2YLLlgwSAJEMmpk= sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==" + dependencies: + cosmiconfig "^5.0.0" + cssnano-preset-default "^4.0.8" + is-resolvable "^1.0.0" + postcss "^7.0.0" + +csso@^4.0.2: + version "4.2.0" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + integrity "sha1-6jpWE0bo3J9UbW/r7dUBh884lSk= sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==" + dependencies: + css-tree "^1.1.2" + +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0", cssom@~0.3.6: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity "sha1-nxJ29bK0Y/IRTT8sdSUK+MGjb0o= sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + +cssom@^0.4.1: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" + integrity "sha1-WmbPk9LQtmHYC/akT7ZfXC5OChA= sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + +cssstyle@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" + integrity "sha1-nTEyginTxWXGHlhrAgQaKPzNzPE= sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==" + dependencies: + cssom "0.3.x" + +cssstyle@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity "sha1-/2ZaDdvcMYZLCWR/NBY0Q9kLCFI= sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==" + dependencies: + cssom "~0.3.6" + +cuid@^2.1.1: + version "2.1.8" + resolved "https://registry.yarnpkg.com/cuid/-/cuid-2.1.8.tgz#cbb88f954171e0d5747606c0139fb65c5101eac0" + integrity "sha1-y7iPlUFx4NV0dgbAE5+2XFEB6sA= sha512-xiEMER6E7TlTPnDxrM4eRiC6TRgjNX9xzEZ5U/Se2YJKr7Mq4pJn/2XEHjl3STcSh96GmkHPcBXLES8M29wyyg==" + +custom-error-instance@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/custom-error-instance/-/custom-error-instance-2.1.1.tgz#3cf6391487a6629a6247eb0ca0ce00081b7e361a" + integrity "sha1-PPY5FIemYppiR+sMoM4ACBt+Nho= sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg==" + +cyclist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" + integrity "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A==" + +d3-collection@1: + version "1.0.7" + resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.7.tgz#349bd2aa9977db071091c13144d5e4f16b5b310e" + integrity "sha1-NJvSqpl32wcQkcExRNXk8WtbMQ4= sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==" + +d3-dispatch@1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-1.0.6.tgz#00d37bcee4dd8cd97729dd893a0ac29caaba5d58" + integrity "sha1-ANN7zuTdjNl3Kd2JOgrCnKq6XVg= sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA==" + +d3-force@^1.0.6: + version "1.2.1" + resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-1.2.1.tgz#fd29a5d1ff181c9e7f0669e4bd72bdb0e914ec0b" + integrity "sha1-/Sml0f8YHJ5/BmnkvXK9sOkU7As= sha512-HHvehyaiUlVo5CxBJ0yF/xny4xoaxFxDnBXNvNcfW9adORGZfyNF1dj6DGLKyk4Yh3brP/1h3rnDzdIAwL08zg==" + dependencies: + d3-collection "1" + d3-dispatch "1" + d3-quadtree "1" + d3-timer "1" + +d3-quadtree@1: + version "1.0.7" + resolved "https://registry.yarnpkg.com/d3-quadtree/-/d3-quadtree-1.0.7.tgz#ca8b84df7bb53763fe3c2f24bd435137f4e53135" + integrity "sha1-youE33u1N2P+PC8kvUNRN/TlMTU= sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA==" + +d3-timer@1: + version "1.0.10" + resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-1.0.10.tgz#dfe76b8a91748831b13b6d9c793ffbd508dd9de5" + integrity "sha1-3+dripF0iDGxO22ceT/71QjdneU= sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw==" + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity "sha1-hpgJU3LVjb7jRv/Qxwk/mfj561o= sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==" + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==" + dependencies: + assert-plus "^1.0.0" + +data-urls@^1.0.0, data-urls@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" + integrity "sha1-Fe4Fgrql4iu1nHcUDaj5x2lju/4= sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==" + dependencies: + abab "^2.0.0" + whatwg-mimetype "^2.2.0" + whatwg-url "^7.0.0" + +de-indent@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" + integrity "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0= sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==" + +deasync@^0.1.15: + version "0.1.23" + resolved "https://registry.yarnpkg.com/deasync/-/deasync-0.1.23.tgz#d52bb1f9cebb511933bb977f2820af1af5d1ec08" + integrity "sha1-1Sux+c67URkzu5d/KCCvGvXR7Ag= sha512-CGZSokFwidI50GOAmkz/7z3QdMzTQqAiUOzt95PuhKgi6VVztn9D03ZCzzi93uUWlp/v6A9osvNWpIvqHvKjTA==" + dependencies: + bindings "^1.5.0" + node-addon-api "^1.7.1" + +debounce@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" + integrity "sha1-OIgdj0FmpcWEgCDBGCe4NLyz4KU= sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" + +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8= sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==" + dependencies: + ms "2.0.0" + +debug@^3.1.1, debug@^3.2.6: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity "sha1-clgLfpFF+zm2Z2+cXl+xALk0F5o= sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==" + dependencies: + ms "^2.1.1" + +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity "sha1-8KScGKyHeeMdSgxgKd+3aHPHQos= sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==" + dependencies: + ms "2.1.2" + +decache@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/decache/-/decache-4.6.0.tgz#87026bc6e696759e82d57a3841c4e251a30356e8" + integrity "sha1-hwJrxuaWdZ6C1Xo4QcTiUaMDVug= sha512-PppOuLiz+DFeaUvFXEYZjLxAkKiMYH/do/b/MxpDe/8AgKBi5GhZxridoVIbBq72GDbL36e4p0Ce2jTGUwwU+w==" + dependencies: + callsite "^1.0.0" + +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==" + +deep-equal@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity "sha1-tcmMlCzv+vfLBR4k4UNKJaLmB2o= sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==" + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + +deep-extend@0.6.0, deep-extend@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity "sha1-xPp8lUBKF6nD6Mp+FTcxK3NjMKw= sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + +deep-is@^0.1.3, deep-is@~0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity "sha1-pvLc5hL63S7x9Rm3NVHxfoUZmDE= sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + +deepmerge@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-1.5.2.tgz#10499d868844cdad4fee0842df8c7f6f0c95a753" + integrity "sha1-EEmdhohEza1P7ghC34x/bwyVp1M= sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==" + +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity "sha1-RNLqNnm49NT/ujPwPYZfwee/SVU= sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + +default-gateway@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" + integrity "sha1-FnEEx1AMIRX23WmwpTa7jtcgVSs= sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==" + dependencies: + execa "^1.0.0" + ip-regex "^2.1.0" + +default-gateway@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-5.0.5.tgz#4fd6bd5d2855d39b34cc5a59505486e9aafc9b10" + integrity "sha1-T9a9XShV05s0zFpZUFSG6ar8mxA= sha512-z2RnruVmj8hVMmAnEJMTIJNijhKCDiGjbLP+BHJFOT7ld3Bo5qcIBpVYDniqhbMIIf+jZDlkP2MkPXiQy/DBLA==" + dependencies: + execa "^3.3.0" + +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + integrity "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==" + dependencies: + clone "^1.0.2" + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity "sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE= sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==" + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==" + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity "sha1-dp66rz9KY6rTr56NMEybvnm/sOY= sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==" + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity "sha1-1Flono1lS6d+AqgX+HENcCyxbp0= sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==" + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +del@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" + integrity "sha1-no8RciLqRKMf86FWwEm5kFKp8LQ= sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==" + dependencies: + "@types/glob" "^7.1.1" + globby "^6.1.0" + is-path-cwd "^2.0.0" + is-path-in-cwd "^2.0.0" + p-map "^2.0.0" + pify "^4.0.1" + rimraf "^2.6.3" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity "sha1-3zrhmayt+31ECqrgsp4icrJOxhk= sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==" + +des.js@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity "sha1-U4IULhvcU/hdhtU+X0qn3rkeCEM= sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==" + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==" + +detect-newline@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" + integrity "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg==" + +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity "sha1-yccHdaScPQO8LAbZpzvlUPl4+LE= sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + +diff-sequences@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" + integrity "sha1-VxXWJE4qpl9Iu6C8ly2wsLEelbU= sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==" + +diff-sequences@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" + integrity "sha1-SLqZFX3hkjQS7tQdtrbUqpynwLE= sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==" + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity "sha1-YPOuy4nV+uUgwRqhnvwruYKq3n0= sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity "sha1-QOjumPVaIUlgcUaSHGPhrl89KHU= sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==" + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dir-glob@^2.0.0, dir-glob@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" + integrity "sha1-+gnwaUFTyJGLGLoN6vrpR2n8UMQ= sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==" + dependencies: + path-type "^3.0.0" + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity "sha1-Vtv3PZkqSpO6FYT0U0Bj/S5BcX8= sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==" + dependencies: + path-type "^4.0.0" + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity "sha1-s55/HabrCnW6nBcySzR1PEfgZU0= sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" + +dns-packet@^1.3.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f" + integrity "sha1-40VQZYJKJQe6iGxVqJljuxB97G8= sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==" + dependencies: + ip "^1.1.0" + safe-buffer "^5.0.1" + +dns-txt@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + integrity "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= sha512-Ix5PrWjphuSoUXV/Zv5gaFHjnaJtb02F2+Si3Ht9dyJ87+Z/lMmy+dpNHtTGraNK958ndXq2i+GLkWsWHcKaBQ==" + dependencies: + buffer-indexof "^1.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity "sha1-rd6+rXKmV023g2OdyHoSF3OXOWE= sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==" + dependencies: + esutils "^2.0.2" + +dom-accessibility-api@^0.5.6: + version "0.5.10" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.10.tgz#caa6d08f60388d0bb4539dd75fe458a9a1d0014c" + integrity "sha1-yqbQj2A4jQu0U53XX+RYqaHQAUw= sha512-Xu9mD0UjrJisTmv7lmVSDMagQcU9R5hwAbxsaAE/35XPnPLJobbuREfV/rraiSaEj/UOvgrzQs66zyTWTlyd+g==" + +dom-align@^1.10.4: + version "1.12.2" + resolved "https://registry.yarnpkg.com/dom-align/-/dom-align-1.12.2.tgz#0f8164ebd0c9c21b0c790310493cd855892acd4b" + integrity "sha1-D4Fk69DJwhsMeQMQSTzYVYkqzUs= sha512-pHuazgqrsTFrGU2WLDdXxCFabkdQDx72ddkraZNih1KsMcN5qsRSTR9O4VJRlwTPCPb5COYg3LOfiMHHcPInHg==" + +dom-closest@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/dom-closest/-/dom-closest-0.2.0.tgz#ebd9f91d1bf22e8d6f477876bbcd3ec90216c0cf" + integrity "sha1-69n5HRvyLo1vR3h2u80+yQIWwM8= sha512-6neTn1BtJlTSt+XSISXpnOsF1uni1CHsP/tmzZMGWxasYFHsBOqrHPnzmneqEgKhpagnfnfSfbvRRW0xFsBHAA==" + dependencies: + dom-matches ">=1.0.1" + +dom-converter@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" + integrity "sha1-ZyGp2u4uKTaClVtq/kFncWJ7t2g= sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==" + dependencies: + utila "~0.4" + +dom-event-types@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dom-event-types/-/dom-event-types-1.0.0.tgz#5830a0a29e1bf837fe50a70cd80a597232813cae" + integrity "sha1-WDCgop4b+Df+UKcM2ApZcjKBPK4= sha512-2G2Vwi2zXTHBGqXHsJ4+ak/iP0N8Ar+G8a7LiD2oup5o4sQWytwqqrZu/O6hIMV0KMID2PL69OhpshLO0n7UJQ==" + +dom-matches@>=1.0.1: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-matches/-/dom-matches-2.0.0.tgz#d2728b416a87533980eb089b848d253cf23a758c" + integrity "sha1-0nKLQWqHUzmA6wibhI0lPPI6dYw= sha512-2VI856xEDCLXi19W+4BechR5/oIS6bKCKqcf16GR8Pg7dGLJ/eBOWVbCmQx2ISvYH6wTNx5Ef7JTOw1dRGRx6A==" + +dom-scroll-into-view@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/dom-scroll-into-view/-/dom-scroll-into-view-2.0.1.tgz#0decc8522801fd8d3f1c6ba355a74d382c5f989b" + integrity "sha1-DezIUigB/Y0/HGujVadNOCxfmJs= sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w==" + +dom-serializer@0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity "sha1-GvuB9TNxcXXUeGVd68XjMtn5u1E= sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==" + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + +dom-serializer@^1.0.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91" + integrity "sha1-YgZDfTLO767HFhgDIwx6ILwbTZE= sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==" + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity "sha1-PTH1AZGmdJ3RN1p/Ui6CPULlTto= sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==" + +domelementtype@1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity "sha1-0EjESzew0Qp/Kj1f7j9DM9eQSB8= sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + +domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" + integrity "sha1-mgtsJ4LtahxzI9QiZxg9+b2LHVc= sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==" + +domexception@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + integrity "sha1-k3RCZEymoxJh7zbj7Gd/6AVYLJA= sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==" + dependencies: + webidl-conversions "^4.0.2" + +domhandler@^4.0.0, domhandler@^4.2.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.2.tgz#e825d721d19a86b8c201a35264e226c678ee755f" + integrity "sha1-6CXXIdGahrjCAaNSZOImxnjudV8= sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==" + dependencies: + domelementtype "^2.2.0" + +dompurify@^2.2.9: + version "2.3.3" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.3.tgz#c1af3eb88be47324432964d8abc75cf4b98d634c" + integrity "sha1-wa8+uIvkcyRDKWTYq8dc9LmNY0w= sha512-dqnqRkPMAjOZE0FogZ+ceJNM2dZ3V/yNOuFB7+39qpO93hHhfRpHw3heYQC7DPK9FqbQTfBKUJhiSfz4MvXYwg==" + +domutils@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity "sha1-Vuo0HoNOBuZ0ivehyyXaZ+qfjCo= sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==" + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^2.5.2, domutils@^2.6.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity "sha1-RDfe9dtuLR9dbuhZvZXKfQIEgTU= sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==" + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + +dot-prop@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" + integrity "sha1-kMzOcIzZzYLMTcjD3dmr3VWyDog= sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==" + dependencies: + is-obj "^2.0.0" + +dotenv-expand@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" + integrity "sha1-P7rwIL/XlIhAcuomsel5HUWmKfA= sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" + +dotenv@^8.2.0: + version "8.6.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b" + integrity "sha1-Bhr2ZNGff02PxuT/m1hM4jety4s= sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==" + +duplexer@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" + integrity "sha1-Or5DrvODX4rgd9E23c4PJ2sEAOY= sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity "sha1-Kk31MX9sz9kfhtb9JdjYoQO4gwk= sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==" + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +easy-stack@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/easy-stack/-/easy-stack-1.0.1.tgz#8afe4264626988cabb11f3c704ccd0c835411066" + integrity "sha1-iv5CZGJpiMq7EfPHBMzQyDVBEGY= sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==" + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +editorconfig@^0.15.3: + version "0.15.3" + resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5" + integrity "sha1-vvhMTnX7jcsM5c7o79UcFZmb78U= sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==" + dependencies: + commander "^2.19.0" + lru-cache "^4.1.5" + semver "^5.6.0" + sigmund "^1.0.1" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + +ejs@^2.6.1: + version "2.7.4" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" + integrity "sha1-SGYSh1c9zFPjZsehrlLDoSDuybo= sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==" + +electron-to-chromium@^1.3.886: + version "1.3.889" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.889.tgz#0b7c6f7628559592d5406deda281788f37107790" + integrity "sha1-C3xvdihVlZLVQG3tooF4jzcQd5A= sha512-suEUoPTD1mExjL9TdmH7cvEiWJVM2oEiAi+Y1p0QKxI2HcRlT44qDTP2c1aZmVwRemIPYOpxmV7CxQCOWcm4XQ==" + +elliptic@^6.5.3: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity "sha1-2jfOvTHnmhNn6UG1ku0fvr1Yq7s= sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==" + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + +emitter-component@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/emitter-component/-/emitter-component-1.1.1.tgz#065e2dbed6959bf470679edabeaf7981d1003ab6" + integrity "sha1-Bl4tvtaVm/RwZ57avq95gdEAOrY= sha512-G+mpdiAySMuB7kesVRLuyvYRqDmshB7ReKEVuyBPkzQlmiDiLrt7hHHIy4Aff552bgknVN7B2/d3lzhGO5dvpQ==" + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity "sha1-kzoEBShgyF6DwSJHnEdIqOTHIVY= sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc= sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity "sha1-TapNnbAPmBmIDHn6RXrlsJof04k= sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==" + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity "sha1-VXBmIEatKeLpFucariYKvf9Pang= sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + +encoding@^0.1.11: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity "sha1-VldK/deR9UqOmyeFwFgqLSYhD6k= sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==" + dependencies: + iconv-lite "^0.6.2" + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity "sha1-WuZKX0UFe682JuwU2gyl5LJDHrA= sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==" + dependencies: + once "^1.4.0" + +enhanced-resolve@^4.0.0, enhanced-resolve@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" + integrity "sha1-Lzz9hNvjtIfxjy2y7x4GSlccpew= sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==" + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.5.0" + tapable "^1.0.0" + +enquire.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/enquire.js/-/enquire.js-2.1.6.tgz#3e8780c9b8b835084c3f60e166dbc3c2a3c89814" + integrity "sha1-PoeAybi4NQhMP2DhZtvDwqPImBQ= sha512-/KujNpO+PT63F7Hlpu4h3pE3TokKRHN26JYmQpPyjkRD/N57R7bPDNojMXdi7uveAKjYB7yQnartCxZnFWr0Xw==" + +enquirer@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity "sha1-Kn/l3WNKHkElqXXsmU/1RW3Dc00= sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==" + dependencies: + ansi-colors "^4.1.1" + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity "sha1-CY3JDruD2N/6CJ1VJWs1HTTE2lU= sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" + +entities@~1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity "sha1-vfpzUplmTfr9NFKe1PhSKidf6lY= sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + +errno@^0.1.1, errno@^0.1.3, errno@~0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity "sha1-i7Ppx9Rjvkl2/4iPdrSAnrwugR8= sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==" + dependencies: + prr "~1.0.1" + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity "sha1-tKxAZIEH/c3PriQvQovqihTU8b8= sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==" + dependencies: + is-arrayish "^0.2.1" + +error-stack-parser@^2.0.2: + version "2.0.6" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.6.tgz#5a99a707bd7a4c58a797902d48d82803ede6aad8" + integrity "sha1-WpmnB716TFinl5AtSNgoA+3mqtg= sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==" + dependencies: + stackframe "^1.1.1" + +es-abstract@^1.17.2, es-abstract@^1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" + integrity "sha1-1IhXlodpFpWd547aoN9FZicRXsM= sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==" + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + get-intrinsic "^1.1.1" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-symbols "^1.0.2" + internal-slot "^1.0.3" + is-callable "^1.2.4" + is-negative-zero "^2.0.1" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.1" + is-string "^1.0.7" + is-weakref "^1.0.1" + object-inspect "^1.11.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.1" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity "sha1-5VzUyc3BiLzvsDs2bHNjI/xciYo= sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==" + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: + version "0.10.53" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" + integrity "sha1-k8WjrP2+8nUiCtcmRK0C7hg2jeE= sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==" + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.3" + next-tick "~1.0.0" + +es6-iterator@^2.0.3, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity "sha1-p96IkUGgWpSwhUQDstCg+/qY87c= sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==" + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-symbol@^3.1.1, es6-symbol@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity "sha1-utXTwbzawoJp9MszHkMceKxwXRg= sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==" + dependencies: + d "^1.0.1" + ext "^1.1.2" + +es6-weak-map@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" + integrity "sha1-ttofFswswNm+Q+a9v8Xn383zHVM= sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==" + dependencies: + d "1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + es6-symbol "^3.1.1" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity "sha1-2M/ccACWXFoBdLSoLqpcBVJ0LkA= sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity "sha1-owME6Z2qMuI7L9IPUbq9B8/8o0Q= sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity "sha1-FLqDpdNz49MR5a/KKc9b+tllvzQ= sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + +escodegen@^1.11.1, escodegen@^1.9.1: + version "1.14.3" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" + integrity "sha1-TnuB+6YVgdyXWC7XjKt/Do1j9QM= sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==" + dependencies: + esprima "^4.0.1" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +eslint-loader@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-2.2.1.tgz#28b9c12da54057af0845e2a6112701a2f6bf8337" + integrity "sha1-KLnBLaVAV68IReKmEScBova/gzc= sha512-RLgV9hoCVsMLvOxCuNjdqOrUqIj9oJg8hF44vzJaYqsAHuY9G2YAeN3joQ9nxP0p5Th9iFSIpKo+SD8KISxXRg==" + dependencies: + loader-fs-cache "^1.0.0" + loader-utils "^1.0.2" + object-assign "^4.0.1" + object-hash "^1.1.4" + rimraf "^2.6.1" + +eslint-plugin-jest@^24.3.6: + version "24.7.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-24.7.0.tgz#206ac0833841e59e375170b15f8d0955219c4889" + integrity "sha1-IGrAgzhB5Z43UXCxX40JVSGcSIk= sha512-wUxdF2bAZiYSKBclsUMrYHH6WxiBreNjyDxbRv345TIvPeoCEgPNEn3Sa+ZrSqsf1Dl9SqqSREXMHExlMMu1DA==" + dependencies: + "@typescript-eslint/experimental-utils" "^4.0.1" + +eslint-plugin-vue@^7.9.0: + version "7.20.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-7.20.0.tgz#98c21885a6bfdf0713c3a92957a5afeaaeed9253" + integrity "sha1-mMIYhaa/3wcTw6kpV6Wv6q7tklM= sha512-oVNDqzBC9h3GO+NTgWeLMhhGigy6/bQaQbHS+0z7C4YEu/qK/yxHvca/2PTZtGNPsCrHwOTgKMrwu02A9iPBmw==" + dependencies: + eslint-utils "^2.1.0" + natural-compare "^1.4.0" + semver "^6.3.0" + vue-eslint-parser "^7.10.0" + +eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity "sha1-ygODMxD2iJoyZHgaqC5j65z+eEg= sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==" + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity "sha1-54blmmbLkrP2wfsNUIqrF0hI9Iw= sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==" + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity "sha1-0t5eA0JOcH3BDHQGjd7a5wh0Gyc= sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==" + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity "sha1-iuuvrOc0W7M1WdsKHxOh0tSMNnI= sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==" + dependencies: + eslint-visitor-keys "^2.0.0" + +eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity "sha1-MOvR73wv3/AcOk8VEESvJfqwUj4= sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + +eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity "sha1-9lMoJZMFknOSyTjtROsKXJsr0wM= sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" + +eslint@^7.25.0: + version "7.32.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" + integrity "sha1-xtMooUvj+wjI0dIeEsAv23oqgS0= sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==" + dependencies: + "@babel/code-frame" "7.12.11" + "@eslint/eslintrc" "^0.4.3" + "@humanwhocodes/config-array" "^0.5.0" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.0.1" + doctrine "^3.0.0" + enquirer "^2.3.5" + escape-string-regexp "^4.0.0" + eslint-scope "^5.1.1" + eslint-utils "^2.1.0" + eslint-visitor-keys "^2.0.0" + espree "^7.3.1" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.1.2" + globals "^13.6.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + progress "^2.0.0" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" + table "^6.0.9" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" + integrity "sha1-d/xy4f10SiBSwg84pbV1gy6Cc0o= sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==" + dependencies: + acorn "^7.1.1" + acorn-jsx "^5.2.0" + eslint-visitor-keys "^1.1.0" + +espree@^7.3.0, espree@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + integrity "sha1-8t8zC3Usb1UBn4vYm3ZgA5wbu7Y= sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==" + dependencies: + acorn "^7.4.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^1.3.0" + +esprima@^4.0.0, esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity "sha1-E7BM2z5sXRnfkatph6hpVhmwqnE= sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + +esquery@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity "sha1-IUj/w4uC6McFff7UhCWz5h8PJKU= sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==" + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.1.0, esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity "sha1-eteWTWeauyi+5yzsY3WLHF0smSE= sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==" + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1, estraverse@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity "sha1-OYrT88WiSUi+dyXoPRGn3ijNvR0= sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity "sha1-LupSkHAvJquP5TcDcP+GyWXSESM= sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" + +estree-walker@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity "sha1-UvAQF4wqTBF6d1fP6UKtt9LaTKw= sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity "sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q= sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" + +event-emitter@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==" + dependencies: + d "1" + es5-ext "~0.10.14" + +event-pubsub@4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/event-pubsub/-/event-pubsub-4.3.0.tgz#f68d816bc29f1ec02c539dc58c8dd40ce72cb36e" + integrity "sha1-9o2Ba8KfHsAsU53FjI3UDOcss24= sha512-z7IyloorXvKbFx9Bpie2+vMJKKx1fH1EN5yiTfp8CiLOTptSYy1g8H4yDpGlEdshL1PBiFtBHepF2cNsqeEeFQ==" + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity "sha1-Lem2j2Uo1WRO9cWVJqG0oHMGFp8= sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + +events@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity "sha1-Mala0Kkk4tLEGagTrrLE6HjqdAA= sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + +eventsource@^1.0.7: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.1.0.tgz#00e8ca7c92109e94b0ddf32dac677d841028cfaf" + integrity "sha1-AOjKfJIQnpSw3fMtrGd9hBAoz68= sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==" + dependencies: + original "^1.0.0" + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity "sha1-f8vbGY3HGVlDLv4ThCaE4FJaywI= sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==" + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +exec-sh@^0.3.2: + version "0.3.6" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc" + integrity "sha1-/yZPnjJVGaYMteJzaSlDSDzKY7w= sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==" + +execa@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" + integrity "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo= sha512-zDWS+Rb1E8BlqqhALSt9kUhss8Qq4nN3iof3gsOdyINksElaPyNBtKUMTR62qhvgVWR0CqCX7sdnKe4MnUbFEA==" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity "sha1-xiNqW7TfbW8V6I5/AXeYIWdJ3dg= sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==" + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^3.3.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89" + integrity "sha1-wI7UVQ72XYWPrCaf/IVyRG8364k= sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==" + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + p-finally "^2.0.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + +exifr@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/exifr/-/exifr-6.3.0.tgz#ba6a49c0a30372a969d109684e1cd8450a05ba43" + integrity "sha1-umpJwKMDcqlp0QloThzYRQoFukM= sha512-NCSOP15py+4QyvD90etFN0QOVj12ygVE8kfEDG8GDc+SXf9YAOxua2x5kGp6WvxbGjufA5C3r/1ZKHOpHbEWFg==" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity "sha1-t3c14xXOMPa27/D4OwQVGiJEliI= sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==" + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expect@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" + integrity "sha1-t1FltIFwdPpKFXeU9G/p8boVtso= sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q==" + dependencies: + "@jest/types" "^24.9.0" + ansi-styles "^3.2.0" + jest-get-type "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-regex-util "^24.9.0" + +express@^4.16.3, express@^4.17.1: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity "sha1-RJH8OGBc9R+GKdOcK10Cb5ikwTQ= sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==" + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +ext@^1.1.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" + integrity "sha1-OHHVBkHodMwXLitT+RmELRnbTFI= sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==" + dependencies: + type "^2.5.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==" + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==" + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo= sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity "sha1-ywP3QL764D6k0oPK7SdBqD8zVJU= sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==" + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity "sha1-rQD+TcYSqSMuhxhxHcXLWrAoVUM= sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==" + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extract-from-css@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/extract-from-css/-/extract-from-css-0.4.4.tgz#1ea7df2e7c7c6eb9922fa08e8adaea486f6f8f92" + integrity "sha1-HqffLnx8brmSL6COitrqSG9vj5I= sha512-41qWGBdtKp9U7sgBxAQ7vonYqSXzgW/SiAYzq4tdWSVhAShvpVCH1nyvPQgjse6EdgbW7Y7ERdT3674/lKr65A==" + dependencies: + css "^2.1.0" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==" + +extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity "sha1-jRcsBkhn8jXAyEpZaAbSeb9LzAc= sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==" + +fast-copy@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/fast-copy/-/fast-copy-2.1.1.tgz#f5cbcf2df64215e59b8e43f0b2caabc19848083a" + integrity "sha1-9cvPLfZCFeWbjkPwssqrwZhICDo= sha512-Qod3DdRgFZ8GUIM6ygeoZYpQ0QLW9cf/FS9KhhjlYggcSZXWAemAw8BOCO5LuYCrR3Uj3qXDVTUzOUwG8C7beQ==" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity "sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU= sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + +fast-equals@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-2.0.3.tgz#7039b0a039909f345a2ce53f6202a14e5f392efc" + integrity "sha1-cDmwoDmQnzRaLOU/YgKhTl85Lvw= sha512-0EMw4TTUxsMDpDkCg0rXor2gsg+npVrMIHbEhvD0HZyIhUX6AktC/yasm+qKwfyswd06Qy95ZKk8p2crTo0iPA==" + +fast-glob@^2.2.6: + version "2.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" + integrity "sha1-aVOFfDr6R1//ku5gFdUtpwpM050= sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==" + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.1.2" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.3" + micromatch "^3.1.10" + +fast-glob@^3.1.1: + version "3.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" + integrity "sha1-/Wy3otfpqnp4RhEehaGW1rL3ZqE= sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==" + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-patch@^3.0.0-1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/fast-json-patch/-/fast-json-patch-3.1.0.tgz#ec8cd9b9c4c564250ec8b9140ef7a55f70acaee6" + integrity "sha1-7IzZucTFZCUOyLkUDvelX3CsruY= sha512-IhpytlsVTRndz0hU5t0/MGzS/etxLlfrpG5V5M9mVbuj9TrJLWaMfsox9REM5rkuGX0T+5qjpe8XA1o0gZ42nA==" + +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity "sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM= sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + +fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity "sha1-YWdg+Ip1Jr38WWt8q4wYk4w2uYw= sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==" + dependencies: + reusify "^1.0.4" + +fault@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.4.tgz#eafcfc0a6d214fc94601e170df29954a4f842f13" + integrity "sha1-6vz8Cm0hT8lGAeFw3ymVSk+ELxM= sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==" + dependencies: + format "^0.2.0" + +faye-websocket@^0.11.3: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity "sha1-fw2Sdc/dhqHJY9yLZfzEUe3Lsdo= sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==" + dependencies: + websocket-driver ">=0.5.1" + +fb-watchman@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" + integrity "sha1-/IT7OdJwnPP/bXQ3BhV7tXCKioU= sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==" + dependencies: + bser "2.1.1" + +fbjs@^0.8.9: + version "0.8.18" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.18.tgz#9835e0addb9aca2eff53295cd79ca1cfc7c9662a" + integrity "sha1-mDXgrduayi7/Uylc15yhz8fJZio= sha512-EQaWFK+fEPSoibjNy8IxUtaFOMXcWsY0JaVrQoZR9zC8N2Ygf9iDITPWjUTVIax95b6I742JFLqASHfsag/vKA==" + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.30" + +figgy-pudding@^3.5.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" + integrity "sha1-tO7oFIq7Adzx0aw0Nn1Z4S+mHW4= sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==" + +figures@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity "sha1-YlwYvSk8YE3EqN2y/r8MiDQXRq8= sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==" + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity "sha1-IRst2WWcsDlLBz5zI6w8kz1SICc= sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==" + dependencies: + flat-cache "^3.0.4" + +file-loader@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-4.3.0.tgz#780f040f729b3d18019f20605f723e844b8a58af" + integrity "sha1-eA8ED3KbPRgBnyBgX3I+hEuKWK8= sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA==" + dependencies: + loader-utils "^1.2.3" + schema-utils "^2.5.0" + +file-loader@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" + integrity "sha1-uu98+OGEDfMl5DkLRISHlIDuvk0= sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==" + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity "sha1-VTp7hEb/b2hDWcRF8eN6BdrMM90= sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + +filesize@^3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" + integrity "sha1-CQuz7gG2+AGoqL6Z0xcQs0Irsxc= sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==" + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity "sha1-GRmmp8df44ssfHflGYU12prN2kA= sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==" + dependencies: + to-regex-range "^5.0.1" + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity "sha1-t+fQAP/RGTjQ/bBTUG9uur6fWH0= sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==" + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-babel-config@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/find-babel-config/-/find-babel-config-1.2.0.tgz#a9b7b317eb5b9860cda9d54740a8c8337a2283a2" + integrity "sha1-qbezF+tbmGDNqdVHQKjIM3oig6I= sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==" + dependencies: + json5 "^0.5.1" + path-exists "^3.0.0" + +find-cache-dir@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" + integrity "sha1-yN765XyKUqinhPnjHFfHQumToLk= sha512-Z9XSBoNE7xQiV6MSgPuCfyMokH2K7JdpRkOYE1+mu3d4BFJtx3GW+f6Bo4q8IX6rlf5MYbLBKW0pjl2cWdkm2A==" + dependencies: + commondir "^1.0.1" + mkdirp "^0.5.1" + pkg-dir "^1.0.0" + +find-cache-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity "sha1-jQ+UzRP+Q8bHwmGg2GEVypGMBfc= sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==" + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-cache-dir@^3.0.0, find-cache-dir@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" + integrity "sha1-swxbbv8HMHMa6pu9nb7L2AJW1ks= sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==" + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==" + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity "sha1-SRafHXmTQwZG2mHsxa41XCHJe3M= sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==" + dependencies: + locate-path "^3.0.0" + +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity "sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk= sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==" + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity "sha1-YbAzgwKy/p+Vfcwy/CqH8cMEixE= sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==" + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flatted@^3.1.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.2.tgz#64bfed5cb68fe3ca78b3eb214ad97b63bedce561" + integrity "sha1-ZL/tXLaP48p4s+shStl7Y77c5WE= sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==" + +flush-write-stream@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity "sha1-jdfYc6G6vCB9lOrQwuDkQnbr8ug= sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==" + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +follow-redirects@^1.0.0, follow-redirects@^1.14.0: + version "1.14.5" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.5.tgz#f09a5848981d3c772b5392309778523f8d85c381" + integrity "sha1-8JpYSJgdPHcrU5Iwl3hSP42Fw4E= sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==" + +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity "sha1-abRH6IoKXTLD5whPPxcQA0shN24= sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==" + dependencies: + is-callable "^1.1.3" + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==" + +"fork-ts-checker-webpack-plugin-v5@npm:fork-ts-checker-webpack-plugin@^5.0.11": + version "5.2.1" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.2.1.tgz#79326d869797906fa8b24e2abcf9421fc805450d" + integrity "sha1-eTJthpeXkG+osk4qvPlCH8gFRQ0= sha512-SVi+ZAQOGbtAsUWrZvGzz38ga2YqjWvca1pXQFUArIVXqli0lLoDQ8uS0wg0kSpcwpZmaW5jVCZXQebkyUQSsw==" + dependencies: + "@babel/code-frame" "^7.8.3" + "@types/json-schema" "^7.0.5" + chalk "^4.1.0" + cosmiconfig "^6.0.0" + deepmerge "^4.2.2" + fs-extra "^9.0.0" + memfs "^3.1.2" + minimatch "^3.0.4" + schema-utils "2.7.0" + semver "^7.3.2" + tapable "^1.0.0" + +fork-ts-checker-webpack-plugin@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-3.1.1.tgz#a1642c0d3e65f50c2cc1742e9c0a80f441f86b19" + integrity "sha1-oWQsDT5l9QwswXQunAqA9EH4axk= sha512-DuVkPNrM12jR41KM2e+N+styka0EgLkTnXmNcXdgOM37vtGeY+oCBK/Jx0hzSeEU6memFCtWb4htrHPMDfwwUQ==" + dependencies: + babel-code-frame "^6.22.0" + chalk "^2.4.1" + chokidar "^3.3.0" + micromatch "^3.1.10" + minimatch "^3.0.4" + semver "^5.6.0" + tapable "^1.0.0" + worker-rpc "^0.1.0" + +form-data-encoder@^1.4.3: + version "1.7.0" + resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.0.tgz#1abcf7ec821e27eea868d5eecf9665910b3ff119" + integrity "sha1-Grz37IIeJ+6oaNXuz5ZlkQs/8Rk= sha512-zGhcpAhxoq7ut+sldaXVwmQHvvrlUHm6jLJoqCMuhf4vjMe+Vn+PAjIB6OrqSFoIk4c3/oK6M69RXJYrYl0zWg==" + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity "sha1-3M5SwF9kTymManq5Nr1yTO/786Y= sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +format@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" + integrity "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs= sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==" + +formdata-node@^4.0.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/formdata-node/-/formdata-node-4.3.1.tgz#e7b78a2a51f524ccc483b4d223c89690fd22061d" + integrity "sha1-57eKKlH1JMzEg7TSI8iWkP0iBh0= sha512-8xKSa9et4zb+yziWsD/bI+EYjdg1z2p9EpKr+o+Yk12F/wP66bmDdvjj2ZXd2K/MJlR3HBzWnuV7f82jzHRqCA==" + dependencies: + node-domexception "1.0.0" + web-streams-polyfill "4.0.0-beta.1" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity "sha1-ImmTZCiq1MFcfr6XeahL8LKoGBE= sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==" + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" + +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-extra@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + integrity "sha1-DYUhIuW8W+tFP7Ao6cDJvzY0DJQ= sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity "sha1-TxicRKoSO4lfcigE9V6iPq3DSOk= sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^9.0.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity "sha1-WVRGDHZKjaIJS6NVS/g55rmnyG0= sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==" + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-monkey@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" + integrity "sha1-rjrJLVO7Mo7+DpodlUH2rY1I4tM= sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==" + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity "sha1-FQStJSMVjKpA20onh8sBQRmU6k8= sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + +fsevents@^1.2.7: + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity "sha1-8yXLBFVZJCi88Rs4M3DvcOO/zDg= sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==" + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity "sha1-ilJveLj99GI7cJ4Ll1xSwkwC/Ro= sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0= sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==" + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity "sha1-MqbudsPX9S1GsrGuXZP+qFgKJeA= sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + +get-caller-file@^2.0.1, get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity "sha1-T5RBKoLbMvNuOwuXQfipf+sDH34= sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity "sha1-FfWfN2+FXERpY5SPDSTNNje0q8Y= sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==" + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" + integrity "sha1-tf3nfyLL4185C04ImSLFC85u9mQ= sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==" + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity "sha1-wbJVV189wh1Zv8ec09K0axw6VLU= sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==" + dependencies: + pump "^3.0.0" + +get-stream@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity "sha1-SWaheV7lrOZecGxLe+txJX1uItM= sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==" + dependencies: + pump "^3.0.0" + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity "sha1-f9uByQAQH71WTdXxowr1qtweWNY= sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==" + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==" + dependencies: + assert-plus "^1.0.0" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==" + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity "sha1-hpgyxYA0/mikCTwX3BXoNA2EAcQ= sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==" + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + integrity "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==" + +glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity "sha1-0VU1r3cy4C6Uj0xBYovZECk/YCM= sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity "sha1-q4eVM4hooLq9hSV1gBjCp+uVxC4= sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + +globals@^13.6.0, globals@^13.9.0: + version "13.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.0.tgz#4d733760304230a0082ed96e21e5c565f898089e" + integrity "sha1-TXM3YDBCMKAILtluIeXFZfiYCJ4= sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==" + dependencies: + type-fest "^0.20.2" + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity "sha1-qjiWs+abSH8X4x7SFD1pqOMMLYo= sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" + +globby@^11.0.3: + version "11.0.4" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" + integrity "sha1-LLr/d8Lypi5x6bKBOme5ejowAaU= sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==" + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==" + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globby@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" + integrity "sha1-+yzP+UAfhgCUXfral0QMypcrhoA= sha512-yANWAN2DUcBtuus5Cpd+SKROzXHs2iVXFZt/Ykrfz6SAXqacLX25NZpltE+39ceMexYF4TtEadjuSTw8+3wX4g==" + dependencies: + array-union "^1.0.1" + dir-glob "^2.0.0" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + +globby@^9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" + integrity "sha1-/QKacGxwPSm90XD0tts6P3p8tj0= sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==" + dependencies: + "@types/glob" "^7.1.1" + array-union "^1.0.2" + dir-glob "^2.2.2" + fast-glob "^2.2.6" + glob "^7.1.3" + ignore "^4.0.3" + pify "^4.0.1" + slash "^2.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.8" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" + integrity "sha1-5BK40z9eAGWTy9PO5t+fLOu+gCo= sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" + +graphlib@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.8.tgz#5761d414737870084c92ec7b5dbcb0592c9d35da" + integrity "sha1-V2HUFHN4cAhMkux7XbywWSydNdo= sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==" + dependencies: + lodash "^4.17.15" + +growly@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + integrity "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==" + +gzip-size@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274" + integrity "sha1-y5vuaS+HwGErIyhAqHOQTkwTUnQ= sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==" + dependencies: + duplexer "^0.1.1" + pify "^4.0.1" + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity "sha1-hX95zjWVgMNA1DCBzGSJcNC7I04= sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==" + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity "sha1-HwgDufjLIMD6E4It8ezds2veHv0= sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==" + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==" + dependencies: + ansi-regex "^2.0.0" + +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity "sha1-ZP5qywIGc+O3jbA1pa9pqp0HsRM= sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity "sha1-tdRU3CGZriJWmfNGfloH87lVuv0= sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s= sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity "sha1-Fl0wcMADCXUqEjakeTMeOsVvFCM= sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity "sha1-fhM4GKfTlHNPlB5zw9P5KR5liyU= sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==" + dependencies: + has-symbols "^1.0.2" + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==" + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==" + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity "sha1-bWHeldkd/Km5oCCJrThL/49it3E= sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==" + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.0, has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y= sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==" + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity "sha1-VcOB2eBuHSmXqIO0o/3f5/DTrzM= sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==" + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash-sum@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-1.0.2.tgz#33b40777754c6432573c120cc3808bbd10d47f04" + integrity "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ= sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==" + +hash-sum@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-2.0.0.tgz#81d01bb5de8ea4a214ad5d6ead1b523460b0b45a" + integrity "sha1-gdAbtd6OpKIUrV1urRtSNGCwtFo= sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity "sha1-C6vKU46NTuSg+JiNaIZlN6ADz0I= sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==" + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hast-util-parse-selector@^2.0.0: + version "2.2.5" + resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz#d57c23f4da16ae3c63b3b6ca4616683313499c3a" + integrity "sha1-1Xwj9NoWrjxjs7bKRhZoMxNJnDo= sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==" + +hastscript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" + integrity "sha1-6HaNfqxWw/3qyKkoMNWOgR5b9kA= sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==" + dependencies: + "@types/hast" "^2.0.0" + comma-separated-tokens "^1.0.0" + hast-util-parse-selector "^2.0.0" + property-information "^5.0.0" + space-separated-tokens "^1.0.0" + +he@1.2.x, he@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity "sha1-hK5l+n6vsWX922FWauFLrwVmTw8= sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + +hex-color-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" + integrity "sha1-TAb8y0YC/iYCs8k9+C1+fb8aio4= sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" + +highlight.js@^10.4.1, highlight.js@^10.7.1, highlight.js@~10.7.0: + version "10.7.3" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" + integrity "sha1-aXJy45kTVuQMPKxWanTu9oF1ZTE= sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" + +highlight.js@^9.12.0: + version "9.18.5" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.18.5.tgz#d18a359867f378c138d6819edfc2a8acd5f29825" + integrity "sha1-0Yo1mGfzeME41oGe38KorNXymCU= sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA==" + +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==" + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hoist-non-react-statics@^3.3.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity "sha1-7OCsr3HWLClpwuxZ/v9CpLGoW0U= sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==" + dependencies: + react-is "^16.7.0" + +hoopy@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" + integrity "sha1-YJIH1mEQADOpqUAq096mdzgcGx0= sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==" + +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity "sha1-3/wL+aIcAiCQkPKqaUKeFBTa8/k= sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==" + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +hsl-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e" + integrity "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4= sha512-M5ezZw4LzXbBKMruP+BNANf0k+19hDQMgpzBIYnya//Al+fjNct9Wf3b1WedLqdEs2hKBvxq/jh+DsHJLj0F9A==" + +hsla-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" + integrity "sha1-wc56MWjIxmFAM6S194d/OyJfnDg= sha512-7Wn5GMLuHBjZCb2bTmnDOycho0p/7UVaAeqXZGbHrBCl6Yd/xDhQJAXe6Ga9AXJH2I5zY1dEdYw2u1UptnSBJA==" + +html-encoding-sniffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + integrity "sha1-5w2EuU2lOqN14R/jo1G+ZkLKRvg= sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==" + dependencies: + whatwg-encoding "^1.0.1" + +html-entities@^1.3.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.4.0.tgz#cfbd1b01d2afaf9adca1b10ae7dffab98c71d2dc" + integrity "sha1-z70bAdKvr5rcobEK59/6uYxx0tw= sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==" + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity "sha1-39YAJ9o2o238viNiYsAKWCJoFFM= sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + +html-minifier@^3.2.3: + version "3.5.21" + resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" + integrity "sha1-0AQOBUcw41TbAIRjWTGUAVIS0gw= sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==" + dependencies: + camel-case "3.0.x" + clean-css "4.2.x" + commander "2.17.x" + he "1.2.x" + param-case "2.1.x" + relateurl "0.2.x" + uglify-js "3.4.x" + +html-tags@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-2.0.0.tgz#10b30a386085f43cede353cc8fa7cb0deeea668b" + integrity "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos= sha512-+Il6N8cCo2wB/Vd3gqy/8TZhTD3QvcVeQLCnZiGkGCH3JP28IgGAY41giccp2W4R3jfyJPAP318FQTa1yU7K7g==" + +html-tags@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140" + integrity "sha1-e15vfmZen7QfMAB+2eDUHpf7IUA= sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==" + +html-webpack-plugin@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz#b01abbd723acaaa7b37b6af4492ebda03d9dd37b" + integrity "sha1-sBq71yOsqqeze2r0SS69oD2d03s= sha512-Br4ifmjQojUP4EmHnRBoUIYcZ9J7M4bTMcm7u6xoIAIuq2Nte4TzXX0533owvkQKQD1WeMTTTyD4Ni4QKxS0Bg==" + dependencies: + html-minifier "^3.2.3" + loader-utils "^0.2.16" + lodash "^4.17.3" + pretty-error "^2.0.2" + tapable "^1.0.0" + toposort "^1.0.0" + util.promisify "1.0.0" + +htmlparser2@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" + integrity "sha1-xNditsM3GgXb5l6UrkOp+EX7j7c= sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==" + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.5.2" + entities "^2.0.0" + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" + +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity "sha1-T1ApzxMjnzEDblsuVSkrz7zIXI8= sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==" + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==" + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity "sha1-bGGeT5xgMIw4UZSYwU+7EKrOuwY= sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==" + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-parser-js@>=0.5.1: + version "0.5.3" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9" + integrity "sha1-AdJwnHnUFpi7AdTezF6dpOSgM9k= sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==" + +http-proxy-middleware@0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" + integrity "sha1-GDx9xKoUeRUDBkmMIQza+WCApDo= sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==" + dependencies: + http-proxy "^1.17.0" + is-glob "^4.0.0" + lodash "^4.17.11" + micromatch "^3.1.10" + +http-proxy-middleware@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-1.3.1.tgz#43700d6d9eecb7419bf086a128d0f7205d9eb665" + integrity "sha1-Q3ANbZ7st0Gb8IahKND3IF2etmU= sha512-13eVVDYS4z79w7f1+NPllJtOQFx/FdUW4btIvVRMaRlUY9VGstAbo5MOhLEuUgZFRHn3x50ufn25zkj/boZnEg==" + dependencies: + "@types/http-proxy" "^1.17.5" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + +http-proxy@^1.17.0, http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity "sha1-QBVB8FNIhLv5UmAzTnL4juOXZUk= sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==" + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==" + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==" + +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity "sha1-xbHNFPUK6uCatsWf5jujOV/k36M= sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==" + +iconv-lite@0.4.24, iconv-lite@^0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs= sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==" + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity "sha1-pS+AvzjaGVLrXGgXkHGYcaGnJQE= sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==" + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +icss-utils@^4.0.0, icss-utils@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" + integrity "sha1-IRcLU3ie4nRHwvR91oMIFAP5pGc= sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==" + dependencies: + postcss "^7.0.14" + +ieee754@^1.1.4, ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity "sha1-jrehCmP/8l0VpXsAFYbRd9Gw01I= sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity "sha1-xg7taebY/bazEEofy8ocGS3FtQE= sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==" + +ignore@^3.3.5: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity "sha1-Cpf7h2mG6AgcYxFg+PnziRV/AEM= sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" + +ignore@^4.0.3, ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity "sha1-dQ49tYYgh7RzfrrIIH/9HvJ7Jfw= sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + +ignore@^5.1.4, ignore@^5.1.8: + version "5.1.9" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.9.tgz#9ec1a5cbe8e1446ec60d4420060d43aa6e7382fb" + integrity "sha1-nsGly+jhRG7GDUQgBg1Dqm5zgvs= sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==" + +image-size@~0.5.0: + version "0.5.5" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" + integrity "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w= sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==" + +immutable@^3.8.1, immutable@^3.x.x: + version "3.8.2" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" + integrity "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM= sha512-15gZoQ38eYjEjxkorfbcgBKBL6R7T459OuK+CpcWt7O3KF4uPCx2tD0uFETlUDIyo+1789crbMhTvQBSR5yBMg==" + +import-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" + integrity "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= sha512-Ew5AZzJQFqrOV5BTW3EIoHAnoie1LojZLXKcCQ/yTRyVZosBhK1x1ViYjHGf5pAFOq8ZyChZp6m/fSN7pJyZtg==" + dependencies: + import-from "^2.1.0" + +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity "sha1-2BNVwVYS04bGH53dOSLUMEgipUY= sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==" + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + +import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity "sha1-NxYsJfy566oublPVtNiM4X2eDCs= sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==" + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-from@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" + integrity "sha1-M1238qev/VOqpHHUuAId7ja387E= sha512-0vdnLL2wSGnhlRmzHJAg5JHjt1l2vYhzJ7tNLGbeVg0fse56tpGaH0uzH+r9Slej+BSXXEHvBKDEnVSLLE9/+w==" + dependencies: + resolve-from "^3.0.0" + +import-local@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity "sha1-VQcL44pZk88Y72236WH1vuXFoJ0= sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==" + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity "sha1-khi5srkoojixPcT7a21XbyMUU+o= sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" + +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + integrity "sha1-8w9xbI4r00bHtn0985FVZqfAVgc= sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==" + +infer-owner@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity "sha1-xM78qo5RBRwqQLos6KPScpWvlGc= sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w= sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==" + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + +ini@^1.3.4: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity "sha1-op2kJbSIBvNHZ6Tvzjlyaa8oQyw= sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + +inquirer@^7.1.0: + version "7.3.3" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" + integrity "sha1-BNF2sq8Er8FXqD/XwQDpjuCq0AM= sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==" + dependencies: + ansi-escapes "^4.2.1" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-width "^3.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.19" + mute-stream "0.0.8" + run-async "^2.4.0" + rxjs "^6.6.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + +internal-ip@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" + integrity "sha1-hFRSuq2dLKO2nGNaE3rLmg2tCQc= sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==" + dependencies: + default-gateway "^4.2.0" + ipaddr.js "^1.9.0" + +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity "sha1-c0fjB97uovqsKsYgXUvH00ln9Zw= sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==" + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + +interpret@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity "sha1-Zlq4vE2iendKQFhOgS4+D6RbGh4= sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" + +intersperse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/intersperse/-/intersperse-1.0.0.tgz#f2561fb1cfef9f5277cc3347a22886b4351a5181" + integrity "sha1-8lYfsc/vn1J3zDNHoiiGtDUaUYE= sha512-LGcfug7OTeWkaQ8PEq8XbTy9Jl6uCNg8DrPnQUmwxSY8UETj1Y+LLmpdD0qHdEj6KVchuH3BE3ZzIXQ1t3oFUw==" + +invariant@^2.0.0, invariant@^2.2.2, invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity "sha1-YQ88ksk1nOHbYW5TgAjSP/NRWOY= sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==" + dependencies: + loose-envify "^1.0.0" + +ip-regex@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + integrity "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw==" + +ip@^1.1.0, ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= sha512-rBtCAQAJm8A110nbwn6YdveUnuZH3WrC36IwkRXxDnq53JvXA2NVQvB7IHyKomxK1MJ4VDNw3UtFDdXQ+AvLYA==" + +ipaddr.js@1.9.1, ipaddr.js@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity "sha1-v/OFQ+64mEglB5/zoqjmy9RngbM= sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + +is-absolute-url@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" + integrity "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= sha512-vOx7VprsKyllwjSkLV79NIhpyLfr3jAp7VaTCMXOJHu4m0Ew1CZ2fcjASwmV1jI3BWuWHB013M48eyeldk9gYg==" + +is-absolute-url@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" + integrity "sha1-lsaiK2ojkpsR6gr7GDbDatSl1pg= sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==" + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY= sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==" + dependencies: + kind-of "^6.0.0" + +is-alphabetical@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" + integrity "sha1-nn1rlJFr4iFTdF0YTCmMv5hqaG0= sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==" + +is-alphanumerical@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf" + integrity "sha1-frmiQx+FX2se8aeOMm31FWlsTb8= sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==" + dependencies: + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity "sha1-FbP4j9oB8ql/7ITKdhpWDxI++ps= sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==" + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity "sha1-RXSirlb3qyBolvtDHq7tBm/fjwM= sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity "sha1-CBR6GHW8KzIAXUHM2Ckd/8ZpHfM= sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==" + dependencies: + has-bigints "^1.0.1" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==" + dependencies: + binary-extensions "^1.0.0" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity "sha1-6h9/O4DwZCNug0cPhsCcJU+0Wwk= sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==" + dependencies: + binary-extensions "^2.0.0" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity "sha1-XG3CACRt2TIa5LiFoRS7H3X2Nxk= sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==" + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity "sha1-76ouqdqg16suoTqXsritUf776L4= sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity "sha1-RzAdWN0CWUB4ZVR4U99tYf5HGUU= sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==" + +is-ci@^1.0.10: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" + integrity "sha1-43ecjuF/zPQoSI9uKBGH8uYyhBw= sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==" + dependencies: + ci-info "^1.5.0" + +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity "sha1-a8YzQYGBDgS1wis9WJ/cpVAmQEw= sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==" + dependencies: + ci-info "^2.0.0" + +is-color-stop@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" + integrity "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U= sha512-H1U8Vz0cfXNujrJzEcvvwMDW9Ra+biSYA3ThdQvAnMLJkEHQXn6bWzLkxHtVYJ+Sdbx0b6finn3jZiaVe7MAHA==" + dependencies: + css-color-names "^0.0.4" + hex-color-regex "^1.1.0" + hsl-regex "^1.0.0" + hsla-regex "^1.0.0" + rgb-regex "^1.0.1" + rgba-regex "^1.0.0" + +is-core-module@^2.2.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" + integrity "sha1-AyEzbD0JJeSX/Zf12VyxFKXM1Ug= sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==" + dependencies: + has "^1.0.3" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==" + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc= sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==" + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity "sha1-CEHVU25yTCVZe/bqYuG9OCmN8x8= sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==" + dependencies: + has-tostringtag "^1.0.0" + +is-decimal@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" + integrity "sha1-ZaOllYocW2OnBuGzM9fNn2MNP6U= sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco= sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==" + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw= sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==" + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==" + +is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity "sha1-M+6r4jz+hvFL3kQIoCwM+4U6zao= sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" + +is-dom@^1.0.9: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-dom/-/is-dom-1.1.0.tgz#af1fced292742443bb59ca3f76ab5e80907b4e8a" + integrity "sha1-rx/O0pJ0JEO7Wco/dqtegJB7Too= sha512-u82f6mvhYxRPKpw8V1N0W8ce1xXwOrQtgGcxl6UCL5zBmZu3is/18K0rR7uFCnMDuAsS/3W54mGL4vsaFUQlEQ==" + dependencies: + is-object "^1.0.1" + is-window "^1.0.2" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==" + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ= sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==" + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==" + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0= sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity "sha1-fRQK3DiarzARqPKipM+m+q3/sRg= sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==" + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity "sha1-ZPYeQsu7LuwgcanawLKLoeZdUIQ= sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==" + dependencies: + is-extglob "^2.1.1" + +is-hexadecimal@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" + integrity "sha1-zDXJdYjaS9Saju3WvECC1E3LI6c= sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" + +is-mobile@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/is-mobile/-/is-mobile-2.2.2.tgz#f6c9c5d50ee01254ce05e739bdd835f1ed4e9954" + integrity "sha1-9snF1Q7gElTOBec5vdg18e1OmVQ= sha512-wW/SXnYJkTjs++tVK5b6kVITZpAZPtUrt9SF80vvxGiF/Oywal+COk1jlRkiVq15RFNEQKQY31TkV24/1T5cVg==" + +is-negative-zero@^2.0.0, is-negative-zero@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" + integrity "sha1-PedGwY3aIxkkGlNnWQjY92bxHCQ= sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" + +is-number-object@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" + integrity "sha1-anqvg4x/BoalC0VT9+VKlklOifA= sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==" + dependencies: + has-tostringtag "^1.0.0" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==" + dependencies: + kind-of "^3.0.2" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss= sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + +is-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity "sha1-PkcprB9f3gJc19g6iW2rn09n2w8= sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==" + +is-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" + integrity "sha1-Rz+wXZc3BeP9liBUUBjKjiLvSYI= sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" + +is-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" + integrity "sha1-pWVS4cZlyelQtKAlRh2ofnL4b88= sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==" + +is-path-cwd@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" + integrity "sha1-Z9Q7gmZKe1GR/ZEZEn6zAASKn9s= sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==" + +is-path-in-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" + integrity "sha1-v+Lcomxp85cmWkAJljYCk1oFOss= sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==" + dependencies: + is-path-inside "^2.1.0" + +is-path-inside@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" + integrity "sha1-fJgQWH1lmkDSe8201WFuqwWUlLI= sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==" + dependencies: + path-is-inside "^1.0.2" + +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity "sha1-caUMhCnfync8kqOQpKA7OfzVHT4= sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==" + +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity "sha1-r28uoUrFpkYYOlu9tbqrvBVq2dc= sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==" + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc= sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==" + dependencies: + isobject "^3.0.1" + +is-promise@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" + integrity "sha1-OauVnMv5p3TPB597QMeib3YxNfE= sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + +is-regex@^1.0.4, is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity "sha1-7vVmPNWfpMCuM5UFMj32hUuxWVg= sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==" + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity "sha1-/S2INUXEa6xaYz57mgnof6LLUGk= sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==" + +is-resolvable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + integrity "sha1-+xj4fOH+uSUWnJpAfBkxijIG7Yg= sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==" + +is-shallow-equal@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-shallow-equal/-/is-shallow-equal-1.0.1.tgz#c410b51eb1c12ee50cd02891d32d1691a132d73c" + integrity "sha1-xBC1HrHBLuUM0CiR0y0WkaEy1zw= sha512-lq5RvK+85Hs5J3p4oA4256M1FEffzmI533ikeDHvJd42nouRRx5wBzt36JuviiGe5dIPyHON/d0/Up+PBo6XkQ==" + +is-shared-array-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" + integrity "sha1-l7DIX72stZycRG/mU7gs8rW3z+Y= sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==" + +is-stream@^1.0.1, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity "sha1-EtSj3U5o4Lec6428hBc66A2RykQ= sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==" + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity "sha1-+sHj1TuXrVqdCunO8jifWBClwHc= sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity "sha1-DdEr8gBvJVu1j2lREO/3SR7rwP0= sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==" + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity "sha1-ptrJO2NbBjymhyI23oiRClevE5w= sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==" + dependencies: + has-symbols "^1.0.2" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + +is-weakref@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.1.tgz#842dba4ec17fa9ac9850df2d6efbc1737274f2a2" + integrity "sha1-hC26TsF/qayYUN8tbvvBc3J08qI= sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==" + dependencies: + call-bind "^1.0.0" + +is-whitespace@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/is-whitespace/-/is-whitespace-0.3.0.tgz#1639ecb1be036aec69a54cbb401cfbed7114ab7f" + integrity "sha1-Fjnssb4DauxppUy7QBz77XEUq38= sha512-RydPhl4S6JwAyj0JJjshWJEFG6hNye3pZFBRZaTUfZFwGHxzppNaNOVgQuS/E/SlhrApuMXrpnK1EEIXfdo3Dg==" + +is-window@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-window/-/is-window-1.0.2.tgz#2c896ca53db97de45d3c33133a65d8c9f563480d" + integrity "sha1-LIlspT25feRdPDMTOmXYyfVjSA0= sha512-uj00kdXyZb9t9RcAUAwMZAnkBUwdYGhYlt7djMXhfyhUCzwNba50tIiBKR7q0l7tdoBtFVw/3JmLY6fI3rmZmg==" + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity "sha1-0YUOuXkezRjmGCzhKjDzlmNLsZ0= sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==" + +is-wsl@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity "sha1-dKTHbnfKn9P5MvKQwX6jJs0VcnE= sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==" + dependencies: + is-docker "^2.0.0" + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + +ismobilejs@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ismobilejs/-/ismobilejs-1.1.1.tgz#c56ca0ae8e52b24ca0f22ba5ef3215a2ddbbaa0e" + integrity "sha1-xWygro5Sskyg8iul7zIVot27qg4= sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==" + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity "sha1-TkMekrEalzFjaqH5yNHMvP2reN8= sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" + +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + integrity "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= sha512-9c4TNAKYXM5PRyVcwUZrF3W09nQ+sO7+jydgs4ZGW9dhsLG2VOlISJABombdQqQRXCwuYG3sYV/puGf5rp0qmA==" + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" + +istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49" + integrity "sha1-Z18KtpUD+tSx2En3NrqsqAM0T0k= sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==" + +istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630" + integrity "sha1-pfY9kfC7wMPkee9MXeAnM17G1jA= sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==" + dependencies: + "@babel/generator" "^7.4.0" + "@babel/parser" "^7.4.3" + "@babel/template" "^7.4.0" + "@babel/traverse" "^7.4.3" + "@babel/types" "^7.4.0" + istanbul-lib-coverage "^2.0.5" + semver "^6.0.0" + +istanbul-lib-report@^2.0.4: + version "2.0.8" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz#5a8113cd746d43c4889eba36ab10e7d50c9b4f33" + integrity "sha1-WoETzXRtQ8SInro2qxDn1QybTzM= sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==" + dependencies: + istanbul-lib-coverage "^2.0.5" + make-dir "^2.1.0" + supports-color "^6.1.0" + +istanbul-lib-source-maps@^3.0.1: + version "3.0.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz#284997c48211752ec486253da97e3879defba8c8" + integrity "sha1-KEmXxIIRdS7EhiU9qX44ed77qMg= sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==" + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^2.0.5" + make-dir "^2.1.0" + rimraf "^2.6.3" + source-map "^0.6.1" + +istanbul-reports@^2.2.6: + version "2.2.7" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.7.tgz#5d939f6237d7b48393cc0959eab40cd4fd056931" + integrity "sha1-XZOfYjfXtIOTzAlZ6rQM1P0FaTE= sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==" + dependencies: + html-escaper "^2.0.0" + +javascript-stringify@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/javascript-stringify/-/javascript-stringify-2.1.0.tgz#27c76539be14d8bd128219a2d731b09337904e79" + integrity "sha1-J8dlOb4U2L0Sghmi1zGwkzeQTnk= sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==" + +jest-changed-files@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.9.0.tgz#08d8c15eb79a7fa3fc98269bc14b451ee82f8039" + integrity "sha1-CNjBXreaf6P8mCabwUtFHugvgDk= sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg==" + dependencies: + "@jest/types" "^24.9.0" + execa "^1.0.0" + throat "^4.0.0" + +jest-cli@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.9.0.tgz#ad2de62d07472d419c6abc301fc432b98b10d2af" + integrity "sha1-rS3mLQdHLUGcarwwH8QyuYsQ0q8= sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg==" + dependencies: + "@jest/core" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + chalk "^2.0.1" + exit "^0.1.2" + import-local "^2.0.0" + is-ci "^2.0.0" + jest-config "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + prompts "^2.0.1" + realpath-native "^1.1.0" + yargs "^13.3.0" + +jest-config@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.9.0.tgz#fb1bbc60c73a46af03590719efa4825e6e4dd1b5" + integrity "sha1-+xu8YMc6Rq8DWQcZ76SCXm5N0bU= sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==" + dependencies: + "@babel/core" "^7.1.0" + "@jest/test-sequencer" "^24.9.0" + "@jest/types" "^24.9.0" + babel-jest "^24.9.0" + chalk "^2.0.1" + glob "^7.1.1" + jest-environment-jsdom "^24.9.0" + jest-environment-node "^24.9.0" + jest-get-type "^24.9.0" + jest-jasmine2 "^24.9.0" + jest-regex-util "^24.3.0" + jest-resolve "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + micromatch "^3.1.10" + pretty-format "^24.9.0" + realpath-native "^1.1.0" + +jest-diff@^24.3.0, jest-diff@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" + integrity "sha1-kxt9DVd4obr3RSy4FuMl43JAVdo= sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==" + dependencies: + chalk "^2.0.1" + diff-sequences "^24.9.0" + jest-get-type "^24.9.0" + pretty-format "^24.9.0" + +jest-diff@^26.0.0: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" + integrity "sha1-GqdGi1LDpo19XF/c381eSb0WQ5Q= sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==" + dependencies: + chalk "^4.0.0" + diff-sequences "^26.6.2" + jest-get-type "^26.3.0" + pretty-format "^26.6.2" + +jest-docblock@^24.3.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.9.0.tgz#7970201802ba560e1c4092cc25cbedf5af5a8ce2" + integrity "sha1-eXAgGAK6Vg4cQJLMJcvt9a9ajOI= sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==" + dependencies: + detect-newline "^2.1.0" + +jest-each@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.9.0.tgz#eb2da602e2a610898dbc5f1f6df3ba86b55f8b05" + integrity "sha1-6y2mAuKmEImNvF8fbfO6hrVfiwU= sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog==" + dependencies: + "@jest/types" "^24.9.0" + chalk "^2.0.1" + jest-get-type "^24.9.0" + jest-util "^24.9.0" + pretty-format "^24.9.0" + +jest-environment-jsdom-fifteen@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom-fifteen/-/jest-environment-jsdom-fifteen-1.0.2.tgz#49a0af55e0d32737a6114a1575dd714702ad63b0" + integrity "sha1-SaCvVeDTJzemEUoVdd1xRwKtY7A= sha512-nfrnAfwklE1872LIB31HcjM65cWTh1wzvMSp10IYtPJjLDUbTTvDpajZgIxUnhRmzGvogdHDayCIlerLK0OBBg==" + dependencies: + "@jest/environment" "^24.3.0" + "@jest/fake-timers" "^24.3.0" + "@jest/types" "^24.3.0" + jest-mock "^24.0.0" + jest-util "^24.0.0" + jsdom "^15.2.1" + +jest-environment-jsdom@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz#4b0806c7fc94f95edb369a69cc2778eec2b7375b" + integrity "sha1-SwgGx/yU+V7bNpppzCd47sK3N1s= sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==" + dependencies: + "@jest/environment" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + jest-util "^24.9.0" + jsdom "^11.5.1" + +jest-environment-node@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.9.0.tgz#333d2d2796f9687f2aeebf0742b519f33c1cbfd3" + integrity "sha1-Mz0tJ5b5aH8q7r8HQrUZ8zwcv9M= sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==" + dependencies: + "@jest/environment" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + jest-util "^24.9.0" + +jest-get-type@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" + integrity "sha1-FoSgyKUPLkkBtmRK6GH1ee7S7w4= sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==" + +jest-get-type@^26.3.0: + version "26.3.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" + integrity "sha1-6X3Dw/U8K0Bsp6+u1Ek7HQmRmeA= sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==" + +jest-haste-map@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" + integrity "sha1-s4pdZCdJNOIfpBeump++t3zqrH0= sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==" + dependencies: + "@jest/types" "^24.9.0" + anymatch "^2.0.0" + fb-watchman "^2.0.0" + graceful-fs "^4.1.15" + invariant "^2.2.4" + jest-serializer "^24.9.0" + jest-util "^24.9.0" + jest-worker "^24.9.0" + micromatch "^3.1.10" + sane "^4.0.3" + walker "^1.0.7" + optionalDependencies: + fsevents "^1.2.7" + +jest-jasmine2@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz#1f7b1bd3242c1774e62acabb3646d96afc3be6a0" + integrity "sha1-H3sb0yQsF3TmKsq7NkbZavw75qA= sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw==" + dependencies: + "@babel/traverse" "^7.1.0" + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + chalk "^2.0.1" + co "^4.6.0" + expect "^24.9.0" + is-generator-fn "^2.0.0" + jest-each "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-runtime "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + pretty-format "^24.9.0" + throat "^4.0.0" + +jest-leak-detector@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz#b665dea7c77100c5c4f7dfcb153b65cf07dcf96a" + integrity "sha1-tmXep8dxAMXE99/LFTtlzwfc+Wo= sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA==" + dependencies: + jest-get-type "^24.9.0" + pretty-format "^24.9.0" + +jest-matcher-utils@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz#f5b3661d5e628dffe6dd65251dfdae0e87c3a073" + integrity "sha1-9bNmHV5ijf/m3WUlHf2uDofDoHM= sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA==" + dependencies: + chalk "^2.0.1" + jest-diff "^24.9.0" + jest-get-type "^24.9.0" + pretty-format "^24.9.0" + +jest-message-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3" + integrity "sha1-Un9UoeOA9eICqNEUmw7IcvQxGeM= sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==" + dependencies: + "@babel/code-frame" "^7.0.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/stack-utils" "^1.0.1" + chalk "^2.0.1" + micromatch "^3.1.10" + slash "^2.0.0" + stack-utils "^1.0.1" + +jest-mock@^24.0.0, jest-mock@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6" + integrity "sha1-wig1VB7jebkIZzrVEIeiGFwT8cY= sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==" + dependencies: + "@jest/types" "^24.9.0" + +jest-pnp-resolver@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" + integrity "sha1-twSsCuAoqJEIpNBAs/kZ393I4zw= sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==" + +jest-regex-util@^24.3.0, jest-regex-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636" + integrity "sha1-wT+zOAveIr9ldUMsST6o/jeWVjY= sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==" + +jest-resolve-dependencies@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz#ad055198959c4cfba8a4f066c673a3f0786507ab" + integrity "sha1-rQVRmJWcTPuopPBmxnOj8HhlB6s= sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g==" + dependencies: + "@jest/types" "^24.9.0" + jest-regex-util "^24.3.0" + jest-snapshot "^24.9.0" + +jest-resolve@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.9.0.tgz#dff04c7687af34c4dd7e524892d9cf77e5d17321" + integrity "sha1-3/BMdoevNMTdflJIktnPd+XRcyE= sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==" + dependencies: + "@jest/types" "^24.9.0" + browser-resolve "^1.11.3" + chalk "^2.0.1" + jest-pnp-resolver "^1.2.1" + realpath-native "^1.1.0" + +jest-runner@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.9.0.tgz#574fafdbd54455c2b34b4bdf4365a23857fcdf42" + integrity "sha1-V0+v29VEVcKzS0vfQ2WiOFf830I= sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg==" + dependencies: + "@jest/console" "^24.7.1" + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + chalk "^2.4.2" + exit "^0.1.2" + graceful-fs "^4.1.15" + jest-config "^24.9.0" + jest-docblock "^24.3.0" + jest-haste-map "^24.9.0" + jest-jasmine2 "^24.9.0" + jest-leak-detector "^24.9.0" + jest-message-util "^24.9.0" + jest-resolve "^24.9.0" + jest-runtime "^24.9.0" + jest-util "^24.9.0" + jest-worker "^24.6.0" + source-map-support "^0.5.6" + throat "^4.0.0" + +jest-runtime@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.9.0.tgz#9f14583af6a4f7314a6a9d9f0226e1a781c8e4ac" + integrity "sha1-nxRYOvak9zFKap2fAibhp4HI5Kw= sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw==" + dependencies: + "@jest/console" "^24.7.1" + "@jest/environment" "^24.9.0" + "@jest/source-map" "^24.3.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/yargs" "^13.0.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.1.15" + jest-config "^24.9.0" + jest-haste-map "^24.9.0" + jest-message-util "^24.9.0" + jest-mock "^24.9.0" + jest-regex-util "^24.3.0" + jest-resolve "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + realpath-native "^1.1.0" + slash "^2.0.0" + strip-bom "^3.0.0" + yargs "^13.3.0" + +jest-serializer-vue@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/jest-serializer-vue/-/jest-serializer-vue-2.0.2.tgz#b238ef286357ec6b480421bd47145050987d59b3" + integrity "sha1-sjjvKGNX7GtIBCG9RxRQUJh9WbM= sha512-nK/YIFo6qe3i9Ge+hr3h4PpRehuPPGZFt8LDBdTHYldMb7ZWlkanZS8Ls7D8h6qmQP2lBQVDLP0DKn5bJ9QApQ==" + dependencies: + pretty "2.0.0" + +jest-serializer@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" + integrity "sha1-5tfX75bTHouQeacUdUxdXFgojnM= sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==" + +jest-snapshot@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.9.0.tgz#ec8e9ca4f2ec0c5c87ae8f925cf97497b0e951ba" + integrity "sha1-7I6cpPLsDFyHro+SXPl0l7DpUbo= sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew==" + dependencies: + "@babel/types" "^7.0.0" + "@jest/types" "^24.9.0" + chalk "^2.0.1" + expect "^24.9.0" + jest-diff "^24.9.0" + jest-get-type "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-resolve "^24.9.0" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + pretty-format "^24.9.0" + semver "^6.2.0" + +jest-transform-stub@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/jest-transform-stub/-/jest-transform-stub-2.0.0.tgz#19018b0851f7568972147a5d60074b55f0225a7d" + integrity "sha1-GQGLCFH3VolyFHpdYAdLVfAiWn0= sha512-lspHaCRx/mBbnm3h4uMMS3R5aZzMwyNpNIJLXj4cEsV0mIUtS4IjYJLSoyjRCtnxb6RIGJ4NL2quZzfIeNhbkg==" + +jest-util@^24.0.0, jest-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.9.0.tgz#7396814e48536d2e85a37de3e4c431d7cb140162" + integrity "sha1-c5aBTkhTbS6Fo33j5MQx18sUAWI= sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==" + dependencies: + "@jest/console" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/source-map" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + callsites "^3.0.0" + chalk "^2.0.1" + graceful-fs "^4.1.15" + is-ci "^2.0.0" + mkdirp "^0.5.1" + slash "^2.0.0" + source-map "^0.6.0" + +jest-validate@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab" + integrity "sha1-B3XFU2DRc82FTkAYB1bU/1Le+Ks= sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==" + dependencies: + "@jest/types" "^24.9.0" + camelcase "^5.3.1" + chalk "^2.0.1" + jest-get-type "^24.9.0" + leven "^3.1.0" + pretty-format "^24.9.0" + +jest-watch-typeahead@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-0.4.2.tgz#e5be959698a7fa2302229a5082c488c3c8780a4a" + integrity "sha1-5b6Vlpin+iMCIppQgsSIw8h4Cko= sha512-f7VpLebTdaXs81rg/oj4Vg/ObZy2QtGzAmGLNsqUS5G5KtSN68tFcIsbvNODfNyQxU78g7D8x77o3bgfBTR+2Q==" + dependencies: + ansi-escapes "^4.2.1" + chalk "^2.4.1" + jest-regex-util "^24.9.0" + jest-watcher "^24.3.0" + slash "^3.0.0" + string-length "^3.1.0" + strip-ansi "^5.0.0" + +jest-watcher@^24.3.0, jest-watcher@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.9.0.tgz#4b56e5d1ceff005f5b88e528dc9afc8dd4ed2b3b" + integrity "sha1-S1bl0c7/AF9biOUo3Jr8jdTtKzs= sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw==" + dependencies: + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/yargs" "^13.0.0" + ansi-escapes "^3.0.0" + chalk "^2.0.1" + jest-util "^24.9.0" + string-length "^2.0.0" + +jest-worker@^24.6.0, jest-worker@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" + integrity "sha1-Xb/bWy0yLphWeJgjipaXvM5ns+U= sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==" + dependencies: + merge-stream "^2.0.0" + supports-color "^6.1.0" + +jest@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" + integrity "sha1-mH0pDAWgi1LFYYjBAC42jtsAcXE= sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw==" + dependencies: + import-local "^2.0.0" + jest-cli "^24.9.0" + +js-base64@^2.6.1: + version "2.6.4" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4" + integrity "sha1-9OaGxd4eofhn28rT1G2WlCjfmMQ= sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==" + +js-beautify@^1.6.12, js-beautify@^1.6.14: + version "1.14.0" + resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.14.0.tgz#2ce790c555d53ce1e3d7363227acf5dc69024c2d" + integrity "sha1-LOeQxVXVPOHj1zYyJ6z13GkCTC0= sha512-yuck9KirNSCAwyNJbqW+BxJqJ0NLJ4PwBUzQQACl5O3qHMBXVkXb/rD0ilh/Lat/tn88zSZ+CAHOlk0DsY7GuQ==" + dependencies: + config-chain "^1.1.12" + editorconfig "^0.15.3" + glob "^7.1.3" + nopt "^5.0.0" + +js-file-download@^0.4.12: + version "0.4.12" + resolved "https://registry.yarnpkg.com/js-file-download/-/js-file-download-0.4.12.tgz#10c70ef362559a5b23cdbdc3bd6f399c3d91d821" + integrity "sha1-EMcO82JVmlsjzb3DvW85nD2R2CE= sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg==" + +js-message@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/js-message/-/js-message-1.0.7.tgz#fbddd053c7a47021871bb8b2c95397cc17c20e47" + integrity "sha1-+93QU8ekcCGHG7iyyVOXzBfCDkc= sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA==" + +js-queue@2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/js-queue/-/js-queue-2.0.2.tgz#0be590338f903b36c73d33c31883a821412cd482" + integrity "sha1-C+WQM4+QOzbHPTPDGIOoIUEs1II= sha512-pbKLsbCfi7kriM3s1J4DDCo7jQkI58zPLHi0heXPzPlj0hjUsm+FesPUbE0DSbIVIK503A36aUBoCN7eMFedkA==" + dependencies: + easy-stack "^1.0.1" + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity "sha1-GSA/tZmR35jjoocFDUZHzerzJJk= sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity "sha1-mGbfOVECEw449/mWvOtlRDIJwls= sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==" + +js-yaml@=4.1.0, js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity "sha1-wftl+PUBeQHN0slRhkuhhFihBgI= sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==" + dependencies: + argparse "^2.0.1" + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity "sha1-2ugS/bOCX6MGYJqHFzg8UMNqBTc= sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity "sha1-peZUwuWi3rXyAdls77yoDA7y9RM= sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" + +jsdom@^11.5.1: + version "11.12.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" + integrity "sha1-GoDUDd03ih3lllbp5txaO6hle8g= sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==" + dependencies: + abab "^2.0.0" + acorn "^5.5.3" + acorn-globals "^4.1.0" + array-equal "^1.0.0" + cssom ">= 0.3.2 < 0.4.0" + cssstyle "^1.0.0" + data-urls "^1.0.0" + domexception "^1.0.1" + escodegen "^1.9.1" + html-encoding-sniffer "^1.0.2" + left-pad "^1.3.0" + nwsapi "^2.0.7" + parse5 "4.0.0" + pn "^1.1.0" + request "^2.87.0" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" + tough-cookie "^2.3.4" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.3" + whatwg-mimetype "^2.1.0" + whatwg-url "^6.4.1" + ws "^5.2.0" + xml-name-validator "^3.0.0" + +jsdom@^15.2.1: + version "15.2.1" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-15.2.1.tgz#d2feb1aef7183f86be521b8c6833ff5296d07ec5" + integrity "sha1-0v6xrvcYP4a+UhuMaDP/UpbQfsU= sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==" + dependencies: + abab "^2.0.0" + acorn "^7.1.0" + acorn-globals "^4.3.2" + array-equal "^1.0.0" + cssom "^0.4.1" + cssstyle "^2.0.0" + data-urls "^1.1.0" + domexception "^1.0.1" + escodegen "^1.11.1" + html-encoding-sniffer "^1.0.2" + nwsapi "^2.2.0" + parse5 "5.1.0" + pn "^1.1.0" + request "^2.88.0" + request-promise-native "^1.0.7" + saxes "^3.1.9" + symbol-tree "^3.2.2" + tough-cookie "^3.0.1" + w3c-hr-time "^1.0.1" + w3c-xmlserializer "^1.1.2" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^7.0.0" + ws "^7.0.0" + xml-name-validator "^3.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity "sha1-gFZNLkg9rPbo7yCWUKZ98/DCg6Q= sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==" + +json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity "sha1-u4Z8+zRQ5pEHwTHRxRS6s9yLyqk= sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity "sha1-fEeAWpQxmSjgV3dAXcEuH3pO4C0= sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + +json-schema-editor-vue@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/json-schema-editor-vue/-/json-schema-editor-vue-1.2.5.tgz#6a4c03ea00f24bd4fef23ea8f0dc6d1f9c161a80" + integrity "sha1-akwD6gDyS9T+8j6o8NxtH5wWGoA= sha512-t63czJnxvOUWOhywnRF8L2vm7D5ZcoSq01MRvePU11etEQ6TNsWf/NnrR9AM67Z/pyEubKLXZemI8Z0Cik88YQ==" + dependencies: + ant-design-vue "^1.7.2" + core-js "^3.6.5" + vue "^2.6.11" + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity "sha1-afaofZUTq4u4/mO9sJecRI5oRmA= sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity "sha1-rnvLNlard6c7pcSb9lTzjmtoYOI= sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= sha512-a3xHnILGMtk+hDOqNwHzF6e2fNbiMrXZvxKQiEv2MlgQP+pjIOzqAmKYD2mDpXYE/44M7g+n9p2bKkYWDUcXCQ==" + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + +json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + integrity "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= sha512-i/J297TW6xyj7sDFa7AmBPkQvLIxWr2kKPWI26tXydnZrzVAocNqn5DMNT1Mzk0vit1V5UkRM7C1KdVNp7Lmcg==" + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + +json2mq@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/json2mq/-/json2mq-0.2.0.tgz#b637bd3ba9eabe122c83e9720483aeb10d2c904a" + integrity "sha1-tje9O6nqvhIsg+lyBIOusQ0skEo= sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==" + dependencies: + string-convert "^0.2.0" + +json3@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" + integrity "sha1-f8EON1/FrkLEcFpcwKpvYr4wW4E= sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==" + +json5@2.x, json5@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity "sha1-Lf7+cgxrpSXZ69kJlQ8FFTFsiaM= sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==" + dependencies: + minimist "^1.2.5" + +json5@^0.5.0, json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==" + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity "sha1-d5+wAYYE+oVOrL9iUhgNg1Q+Pb4= sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==" + dependencies: + minimist "^1.2.0" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity "sha1-vFWyY0eTxnnsZAMJTrE2mKbsCq4= sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==" + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= sha512-trvBk1ki43VZptdBI5rIlG4YOzyeH/WefQt5rj1grasPn4iiZWKet8nkgc4GlsAylaztn0qZfUYOiTsASJFdNA==" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= sha512-4Dj8Rf+fQ+/Pn7C5qeEX02op1WfOss3PKTE9Nsop3Dx+6UPxlm1dr/og7o2cRa5hNN07CACr4NFzRLtj/rjWog==" + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +just-kebab-case@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/just-kebab-case/-/just-kebab-case-1.1.0.tgz#ebe854fde84b0afa4e597fcd870b12eb3c026755" + integrity "sha1-6+hU/ehLCvpOWX/NhwsS6zwCZ1U= sha512-QkuwuBMQ9BQHMUEkAtIA4INLrkmnnveqlFB1oFi09gbU0wBdZo6tTnyxNWMR84zHxBuwK7GLAwqN8nrvVxOLTA==" + +katex@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/katex/-/katex-0.6.0.tgz#12418e09121c05c92041b6b3b9fb6bab213cb6f3" + integrity "sha1-EkGOCRIcBckgQbazuftrqyE8tvM= sha512-rS4mY3SvHYg5LtQV6RBcK0if7ur6plyEukAOV+jGGPqFImuzu8fHL6M752iBmRGoUyF0bhZbAPoezehn7xYksA==" + dependencies: + match-at "^0.1.0" + +killable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" + integrity "sha1-TIzkQRh6Bhx0dPuHygjipjgZSJI= sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==" + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity "sha1-IIE989cSkosgc3hpGkUGb65y3Vc= sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==" + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0= sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity "sha1-B8BQNKbDSfoG4k+jWqdttFgM5N0= sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity "sha1-p5yezIbuHOP6YgbRIWxQHxR/wH4= sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + +klona@^2.0.4: + version "2.0.5" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc" + integrity "sha1-0WZXTZAHY5XZljqnqSj6u412r7w= sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==" + +launch-editor-middleware@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/launch-editor-middleware/-/launch-editor-middleware-2.2.1.tgz#e14b07e6c7154b0a4b86a0fd345784e45804c157" + integrity "sha1-4UsH5scVSwpLhqD9NFeE5FgEwVc= sha512-s0UO2/gEGiCgei3/2UN3SMuUj1phjQN8lcpnvgLSz26fAzNWPQ6Nf/kF5IFClnfU2ehp6LrmKdMU/beveO+2jg==" + dependencies: + launch-editor "^2.2.1" + +launch-editor@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.2.1.tgz#871b5a3ee39d6680fcc26d37930b6eeda89db0ca" + integrity "sha1-hxtaPuOdZoD8wm03kwtu7aidsMo= sha512-On+V7K2uZK6wK7x691ycSUbLD/FyKKelArkbaAMSSJU8JmqmhwN2+mnJDNINuJWSrh2L0kDk+ZQtbC/gOWUwLw==" + dependencies: + chalk "^2.3.0" + shell-quote "^1.6.1" + +left-pad@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" + integrity "sha1-W4o6d2Xf4AEmHd6RVYnngvjJTR4= sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==" + +less-loader@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-5.0.0.tgz#498dde3a6c6c4f887458ee9ed3f086a12ad1b466" + integrity "sha1-SY3eOmxsT4h0WO6e0/CGoSrRtGY= sha512-bquCU89mO/yWLaUq0Clk7qCsKhsF/TZpJUzETRvJa9KSVEL9SO3ovCvdEHISBhrC81OwC8QSVX7E0bzElZj9cg==" + dependencies: + clone "^2.1.1" + loader-utils "^1.1.0" + pify "^4.0.1" + +less@3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/less/-/less-3.0.4.tgz#d27dcedbac96031c9e7b76f1da1e4b7d83760814" + integrity "sha1-0n3O26yWAxyee3bx2h5LfYN2CBQ= sha512-q3SyEnPKbk9zh4l36PGeW2fgynKu+FpbhiUNx/yaiBUQ3V0CbACCgb9FzYWcRgI2DJlP6eI4jc8XPrCTi55YcQ==" + optionalDependencies: + errno "^0.1.1" + graceful-fs "^4.1.2" + image-size "~0.5.0" + mime "^1.4.1" + mkdirp "^0.5.0" + promise "^7.1.1" + request "^2.83.0" + source-map "~0.6.0" + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity "sha1-d4kd6DQGTMy6gq54QrtrFKE+1/I= sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity "sha1-rkViwAdHO5MqYgDUAyaN0v/8at4= sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==" + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= sha512-8ZmlJFVK9iCmtLz19HpSsR8HaAMWBT284VMNednLwlIMDP2hJDCIhUp0IZ2xUcZ+Ob6BM0VvCSJwzASDM45NLQ==" + +linkify-it@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf" + integrity "sha1-47VGl+eL+RXHCjis14/QngBYsc8= sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==" + dependencies: + uc.micro "^1.0.1" + +linkify-it@~1.2.2: + version "1.2.4" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-1.2.4.tgz#0773526c317c8fd13bd534ee1d180ff88abf881a" + integrity "sha1-B3NSbDF8j9E71TTuHRgP+Iq/iBo= sha512-eGHwtlABkp1NOJSiKUNqBf3SYAS5jPHtvRXPAgNaQwTqmkTahjtiLH9NtxdR5IOPhNvwNMN/diswSfZKzUkhGg==" + dependencies: + uc.micro "^1.0.1" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity "sha1-L19Fq5HjMhYjT9U62rZo607AmTs= sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==" + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +loader-fs-cache@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz#f08657646d607078be2f0a032f8bd69dd6f277d9" + integrity "sha1-8IZXZG1gcHi+LwoDL4vWndbyd9k= sha512-ldcgZpjNJj71n+2Mf6yetz+c9bM4xpKtNds4LbqXzU/PTdeAX0g3ytnU1AJMEcTk2Lex4Smpe3Q/eCTsvUBxbA==" + dependencies: + find-cache-dir "^0.1.1" + mkdirp "^0.5.1" + +loader-runner@^2.3.1, loader-runner@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity "sha1-7UcGa/5TTX6ExMe5mYwqdWB9k1c= sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==" + +loader-utils@^0.2.16: + version "0.2.17" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" + integrity "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g= sha512-tiv66G0SmiOx+pLWMtGEkfSEejxvb6N6uRrQjfWJIT79W9GMpgKeCAmm9aVBKtd4WEgntciI8CsGqjpDoCWJug==" + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + object-assign "^4.0.1" + +loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity "sha1-xXm140yzSxp07cbB+za/o3HVphM= sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==" + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +loader-utils@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129" + integrity "sha1-1uO0+4GHByGuTghoqxHdY4NowSk= sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==" + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity "sha1-2+w7OrdZdYBxtY/ln8QYca8hQA4= sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==" + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity "sha1-Gvujlq/WdqbUJQTQpno6frn2KqA= sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==" + dependencies: + p-locate "^4.1.0" + +lodash-es@^4.2.1: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" + integrity "sha1-Q+YmxG5lkbd1C+srUBFzkMYJ4+4= sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + +lodash._baseiteratee@~4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash._baseiteratee/-/lodash._baseiteratee-4.7.0.tgz#34a9b5543572727c3db2e78edae3c0e9e66bd102" + integrity "sha1-NKm1VDVycnw9sueO2uPA6eZr0QI= sha512-nqB9M+wITz0BX/Q2xg6fQ8mLkyfF7MU7eE+MNBNjTHFKeKaZAPEzEg+E8LWxKWf1DQVflNEn9N49yAuqKh2mWQ==" + dependencies: + lodash._stringtopath "~4.8.0" + +lodash._basetostring@~4.12.0: + version "4.12.0" + resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-4.12.0.tgz#9327c9dc5158866b7fa4b9d42f4638e5766dd9df" + integrity "sha1-kyfJ3FFYhmt/pLnUL0Y45XZt2d8= sha512-SwcRIbyxnN6CFEEK4K1y+zuApvWdpQdBHM/swxP962s8HIxPO3alBH5t3m/dl+f4CMUug6sJb7Pww8d13/9WSw==" + +lodash._baseuniq@~4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" + integrity "sha1-DrtE5FaBSveQXGIS+iybLVG4Qeg= sha512-Ja1YevpHZctlI5beLA7oc5KNDhGcPixFhcqSiORHNsp/1QTv7amAXzw+gu4YOvErqVlMVyIJGgtzeepCnnur0A==" + dependencies: + lodash._createset "~4.0.0" + lodash._root "~3.0.0" + +lodash._createset@~4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" + integrity "sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY= sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA==" + +lodash._reinterpolate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==" + +lodash._root@~3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" + integrity "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI= sha512-O0pWuFSK6x4EXhM1dhZ8gchNtG7JMqBtrHdoUFUWXD7dJnNSUze1GuyQr5sOs0aCvgGeI3o/OJW8f4ca7FDxmQ==" + +lodash._stringtopath@~4.8.0: + version "4.8.0" + resolved "https://registry.yarnpkg.com/lodash._stringtopath/-/lodash._stringtopath-4.8.0.tgz#941bcf0e64266e5fc1d66fed0a6959544c576824" + integrity "sha1-lBvPDmQmbl/B1m/tCmlZVExXaCQ= sha512-SXL66C731p0xPDC5LZg4wI5H+dJo/EO4KTqOMwLYCH3+FmmfAKJEZCm6ohGpI+T1xwsDsJCfL4OnhorllvlTPQ==" + dependencies: + lodash._basetostring "~4.12.0" + +lodash.debounce@^4, lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity "sha1-gteb/zCmfEAF/9XiUVMArZyk168= sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + +lodash.defaultsdeep@^4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" + integrity "sha1-US6b1yHSctlOPTpjZT+hdRZ0HKY= sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==" + +lodash.kebabcase@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" + integrity "sha1-hImxyw0p/4gZXM7KRI/21swpXDY= sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==" + +lodash.mapvalues@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c" + integrity "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw= sha512-JPFqXFeZQ7BfS00H58kClY7SPVeHertPE0lNuCyZ26/XlN8TvakYD7b9bGyNmXbT/D3BbtPAAmq90gPWqLkxlQ==" + +lodash.memoize@4.x, lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity "sha1-VYqlO0O2YeGSWgr9+japoQhf5Xo= sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" + +lodash.template@^4.4.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" + integrity "sha1-+XYZXPPzR9DV9SSDVp/oAxzM6Ks= sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==" + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" + integrity "sha1-5IExDwSdPPbUfpEq0JMTsVTw+zM= sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==" + dependencies: + lodash._reinterpolate "^3.0.0" + +lodash.throttle@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" + integrity "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==" + +lodash.transform@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.transform/-/lodash.transform-4.6.0.tgz#12306422f63324aed8483d3f38332b5f670547a0" + integrity "sha1-EjBkIvYzJK7YSD0/ODMrX2cFR6A= sha512-LO37ZnhmBVx0GvOU/caQuipEh4GN82TcWv3yHlebGDgOxbxiwwzW5Pcx2AcvpIv2WmvmSMoC492yQFNhy/l/UQ==" + +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==" + +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + +lodash.uniqby@4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.5.0.tgz#a3a17bbf62eeb6240f491846e97c1c4e2a5e1e21" + integrity "sha1-o6F7v2LutiQPSRhG6XwcTipeHiE= sha512-IRt7cfTtHy6f1aRVA5n7kT8rgN3N1nH6MOWLcHfpWG2SH19E3JksLK38MktLxZDhlAjCP9jpIXkOnRXlu6oByQ==" + dependencies: + lodash._baseiteratee "~4.7.0" + lodash._baseuniq "~4.6.0" + +lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity "sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw= sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + +log-symbols@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity "sha1-V0Dhxdbw39pK2TI7UzIQfva0xAo= sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==" + dependencies: + chalk "^2.0.1" + +loglevel@^1.6.8: + version "1.7.1" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" + integrity "sha1-AF/eL15uRwaPk1/yhXPhJe9y8Zc= sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==" + +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity "sha1-ce5R+nvkyuwaY4OffmgtgTLTDK8= sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==" + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lower-case@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + integrity "sha1-miyr0bno4K6ZOkv31YdcOcQujqw= sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==" + +lowlight@^1.17.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.20.0.tgz#ddb197d33462ad0d93bf19d17b6c301aa3941888" + integrity "sha1-3bGX0zRirQ2TvxnRe2wwGqOUGIg= sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==" + dependencies: + fault "^1.0.0" + highlight.js "~10.7.0" + +lru-cache@^4.0.1, lru-cache@^4.1.2, lru-cache@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity "sha1-i75Q6oW+1ZvJ4z3KuCNe6bz0Q80= sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity "sha1-HaJ+ZxAnGUdpXa9oSOhH8B2EuSA= sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==" + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity "sha1-bW/mVw69lqr5D8rR2vo7JWbbOpQ= sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==" + dependencies: + yallist "^4.0.0" + +lru-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" + integrity "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM= sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==" + dependencies: + es5-ext "~0.10.2" + +luxon@^1.25.0, luxon@^1.27.0: + version "1.28.0" + resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.28.0.tgz#e7f96daad3938c06a62de0fb027115d251251fbf" + integrity "sha1-5/ltqtOTjAamLeD7AnEV0lElH78= sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ==" + +lz-string@^1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" + integrity "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY= sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==" + +magic-string@^0.25.7: + version "0.25.7" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" + integrity "sha1-P0l9b9NMZpxnmNy4IfLvMfVEUFE= sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==" + dependencies: + sourcemap-codec "^1.4.4" + +make-dir@^2.0.0, make-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity "sha1-XwMQ4YuL6JjMBwCSlaMK5B6R5vU= sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==" + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +make-dir@^3.0.2, make-dir@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity "sha1-QV6WcEazp/HRhSd9hKpYIDcmoT8= sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==" + dependencies: + semver "^6.0.0" + +make-error@1.x: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity "sha1-LrLjfqm2fEiR9oShOUeZr0hM96I= sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity "sha1-Pl3SB5qC6BLpg8xmEMSiyw6qgBo= sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==" + dependencies: + tmpl "1.0.5" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==" + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==" + dependencies: + object-visit "^1.0.0" + +markdown-it-abbr@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/markdown-it-abbr/-/markdown-it-abbr-1.0.4.tgz#d66b5364521cbb3dd8aa59dadfba2fb6865c8fd8" + integrity "sha1-1mtTZFIcuz3Yqlna37ovtoZcj9g= sha512-ZeA4Z4SaBbYysZap5iZcxKmlPL6bYA8grqhzJIHB1ikn7njnzaP8uwbtuXc4YXD5LicI4/2Xmc0VwmSiFV04gg==" + +markdown-it-deflist@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/markdown-it-deflist/-/markdown-it-deflist-2.1.0.tgz#50d7a56b9544cd81252f7623bd785e28a8dcef5c" + integrity "sha1-UNela5VEzYElL3YjvXheKKjc71w= sha512-3OuqoRUlSxJiuQYu0cWTLHNhhq2xtoSFqsZK8plANg91+RJQU1ziQ6lA2LzmFAEes18uPBsHZpcX6We5l76Nzg==" + +markdown-it-emoji@^1.1.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz#9bee0e9a990a963ba96df6980c4fddb05dfb4dcc" + integrity "sha1-m+4OmpkKljupbfaYDE/dsF37Tcw= sha512-QCz3Hkd+r5gDYtS2xsFXmBYrgw6KuWcJZLCEkdfAuwzZbShCmCfta+hwAMq4NX/4xPzkSHduMKgMkkPUJxSXNg==" + +markdown-it-footnote@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/markdown-it-footnote/-/markdown-it-footnote-2.0.0.tgz#14e9c4f68ff12cf354fa365ae378276e8104ca94" + integrity "sha1-FOnE9o/xLPNU+jZa43gnboEEypQ= sha512-GMWkJXSHh5tiQt77zCLOSZI2Xy3Oqdb82GmT0Q0h2UT6SbUrMCAiHEiMBIt5V7Xfm73rBxS0VOhlLndkn1GPnw==" + +markdown-it-ins@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/markdown-it-ins/-/markdown-it-ins-2.0.0.tgz#a5aa6a30f1e2f71e9497567cfdff40f1fde67483" + integrity "sha1-papqMPHi9x6Ul1Z8/f9A8f3mdIM= sha512-DhLLxseIg2C7+AULvoyVI+zMeufR0QFvXJ2o0oV013hN5HvBvNh2rbVtTdxZjI959+hgo2AA0aRdtEIUaKPbhg==" + +markdown-it-katex@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/markdown-it-katex/-/markdown-it-katex-2.0.3.tgz#d7b86a1aea0b9d6496fab4e7919a18fdef589c39" + integrity "sha1-17hqGuoLnWSW+rTnkZoY/e9YnDk= sha512-nUkkMtRWeg7OpdflamflE/Ho/pWl64Lk9wNBKOmaj33XkQdumhXAIYhI0WO03GeiycPCsxbmX536V5NEXpC3Ng==" + dependencies: + katex "^0.6.0" + +markdown-it-mark@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/markdown-it-mark/-/markdown-it-mark-2.0.0.tgz#46a1aa947105aed8188978e0a016179e404f42c7" + integrity "sha1-RqGqlHEFrtgYiXjgoBYXnkBPQsc= sha512-iT8ua0Bda8QrVwHDOUNw1eyCuL7irXeYch5n8zGS4tb7wsDIn7EjQZLjihKaijzBiL0ikfWL2zAvL/ECqTvsNA==" + +markdown-it-sub@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/markdown-it-sub/-/markdown-it-sub-1.0.0.tgz#375fd6026eae7ddcb012497f6411195ea1e3afe8" + integrity "sha1-N1/WAm6ufdywEkl/ZBEZXqHjr+g= sha512-z2Rm/LzEE1wzwTSDrI+FlPEveAAbgdAdPhdWarq/ZGJrGW/uCQbKAnhoCsE4hAbc3SEym26+W2z/VQB0cQiA9Q==" + +markdown-it-sup@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/markdown-it-sup/-/markdown-it-sup-1.0.0.tgz#cb9c9ff91a5255ac08f3fd3d63286e15df0a1fc3" + integrity "sha1-y5yf+RpSVawI8/09YyhuFd8KH8M= sha512-E32m0nV9iyhRR7CrhnzL5msqic7rL1juWre6TQNxsnApg7Uf+F97JOKxUijg5YwXz86lZ0mqfOnutoryyNdntQ==" + +markdown-it-task-lists@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/markdown-it-task-lists/-/markdown-it-task-lists-2.1.1.tgz#f68f4d2ac2bad5a2c373ba93081a1a6848417088" + integrity "sha1-9o9NKsK61aLDc7qTCBoaaEhBcIg= sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA==" + +markdown-it-toc-and-anchor@^4.1.2: + version "4.2.0" + resolved "https://registry.yarnpkg.com/markdown-it-toc-and-anchor/-/markdown-it-toc-and-anchor-4.2.0.tgz#d1613327cc63c61f82cd66cbac5564f4db12c0e9" + integrity "sha1-0WEzJ8xjxh+CzWbLrFVk9NsSwOk= sha512-DusSbKtg8CwZ92ztN7bOojDpP4h0+w7BVOPuA3PHDIaabMsERYpwsazLYSP/UlKedoQjOz21mwlai36TQ04EpA==" + dependencies: + clone "^2.1.0" + uslug "^1.0.4" + +markdown-it@^6.0.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-6.1.1.tgz#ced037f4473ee9f5153ac414f77dc83c91ba927c" + integrity "sha1-ztA39Ec+6fUVOsQU933IPJG6knw= sha512-woFl7h/sqt9xRmiMweNuO7nu+w8Lz3SXsDlvE3TYeu1SdPqQ+VW4GZyaKP442Bq6XUN6V6IQjJTR93RDYG2mjw==" + dependencies: + argparse "^1.0.7" + entities "~1.1.1" + linkify-it "~1.2.2" + mdurl "~1.0.1" + uc.micro "^1.0.1" + +markdown-it@^8.4.2: + version "8.4.2" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.2.tgz#386f98998dc15a37722aa7722084f4020bdd9b54" + integrity "sha1-OG+YmY3BWjdyKqdyIIT0Agvdm1Q= sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==" + dependencies: + argparse "^1.0.7" + entities "~1.1.1" + linkify-it "^2.0.0" + mdurl "^1.0.1" + uc.micro "^1.0.5" + +match-all@^1.2.5: + version "1.2.6" + resolved "https://registry.yarnpkg.com/match-all/-/match-all-1.2.6.tgz#66d276ad6b49655551e63d3a6ee53e8be0566f8d" + integrity "sha1-ZtJ2rWtJZVVR5j06buU+i+BWb40= sha512-0EESkXiTkWzrQQntBu2uzKvLu6vVkUGz40nGPbSZuegcfE5UuSzNjLaIu76zJWuaT/2I3Z/8M06OlUOZLGwLlQ==" + +match-at@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/match-at/-/match-at-0.1.1.tgz#25d040d291777704d5e6556bbb79230ec2de0540" + integrity "sha1-JdBA0pF3dwTV5lVru3kjDsLeBUA= sha512-h4Yd392z9mST+dzc+yjuybOGFNOZjmXIPKWjxBd1Bb23r4SmDOsk2NYCU2BMUBGbSpZqwVsZYNq26QS3xfaT3Q==" + +math-log2@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/math-log2/-/math-log2-1.0.1.tgz#fb8941be5f5ebe8979e718e6273b178e58694565" + integrity "sha1-+4lBvl9evol55xjmJzsXjlhpRWU= sha512-9W0yGtkaMAkf74XGYVy4Dqw3YUMnTNB2eeiw9aQbUl4A3KmuCEHTt2DgAB07ENzOYAjsYSAYufkAq0Zd+jU7zA==" + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity "sha1-tdB7jjIW4+J81yjXL3DR5qNCAF8= sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==" + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +mdn-data@2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" + integrity "sha1-cRP8QoGRfWPOKbQ0RvcB5owlulA= sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + +mdn-data@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" + integrity "sha1-aZs8OKxvHXKAkaZGULZdOIUC/Vs= sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" + +mdurl@^1.0.1, mdurl@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" + +memfs@^3.1.2: + version "3.3.0" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.3.0.tgz#4da2d1fc40a04b170a56622c7164c6be2c4cbef2" + integrity "sha1-TaLR/ECgSxcKVmIscWTGvixMvvI= sha512-BEE62uMfKOavX3iG7GYX43QJ+hAeeWnwIAuJ/R6q96jaMtiLzhsxHJC8B1L7fK7Pt/vXDRwb3SG/yBpNGDPqzg==" + dependencies: + fs-monkey "1.0.3" + +memoize-one@^5.0.4: + version "5.2.1" + resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e" + integrity "sha1-gzeqPEM1WBg57AHD1ZQJDOvo8A4= sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" + +memoizee@^0.4.15: + version "0.4.15" + resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.15.tgz#e6f3d2da863f318d02225391829a6c5956555b72" + integrity "sha1-5vPS2oY/MY0CIlORgppsWVZVW3I= sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==" + dependencies: + d "^1.0.1" + es5-ext "^0.10.53" + es6-weak-map "^2.0.3" + event-emitter "^0.3.5" + is-promise "^2.2.2" + lru-queue "^0.1.0" + next-tick "^1.1.0" + timers-ext "^0.1.7" + +memory-fs@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==" + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity "sha1-MkwBKIuIZSlm0WHbd4OHIIRajjw= sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==" + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + +merge-source-map@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" + integrity "sha1-L93n5gIJOfcJBqaPLXrmheTIxkY= sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==" + dependencies: + source-map "^0.6.1" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity "sha1-UoI2KaFN0AyXcPtq1H3GMQ8sH2A= sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + +merge2@^1.2.3, merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity "sha1-Q2iJL4hekHRVpv19xVwMnUBJkK4= sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" + +microevent.ts@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0" + integrity "sha1-cLCbg/Q99RctAgWmMCW84Pc1f6A= sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==" + +micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity "sha1-cIWbyVyYQJUvNZoGij/En57PrCM= sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity "sha1-iW1Rnf6dsl/OlM63pQCRm/iB6/k= sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==" + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity "sha1-8IA1HIZbDcViqEYpZtqlNUPHik0= sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==" + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.50.0, "mime-db@>= 1.43.0 < 2": + version "1.50.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.50.0.tgz#abd4ac94e98d3c0e185016c67ab45d5fde40c11f" + integrity "sha1-q9SslOmNPA4YUBbGerRdX95AwR8= sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==" + +mime-match@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/mime-match/-/mime-match-1.0.2.tgz#3f87c31e9af1a5fd485fb9db134428b23bbb7ba8" + integrity "sha1-P4fDHprxpf1IX7nbE0Qosju7e6g= sha512-VXp/ugGDVh3eCLOBCiHZMYWQaTNUHv2IJrut+yXA6+JbLPXHglHwfS/5A5L0ll+jkCY7fIzRJcH6OIunF+c6Cg==" + dependencies: + wildcard "^1.1.0" + +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: + version "2.1.33" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.33.tgz#1fa12a904472fafd068e48d9e8401f74d3f70edb" + integrity "sha1-H6EqkERy+v0GjkjZ6EAfdNP3Dts= sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==" + dependencies: + mime-db "1.50.0" + +mime@1.6.0, mime@^1.4.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE= sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + +mime@^2.4.4: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity "sha1-oqaCqVzU0MsdYlfij4PafjWAA2c= sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==" + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity "sha1-ggyGo5M0ZA6ZUWkovQP8qIBX0CI= sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity "sha1-ftLCzMyvhNP/y3pptXcR/CCDQBs= sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + +mini-css-extract-plugin@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz#47f2cf07aa165ab35733b1fc97d4c46c0564339e" + integrity "sha1-R/LPB6oWWrNXM7H8l9TEbAVkM54= sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A==" + dependencies: + loader-utils "^1.1.0" + normalize-url "1.9.1" + schema-utils "^1.0.0" + webpack-sources "^1.1.0" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity "sha1-LhlN4ERibUoQ5/f7wAznPoPk1cc= sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM= sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==" + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity "sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI= sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + +minipass@^3.1.1: + version "3.1.5" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.5.tgz#71f6251b0a33a49c01b3cf97ff77eda030dff732" + integrity "sha1-cfYlGwozpJwBs8+X/3ftoDDf9zI= sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==" + dependencies: + yallist "^4.0.0" + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity "sha1-6goykfl+C16HdrNj1fChLZTGcCI= sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==" + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity "sha1-ESC0PcNZp4Xc5ltVuC4lfM9HlWY= sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==" + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@0.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity "sha1-2Rzv1i0UNsoPQWIOJRKI1CAJne8= sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==" + dependencies: + minimist "^1.2.5" + +moment@^2.10.2, moment@^2.21.0: + version "2.29.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" + integrity "sha1-sr52n6MZQL6e7qZGnAdeNQBvo9M= sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==" + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity "sha1-MKWGTrPrsKZvLr5tcnrwagnYbgo= sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk= sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity "sha1-V0yBOM4dK1hh8LRFedut1gxmFbI= sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + +multicast-dns-service-types@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + integrity "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= sha512-cnAsSVxIDsYt0v7HmC0hWZFwwXSh+E6PgCrREDuN/EsjgLwA5XRmlMHhSiDPrt6HxY1gTivEa/Zh7GtODoLevQ==" + +multicast-dns@^6.0.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" + integrity "sha1-oOx72QVcQoL3kMPIL04o2zsxsik= sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==" + dependencies: + dns-packet "^1.3.1" + thunky "^1.0.2" + +mutationobserver-shim@^0.3.2: + version "0.3.7" + resolved "https://registry.yarnpkg.com/mutationobserver-shim/-/mutationobserver-shim-0.3.7.tgz#8bf633b0c0b0291a1107255ed32c13088a8c5bf3" + integrity "sha1-i/YzsMCwKRoRByVe0ywTCIqMW/M= sha512-oRIDTyZQU96nAiz2AQyngwx1e89iApl2hN5AOYwyxLUB47UYsU3Wv9lJWqH5y/QdiYkc5HQLi23ZNB3fELdHcQ==" + +mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity "sha1-FjDEKyJR/4HiooPelqVJfqkuXg0= sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + +mz@^2.4.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity "sha1-lQCAV6Vsr63CvGPd5/n/aVWUjjI= sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==" + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +namespace-emitter@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/namespace-emitter/-/namespace-emitter-2.0.1.tgz#978d51361c61313b4e6b8cf6f3853d08dfa2b17c" + integrity "sha1-l41RNhxhMTtOa4z284U9CN+isXw= sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g==" + +nan@^2.12.1: + version "2.15.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" + integrity "sha1-PzSkc/8Y4VwbVia2KQO1rW5mX+4= sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" + +nanoid@^3.1.30: + version "3.1.30" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362" + integrity "sha1-Y/k8xUjSoRPcXfvGO/oJ4rm2Q2I= sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==" + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity "sha1-uHqKpPwN6P5r6IiVs4mD/yZb0Rk= sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +nanopop@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/nanopop/-/nanopop-2.1.0.tgz#23476513cee2405888afd2e8a4b54066b70b9e60" + integrity "sha1-I0dlE87iQFiIr9LopLVAZrcLnmA= sha512-jGTwpFRexSH+fxappnGQtN9dspgE2ipa1aOjtR24igG0pv6JCxImIAmrLRHX+zUF5+1wtsFVbKyfP51kIGAVNw==" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity "sha1-/qz3zPUlp3rpY0Q2pkiD/+yjRvs= sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + +neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1, neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity "sha1-tKr7k+OustgXTKU88WOrfXMIMF8= sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + +next-tick@1, next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity "sha1-GDbuMK1W1n7ygbIr0Zn3CUSbNes= sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + +next-tick@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity "sha1-yobR/ogoFpsBICCOPchCS524NCw= sha512-mc/caHeUcdjnC/boPWJefDr4KUIWQNv+tlnFnJd38QMou86QtxQzBJfxgGRzvx8jazYRqrVlaHarfO72uNxPOg==" + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity "sha1-ozeKdpbOfSI+iPybdkvX7xCJ42Y= sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + +no-case@^2.2.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" + integrity "sha1-YLgTOWvjmz8SiKTB7V0efSi0ZKw= sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==" + dependencies: + lower-case "^1.1.1" + +node-addon-api@^1.7.1: + version "1.7.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.7.2.tgz#3df30b95720b53c24e59948b49532b662444f54d" + integrity "sha1-PfMLlXILU8JOWZSLSVMrZiRE9U0= sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==" + +node-cache@^4.1.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/node-cache/-/node-cache-4.2.1.tgz#efd8474dee4edec4138cdded580f5516500f7334" + integrity "sha1-79hHTe5O3sQTjN3tWA9VFlAPczQ= sha512-BOb67bWg2dTyax5kdef5WfU3X8xu4wPg+zHzkvls0Q/QpYycIFRLEEIdAx9Wma43DxG6Qzn4illdZoYseKWa4A==" + dependencies: + clone "2.x" + lodash "^4.17.15" + +node-domexception@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" + integrity "sha1-aIjbRqH3HAt2s/dVUBa2P+ZHZuU= sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" + +node-emoji@^1.10.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" + integrity "sha1-aaAVDmlG4vEV6dfqTfeXHiYoMBw= sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==" + dependencies: + lodash "^4.17.21" + +node-fetch@2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity "sha1-BFvTI2Mfdu0uK1VXM5RBa2OaAFI= sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + +node-fetch@^1.0.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + integrity "sha1-mA9vcthSEaU0fGsrwYxbhMPrR+8= sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==" + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +node-forge@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" + integrity "sha1-Mt6ir7Ppkm8C7lzoeUkCaRpna/M= sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" + +node-ipc@^9.1.1: + version "9.2.1" + resolved "https://registry.yarnpkg.com/node-ipc/-/node-ipc-9.2.1.tgz#b32f66115f9d6ce841dc4ec2009d6a733f98bb6b" + integrity "sha1-sy9mEV+dbOhB3E7CAJ1qcz+Yu2s= sha512-mJzaM6O3xHf9VT8BULvJSbdVbmHUKRNOH7zDDkCrA1/T+CVjq2WVIDfLt0azZRXpgArJtl3rtmEozrbXPZ9GaQ==" + dependencies: + event-pubsub "4.3.0" + js-message "1.0.7" + js-queue "2.0.2" + +node-libs-browser@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + integrity "sha1-tk9RPRgzhiX5A0bSew0jXmMfZCU= sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==" + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.1" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "^1.0.1" + +node-modules-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" + integrity "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= sha512-JMaRS9L4wSRIR+6PTVEikTrq/lMGEZR43a48ETeilY0Q0iMwVnccMFrUM1k+tNzmYuIU0Vh710bCUqHX+/+ctQ==" + +node-notifier@^5.4.2: + version "5.4.5" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.5.tgz#0cbc1a2b0f658493b4025775a13ad938e96091ef" + integrity "sha1-DLwaKw9lhJO0Ald1oTrZOOlgke8= sha512-tVbHs7DyTLtzOiN78izLA85zRqB9NvEXkAf014Vx3jtSvn/xBl6bR8ZYifj+dFcFrKI21huSQgJZ6ZtL3B4HfQ==" + dependencies: + growly "^1.3.0" + is-wsl "^1.1.0" + semver "^5.5.0" + shellwords "^0.1.1" + which "^1.3.0" + +node-releases@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" + integrity "sha1-PR05XyBPHy8ppUNYuftnh2WtL8U= sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==" + +nopt@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" + integrity "sha1-UwlCu1ilEvzK/lP+IQ8TolNV3Ig= sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==" + dependencies: + abbrev "1" + +normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity "sha1-5m2xg4sgDB38IzIl0SyzZSDiNKg= sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==" + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" + integrity "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k= sha512-7WyT0w8jhpDStXRq5836AMmihQwq2nrUVQrgjvUo/p/NZf9uy/MeJ246lBJVmWuYXMlJuG9BNZHF0hWjfTbQUA==" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==" + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity "sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU= sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==" + +normalize-url@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" + integrity "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= sha512-A48My/mtCklowHBlI8Fq2jFWK4tX4lJ5E6ytFsSOq1fzpvT0SQSgKhSg7lN5c2uYFOrUAOQp6zhhJnpp1eMloQ==" + dependencies: + object-assign "^4.0.1" + prepend-http "^1.0.0" + query-string "^4.1.0" + sort-keys "^1.0.0" + +normalize-url@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" + integrity "sha1-suHE3E98bVd0PfczpPWXjRhlBVk= sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==" + dependencies: + path-key "^2.0.0" + +npm-run-path@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity "sha1-t+zR5e1T2o43pV4cImnguX7XSOo= sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==" + dependencies: + path-key "^3.0.0" + +nth-check@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity "sha1-sr0pXDfj3VijvwcAN2Zjuk2c8Fw= sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==" + dependencies: + boolbase "~1.0.0" + +nth-check@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" + integrity "sha1-Lv4WL1w9oGoolZ+9PbddvuqfD8I= sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==" + dependencies: + boolbase "^1.0.0" + +null-loader@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/null-loader/-/null-loader-3.0.0.tgz#3e2b6c663c5bda8c73a54357d8fa0708dc61b245" + integrity "sha1-PitsZjxb2oxzpUNX2PoHCNxhskU= sha512-hf5sNLl8xdRho4UPBOOeoIwT3WhjYcMUQm0zj44EhD6UscMAz72o2udpoDFBgykucdEDGIcd6SXbc/G6zssbzw==" + dependencies: + loader-utils "^1.2.3" + schema-utils "^1.0.0" + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + integrity "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==" + +nwsapi@^2.0.7, nwsapi@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" + integrity "sha1-IEh5qePQaP8qVROcLHcngGgaOLc= sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity "sha1-R6ewFrqmi1+g7PPe4IqFxnmsZFU= sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + +object-assign@4.x, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity "sha1-fn2Fi3gb18mRpBupde04EnVOmYw= sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==" + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-hash@^1.1.4: + version "1.3.1" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" + integrity "sha1-/eRSCYqVHLFF8Dm7fUVUSd3BJt8= sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==" + +object-hash@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5" + integrity "sha1-WtUYWB7vxEO9djRyuP8unCwNVKU= sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==" + +object-inspect@^1.11.0, object-inspect@^1.9.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" + integrity "sha1-nc6xRs7dQUig2eUauI00z1CZIrE= sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==" + +object-is@^1.0.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity "sha1-ud7qpfx/GEag+uzc7sE45XePU6w= sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==" + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity "sha1-HEfyct8nfzsdrwYWd9nILiMixg4= sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==" + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.0, object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity "sha1-DtVKNC7Os3s4/3brgxoOeIy2OUA= sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==" + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0, object.getownpropertydescriptors@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz#b223cf38e17fefb97a63c10c91df72ccb386df9e" + integrity "sha1-siPPOOF/77l6Y8EMkd9yzLOG354= sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==" + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==" + dependencies: + isobject "^3.0.1" + +object.values@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" + integrity "sha1-lZ9j486e8QhyAzMIITHkpFm3Fqw= sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==" + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity "sha1-Cb6jND1BhZ69RGKS0RydTbYZCE4= sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + +omit.js@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/omit.js/-/omit.js-1.0.2.tgz#91a14f0eba84066dfa015bf30e474c47f30bc858" + integrity "sha1-kaFPDrqEBm36AVvzDkdMR/MLyFg= sha512-/QPc6G2NS+8d4L/cQhbk6Yit1WTB6Us2g84A7A/1+w9d/eRGHyEqC5kkQtHVoHZ5NFWGG7tUGgrhVZwgZanKrQ==" + dependencies: + babel-runtime "^6.23.0" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==" + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity "sha1-dysK5qqlJcOZ5Imt+tkMQD6zwo8= sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity "sha1-WDsap3WWHUsROsF9nFC6753Xa9E= sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==" + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==" + dependencies: + mimic-fn "^1.0.0" + +onetime@^5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity "sha1-0Oluu1awdHbfHdnEgG5SN5hcpF4= sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==" + dependencies: + mimic-fn "^2.1.0" + +open@^6.3.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/open/-/open-6.4.0.tgz#5c13e96d0dc894686164f18965ecfe889ecfc8a9" + integrity "sha1-XBPpbQ3IlGhhZPGJZez+iJ7PyKk= sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==" + dependencies: + is-wsl "^1.1.0" + +opener@^1.5.1: + version "1.5.2" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" + integrity "sha1-XTfh81B3udysQwE3InGv3rKhNZg= sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==" + +opn@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" + integrity "sha1-/HFk+rVtI1kExRw7J9pnWMo7m/w= sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==" + dependencies: + is-wsl "^1.1.0" + +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity "sha1-hPodA2/p08fiHZmIS2ARZ+yPtJU= sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity "sha1-TyNqY3Pa4FZqbUPhMmZ09QwpFJk= sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==" + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + +ora@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/ora/-/ora-3.4.0.tgz#bf0752491059a3ef3ed4c85097531de9fdbcd318" + integrity "sha1-vwdSSRBZo+8+1MhQl1Md6f280xg= sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==" + dependencies: + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-spinners "^2.0.0" + log-symbols "^2.2.0" + strip-ansi "^5.2.0" + wcwidth "^1.0.1" + +original@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" + integrity "sha1-5EKmHP/hxf0gpl8yYcJmY7MD8l8= sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==" + dependencies: + url-parse "^1.4.3" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==" + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==" + +p-each-series@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" + integrity "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E= sha512-J/e9xiZZQNrt+958FFzJ+auItsBGq+UrQ7nE89AUP7UOTtjHnkISANXLdayhVzh538UnLMCSlf13lFfRIAKQOA==" + dependencies: + p-reduce "^1.0.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==" + +p-finally@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" + integrity "sha1-vW/KqcVZoJa2gIBvTWV7Pw8kBWE= sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==" + +p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.2.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity "sha1-PdM8ZHohT9//2DWTPrCG2g3CHbE= sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==" + dependencies: + p-try "^2.0.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity "sha1-Mi1poFwCZLJZl9n0DNiokasAZKQ= sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==" + dependencies: + p-limit "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity "sha1-o0KLtwiLOmApL2aRkni3wpetTwc= sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==" + dependencies: + p-limit "^2.2.0" + +p-map@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" + integrity "sha1-MQko/u+cnsxltosXaTAYpmXOoXU= sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==" + +p-reduce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" + integrity "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= sha512-3Tx1T3oM1xO/Y8Gj0sWyE78EIJZ+t+aEmXUdvQgvGmSMri7aPTHoovbXEreWKkL5j21Er60XAWLTzKbAKYOujQ==" + +p-retry@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328" + integrity "sha1-MWtMiJPiyNwc+okfQGxLQivr8yg= sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==" + dependencies: + retry "^0.12.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY= sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + +pako@~1.0.5: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity "sha1-bJWZ00DVTf05RjgCUqNXBaa5kr8= sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + +parallel-transform@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" + integrity "sha1-kEnKN9bLIYLDsdLHIL6U0UpYFPw= sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==" + dependencies: + cyclist "^1.0.1" + inherits "^2.0.3" + readable-stream "^2.1.5" + +param-case@2.1.x: + version "2.1.1" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" + integrity "sha1-35T9jPZTHs915r75oIWPvHK+Ikc= sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==" + dependencies: + no-case "^2.2.0" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity "sha1-aR0nCeeMefrjoVZiJFLQB2LKqqI= sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==" + dependencies: + callsites "^3.0.0" + +parse-asn1@^5.0.0, parse-asn1@^5.1.5: + version "5.1.6" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" + integrity "sha1-OFCAo+wTy2KmLTlAnLPoiETNrtQ= sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==" + dependencies: + asn1.js "^5.2.0" + browserify-aes "^1.0.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-entities@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" + integrity "sha1-U8brW5MUofTsmfoP33zgHs2gy+g= sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==" + dependencies: + character-entities "^1.0.0" + character-entities-legacy "^1.0.0" + character-reference-invalid "^1.0.0" + is-alphanumerical "^1.0.0" + is-decimal "^1.0.0" + is-hexadecimal "^1.0.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==" + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity "sha1-x2/Gbe5UIxyWKyK8yKcs8vmXU80= sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==" + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parse5-htmlparser2-tree-adapter@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" + integrity "sha1-LN+a2CMyEUA3DU2/XT6Sx8jdxuY= sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==" + dependencies: + parse5 "^6.0.1" + +parse5@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" + integrity "sha1-bXhlbj2o14tOwLkG98CO8d/j9gg= sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==" + +parse5@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" + integrity "sha1-xZNByXI/QUxFKXVWTHwApo1YrNI= sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==" + +parse5@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" + integrity "sha1-9o5OW6GFKsLK3AD0VV//bCq7YXg= sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==" + +parse5@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity "sha1-4aHAhcVps9wIMhGE8Zo5zCf3wws= sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity "sha1-naGee+6NEt/wUT7Vt2lXeTvC6NQ= sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==" + +path-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity "sha1-5sTd1+06onxoogzE5Q4aTug7vEo= sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==" + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==" + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM= sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity "sha1-F0uSaHNVNP+8es5r9TpanhtcX18= sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + +path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==" + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity "sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U= sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + +path-parse@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity "sha1-+8EUtgykKzDZ2vWFjkvWi77bZzU= sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity "sha1-zvMdyOCho7sNEFwM2Xzzv0f0428= sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==" + dependencies: + pify "^3.0.0" + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity "sha1-hO0BwKe6OAr+CdkKjBgNzZ0DBDs= sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + +pbkdf2@^3.0.3: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity "sha1-3YIqoIh1gOUvGgOdw+2hCO+uMHU= sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==" + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" + integrity "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU= sha512-YHk5ez1hmMR5LOkb9iJkLKqoBlL7WD5M8ljC75ZfzXriuBIVNuecaXuU7e+hOwyqf24Wxhh7Vxgt7Hnw9288Tg==" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + +picocolors@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" + integrity "sha1-VwZw95NkaFHRuhNZlpYqutWHhZ8= sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity "sha1-y1vcdP8/UYkiNur3nWi8RFZKuBw= sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity "sha1-8fBh3o9qS/AiiS4tEoI0+5gwKXI= sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==" + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity "sha1-7RQaasBDqEnqWISY59yosVMw6Qw= sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==" + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE= sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity "sha1-ITXW36ejWMBprJsXh3YogihFD/o= sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity "sha1-clVrgM+g1IqXToDnckjoDtT3+HA= sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==" + +pirates@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" + integrity "sha1-ZDqSyviUVm+RsrmG0sZpUKji+4c= sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==" + dependencies: + node-modules-regexp "^1.0.0" + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + integrity "sha1-ektQio1bstYp1EcFb/TpyTFM89Q= sha512-c6pv3OE78mcZ92ckebVDqg0aWSoKhOTbwCV6qbCWMk546mAL9pZln0+QsN/yQ7fkucd4+yJPLrCBXNt8Ruk+Eg==" + dependencies: + find-up "^1.0.0" + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity "sha1-J0kCDyOe2ZCIGx9xIQ1R62UjvqM= sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==" + dependencies: + find-up "^3.0.0" + +pkg-dir@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity "sha1-8JkTPfft5CLoHR2ESCcO6z5CYfM= sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==" + dependencies: + find-up "^4.0.0" + +pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + integrity "sha1-4vTO8OIZ9GPBeas3Rj5OHs3Muvs= sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" + +pnp-webpack-plugin@^1.6.4: + version "1.7.0" + resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.7.0.tgz#65741384f6d8056f36e2255a8d67ffc20866f5c9" + integrity "sha1-ZXQThPbYBW824iVajWf/wghm9ck= sha512-2Rb3vm+EXble/sMXNSu6eoBx8e79gKqhNq9F5ZWW6ERNCTE/Q0wQNne5541tE5vKjfM8hpNCYL+LGc1YTfI0dg==" + dependencies: + ts-pnp "^1.1.6" + +portfinder@^1.0.26: + version "1.0.28" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" + integrity "sha1-Z8RiKFK9U3TdHdkA93n1NGL6x3g= sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==" + dependencies: + async "^2.6.2" + debug "^3.1.1" + mkdirp "^0.5.5" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==" + +postcss-calc@^7.0.1: + version "7.0.5" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.5.tgz#f8a6e99f12e619c2ebc23cf6c486fdc15860933e" + integrity "sha1-+KbpnxLmGcLrwjz2xIb9wVhgkz4= sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==" + dependencies: + postcss "^7.0.27" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.0.2" + +postcss-colormin@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-4.0.3.tgz#ae060bce93ed794ac71264f08132d550956bd381" + integrity "sha1-rgYLzpPteUrHEmTwgTLVUJVr04E= sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==" + dependencies: + browserslist "^4.0.0" + color "^3.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-convert-values@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f" + integrity "sha1-yjgT7U2g+BL51DcDWE5Enr4Ymn8= sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==" + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-discard-comments@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz#1fbabd2c246bff6aaad7997b2b0918f4d7af4033" + integrity "sha1-H7q9LCRr/2qq15l7KwkY9NevQDM= sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==" + dependencies: + postcss "^7.0.0" + +postcss-discard-duplicates@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz#3fe133cd3c82282e550fc9b239176a9207b784eb" + integrity "sha1-P+EzzTyCKC5VD8myORdqkge3hOs= sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==" + dependencies: + postcss "^7.0.0" + +postcss-discard-empty@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz#c8c951e9f73ed9428019458444a02ad90bb9f765" + integrity "sha1-yMlR6fc+2UKAGUWERKAq2Qu592U= sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==" + dependencies: + postcss "^7.0.0" + +postcss-discard-overridden@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz#652aef8a96726f029f5e3e00146ee7a4e755ff57" + integrity "sha1-ZSrvipZybwKfXj4AFG7npOdV/1c= sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==" + dependencies: + postcss "^7.0.0" + +postcss-load-config@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.1.2.tgz#c5ea504f2c4aef33c7359a34de3573772ad7502a" + integrity "sha1-xepQTyxK7zPHNZo03jVzdyrXUCo= sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==" + dependencies: + cosmiconfig "^5.0.0" + import-cwd "^2.0.0" + +postcss-loader@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-3.0.0.tgz#6b97943e47c72d845fa9e03f273773d4e8dd6c2d" + integrity "sha1-a5eUPkfHLYRfqeA/Jzdz1OjdbC0= sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==" + dependencies: + loader-utils "^1.1.0" + postcss "^7.0.0" + postcss-load-config "^2.0.0" + schema-utils "^1.0.0" + +postcss-merge-longhand@^4.0.11: + version "4.0.11" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz#62f49a13e4a0ee04e7b98f42bb16062ca2549e24" + integrity "sha1-YvSaE+Sg7gTnuY9CuxYGLKJUniQ= sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==" + dependencies: + css-color-names "0.0.4" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + stylehacks "^4.0.0" + +postcss-merge-rules@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz#362bea4ff5a1f98e4075a713c6cb25aefef9a650" + integrity "sha1-NivqT/Wh+Y5AdacTxsslrv75plA= sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==" + dependencies: + browserslist "^4.0.0" + caniuse-api "^3.0.0" + cssnano-util-same-parent "^4.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + vendors "^1.0.0" + +postcss-minify-font-values@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz#cd4c344cce474343fac5d82206ab2cbcb8afd5a6" + integrity "sha1-zUw0TM5HQ0P6xdgiBqssvLiv1aY= sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==" + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-minify-gradients@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz#93b29c2ff5099c535eecda56c4aa6e665a663471" + integrity "sha1-k7KcL/UJnFNe7NpWxKpuZlpmNHE= sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==" + dependencies: + cssnano-util-get-arguments "^4.0.0" + is-color-stop "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-minify-params@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz#6b9cef030c11e35261f95f618c90036d680db874" + integrity "sha1-a5zvAwwR41Jh+V9hjJADbWgNuHQ= sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==" + dependencies: + alphanum-sort "^1.0.0" + browserslist "^4.0.0" + cssnano-util-get-arguments "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + uniqs "^2.0.0" + +postcss-minify-selectors@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz#e2e5eb40bfee500d0cd9243500f5f8ea4262fbd8" + integrity "sha1-4uXrQL/uUA0M2SQ1APX46kJi+9g= sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==" + dependencies: + alphanum-sort "^1.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + +postcss-modules-extract-imports@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" + integrity "sha1-gYcZoa4doyX5gyRGsBE27rSTzX4= sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==" + dependencies: + postcss "^7.0.5" + +postcss-modules-local-by-default@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz#bb14e0cc78279d504dbdcbfd7e0ca28993ffbbb0" + integrity "sha1-uxTgzHgnnVBNvcv9fgyiiZP/u7A= sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==" + dependencies: + icss-utils "^4.1.1" + postcss "^7.0.32" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" + integrity "sha1-OFyuATzHdD9afXYC0Qc6iequYu4= sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==" + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" + +postcss-modules-values@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" + integrity "sha1-W1AA1uuuKbQlUwG0o6VFdEI+fxA= sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==" + dependencies: + icss-utils "^4.0.0" + postcss "^7.0.6" + +postcss-normalize-charset@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4" + integrity "sha1-izWt067oOhNrBHHg1ZvlilAoXdQ= sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==" + dependencies: + postcss "^7.0.0" + +postcss-normalize-display-values@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz#0dbe04a4ce9063d4667ed2be476bb830c825935a" + integrity "sha1-Db4EpM6QY9RmftK+R2u4MMglk1o= sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==" + dependencies: + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-positions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz#05f757f84f260437378368a91f8932d4b102917f" + integrity "sha1-BfdX+E8mBDc3g2ipH4ky1LECkX8= sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==" + dependencies: + cssnano-util-get-arguments "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-repeat-style@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz#c4ebbc289f3991a028d44751cbdd11918b17910c" + integrity "sha1-xOu8KJ85kaAo1EdRy90RkYsXkQw= sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==" + dependencies: + cssnano-util-get-arguments "^4.0.0" + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-string@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz#cd44c40ab07a0c7a36dc5e99aace1eca4ec2690c" + integrity "sha1-zUTECrB6DHo23F6Zqs4eyk7CaQw= sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==" + dependencies: + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-timing-functions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz#8e009ca2a3949cdaf8ad23e6b6ab99cb5e7d28d9" + integrity "sha1-jgCcoqOUnNr4rSPmtquZy159KNk= sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==" + dependencies: + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-unicode@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz#841bd48fdcf3019ad4baa7493a3d363b52ae1cfb" + integrity "sha1-hBvUj9zzAZrUuqdJOj02O1KuHPs= sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==" + dependencies: + browserslist "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-url@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz#10e437f86bc7c7e58f7b9652ed878daaa95faae1" + integrity "sha1-EOQ3+GvHx+WPe5ZS7YeNqqlfquE= sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==" + dependencies: + is-absolute-url "^2.0.0" + normalize-url "^3.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-whitespace@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz#bf1d4070fe4fcea87d1348e825d8cc0c5faa7d82" + integrity "sha1-vx1AcP5Pzqh9E0joJdjMDF+qfYI= sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==" + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-ordered-values@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz#0cf75c820ec7d5c4d280189559e0b571ebac0eee" + integrity "sha1-DPdcgg7H1cTSgBiVWeC1ceusDu4= sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==" + dependencies: + cssnano-util-get-arguments "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-reduce-initial@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz#7fd42ebea5e9c814609639e2c2e84ae270ba48df" + integrity "sha1-f9QuvqXpyBRgljniwuhK4nC6SN8= sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==" + dependencies: + browserslist "^4.0.0" + caniuse-api "^3.0.0" + has "^1.0.0" + postcss "^7.0.0" + +postcss-reduce-transforms@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz#17efa405eacc6e07be3414a5ca2d1074681d4e29" + integrity "sha1-F++kBerMbge+NBSlyi0QdGgdTik= sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==" + dependencies: + cssnano-util-get-match "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-selector-parser@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz#b310f5c4c0fdaf76f94902bbaa30db6aa84f5270" + integrity "sha1-sxD1xMD9r3b5SQK7qjDbaqhPUnA= sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==" + dependencies: + dot-prop "^5.2.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: + version "6.0.6" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" + integrity "sha1-LFu6gXSsL2mBq2MaQqsO5UrzMuo= sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==" + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-svgo@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.3.tgz#343a2cdbac9505d416243d496f724f38894c941e" + integrity "sha1-NDos26yVBdQWJD1Jb3JPOIlMlB4= sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==" + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + svgo "^1.0.0" + +postcss-unique-selectors@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz#9446911f3289bfd64c6d680f073c03b1f9ee4bac" + integrity "sha1-lEaRHzKJv9ZMbWgPBzwDsfnuS6w= sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==" + dependencies: + alphanum-sort "^1.0.0" + postcss "^7.0.0" + uniqs "^2.0.0" + +postcss-value-parser@^3.0.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity "sha1-n/giVH4okyE88cMO+lGsX9G6goE= sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + +postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" + integrity "sha1-RD9qIM7WSBor2k+oUypuVdeJoss= sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" + +postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.27, postcss@^7.0.32, postcss@^7.0.36, postcss@^7.0.5, postcss@^7.0.6: + version "7.0.39" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" + integrity "sha1-liQ3XZZWMOLh8sAqk1yCpZy0gwk= sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==" + dependencies: + picocolors "^0.2.1" + source-map "^0.6.1" + +postcss@^8.1.10: + version "8.3.11" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.11.tgz#c3beca7ea811cd5e1c4a3ec6d2e7599ef1f8f858" + integrity "sha1-w77KfqgRzV4cSj7G0udZnvH4+Fg= sha512-hCmlUAIlUiav8Xdqw3Io4LcpA1DOt7h3LSTAC4G6JGHFFaWzI6qvFt9oilvl8BmkbBRX1IhM90ZAmpk68zccQA==" + dependencies: + nanoid "^3.1.30" + picocolors "^1.0.0" + source-map-js "^0.6.2" + +preact@8.2.9: + version "8.2.9" + resolved "https://registry.yarnpkg.com/preact/-/preact-8.2.9.tgz#813ba9dd45e5d97c5ea0d6c86d375b3be711cc40" + integrity "sha1-gTup3UXl2XxeoNbIbTdbO+cRzEA= sha512-ThuGXBmJS3VsT+jIP+eQufD3L8pRw/PY3FoCys6O9Pu6aF12Pn9zAJDX99TfwRAFOCEKm/P0lwiPTbqKMJp0fA==" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity "sha1-3rxkidem5rDnYRiIzsiAM30xY5Y= sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==" + +prepend-http@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==" + +"prettier@^1.18.2 || ^2.0.0": + version "2.4.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c" + integrity "sha1-Zx4RyJwUpM/Ids5WQQbEpnJsn1w= sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==" + +pretty-bytes@^5.1.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" + integrity "sha1-NWJW9kOAR3PIL2RyP+eMksYr6us= sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==" + +pretty-error@^2.0.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.2.tgz#be89f82d81b1c86ec8fdfbc385045882727f93b6" + integrity "sha1-von4LYGxyG7I/fvDhQRYgnJ/k7Y= sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==" + dependencies: + lodash "^4.17.20" + renderkid "^2.0.4" + +pretty-format@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" + integrity "sha1-EvrDGzcBmk7qPBGqmpWet2KKp8k= sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==" + dependencies: + "@jest/types" "^24.9.0" + ansi-regex "^4.0.0" + ansi-styles "^3.2.0" + react-is "^16.8.4" + +pretty-format@^26.0.0, pretty-format@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" + integrity "sha1-41wnBfFMt/4v6U+geDRbREEg/JM= sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==" + dependencies: + "@jest/types" "^26.6.2" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^17.0.1" + +pretty@2.0.0, pretty@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pretty/-/pretty-2.0.0.tgz#adbc7960b7bbfe289a557dc5f737619a220d06a5" + integrity "sha1-rbx5YLe7/iiaVX3F9zdhmiINBqU= sha512-G9xUchgTEiNpormdYBl+Pha50gOUovT18IvAe7EYMZ1/f9W/WWMPRn+xI68yXNMUk3QXHDwo/1wV/4NejVNe1w==" + dependencies: + condense-newlines "^0.2.1" + extend-shallow "^2.0.1" + js-beautify "^1.6.12" + +prismjs@^1.22.0, prismjs@~1.25.0: + version "1.25.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.25.0.tgz#6f822df1bdad965734b310b315a23315cf999756" + integrity "sha1-b4It8b2tllc0sxCzFaIzFc+Zl1Y= sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg==" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity "sha1-eCDZsWEgzFXKmud5JoCufbptf+I= sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity "sha1-czIwDoQBYb2j5podHZGn1LwW8YI= sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity "sha1-foz42PW48jnBvGi+tOt4Vn1XLvg= sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity "sha1-mEcocL8igTL8vdhoEputEsPAKeM= sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==" + +promise@^7.1.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + integrity "sha1-BktyYCsY+Q8pGSuLG8QY/9Hr078= sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==" + dependencies: + asap "~2.0.3" + +prompts@^2.0.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity "sha1-e1fnOzpIAprRDr1E90sBcipMsGk= sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==" + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.7.2: + version "15.7.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity "sha1-UsQedbjIfnK52TYOAga5ncv/psU= sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==" + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.8.1" + +proper-lockfile@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-2.0.1.tgz#159fb06193d32003f4b3691dd2ec1a634aa80d1d" + integrity "sha1-FZ+wYZPTIAP0s2kd0uwaY0qoDR0= sha512-rjaeGbsmhNDcDInmwi4MuI6mRwJu6zq8GjYCLuSuE7GF+4UjgzkL69sVKKJ2T2xH61kK7rXvGYpvaTu909oXaQ==" + dependencies: + graceful-fs "^4.1.2" + retry "^0.10.0" + +property-expr@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-1.5.1.tgz#22e8706894a0c8e28d58735804f6ba3a3673314f" + integrity "sha1-IuhwaJSgyOKNWHNYBPa6OjZzMU8= sha512-CGuc0VUTGthpJXL36ydB6jnbyOf/rAHFvmVrJlH+Rg0DqqLFQGAP6hIaxD/G0OAmBJPhXDHuEJigrp0e0wFV6g==" + +property-information@^5.0.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69" + integrity "sha1-YWdVRfsjAC8kXGVA7EYHfU2j7Wk= sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==" + dependencies: + xtend "^4.0.0" + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" + +proxy-addr@~2.0.5: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity "sha1-8Z/mnOqzEe65S0LnDowgcPm6ECU= sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==" + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity "sha1-0/wRS6BplaRexok/SEzrHXj19HY= sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==" + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity "sha1-8FKijacOYYkX7wqKw0wa5aaChrM= sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" + +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity "sha1-kyb4vPsBOtzABf3/BWrM4CDlHCQ= sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity "sha1-T8ydd6B+SLp1J+fL4N4z0HATMeA= sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==" + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity "sha1-Ejma3W5M91Jtlzy8i1zi4pCLOQk= sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==" + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity "sha1-tKIRaBW94vTh6mAjVOjHVWUQemQ= sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==" + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity "sha1-NlE74karJ1cLGjdKXOJ4v9dDcM4= sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==" + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" + +punycode@^1.2.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity "sha1-wNWmOycYgArY4esPpSachN1BhF4= sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity "sha1-tYsBCsQMIsVldhbI0sLALHv0eew= sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + +q@^1.1.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + integrity "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" + +qs-stringify@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/qs-stringify/-/qs-stringify-1.2.1.tgz#9b39ef6b816bd83309628fc9dad435fc0eccc28b" + integrity "sha1-mznva4Fr2DMJYo/J2tQ1/A7Mwos= sha512-2N5xGLGZUxpgAYq1fD1LmBSCbxQVsXYt5JU0nU3FuPWO8PlCnKNFQwXkZgyB6mrTdg7IbexX4wxIR403dJw9pw==" + +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity "sha1-QdwaAV49WB8WIXdr4xr7KHapsbw= sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + +qs@^6.9.4: + version "6.10.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.1.tgz#4931482fa8d647a5aab799c5271d2133b981fb6a" + integrity "sha1-STFIL6jWR6Wqt5nFJx0hM7mB+2o= sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==" + dependencies: + side-channel "^1.0.4" + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY= sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + +query-string@^4.1.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" + integrity "sha1-u7aTucqRXCMlFbIosaArYJBD2+s= sha512-O2XLNDBIg1DnTOa+2XrIwSiXEV8h2KImXUnjhhn2+UsvZ+Es2uyd5CCRTNQlDGbzUQOW3aYCBx9rVA6dzsiY7Q==" + dependencies: + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==" + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==" + +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity "sha1-M0WUG0FTy50ILY7uTNogFqmu9/Y= sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity "sha1-SSkii7xyTfrEPg77BYyve2z7YkM= sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + +raf@^3.1.0, raf@^3.4.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" + integrity "sha1-B0LpmkplUvRF1z4+4DKK8P8e3jk= sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==" + dependencies: + performance-now "^2.1.0" + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity "sha1-32+ENy8CcNxlzfYpE0mrekc9Tyo= sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==" + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity "sha1-ySGW/IarQr6YPxvzF3giSTHWFFg= sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==" + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity "sha1-PPNwI9GZ4cJNGlW4SADC8+ZGgDE= sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity "sha1-oc5vucm8NWylLoklarWQWeE9AzI= sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==" + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +react-copy-to-clipboard@5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.3.tgz#2a0623b1115a1d8c84144e9434d3342b5af41ab4" + integrity "sha1-KgYjsRFaHYyEFE6UNNM0K1r0GrQ= sha512-9S3j+m+UxDZOM0Qb8mhnT/rMR0NGSrj9A/073yz2DSxPMYhmYFBMYIdI2X4o8AjOjyFsSNxDRnCX6s/gRxpriw==" + dependencies: + copy-to-clipboard "^3" + prop-types "^15.5.8" + +react-debounce-input@^3.2.3: + version "3.2.5" + resolved "https://registry.yarnpkg.com/react-debounce-input/-/react-debounce-input-3.2.5.tgz#3a29682c4b9dcd62694d6e03f85d7bfa96cec433" + integrity "sha1-OiloLEudzWJpTW4D+F17+pbOxDM= sha512-WDc9nvZ8E/cT4nW1RlD/r+Nsc5Z5+Jmj2v9HT9RzsPtxkwRTQUBCKJvdt1fCYy5ME/nQPoqVYmWUWSv7whGmig==" + dependencies: + lodash.debounce "^4" + prop-types "^15.7.2" + +react-dom@=15.7.0: + version "15.7.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.7.0.tgz#39106dee996d0742fb0f43d567ef8b8153483ab2" + integrity "sha1-ORBt7pltB0L7D0PVZ++LgVNIOrI= sha512-mpjXqC2t1FuYsILOLCj0kg6pbg460byZkVA/80VtDmKU/pYmoTdHOtaMcTRIDiyXLz4sIur0cQ04nOC6iGndJg==" + dependencies: + fbjs "^0.8.9" + loose-envify "^1.1.0" + object-assign "^4.1.0" + prop-types "^15.5.10" + +react-immutable-proptypes@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/react-immutable-proptypes/-/react-immutable-proptypes-2.2.0.tgz#cce96d68cc3c18e89617cbf3092d08e35126af4a" + integrity "sha1-zOltaMw8GOiWF8vzCS0I41Emr0o= sha512-Vf4gBsePlwdGvSZoLSBfd4HAP93HDauMY4fDjXhreg/vg6F3Fj/MXDNyTbltPC/xZKmZc+cjLu3598DdYK6sgQ==" + dependencies: + invariant "^2.2.2" + +react-immutable-pure-component@^1.1.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/react-immutable-pure-component/-/react-immutable-pure-component-1.2.4.tgz#ad2cdbd074fedecc799e5723d5e8e57b429e3e2c" + integrity "sha1-rSzb0HT+3sx5nlcj1ejle0KePiw= sha512-zPXaFWxaF4+ztVMFNMlCFkrhjpb9MPcL3JnXUpb6wKGF1+vBoSgClFbpbOsZAji7gm+RHBE24H44Lday2xxPjw==" + +react-inspector@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-2.3.1.tgz#f0eb7f520669b545b441af9d38ec6d706e5f649c" + integrity "sha1-8Ot/UgZptUW0Qa+dOOxtcG5fZJw= sha512-tUUK7t3KWgZEIUktOYko5Ic/oYwvjEvQUFAGC1UeMeDaQ5za2yZFtItJa2RTwBJB//NxPr000WQK6sEbqC6y0Q==" + dependencies: + babel-runtime "^6.26.0" + is-dom "^1.0.9" + prop-types "^15.6.1" + +react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity "sha1-eJcppNw23imZ3BVt1sHZwYzqVqQ= sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity "sha1-5pHUqOnHiTZWVVOas3J2Kw77VPA= sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + +react-motion@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/react-motion/-/react-motion-0.5.2.tgz#0dd3a69e411316567927917c6626551ba0607316" + integrity "sha1-DdOmnkETFlZ5J5F8ZiZVG6BgcxY= sha512-9q3YAvHoUiWlP3cK0v+w1N5Z23HXMj4IF4YuvjvWegWqNPfLXsOBE/V7UvQGpXxHFKRQQcNcVQE31g9SB/6qgQ==" + dependencies: + performance-now "^0.2.0" + prop-types "^15.5.8" + raf "^3.1.0" + +react-redux@=4.4.10: + version "4.4.10" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-4.4.10.tgz#ad57bd1db00c2d0aa7db992b360ce63dd0b80ec5" + integrity "sha1-rVe9HbAMLQqn25krNgzmPdC4DsU= sha512-tjL0Bmpkj75Td0k+lXlF8Fc8a9GuXFv/3ahUOCXExWs/jhsKiQeTffdH0j5byejCGCRL4tvGFYlrwBF1X/Aujg==" + dependencies: + create-react-class "^15.5.1" + hoist-non-react-statics "^3.3.0" + invariant "^2.0.0" + lodash "^4.17.11" + loose-envify "^1.4.0" + prop-types "^15.7.2" + +react-syntax-highlighter@^15.4.4: + version "15.4.4" + resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-15.4.4.tgz#dc9043f19e7bd063ff3ea78986d22a6eaa943b2a" + integrity "sha1-3JBD8Z570GP/PqeJhtIqbqqUOyo= sha512-PsOFHNTzkb3OroXdoR897eKN5EZ6grht1iM+f1lJSq7/L0YVnkJaNVwC3wEUYPOAmeyl5xyer1DjL6MrumO6Zw==" + dependencies: + "@babel/runtime" "^7.3.1" + highlight.js "^10.4.1" + lowlight "^1.17.0" + prismjs "^1.22.0" + refractor "^3.2.0" + +react@=15.7.0: + version "15.7.0" + resolved "https://registry.yarnpkg.com/react/-/react-15.7.0.tgz#10308fd42ac6912a250bf00380751abc41ac7106" + integrity "sha1-EDCP1CrGkSolC/ADgHUavEGscQY= sha512-5/MMRYmpmM0sMTHGLossnJCrmXQIiJilD6y3YN3TzAwGFj6zdnMtFv6xmi65PHKRV+pehIHpT7oy67Sr6s9AHA==" + dependencies: + create-react-class "^15.6.0" + fbjs "^0.8.9" + loose-envify "^1.1.0" + object-assign "^4.1.0" + prop-types "^15.5.10" + +read-pkg-up@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" + integrity "sha1-GyIcYIi6d5lgHICPkRYcZuWPiXg= sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==" + dependencies: + find-up "^3.0.0" + read-pkg "^3.0.0" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==" + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +read-pkg@^5.1.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" + integrity "sha1-e/KVQ4yloz5WzTDgU7NO5yUMk8w= sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==" + dependencies: + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^2.5.0" + parse-json "^5.0.0" + type-fest "^0.6.0" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity "sha1-Hsoc9xGu+BTAT2IlKjamL2yyO1c= sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6, readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity "sha1-M3u9o63AcGvT4CRCaihtS0sskZg= sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==" + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity "sha1-DodiKjMlqjPokihcr4tOhGUppSU= sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==" + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity "sha1-dKNwvYVxFuJFspzJc0DNQxoCpsc= sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==" + dependencies: + picomatch "^2.2.1" + +realpath-native@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" + integrity "sha1-IAMpT+oj+wZy8kduviL89Jii1lw= sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==" + dependencies: + util.promisify "^1.0.0" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==" + dependencies: + resolve "^1.1.6" + +redux-immutable@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/redux-immutable/-/redux-immutable-3.1.0.tgz#cafbd686e0711261119b9c28960935dc47a49d0a" + integrity "sha1-yvvWhuBxEmERm5wolgk13EeknQo= sha512-1W+0w6jKurzRnLLpYXRSOgaBTDpJthbnFJkkRei7598uNkiRYn5BZZ4QcGDX2I5Sin8L7W3hOHzQ9ne0oO8y8A==" + dependencies: + immutable "^3.8.1" + +redux@=3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/redux/-/redux-3.7.2.tgz#06b73123215901d25d065be342eb026bc1c8537b" + integrity "sha1-BrcxIyFZAdJdBlvjQusCa8HIU3s= sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==" + dependencies: + lodash "^4.2.1" + lodash-es "^4.2.1" + loose-envify "^1.1.0" + symbol-observable "^1.0.3" + +refractor@^3.2.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/refractor/-/refractor-3.5.0.tgz#334586f352dda4beaf354099b48c2d18e0819aec" + integrity "sha1-M0WG81LdpL6vNUCZtIwtGOCBmuw= sha512-QwPJd3ferTZ4cSPPjdP5bsYHMytwWYnAN5EEnLtGvkqp/FCCnGsBgxrm9EuIDnjUC3Uc/kETtvVi7fSIVC74Dg==" + dependencies: + hastscript "^6.0.0" + parse-entities "^2.0.0" + prismjs "~1.25.0" + +regenerate-unicode-properties@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz#54d09c7115e1f53dc2314a974b32c1c344efe326" + integrity "sha1-VNCccRXh9T3CMUqXSzLBw0Tv4yY= sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==" + dependencies: + regenerate "^1.4.2" + +regenerate@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity "sha1-uTRtiCfo9aMve6KWN9OYtpAUhIo= sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity "sha1-vgWtf5v30i4Fb5cmzuUBf78Z4uk= sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + +regenerator-runtime@^0.13.4: + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity "sha1-iSV0Kpj/2QgUmI11Zq0wyjsmO1I= sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + +regenerator-transform@^0.14.2: + version "0.14.5" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" + integrity "sha1-yY2hVGg2ccnE3LFuznNlF+G3/rQ= sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==" + dependencies: + "@babel/runtime" "^7.8.4" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity "sha1-H07OJ+ALC2XgJHpoEOaoXYOldSw= sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==" + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexp.prototype.flags@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" + integrity "sha1-fvNSro0VnnWMDq3Kb4/LTu8HviY= sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==" + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +regexpp@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity "sha1-BCWido2PI7rXDKS5BGH6LxIT4bI= sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==" + +regexpu-core@^4.7.1: + version "4.8.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.8.0.tgz#e5605ba361b67b1718478501327502f4479a98f0" + integrity "sha1-5WBbo2G2excYR4UBMnUC9EeamPA= sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==" + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties "^9.0.0" + regjsgen "^0.5.2" + regjsparser "^0.7.0" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.0.0" + +register-service-worker@^1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/register-service-worker/-/register-service-worker-1.7.2.tgz#6516983e1ef790a98c4225af1216bc80941a4bd2" + integrity "sha1-ZRaYPh73kKmMQiWvEha8gJQaS9I= sha512-CiD3ZSanZqcMPRhtfct5K9f7i3OLCcBBWsJjLh1gW9RO/nS94sVzY59iS+fgYBOBqaBpf4EzfqUF3j9IG+xo8A==" + +regjsgen@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" + integrity "sha1-kv8pX7He7L9uzaslQ9IH6RqjNzM= sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==" + +regjsparser@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.7.0.tgz#a6b667b54c885e18b52554cb4960ef71187e9968" + integrity "sha1-prZntUyIXhi1JVTLSWDvcRh+mWg= sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==" + dependencies: + jsesc "~0.5.0" + +relateurl@0.2.x: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==" + +remarkable@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/remarkable/-/remarkable-2.0.1.tgz#280ae6627384dfb13d98ee3995627ca550a12f31" + integrity "sha1-KArmYnOE37E9mO45lWJ8pVChLzE= sha512-YJyMcOH5lrR+kZdmB0aJJ4+93bEojRZ1HGDn9Eagu6ibg7aVZhc3OWbbShRid+Q5eAfsEqWxpe+g5W5nYNfNiA==" + dependencies: + argparse "^1.0.10" + autolinker "^3.11.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity "sha1-wkvOKig62tW8P1jg1IJJuSN52O8= sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==" + +renderkid@^2.0.4: + version "2.0.7" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.7.tgz#464f276a6bdcee606f4a15993f9b29fc74ca8609" + integrity "sha1-Rk8namvc7mBvShWZP5sp/HTKhgk= sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==" + dependencies: + css-select "^4.1.3" + dom-converter "^0.2.0" + htmlparser2 "^6.1.0" + lodash "^4.17.21" + strip-ansi "^3.0.1" + +repeat-element@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity "sha1-vmgVIIR6tYx1aKx1+/rSjtQtOek= sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==" + +repeat-string@^1.5.2, repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity "sha1-jcrkcOHIirwtYA//Sndihtp15jc= sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==" + +request-promise-core@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" + integrity "sha1-Pu3UIjII1BmGe3jOgVFn0QWToi8= sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==" + dependencies: + lodash "^4.17.19" + +request-promise-native@^1.0.5, request-promise-native@^1.0.7: + version "1.0.9" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" + integrity "sha1-5AcSBSal79yaObKKVnm/R7nZ3Cg= sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==" + dependencies: + request-promise-core "1.1.4" + stealthy-require "^1.1.1" + tough-cookie "^2.3.3" + +request@^2.83.0, request@^2.87.0, request@^2.88.0, request@^2.88.2: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity "sha1-1zyRhzHLWofaBH4gcjQUb2ZNErM= sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity "sha1-jGStX9MNqxyXbiNE/+f3kqam30I= sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity "sha1-iaf92TgmEmcxjq/hT5wy5ZjDaQk= sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity "sha1-0LMp7MfMD2Fkn2IhW+aa9UqomJs= sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + +reselect@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.2.tgz#7bf642992d143d4f3b0f2dca8aa52018808a1d51" + integrity "sha1-e/ZCmS0UPU87Dy3KiqUgGICKHVE= sha512-wg60ebcPOtxcptIUfrr7Jt3h4BR86cCW3R7y4qt65lnNb4yz4QgrXcbSioVsIOYguyz42+XTHIyJ5TEruzkFgQ==" + +resize-observer-polyfill@^1.5.0, resize-observer-polyfill@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" + integrity "sha1-DpAg3T0hAkRY1OvSfiPkAmmBBGQ= sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg==" + dependencies: + resolve-from "^3.0.0" + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity "sha1-six699nWiBvItuZTM17rywoYh0g= sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity "sha1-SrzYUq0y3Xuqv+m0DgCjbbXzkuY= sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==" + +resolve@1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==" + +resolve@1.x, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.3.2: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity "sha1-YpoBP7P3B1XW8LeTXMHCxTeLGXU= sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==" + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity "sha1-n37ih/gv0ybU/RYpI9YhKe7g368= sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==" + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity "sha1-OfZ8VLOnpYzqUjbZXPADQjljH34= sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==" + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity "sha1-uKSCXVvbH8P29Twrwz+BOIaBx7w= sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + +retry@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" + integrity "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q= sha512-ZXUSQYTHdl3uS7IuCehYfMzKyIDBNoAuUblvy5oGO5UJSUTmStUUVPXbA9Qxd173Bgre53yCQczQuHgRWAdvJQ==" + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity "sha1-kNo4Kx4SbvwCFG6QhFqI2xKSXXY= sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + +rgb-regex@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1" + integrity "sha1-wODWiC3w4jviVKR16O3UGRX+rrE= sha512-gDK5mkALDFER2YLqH6imYvK6g02gpNGM4ILDZ472EwWfXZnC2ZEpoB2ECXTyOVUKuk/bPJZMzwQPBYICzP+D3w==" + +rgba-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" + integrity "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= sha512-zgn5OjNQXLUTdq8m17KdaicF6w89TZs8ZU8y0AYENIU6wG8GG6LLm0yLSiPY8DmaYmHdgRW8rnApjoT0fQRfMg==" + +rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity "sha1-NXl/E6f9rcVmFCwp1PB8ytSD4+w= sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==" + dependencies: + glob "^7.1.3" + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity "sha1-8aVAK6YiCtUswSgrrBrjqkn9Bho= sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==" + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity "sha1-ocGm9iR1FXe6XQeRTLyShQWFiQw= sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==" + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +rsvp@^4.8.4: + version "4.8.5" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" + integrity "sha1-yPFVMR0Wf2jyHhaN9x7FsIMRNzQ= sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==" + +run-async@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" + integrity "sha1-hEDsz5nqPnC9QJ1JqriOEMGJpFU= sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity "sha1-ZtE2jae9+SHrnZW9GpIp5/IaQ+4= sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==" + dependencies: + queue-microtask "^1.2.2" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==" + dependencies: + aproba "^1.1.1" + +rxjs@^6.6.0: + version "6.6.7" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" + integrity "sha1-kKwBisq/SRv2UEQjXVhjxNq4BMk= sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==" + dependencies: + tslib "^1.9.0" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity "sha1-mR7GnSluAxN0fVm9/St0XDX4go0= sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + +safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity "sha1-Hq+fqb2x/dTsdfWPnNtOa3gn7sY= sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity "sha1-QKNmnzsHfR6UPURinhV91IAjvy4= sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==" + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo= sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + +sane@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" + integrity "sha1-7Ygf2SJzOmxGG8GJ3CtsAG8//e0= sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==" + dependencies: + "@cnakazawa/watch" "^1.0.3" + anymatch "^2.0.0" + capture-exit "^2.0.0" + exec-sh "^0.3.2" + execa "^1.0.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + +sass-loader@^10: + version "10.2.0" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.2.0.tgz#3d64c1590f911013b3fa48a0b22a83d5e1494716" + integrity "sha1-PWTBWQ+REBOz+kigsiqD1eFJRxY= sha512-kUceLzC1gIHz0zNJPpqRsJyisWatGYNFRmv2CKZK2/ngMJgLqxTbXwe/hJ85luyvZkgqU3VlJ33UVF2T/0g6mw==" + dependencies: + klona "^2.0.4" + loader-utils "^2.0.0" + neo-async "^2.6.2" + schema-utils "^3.0.0" + semver "^7.3.2" + +sass@1.32.12: + version "1.32.12" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.32.12.tgz#a2a47ad0f1c168222db5206444a30c12457abb9f" + integrity "sha1-oqR60PHBaCIttSBkRKMMEkV6u58= sha512-zmXn03k3hN0KaiVTjohgkg98C3UowhL1/VSGdj4/VAAiMKGQOE80PFPxFP2Kyq0OUskPKcY5lImkhBKEHlypJA==" + dependencies: + chokidar ">=3.0.0 <4.0.0" + +sax@^1.2.4, sax@~1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity "sha1-KBYjTiN4vdxOU1T6tcqold9xANk= sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + +saxes@^3.1.9: + version "3.1.11" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-3.1.11.tgz#d59d1fd332ec92ad98a2e0b2ee644702384b1c5b" + integrity "sha1-1Z0f0zLskq2YouCy7mRHAjhLHFs= sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==" + dependencies: + xmlchars "^2.1.1" + +schema-utils@2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" + integrity "sha1-FxUfdtjq5n+793lgwzxnatn078c= sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==" + dependencies: + "@types/json-schema" "^7.0.4" + ajv "^6.12.2" + ajv-keywords "^3.4.1" + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity "sha1-C3mpMgTXtgDUsoUNH2bCo0lRx3A= sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==" + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +schema-utils@^2.0.0, schema-utils@^2.5.0, schema-utils@^2.6.5, schema-utils@^2.7.0: + version "2.7.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" + integrity "sha1-HKTzLRskxZDCA7jnpQvw6kzTlNc= sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==" + dependencies: + "@types/json-schema" "^7.0.5" + ajv "^6.12.4" + ajv-keywords "^3.5.2" + +schema-utils@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" + integrity "sha1-vHTEtraZXB2I92qLd76nIZ4MgoE= sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==" + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" + +selfsigned@^1.10.8: + version "1.10.11" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.11.tgz#24929cd906fe0f44b6d01fb23999a739537acbe9" + integrity "sha1-JJKc2Qb+D0S20B+yOZmnOVN6y+k= sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA==" + dependencies: + node-forge "^0.10.0" + +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5, semver@^5.5.0, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc= sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + +semver@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity "sha1-XzyjV2HkfgWyBsba/yz4FPAxa44= sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==" + +semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity "sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0= sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + +semver@^7.1.2, semver@^7.2.1, semver@^7.3.2, semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity "sha1-C2Ich5NI2JmOSw5L6Us/EuYBjvc= sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==" + dependencies: + lru-cache "^6.0.0" + +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity "sha1-wdiwWfeQD3Rm3Uk4vcROEd2zdsg= sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==" + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.7.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serialize-error@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-8.1.0.tgz#3a069970c712f78634942ddd50fbbc0eaebe2f67" + integrity "sha1-OgaZcMcS94Y0lC3dUPu8Dq6+L2c= sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==" + dependencies: + type-fest "^0.20.2" + +serialize-javascript@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" + integrity "sha1-tSXhI4SJpez8Qq+sw/6Z5mb0sao= sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==" + dependencies: + randombytes "^2.1.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==" + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity "sha1-Zm5jbcTwEPfvKZcKiKZ0MgiYsvk= sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==" + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity "sha1-BF+XgtARrppoA93TgrJDkrPYkPc= sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity "sha1-oY1AUw5vB95CKMfe/kInr4ytAFs= sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4, setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY= sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity "sha1-fpWsskqpL1iF4KvvW6ExMw1K5oM= sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + +sha.js@^2.4.0, sha.js@^2.4.11, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity "sha1-N6XPC4HsvGlD3hCbopYNGyZYSuc= sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shallow-equal@^1.0.0, shallow-equal@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.2.1.tgz#4c16abfa56043aa20d050324efa68940b0da79da" + integrity "sha1-TBar+lYEOqINBQMk76aJQLDaedo= sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==" + +shallowequal@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" + integrity "sha1-GI1SHelbkIdAT9TctosT3wrk5/g= sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==" + dependencies: + shebang-regex "^1.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity "sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo= sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==" + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity "sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI= sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + +shell-quote@^1.6.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" + integrity "sha1-qkDtrBcERbmkMeF7tiwLiBucQSM= sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==" + +shelljs@^0.8.3: + version "0.8.4" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2" + integrity "sha1-3naE/ut2f4cWsyYHiooAh1iQ48I= sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==" + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" + integrity "sha1-1rkYHBpI05cyTISHHvvPxz/AZUs= sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity "sha1-785cj9wQTudRslxY1CkAEfpeos8= sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==" + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +sigmund@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + integrity "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g==" + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.5" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.5.tgz#9e3e8cc0c75a99472b44321033a7702e7738252f" + integrity "sha1-nj6MwMdamUcrRDIQM6dwLnc4JS8= sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==" + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==" + dependencies: + is-arrayish "^0.3.1" + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity "sha1-E01oEpd1ZDfMBcoBNw06elcQde0= sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==" + +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity "sha1-3lUoUaF1nfOo8gZTVEL17E3eq0Q= sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity "sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ= sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity "sha1-UA6N0P1VsFgVCGJVsxla3ypF/ms= sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==" + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity "sha1-bBdfhv8UvbByRWPo88GwIaKGhTs= sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==" + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity "sha1-+VZHlIbyrNeXAGk/b3uAXkWrVuI= sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==" + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity "sha1-ZJIufFZbDhQgS6GqfWlkJ40lGC0= sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==" + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +sockjs-client@^1.5.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.5.2.tgz#4bc48c2da9ce4769f19dc723396b50f5c12330a3" + integrity "sha1-S8SMLanOR2nxnccjOWtQ9cEjMKM= sha512-ZzRxPBISQE7RpzlH4tKJMQbHM9pabHluk0WBaxAQ+wm/UieeBVBou0p4wVnSQGN9QmpAZygQ0cDIypWuqOFmFQ==" + dependencies: + debug "^3.2.6" + eventsource "^1.0.7" + faye-websocket "^0.11.3" + inherits "^2.0.4" + json3 "^3.3.3" + url-parse "^1.5.3" + +sockjs@^0.3.21: + version "0.3.21" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.21.tgz#b34ffb98e796930b60a0cfa11904d6a339a7d417" + integrity "sha1-s0/7mOeWkwtgoM+hGQTWozmn1Bc= sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==" + dependencies: + faye-websocket "^0.11.3" + uuid "^3.4.0" + websocket-driver "^0.7.4" + +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity "sha1-RBttTTRnmPG05J6JIK37oOVD+a0= sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==" + dependencies: + is-plain-obj "^1.0.0" + +sortablejs@1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/sortablejs/-/sortablejs-1.10.2.tgz#6e40364d913f98b85a14f6678f92b5c1221f5290" + integrity "sha1-bkA2TZE/mLhaFPZnj5K1wSIfUpA= sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A==" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity "sha1-OZO9hzv8SEecyp6jpUeDXHwVSzQ= sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + +source-map-js@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" + integrity "sha1-C7XeYxtBz72mz7qL0FqA79/SOF4= sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==" + +source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity "sha1-GQhmvs51U+H48mei7oLGBrVQmho= sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==" + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.5.6, source-map-support@~0.5.12: + version "0.5.20" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" + integrity "sha1-EhZgifj15ejFaSazd2Mzkt0stsk= sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==" + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity "sha1-CvZmBadFpaL5HPG7+KevvCg97FY= sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==" + +source-map@^0.5.0, source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity "sha1-dHIq8y6WFOnCh6jQu95IteLxomM= sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + +source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity "sha1-UwL4FpAxc1ImVECS5kmB91F1A4M= sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + +sourcemap-codec@^1.4.4: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity "sha1-6oBL2UhXQC5pktBaOO8a41qatMQ= sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" + +space-separated-tokens@^1.0.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" + integrity "sha1-hfMsPRDZaCAH6RdBTdxcJtGqaJk= sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==" + +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity "sha1-3s6BrJweZxPl99G28X1Gj6U9iak= sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==" + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity "sha1-PyjOGnegA3JoPq3kpDMYNSeiFj0= sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity "sha1-z3D1BILu/cmOPOCmgz5KU87rpnk= sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==" + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.10" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz#0d9becccde7003d6c658d487dd48a32f0bf3014b" + integrity "sha1-DZvszN5wA9bGWNSH3UijLwvzAUs= sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==" + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity "sha1-ANSGOmQArXXfkzYaFghgXl3NzzE= sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==" + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity "sha1-t09GYgOj7aRSwCSSuR+56EonZ3s= sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==" + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity "sha1-fLCd2jqGWFcFxks5pkZgOGguj+I= sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==" + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity "sha1-+2YcC+8ps520B2nuOfpwCT1vaHc= sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +ssri@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5" + integrity "sha1-FXk5E08gRk5zAd26PpD/qPdyisU= sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==" + dependencies: + figgy-pudding "^3.5.1" + +ssri@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" + integrity "sha1-Y45OQ54v+9LNKJd21cpFfE9Roq8= sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==" + dependencies: + minipass "^3.1.1" + +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity "sha1-g26zyDgv4pNv6vVEYxAXzn1Ho88= sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" + +stack-utils@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.5.tgz#a19b0b01947e0029c8e451d5d61a498f5bb1471b" + integrity "sha1-oZsLAZR+ACnI5FHV1hpJj1uxRxs= sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==" + dependencies: + escape-string-regexp "^2.0.0" + +stackframe@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303" + integrity "sha1-UkKUktY8YuuYmATBFVLj0i53kwM= sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==" + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==" + +stealthy-require@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + integrity "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==" + +stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity "sha1-h1IdOKRKp+6RzhzSpH3wy0ndZgs= sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==" + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity "sha1-6+J6DDibBPvMIzZClS4Qcxr6m64= sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==" + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity "sha1-stJCRpKIpaJ+xP6JM6z2I95lFPw= sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==" + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity "sha1-1wiCgVWasneEJCebCHfaPDktWj0= sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + +stream@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/stream/-/stream-0.0.2.tgz#7f5363f057f6592c5595f00bc80a27f5cec1f0ef" + integrity "sha1-f1Nj8Ff2WSxVlfALyAon9c7B8O8= sha512-gCq3NDI2P35B2n6t76YJuOp7d6cN/C7Rt0577l91wllh0sY9ZBuw9KaSGqH/b0hzn3CWWJbpbW0W0WvQ1H/Q7g==" + dependencies: + emitter-component "^1.1.1" + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==" + +string-convert@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/string-convert/-/string-convert-0.2.1.tgz#6982cc3049fbb4cd85f8b24568b9d9bf39eeff97" + integrity "sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c= sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==" + +string-length@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" + integrity "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0= sha512-Qka42GGrS8Mm3SZ+7cH8UXiIWI867/b/Z/feQSpQx/rbfB8UGknGEZVaUQMOUVj+soY6NpWAxily63HI1OckVQ==" + dependencies: + astral-regex "^1.0.0" + strip-ansi "^4.0.0" + +string-length@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-3.1.0.tgz#107ef8c23456e187a8abd4a61162ff4ac6e25837" + integrity "sha1-EH74wjRW4Yeoq9SmEWL/SsbiWDc= sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==" + dependencies: + astral-regex "^1.0.0" + strip-ansi "^5.2.0" + +string-width@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4= sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity "sha1-InZ74htirxCBV0MG9prFG2IgOWE= sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==" + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity "sha1-JpxxF9J7Ba0uU2gwqOyJXvnG0BA= sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==" + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity "sha1-51rpDClCxjUEaGwYsoe0oLGkX4A= sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==" + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity "sha1-s2OZr0qymZtMnGSL16P7K7Jv7u0= sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==" + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string_decoder@^1.0.0, string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity "sha1-QvEUWUpGzxqOMLCoT1bHjD7awh4= sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==" + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g= sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==" + dependencies: + safe-buffer "~5.1.0" + +stringify-object@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + integrity "sha1-cDBlrvyhkwDTzoivT1s5VtdVZik= sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==" + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity "sha1-qEeQIusaw2iocTibY1JixQXuNo8= sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==" + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5, strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4= sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==" + dependencies: + ansi-regex "^4.1.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity "sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk= sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==" + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==" + +strip-comments@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-1.0.2.tgz#82b9c45e7f05873bee53f37168af930aa368679d" + integrity "sha1-grnEXn8FhzvuU/NxaK+TCqNoZ50= sha512-kL97alc47hoyIQSV165tTt9rG5dn4w1dNnBhOQ3bOU1Nc1hel09jnXANaHJ7vzHLd4Ju8kseDGzlev96pghLFw==" + dependencies: + babel-extract-comments "^1.0.0" + babel-plugin-transform-object-rest-spread "^6.26.0" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==" + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity "sha1-ibhS+y/L6Tb29LMYevsKEsGrWK0= sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" + +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + integrity "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA==" + +strip-json-comments@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity "sha1-PFMZQukIwml8DsNEhYwobHygpgo= sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" + +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity "sha1-MfEoGzgyYwQ0gxwxDAHMzajL4AY= sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" + +stylehacks@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5" + integrity "sha1-Zxj8r00eB9ihMYaQiB6NlnJqcdU= sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==" + dependencies: + browserslist "^4.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8= sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==" + dependencies: + has-flag "^3.0.0" + +supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity "sha1-B2Srxpxj1ayELdSGfo0CXogN+PM= sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==" + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo= sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==" + dependencies: + has-flag "^4.0.0" + +svg-tags@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" + integrity "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q= sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==" + +svgo@^1.0.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" + integrity "sha1-ttxRHAYzRsnkFbgeQ0ARRbltQWc= sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==" + dependencies: + chalk "^2.4.1" + coa "^2.0.2" + css-select "^2.0.0" + css-select-base-adapter "^0.1.1" + css-tree "1.0.0-alpha.37" + csso "^4.0.2" + js-yaml "^3.13.1" + mkdirp "~0.5.1" + object.values "^1.1.0" + sax "~1.2.4" + stable "^0.1.8" + unquote "~1.1.1" + util.promisify "~1.0.0" + +swagger-client@^3.17.0: + version "3.17.0" + resolved "https://registry.yarnpkg.com/swagger-client/-/swagger-client-3.17.0.tgz#13e35e8ef7b5f05ab05dfaeb48acaa86b0882c64" + integrity "sha1-E+Nejve18FqwXfrrSKyqhrCILGQ= sha512-d8DOEME49wTXm+uT+lBAjJ5D6IDjEHdbkqa7MbcslR2c+oHIhi13ObwleVWGfr89MPkWgBl6RBq9VUHmrBJRbg==" + dependencies: + "@babel/runtime-corejs3" "^7.11.2" + btoa "^1.2.1" + cookie "~0.4.1" + cross-fetch "^3.1.4" + deep-extend "~0.6.0" + fast-json-patch "^3.0.0-1" + form-data-encoder "^1.4.3" + formdata-node "^4.0.0" + js-yaml "^4.1.0" + lodash "^4.17.21" + qs "^6.9.4" + traverse "~0.6.6" + url "~0.11.0" + +swagger-ui@^3.50.0: + version "3.52.5" + resolved "https://registry.yarnpkg.com/swagger-ui/-/swagger-ui-3.52.5.tgz#bffb736e737ad8783d2d8b06d08224ba611d3507" + integrity "sha1-v/tzbnN62Hg9LYsG0IIkumEdNQc= sha512-GvxNYvSaFkU9OoG4BQxjmengl5fA+A5wAuG4rtAbBLWlrLkBiQiHXKQPzyDMUUa3/8nielKpEK1NunnxwpY9Mg==" + dependencies: + "@babel/runtime-corejs3" "^7.14.7" + "@braintree/sanitize-url" "^5.0.2" + "@kyleshockey/object-assign-deep" "^0.4.2" + "@kyleshockey/xml" "^1.0.2" + base64-js "^1.5.1" + classnames "^2.3.1" + css.escape "1.5.1" + deep-extend "0.6.0" + dompurify "^2.2.9" + ieee754 "^1.2.1" + immutable "^3.x.x" + js-file-download "^0.4.12" + js-yaml "=4.1.0" + lodash "^4.17.21" + memoizee "^0.4.15" + prop-types "^15.7.2" + randombytes "^2.1.0" + react "=15.7.0" + react-copy-to-clipboard "5.0.3" + react-debounce-input "^3.2.3" + react-dom "=15.7.0" + react-immutable-proptypes "2.2.0" + react-immutable-pure-component "^1.1.1" + react-inspector "^2.3.0" + react-motion "^0.5.2" + react-redux "=4.4.10" + react-syntax-highlighter "^15.4.4" + redux "=3.7.2" + redux-immutable "3.1.0" + remarkable "^2.0.1" + reselect "^4.0.0" + serialize-error "^8.1.0" + sha.js "^2.4.11" + swagger-client "^3.17.0" + url-parse "^1.5.2" + xml-but-prettier "^1.0.1" + zenscroll "^4.0.2" + +symbol-observable@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity "sha1-wiaIrtTqs83C3+rLtWFmBWCgCAQ= sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" + +symbol-tree@^3.2.2: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity "sha1-QwY30ki6d+B4iDlR+5qg7tfGP6I= sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + +table@^6.0.9: + version "6.7.3" + resolved "https://registry.yarnpkg.com/table/-/table-6.7.3.tgz#255388439715a738391bd2ee4cbca89a4d05a9b7" + integrity "sha1-JVOIQ5cVpzg5G9LuTLyomk0Fqbc= sha512-5DkIxeA7XERBqMwJq0aHZOdMadBx4e6eDoFRuyT5VR82J0Ycg2DwM6GfA/EQAhJ+toRTaS1lIdSQCqgrmhPnlw==" + dependencies: + ajv "^8.0.1" + lodash.truncate "^4.4.2" + slice-ansi "^4.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" + +tapable@^1.0.0, tapable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity "sha1-ofzMBrWNth/XpF2i2kT186Pme6I= sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" + +terser-webpack-plugin@^1.4.3, terser-webpack-plugin@^1.4.4: + version "1.4.5" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b" + integrity "sha1-oheu+uozDnNP+sthIOwfoxLWBAs= sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==" + dependencies: + cacache "^12.0.2" + find-cache-dir "^2.1.0" + is-wsl "^1.1.0" + schema-utils "^1.0.0" + serialize-javascript "^4.0.0" + source-map "^0.6.1" + terser "^4.1.2" + webpack-sources "^1.4.0" + worker-farm "^1.7.0" + +terser@^4.1.2: + version "4.8.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" + integrity "sha1-YwVjQ9fHC7KfOvZlhlpG/gOg3xc= sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==" + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +test-exclude@^5.2.3: + version "5.2.3" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.2.3.tgz#c3d3e1e311eb7ee405e092dac10aefd09091eac0" + integrity "sha1-w9Ph4xHrfuQF4JLawQrv0JCR6sA= sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==" + dependencies: + glob "^7.1.3" + minimatch "^3.0.4" + read-pkg-up "^4.0.0" + require-main-filename "^2.0.0" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==" + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity "sha1-iTLmhqQGYDigFt2eLKRq3Zg4qV8= sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==" + dependencies: + any-promise "^1.0.0" + +thread-loader@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/thread-loader/-/thread-loader-2.1.3.tgz#cbd2c139fc2b2de6e9d28f62286ab770c1acbdda" + integrity "sha1-y9LBOfwrLebp0o9iKGq3cMGsvdo= sha512-wNrVKH2Lcf8ZrWxDF/khdlLlsTMczdcwPA9VEK4c2exlEPynYWxi9op3nPTo5lAnDIkE0rQEB3VBP+4Zncc9Hg==" + dependencies: + loader-runner "^2.3.1" + loader-utils "^1.1.0" + neo-async "^2.6.0" + +throat@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" + integrity "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= sha512-wCVxLDcFxw7ujDxaeJC6nfl2XfHJNYs8yUYJnvMgtPEFlttP9tHSfRUv2vBe6C4hkVFPWoP1P6ZccbYjmSEkKA==" + +through2@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity "sha1-AcHjnrMdB8t9A6lqcIIyYLIxMs0= sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==" + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity "sha1-Wrr3FKlAXbBQRzK7zNLO3Z75U30= sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" + +timers-browserify@^2.0.4: + version "2.0.12" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" + integrity "sha1-RKRcEfv0B/NPl7zNFXfGUjYbAO4= sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==" + dependencies: + setimmediate "^1.0.4" + +timers-ext@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6" + integrity "sha1-b1ethXjgej+5+R2Th9ZWR1VeJcY= sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==" + dependencies: + es5-ext "~0.10.46" + next-tick "1" + +timsort@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" + integrity "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==" + +tinycolor2@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803" + integrity "sha1-P2pNEHGtB2dtf6Ry4frECnGdiAM= sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==" + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity "sha1-bTQzWIl2jSGyvNoKonfO07G/rfk= sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==" + dependencies: + os-tmpdir "~1.0.2" + +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity "sha1-hoPguQK7nCDE9ybjwLafNlGMB8w= sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==" + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + integrity "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==" + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==" + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==" + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ= sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==" + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity "sha1-E8/dmzNlUvMLUfM6iuG0Knp1mc4= sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==" + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +toggle-selection@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" + integrity "sha1-bkWxJj8gF/oKzH2J14sVuL932jI= sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity "sha1-fhvjRw8ed5SLxD2Uo8j013UrpVM= sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + +toposort@^1.0.0: + version "1.0.7" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029" + integrity "sha1-LmhELZ9k7HILjMieZEOsbKqVACk= sha512-FclLrw8b9bMWf4QlCJuHBEVhSRsqDj6u3nIjAzPeJvgl//1hBlffdlk0MALceL14+koWEdU4ofRAXofbODxQzg==" + +tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity "sha1-zZ+yoKodWhK0c72fuW+j3P9lreI= sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==" + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tough-cookie@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2" + integrity "sha1-nfT1fnOcJpMKAYGEiH9K233Kc7I= sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==" + dependencies: + ip-regex "^2.1.0" + psl "^1.1.28" + punycode "^2.1.1" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==" + dependencies: + punycode "^2.1.0" + +traverse@~0.6.6: + version "0.6.6" + resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" + integrity "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc= sha512-kdf4JKs8lbARxWdp7RKdNzoJBhGUcIalSYibuGyHJbmk40pOysQ0+QPvlkCOICOivDWU2IJo2rkrxyTK2AH4fw==" + +tryer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" + integrity "sha1-8shUBoALmw90yfdGW4HqrSQSUvg= sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" + +ts-jest@^24.2.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.3.0.tgz#b97814e3eab359ea840a1ac112deae68aa440869" + integrity "sha1-uXgU4+qzWeqEChrBEt6uaKpECGk= sha512-Hb94C/+QRIgjVZlJyiWwouYUF+siNJHJHknyspaOcZ+OQAIdFG/UrdQVXw/0B8Z3No34xkUXZJpOTy9alOWdVQ==" + dependencies: + bs-logger "0.x" + buffer-from "1.x" + fast-json-stable-stringify "2.x" + json5 "2.x" + lodash.memoize "4.x" + make-error "1.x" + mkdirp "0.x" + resolve "1.x" + semver "^5.5" + yargs-parser "10.x" + +ts-loader@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-6.2.2.tgz#dffa3879b01a1a1e0a4b85e2b8421dc0dfff1c58" + integrity "sha1-3/o4ebAaGh4KS4XiuEIdwN//HFg= sha512-HDo5kXZCBml3EUPcc7RlZOV/JGlLHwppTLEHb3SHnr5V7NXD4klMEkrhJe5wgRbaWsSXi+Y1SIBN/K9B6zWGWQ==" + dependencies: + chalk "^2.3.0" + enhanced-resolve "^4.0.0" + loader-utils "^1.0.2" + micromatch "^4.0.0" + semver "^6.0.0" + +ts-pnp@^1.1.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" + integrity "sha1-pQCtCEsHmPHDBxrzkeZZEshrypI= sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==" + +tsconfig@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/tsconfig/-/tsconfig-7.0.0.tgz#84538875a4dc216e5c4a5432b3a4dec3d54e91b7" + integrity "sha1-hFOIdaTcIW5cSlQys6Tew9VOkbc= sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==" + dependencies: + "@types/strip-bom" "^3.0.0" + "@types/strip-json-comments" "0.0.30" + strip-bom "^3.0.0" + strip-json-comments "^2.0.0" + +tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity "sha1-zy04vcNKE0vK8QkcQfZhni9nLQA= sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + +tslint@^5.20.1: + version "5.20.1" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.20.1.tgz#e401e8aeda0152bc44dd07e614034f3f80c67b7d" + integrity "sha1-5AHortoBUrxE3QfmFANPP4DGe30= sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==" + dependencies: + "@babel/code-frame" "^7.0.0" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" + diff "^4.0.1" + glob "^7.1.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + mkdirp "^0.5.1" + resolve "^1.3.2" + semver "^5.3.0" + tslib "^1.8.0" + tsutils "^2.29.0" + +tsutils@^2.29.0: + version "2.29.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" + integrity "sha1-MrSIUBRnrL7dS4VJhnOggSrKC5k= sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==" + dependencies: + tslib "^1.8.1" + +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity "sha1-tIcX05TOpsHglpg+7Vjp1hcVtiM= sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==" + dependencies: + tslib "^1.8.1" + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==" + dependencies: + safe-buffer "^5.0.1" + +tus-js-client@^2.1.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tus-js-client/-/tus-js-client-2.3.0.tgz#5d76145476cea46a4e7c045a0054637cddf8dc39" + integrity "sha1-XXYUVHbOpGpOfARaAFRjfN343Dk= sha512-I4cSwm6N5qxqCmBqenvutwSHe9ntf81lLrtf6BmLpG2v4wTl89atCQKqGgqvkodE6Lx+iKIjMbaXmfvStTg01g==" + dependencies: + buffer-from "^0.1.1" + combine-errors "^3.0.3" + is-stream "^2.0.0" + js-base64 "^2.6.1" + lodash.throttle "^4.1.1" + proper-lockfile "^2.0.1" + url-parse "^1.4.3" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity "sha1-B7ggO/pwVsBlcFDjzNLDdzC6uPE= sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==" + dependencies: + prelude-ls "^1.2.1" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==" + dependencies: + prelude-ls "~1.1.2" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity "sha1-G/IH9LKPkVg2ZstfvTJ4hzAc1fQ= sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity "sha1-0mCiSwGYQ24TP6JqUkptZfo7Ljc= sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + +type-fest@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" + integrity "sha1-jSojcNPfiG61yQraHFv2GIrPg4s= sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + +type-is@~1.6.17, type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity "sha1-TlUs0F3wlGfcvE73Od6J8s83wTE= sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==" + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity "sha1-hI3XaY2vo+VKbEeedZxLw/GIR6A= sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + +type@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.5.0.tgz#0a2e78c2e77907b252abe5f298c1b01c63f0db3d" + integrity "sha1-Ci54wud5B7JSq+XymMGwHGPw2z0= sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + +typescript@^4.2.4: + version "4.4.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.4.tgz#2cd01a1a1f160704d3101fd5a58ff0f9fcb8030c" + integrity "sha1-LNAaGh8WBwTTEB/VpY/w+fy4Aww= sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==" + +ua-parser-js@^0.7.30: + version "0.7.31" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" + integrity "sha1-ZJplaxkd/6tPIdXgU+J8oXy/9cY= sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==" + +uc.micro@^1.0.1, uc.micro@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" + integrity "sha1-nEEagCpAmpH8bPdAgbq6NLJEmaw= sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + +uglify-js@3.4.x: + version "3.4.10" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" + integrity "sha1-mtlWPY6zrN+404WX0q8dgV9qdV8= sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==" + dependencies: + commander "~2.19.0" + source-map "~0.6.1" + +unbox-primitive@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity "sha1-CF4hViXsMWJXTciFmr7nilmxRHE= sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==" + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" + integrity "sha1-MBrNxSVjFnDTn2FG4Od/9rvevdw= sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==" + +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity "sha1-VP0W4OyxZ88Ezx91a9zJLrp5dsM= sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==" + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + +unicode-match-property-value-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" + integrity "sha1-GgGqVyR8FMVouJd1pUk4eIGJpxQ= sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==" + +unicode-property-aliases-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" + integrity "sha1-CjbLmlhcT2q9Ua0d7dsoXBZSl8g= sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==" + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity "sha1-C2/nuDWuzaYcbqTU8CwUIh4QmEc= sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==" + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + integrity "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==" + +uniqs@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" + integrity "sha1-/+3ks2slKQaW5uFl1KWe25mOawI= sha512-mZdDpf3vBV5Efh29kMw5tXoup/buMgxLzOt/XKFKcVmi+15ManNQWr6HfZ2aiZTYlYixbdNJ0KFmIZIv52tHSQ==" + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity "sha1-HWl2k2mtoFgxA6HmrodoG1ZXMjA= sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==" + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity "sha1-uqvOkQg/xk6UWw861hPiZPfNTmw= sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==" + dependencies: + imurmurhash "^0.1.4" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity "sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY= sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity "sha1-daSYTv7cSwiXXFrrc/Uw0C3yVxc= sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + +"unorm@>= 1.0.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.6.0.tgz#029b289661fba714f1a9af439eb51d9b16c205af" + integrity "sha1-ApsolmH7pxTxqa9DnrUdmxbCBa8= sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + +unquote@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" + integrity "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==" + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==" + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity "sha1-j2bbzVWog6za5ECK+LA1pQRMGJQ= sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" + +upper-case@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" + integrity "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity "sha1-mxpSWVIlhZ5V9mnZKPiMbFfyp34= sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==" + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==" + +url-loader@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-2.3.0.tgz#e0e2ef658f003efb8ca41b0f3ffbf76bab88658b" + integrity "sha1-4OLvZY8APvuMpBsPP/v3a6uIZYs= sha512-goSdg8VY+7nPZKUEChZSEtW5gjbS66USIGCeSJ1OVOJ7Yfuh/36YxCwMi5HVEJh6mqUYOoy3NJ0vlOMrWsSHog==" + dependencies: + loader-utils "^1.2.3" + mime "^2.4.4" + schema-utils "^2.5.0" + +url-parse@^1.4.3, url-parse@^1.4.7, url-parse@^1.5.2, url-parse@^1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.3.tgz#71c1303d38fb6639ade183c2992c8cc0686df862" + integrity "sha1-ccEwPTj7Zjmt4YPCmSyMwGht+GI= sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==" + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + +url@^0.11.0, url@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==" + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity "sha1-1QyMrHmhn7wg8pEfVuuXP04QBw8= sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + +uslug@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/uslug/-/uslug-1.0.4.tgz#b9a22f0914e0a86140633dacc302e5f4fa450677" + integrity "sha1-uaIvCRTgqGFAYz2swwLl9PpFBnc= sha512-Jrbpp/NS3TvIGNjfJT1sn3/BCeykoxR8GbNYW5lF6fUscLkbXFwj1b7m4DvIkHm8k3Qr6Co68lbTmoZTMGk/ow==" + dependencies: + unorm ">= 1.0.0" + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + +util.promisify@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + integrity "sha1-RA9xZaRZyaFtwUXrjnLzVocJcDA= sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==" + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + +util.promisify@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.1.1.tgz#77832f57ced2c9478174149cae9b96e9918cd54b" + integrity "sha1-d4MvV87SyUeBdBScrpuW6ZGM1Us= sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw==" + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + for-each "^0.3.3" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.1" + +util.promisify@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" + integrity "sha1-a693dLgO6w91INi4HQeYKlmruu4= sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==" + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.2" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.0" + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity "sha1-evsa/lCAUkZInj23/g7TeTNqwPk= sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==" + dependencies: + inherits "2.0.1" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity "sha1-MjZzNyDsZLsn9uJvQhqqLhtYjWE= sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==" + dependencies: + inherits "2.0.3" + +utila@~0.4: + version "0.4.0" + resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" + integrity "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" + +uuid@^3.3.2, uuid@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity "sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4= sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + +v8-compile-cache@^2.0.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity "sha1-LeGWGMZtwkfc+2+ZM4A12CRaLO4= sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity "sha1-/JH2uce6FchX9MssXe/uw51PQQo= sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==" + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" + +vendors@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" + integrity "sha1-4rgApT56Kbk1BsPPQRANFsTErY4= sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==" + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==" + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vm-browserify@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity "sha1-eGQcSIuObKkadfUR56OzKobl3aA= sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" + +vue-axios@^3.2.4: + version "3.4.0" + resolved "https://registry.yarnpkg.com/vue-axios/-/vue-axios-3.4.0.tgz#059d7fcbe83f786cda24e9501317174736927b37" + integrity "sha1-BZ1/y+g/eGzaJOlQExcXRzaSezc= sha512-S3YTCJeEndzmtaYzyz919Z54wY1D2OftWEhioGbHED3VUSta8ti0OHjDipTPkb1StxOzQLAAO2hSUq830i14KA==" + +vue-chartjs@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/vue-chartjs/-/vue-chartjs-3.5.1.tgz#d25e845708f7744ae51bed9d23a975f5f8fc6529" + integrity "sha1-0l6EVwj3dErlG+2dI6l19fj8ZSk= sha512-foocQbJ7FtveICxb4EV5QuVpo6d8CmZFmAopBppDIGKY+esJV8IJgwmEW0RexQhxqXaL/E1xNURsgFFYyKzS/g==" + dependencies: + "@types/chart.js" "^2.7.55" + +vue-class-component@^7.2.6: + version "7.2.6" + resolved "https://registry.yarnpkg.com/vue-class-component/-/vue-class-component-7.2.6.tgz#8471e037b8e4762f5a464686e19e5afc708502e4" + integrity "sha1-hHHgN7jkdi9aRkaG4Z5a/HCFAuQ= sha512-+eaQXVrAm/LldalI272PpDe3+i4mPis0ORiMYxF6Ae4hyuCh15W8Idet7wPUEs4N4YptgFHGys4UrgNQOMyO6w==" + +vue-cli-plugin-vuetify@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/vue-cli-plugin-vuetify/-/vue-cli-plugin-vuetify-2.3.1.tgz#9e45a686902351320e876881d057eb69c646a22b" + integrity "sha1-nkWmhpAjUTIOh2iB0FfracZGois= sha512-96NLmCE12FalyWSxbfFerbOKSwuPq5b4zYRei5BRLbdCBq+YgmCMv8zgZl8Rx/kR/91T4i8XZDCNgfQ78mpQ3A==" + dependencies: + null-loader "^3.0.0" + semver "^7.1.2" + shelljs "^0.8.3" + +vue-cropperjs@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/vue-cropperjs/-/vue-cropperjs-4.2.0.tgz#6bce4c17478cecec56571d4060892a386307c60e" + integrity "sha1-a85MF0eM7OxWVx1AYIkqOGMHxg4= sha512-dvwCBtjGMiznkNIK2GFd1SQm1x+wmtWg4g4t+NrJSPj/fpHnubXxAUOIvY7lMFeR2lawRLsigCaGZrcXCzuTKA==" + dependencies: + cropperjs "^1.5.6" + +vue-d3-network@^0.1.28: + version "0.1.28" + resolved "https://registry.yarnpkg.com/vue-d3-network/-/vue-d3-network-0.1.28.tgz#9cfa24f3c7e94a4218da425f1b2bf6387baa7802" + integrity "sha1-nPok88fpSkIY2kJfGyv2OHuqeAI= sha512-36Id0gT/fMEK0i+rV7ikAbqXdB0wDHK9cBOlXDjLK2FYBB8yAExN82dYsmTF4GPiGx59hsQV/MvgWmercRjDww==" + dependencies: + d3-force "^1.0.6" + +vue-eslint-parser@^7.0.0, vue-eslint-parser@^7.10.0: + version "7.11.0" + resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-7.11.0.tgz#214b5dea961007fcffb2ee65b8912307628d0daf" + integrity "sha1-IUtd6pYQB/z/su5luJEjB2KNDa8= sha512-qh3VhDLeh773wjgNTl7ss0VejY9bMMa0GoDG2fQVyDzRFdiU3L7fw74tWZDHNQXdZqxO3EveQroa9ct39D2nqg==" + dependencies: + debug "^4.1.1" + eslint-scope "^5.1.1" + eslint-visitor-keys "^1.1.0" + espree "^6.2.1" + esquery "^1.4.0" + lodash "^4.17.21" + semver "^6.3.0" + +vue-hot-reload-api@^2.3.0: + version "2.3.4" + resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2" + integrity "sha1-UylVzB6yCKPZkLOp+acFdGV+CPI= sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==" + +vue-jest@^3.0.5: + version "3.0.7" + resolved "https://registry.yarnpkg.com/vue-jest/-/vue-jest-3.0.7.tgz#a6d29758a5cb4d750f5d1242212be39be4296a33" + integrity "sha1-ptKXWKXLTXUPXRJCISvjm+QpajM= sha512-PIOxFM+wsBMry26ZpfBvUQ/DGH2hvp5khDQ1n51g3bN0TwFwTy4J85XVfxTRMukqHji/GnAoGUnlZ5Ao73K62w==" + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.26.0" + chalk "^2.1.0" + deasync "^0.1.15" + extract-from-css "^0.4.4" + find-babel-config "^1.1.0" + js-beautify "^1.6.14" + node-cache "^4.1.1" + object-assign "^4.1.1" + source-map "^0.5.6" + tsconfig "^7.0.0" + vue-template-es2015-compiler "^1.6.0" + +"vue-loader-v16@npm:vue-loader@^16.1.0": + version "16.8.3" + resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-16.8.3.tgz#d43e675def5ba9345d6c7f05914c13d861997087" + integrity "sha1-1D5nXe9bqTRdbH8FkUwT2GGZcIc= sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==" + dependencies: + chalk "^4.1.0" + hash-sum "^2.0.0" + loader-utils "^2.0.0" + +vue-loader@^15.9.2: + version "15.9.8" + resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.9.8.tgz#4b0f602afaf66a996be1e534fb9609dc4ab10e61" + integrity "sha1-Sw9gKvr2aplr4eU0+5YJ3EqxDmE= sha512-GwSkxPrihfLR69/dSV3+5CdMQ0D+jXg8Ma1S4nQXKJAznYFX14vHdc/NetQc34Dw+rBbIJyP7JOuVb9Fhprvog==" + dependencies: + "@vue/component-compiler-utils" "^3.1.0" + hash-sum "^1.0.2" + loader-utils "^1.1.0" + vue-hot-reload-api "^2.3.0" + vue-style-loader "^4.1.0" + +vue-lodash@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/vue-lodash/-/vue-lodash-2.1.2.tgz#1ec2b1471ee289518e8d285250a25516adee6c51" + integrity "sha1-HsKxRx7iiVGOjShSUKJVFq3ubFE= sha512-6QsNC7/XjrK4xKxFhh6Ppvcrfm0uAeR/lFsySsMgfEFUWkvRztcAIS3MsqAI4bBnAaLo9ou+8tUfJ8d+yrljQg==" + +vue-luxon@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/vue-luxon/-/vue-luxon-0.10.0.tgz#82d31da8ca8d2c04166ca591326adb6675564eec" + integrity "sha1-gtMdqMqNLAQWbKWRMmrbZnVWTuw= sha512-edMqK3qfWNze9z7Upbkb6RSI5XFFwaU3LwD6ZPJJPBhinTg1VBH7Rn8qNi5+5GmHMcbp2ybnOWm78m5lTjznFw==" + dependencies: + luxon "^1.25.0" + +vue-markdown@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/vue-markdown/-/vue-markdown-2.2.4.tgz#db0f774178f3bc91ee18c626d86a3a0d2de22746" + integrity "sha1-2w93QXjzvJHuGMYm2Go6DS3iJ0Y= sha512-hoTX/W1UIdHZrp/b0vpHSsJXAEfWsafaQLgtE2VX4gY8O/C3L2Gabqu95gyG429rL4ML1SwGv+xsPABX7yfFIQ==" + dependencies: + highlight.js "^9.12.0" + markdown-it "^6.0.1" + markdown-it-abbr "^1.0.3" + markdown-it-deflist "^2.0.1" + markdown-it-emoji "^1.1.1" + markdown-it-footnote "^2.0.0" + markdown-it-ins "^2.0.0" + markdown-it-katex "^2.0.3" + markdown-it-mark "^2.0.0" + markdown-it-sub "^1.0.0" + markdown-it-sup "^1.0.0" + markdown-it-task-lists "^2.0.1" + markdown-it-toc-and-anchor "^4.1.2" + +vue-native-websocket@^2.0.14: + version "2.0.15" + resolved "https://registry.yarnpkg.com/vue-native-websocket/-/vue-native-websocket-2.0.15.tgz#e94af2bb7f54beeaac5281d953751d2858b76964" + integrity "sha1-6Uryu39UvuqsUoHZU3UdKFi3aWQ= sha512-i3UvRL99rY8ytV0VJzcWDwY3fRPoeh2fGYvB9862JocEQOx/oCw/VtPIUwP4tSzmzJvJZNkvP71wfhfS1sVhxQ==" + +vue-pipeline@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/vue-pipeline/-/vue-pipeline-1.0.12.tgz#d0bcdc352f365336f18c15f548fee1346e0c8bbc" + integrity "sha1-0LzcNS82UzbxjBX1SP7hNG4Mi7w= sha512-iVRGipthPd/KOr9XGw7TJt1VOfJvBYrPUbA4wNW/QQ4GLOrQXC+cMhN7mulJoWlXn0g/FkxM4hnDlPMo36yhvQ==" + dependencies: + string-width "^4.2.0" + +vue-prism-editor@^1.2.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/vue-prism-editor/-/vue-prism-editor-1.3.0.tgz#dcef6d8731623227db27d59be7ffca50bc57b6d3" + integrity "sha1-3O9thzFiMifbJ9Wb5//KULxXttM= sha512-54RfgtMGRMNr9484zKMOZs1wyLDR6EfFylzE2QrMCD9alCvXyYYcS0vX8oUHh+6pMUu6ts59uSN9cHglpU2NRQ==" + +vue-property-decorator@^9.1.2: + version "9.1.2" + resolved "https://registry.yarnpkg.com/vue-property-decorator/-/vue-property-decorator-9.1.2.tgz#266a2eac61ba6527e2e68a6933cfb98fddab5457" + integrity "sha1-JmourGG6ZSfi5oppM8+5j92rVFc= sha512-xYA8MkZynPBGd/w5QFJ2d/NM0z/YeegMqYTphy7NJQXbZcuU6FC6AOdUAcy4SXP+YnkerC6AfH+ldg7PDk9ESQ==" + +vue-ref@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/vue-ref/-/vue-ref-2.0.0.tgz#483084d732abed11da796778a8266a3af0ea1a9c" + integrity "sha1-SDCE1zKr7RHaeWd4qCZqOvDqGpw= sha512-uKNKpFOVeWNqS2mrBZqnpLyXJo5Q+vnkex6JvpENvhXHFNBW/SJTP8vJywLuVT3DpxwXcF9N0dyIiZ4/NpTexQ==" + +vue-router@^3.2.0: + version "3.5.3" + resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.5.3.tgz#041048053e336829d05dafacf6a8fb669a2e7999" + integrity "sha1-BBBIBT4zaCnQXa+s9qj7ZpoueZk= sha512-FUlILrW3DGitS2h+Xaw8aRNvGTwtuaxrRkNSHWTizOfLUie7wuYwezeZ50iflRn8YPV5kxmU2LQuu3nM/b3Zsg==" + +vue-style-loader@^4.1.0, vue-style-loader@^4.1.2: + version "4.1.3" + resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-4.1.3.tgz#6d55863a51fa757ab24e89d9371465072aa7bc35" + integrity "sha1-bVWGOlH6dXqyTonZNxRlByqnvDU= sha512-sFuh0xfbtpRlKfm39ss/ikqs9AbKCoXZBpHeVZ8Tx650o0k0q/YCM7FRvigtxpACezfq6af+a7JeqVTWvncqDg==" + dependencies: + hash-sum "^1.0.2" + loader-utils "^1.0.2" + +vue-template-compiler@^2.6.14: + version "2.6.14" + resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.14.tgz#a2f0e7d985670d42c9c9ee0d044fed7690f4f763" + integrity "sha1-ovDn2YVnDULJye4NBE/tdpD092M= sha512-ODQS1SyMbjKoO1JBJZojSw6FE4qnh9rIpUZn2EUT86FKizx9uH5z6uXiIrm4/Nb/gwxTi/o17ZDEGWAXHvtC7g==" + dependencies: + de-indent "^1.0.2" + he "^1.1.0" + +vue-template-es2015-compiler@^1.6.0, vue-template-es2015-compiler@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" + integrity "sha1-HuO8mhbsv1EYvjNLsV+cRvgvWCU= sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==" + +vue@2.6.14, vue@^2.5.16, vue@^2.6.11: + version "2.6.14" + resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.14.tgz#e51aa5250250d569a3fbad3a8a5a687d6036e235" + integrity "sha1-5RqlJQJQ1Wmj+606ilpofWA24jU= sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ==" + +vuedraggable@^2.24.3: + version "2.24.3" + resolved "https://registry.yarnpkg.com/vuedraggable/-/vuedraggable-2.24.3.tgz#43c93849b746a24ce503e123d5b259c701ba0d19" + integrity "sha1-Q8k4SbdGokzlA+Ej1bJZxwG6DRk= sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==" + dependencies: + sortablejs "1.10.2" + +vuetify-loader@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/vuetify-loader/-/vuetify-loader-1.7.2.tgz#5cdc45309496cf3a5fe431fd7611706ffa4aa8c8" + integrity "sha1-XNxFMJSWzzpf5DH9dhFwb/pKqMg= sha512-2GSo4KvRAOThBsj8mvtIEeIoyBAZx38GDfh8D90e/or7Hzx4813krJKvcQAllyLO/Ln0eQWrq2IuvBXnZ55cSA==" + dependencies: + decache "^4.6.0" + file-loader "^6.2.0" + loader-utils "^2.0.0" + +vuetify@2.4.6: + version "2.4.6" + resolved "https://registry.yarnpkg.com/vuetify/-/vuetify-2.4.6.tgz#127b37bd36c7a63f61615e0cd6f97e8b203e7a07" + integrity "sha1-Ens3vTbHpj9hYV4M1vl+iyA+egc= sha512-oqAWKAin07ip/QuT/p4bL1LegE3MYPbfojrOcj80RATZDSnJyco2PZD8QuIzd0RhYfdAuSTkY8elvHsLu90RuQ==" + +vuex@^3.6.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.6.2.tgz#236bc086a870c3ae79946f107f16de59d5895e71" + integrity "sha1-I2vAhqhww655lG8QfxbeWdWJXnE= sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==" + +w3c-hr-time@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity "sha1-ConN9cwVgi35w2BUNnaWPgzDCM0= sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==" + dependencies: + browser-process-hrtime "^1.0.0" + +w3c-xmlserializer@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz#30485ca7d70a6fd052420a3d12fd90e6339ce794" + integrity "sha1-MEhcp9cKb9BSQgo9Ev2Q5jOc55Q= sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==" + dependencies: + domexception "^1.0.1" + webidl-conversions "^4.0.2" + xml-name-validator "^3.0.0" + +walker@^1.0.7, walker@~1.0.5: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity "sha1-vUmNtHev5XPcBBhfAR06uKjXZT8= sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==" + dependencies: + makeerror "1.0.12" + +warning@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" + integrity "sha1-Fungd+uKhtavfWSqHgX9hbRnjKM= sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==" + dependencies: + loose-envify "^1.0.0" + +watchpack-chokidar2@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" + integrity "sha1-OFAAcu5uzmbzdpk2lQ6hdxvhyVc= sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==" + dependencies: + chokidar "^2.1.8" + +watchpack@^1.7.4: + version "1.7.5" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" + integrity "sha1-EmfmxV4Lm1vkTCAjrtVDeiwmxFM= sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==" + dependencies: + graceful-fs "^4.1.2" + neo-async "^2.5.0" + optionalDependencies: + chokidar "^3.4.1" + watchpack-chokidar2 "^2.0.1" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity "sha1-wdjRSTFtPqhShIiVy2oL/oh7h98= sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==" + dependencies: + minimalistic-assert "^1.0.0" + +wcwidth@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==" + dependencies: + defaults "^1.0.3" + +web-streams-polyfill@4.0.0-beta.1: + version "4.0.0-beta.1" + resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.1.tgz#3b19b9817374b7cee06d374ba7eeb3aeb80e8c95" + integrity "sha1-Oxm5gXN0t87gbTdLp+6zrrgOjJU= sha512-3ux37gEX670UUphBF9AMCq8XM6iQ8Ac6A+DSRRjDoRBm1ufCkaCDdNVbaqq60PsEkdNlLKrGtv/YBP4EJXqNtQ==" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity "sha1-qFWYCx8LazWbodXZ+zmulB+qY60= sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + +webpack-bundle-analyzer@^3.8.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.9.0.tgz#f6f94db108fb574e415ad313de41a2707d33ef3c" + integrity "sha1-9vlNsQj7V05BWtMT3kGicH0z7zw= sha512-Ob8amZfCm3rMB1ScjQVlbYYUEJyEjdEtQ92jqiFUYt5VkEeO2v5UMbv49P/gnmCZm3A6yaFQzCBvpZqN4MUsdA==" + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + bfj "^6.1.1" + chalk "^2.4.1" + commander "^2.18.0" + ejs "^2.6.1" + express "^4.16.3" + filesize "^3.6.1" + gzip-size "^5.0.0" + lodash "^4.17.19" + mkdirp "^0.5.1" + opener "^1.5.1" + ws "^6.0.0" + +webpack-chain@^6.4.0: + version "6.5.1" + resolved "https://registry.yarnpkg.com/webpack-chain/-/webpack-chain-6.5.1.tgz#4f27284cbbb637e3c8fbdef43eef588d4d861206" + integrity "sha1-TycoTLu2N+PI+970Pu9YjU2GEgY= sha512-7doO/SRtLu8q5WM0s7vPKPWX580qhi0/yBHkOxNkv50f6qB76Zy9o2wRTrrPULqYTvQlVHuvbA8v+G5ayuUDsA==" + dependencies: + deepmerge "^1.5.2" + javascript-stringify "^2.0.1" + +webpack-dev-middleware@^3.7.2: + version "3.7.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5" + integrity "sha1-Bjk3KxQyYuK4SrldO5GnWXBhwsU= sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==" + dependencies: + memory-fs "^0.4.1" + mime "^2.4.4" + mkdirp "^0.5.1" + range-parser "^1.2.1" + webpack-log "^2.0.0" + +webpack-dev-server@^3.11.0: + version "3.11.2" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.2.tgz#695ebced76a4929f0d5de7fd73fafe185fe33708" + integrity "sha1-aV687Xakkp8NXef9c/r+GF/jNwg= sha512-A80BkuHRQfCiNtGBS1EMf2ChTUs0x+B3wGDFmOeT4rmJOHhHTCH2naNxIHhmkr0/UillP4U3yeIyv1pNp+QDLQ==" + dependencies: + ansi-html "0.0.7" + bonjour "^3.5.0" + chokidar "^2.1.8" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + debug "^4.1.1" + del "^4.1.1" + express "^4.17.1" + html-entities "^1.3.1" + http-proxy-middleware "0.19.1" + import-local "^2.0.0" + internal-ip "^4.3.0" + ip "^1.1.5" + is-absolute-url "^3.0.3" + killable "^1.0.1" + loglevel "^1.6.8" + opn "^5.5.0" + p-retry "^3.0.1" + portfinder "^1.0.26" + schema-utils "^1.0.0" + selfsigned "^1.10.8" + semver "^6.3.0" + serve-index "^1.9.1" + sockjs "^0.3.21" + sockjs-client "^1.5.0" + spdy "^4.0.2" + strip-ansi "^3.0.1" + supports-color "^6.1.0" + url "^0.11.0" + webpack-dev-middleware "^3.7.2" + webpack-log "^2.0.0" + ws "^6.2.1" + yargs "^13.3.2" + +webpack-log@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" + integrity "sha1-W3ko4GN1k/EZ0y9iJ8HgrDHhtH8= sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==" + dependencies: + ansi-colors "^3.0.0" + uuid "^3.3.2" + +webpack-merge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" + integrity "sha1-onxS6ng9E5iv0gh/VH17nS9DY00= sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==" + dependencies: + lodash "^4.17.15" + +webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity "sha1-7t2OwLko+/HL/plOItLYkPMwqTM= sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==" + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@^4.0.0: + version "4.46.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.46.0.tgz#bf9b4404ea20a073605e0a011d188d77cb6ad542" + integrity "sha1-v5tEBOogoHNgXgoBHRiNd8tq1UI= sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q==" + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + acorn "^6.4.1" + ajv "^6.10.2" + ajv-keywords "^3.4.1" + chrome-trace-event "^1.0.2" + enhanced-resolve "^4.5.0" + eslint-scope "^4.0.3" + json-parse-better-errors "^1.0.2" + loader-runner "^2.4.0" + loader-utils "^1.2.3" + memory-fs "^0.4.1" + micromatch "^3.1.10" + mkdirp "^0.5.3" + neo-async "^2.6.1" + node-libs-browser "^2.2.1" + schema-utils "^1.0.0" + tapable "^1.1.3" + terser-webpack-plugin "^1.4.3" + watchpack "^1.7.4" + webpack-sources "^1.4.1" + +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity "sha1-ia1Slbv2S0gKvLox5JU6ynBvV2A= sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==" + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity "sha1-f4RzvIOd/YdgituV1+sHUhFXikI= sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" + +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3, whatwg-encoding@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity "sha1-WrrPd3wyFmpR0IXWtPPn0nET3bA= sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==" + dependencies: + iconv-lite "0.4.24" + +whatwg-fetch@>=0.10.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" + integrity "sha1-3O0k838mJO0CgXJdUdDi4/5nf4w= sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" + +whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity "sha1-PUseAxLSB5h5+Cav8Y2+7KWWD78= sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + +whatwg-url@^6.4.1: + version "6.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" + integrity "sha1-8t8Cv/F2/WUHDfdK1cy7WhmZZag= sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==" + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +whatwg-url@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + integrity "sha1-wsSS8eymEpiO/T0iZr4bn8YXDQY= sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==" + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity "sha1-E3V7yJsgmwSf5dhkMOIc9AqJqOY= sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==" + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==" + +which@^1.2.9, which@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity "sha1-pFBD1U9YBTFtqNYvn1CRjT2nCwo= sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==" + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity "sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE= sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==" + dependencies: + isexe "^2.0.0" + +wildcard@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-1.1.2.tgz#a7020453084d8cd2efe70ba9d3696263de1710a5" + integrity "sha1-pwIEUwhNjNLv5wup02liY94XEKU= sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng==" + +word-wrap@^1.2.3, word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity "sha1-YQY29rH3A4kb00dxzLF/uTtHB5w= sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + +workbox-background-sync@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-4.3.1.tgz#26821b9bf16e9e37fd1d640289edddc08afd1950" + integrity "sha1-JoIbm/Funjf9HWQCie3dwIr9GVA= sha512-1uFkvU8JXi7L7fCHVBEEnc3asPpiAL33kO495UMcD5+arew9IbKW2rV5lpzhoWcm/qhGB89YfO4PmB/0hQwPRg==" + dependencies: + workbox-core "^4.3.1" + +workbox-broadcast-update@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-broadcast-update/-/workbox-broadcast-update-4.3.1.tgz#e2c0280b149e3a504983b757606ad041f332c35b" + integrity "sha1-4sAoCxSeOlBJg7dXYGrQQfMyw1s= sha512-MTSfgzIljpKLTBPROo4IpKjESD86pPFlZwlvVG32Kb70hW+aob4Jxpblud8EhNb1/L5m43DUM4q7C+W6eQMMbA==" + dependencies: + workbox-core "^4.3.1" + +workbox-build@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-build/-/workbox-build-4.3.1.tgz#414f70fb4d6de47f6538608b80ec52412d233e64" + integrity "sha1-QU9w+01t5H9lOGCLgOxSQS0jPmQ= sha512-UHdwrN3FrDvicM3AqJS/J07X0KXj67R8Cg0waq1MKEOqzo89ap6zh6LmaLnRAjpB+bDIz+7OlPye9iii9KBnxw==" + dependencies: + "@babel/runtime" "^7.3.4" + "@hapi/joi" "^15.0.0" + common-tags "^1.8.0" + fs-extra "^4.0.2" + glob "^7.1.3" + lodash.template "^4.4.0" + pretty-bytes "^5.1.0" + stringify-object "^3.3.0" + strip-comments "^1.0.2" + workbox-background-sync "^4.3.1" + workbox-broadcast-update "^4.3.1" + workbox-cacheable-response "^4.3.1" + workbox-core "^4.3.1" + workbox-expiration "^4.3.1" + workbox-google-analytics "^4.3.1" + workbox-navigation-preload "^4.3.1" + workbox-precaching "^4.3.1" + workbox-range-requests "^4.3.1" + workbox-routing "^4.3.1" + workbox-strategies "^4.3.1" + workbox-streams "^4.3.1" + workbox-sw "^4.3.1" + workbox-window "^4.3.1" + +workbox-cacheable-response@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-4.3.1.tgz#f53e079179c095a3f19e5313b284975c91428c91" + integrity "sha1-9T4HkXnAlaPxnlMTsoSXXJFCjJE= sha512-Rp5qlzm6z8IOvnQNkCdO9qrDgDpoPNguovs0H8C+wswLuPgSzSp9p2afb5maUt9R1uTIwOXrVQMmPfPypv+npw==" + dependencies: + workbox-core "^4.3.1" + +workbox-core@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-4.3.1.tgz#005d2c6a06a171437afd6ca2904a5727ecd73be6" + integrity "sha1-AF0sagahcUN6/WyikEpXJ+zXO+Y= sha512-I3C9jlLmMKPxAC1t0ExCq+QoAMd0vAAHULEgRZ7kieCdUd919n53WC0AfvokHNwqRhGn+tIIj7vcb5duCjs2Kg==" + +workbox-expiration@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-4.3.1.tgz#d790433562029e56837f341d7f553c4a78ebe921" + integrity "sha1-15BDNWICnlaDfzQdf1U8Snjr6SE= sha512-vsJLhgQsQouv9m0rpbXubT5jw0jMQdjpkum0uT+d9tTwhXcEZks7qLfQ9dGSaufTD2eimxbUOJfWLbNQpIDMPw==" + dependencies: + workbox-core "^4.3.1" + +workbox-google-analytics@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-4.3.1.tgz#9eda0183b103890b5c256e6f4ea15a1f1548519a" + integrity "sha1-ntoBg7EDiQtcJW5vTqFaHxVIUZo= sha512-xzCjAoKuOb55CBSwQrbyWBKqp35yg1vw9ohIlU2wTy06ZrYfJ8rKochb1MSGlnoBfXGWss3UPzxR5QL5guIFdg==" + dependencies: + workbox-background-sync "^4.3.1" + workbox-core "^4.3.1" + workbox-routing "^4.3.1" + workbox-strategies "^4.3.1" + +workbox-navigation-preload@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-navigation-preload/-/workbox-navigation-preload-4.3.1.tgz#29c8e4db5843803b34cd96dc155f9ebd9afa453d" + integrity "sha1-Kcjk21hDgDs0zZbcFV+evZr6RT0= sha512-K076n3oFHYp16/C+F8CwrRqD25GitA6Rkd6+qAmLmMv1QHPI2jfDwYqrytOfKfYq42bYtW8Pr21ejZX7GvALOw==" + dependencies: + workbox-core "^4.3.1" + +workbox-precaching@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-4.3.1.tgz#9fc45ed122d94bbe1f0ea9584ff5940960771cba" + integrity "sha1-n8Re0SLZS74fDqlYT/WUCWB3HLo= sha512-piSg/2csPoIi/vPpp48t1q5JLYjMkmg5gsXBQkh/QYapCdVwwmKlU9mHdmy52KsDGIjVaqEUMFvEzn2LRaigqQ==" + dependencies: + workbox-core "^4.3.1" + +workbox-range-requests@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-4.3.1.tgz#f8a470188922145cbf0c09a9a2d5e35645244e74" + integrity "sha1-+KRwGIkiFFy/DAmpotXjVkUkTnQ= sha512-S+HhL9+iTFypJZ/yQSl/x2Bf5pWnbXdd3j57xnb0V60FW1LVn9LRZkPtneODklzYuFZv7qK6riZ5BNyc0R0jZA==" + dependencies: + workbox-core "^4.3.1" + +workbox-routing@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-4.3.1.tgz#a675841af623e0bb0c67ce4ed8e724ac0bed0cda" + integrity "sha1-pnWEGvYj4LsMZ85O2OckrAvtDNo= sha512-FkbtrODA4Imsi0p7TW9u9MXuQ5P4pVs1sWHK4dJMMChVROsbEltuE79fBoIk/BCztvOJ7yUpErMKa4z3uQLX+g==" + dependencies: + workbox-core "^4.3.1" + +workbox-strategies@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-4.3.1.tgz#d2be03c4ef214c115e1ab29c9c759c9fe3e9e646" + integrity "sha1-0r4DxO8hTBFeGrKcnHWcn+Pp5kY= sha512-F/+E57BmVG8dX6dCCopBlkDvvhg/zj6VDs0PigYwSN23L8hseSRwljrceU2WzTvk/+BSYICsWmRq5qHS2UYzhw==" + dependencies: + workbox-core "^4.3.1" + +workbox-streams@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-4.3.1.tgz#0b57da70e982572de09c8742dd0cb40a6b7c2cc3" + integrity "sha1-C1facOmCVy3gnIdC3Qy0Cmt8LMM= sha512-4Kisis1f/y0ihf4l3u/+ndMkJkIT4/6UOacU3A4BwZSAC9pQ9vSvJpIi/WFGQRH/uPXvuVjF5c2RfIPQFSS2uA==" + dependencies: + workbox-core "^4.3.1" + +workbox-sw@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-sw/-/workbox-sw-4.3.1.tgz#df69e395c479ef4d14499372bcd84c0f5e246164" + integrity "sha1-32njlcR5700USZNyvNhMD14kYWQ= sha512-0jXdusCL2uC5gM3yYFT6QMBzKfBr2XTk0g5TPAV4y8IZDyVNDyj1a8uSXy3/XrvkVTmQvLN4O5k3JawGReXr9w==" + +workbox-webpack-plugin@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-webpack-plugin/-/workbox-webpack-plugin-4.3.1.tgz#47ff5ea1cc074b6c40fb5a86108863a24120d4bd" + integrity "sha1-R/9eocwHS2xA+1qGEIhjokEg1L0= sha512-gJ9jd8Mb8wHLbRz9ZvGN57IAmknOipD3W4XNE/Lk/4lqs5Htw4WOQgakQy/o/4CoXQlMCYldaqUg+EJ35l9MEQ==" + dependencies: + "@babel/runtime" "^7.0.0" + json-stable-stringify "^1.0.1" + workbox-build "^4.3.1" + +workbox-window@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-4.3.1.tgz#ee6051bf10f06afa5483c9b8dfa0531994ede0f3" + integrity "sha1-7mBRvxDwavpUg8m436BTGZTt4PM= sha512-C5gWKh6I58w3GeSc0wp2Ne+rqVw8qwcmZnQGpjiek8A2wpbxSJb1FdCoQVO+jDJs35bFgo/WETgl1fqgsxN0Hg==" + dependencies: + workbox-core "^4.3.1" + +worker-farm@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + integrity "sha1-JqlMU5G7ypJhUgAvabhKS/dy5ag= sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==" + dependencies: + errno "~0.1.7" + +worker-rpc@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/worker-rpc/-/worker-rpc-0.1.1.tgz#cb565bd6d7071a8f16660686051e969ad32f54d5" + integrity "sha1-y1Zb1tcHGo8WZgaGBR6WmtMvVNU= sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg==" + dependencies: + microevent.ts "~0.1.1" + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity "sha1-H9H2cjXVttD+54EFYAG/tpTAOwk= sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==" + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity "sha1-6Tk7oHEC5skaOyIUePAlfNKFblM= sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==" + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity "sha1-Z+FFz/UQpqaYS98RUpEdadLrnkM= sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==" + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + +write-file-atomic@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.1.tgz#d0b05463c188ae804396fd5ab2a370062af87529" + integrity "sha1-0LBUY8GIroBDlv1asqNwBir4dSk= sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +ws@^5.2.0: + version "5.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.3.tgz#05541053414921bc29c63bee14b8b0dd50b07b3d" + integrity "sha1-BVQQU0FJIbwpxjvuFLiw3VCwez0= sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA==" + dependencies: + async-limiter "~1.0.0" + +ws@^6.0.0, ws@^6.2.1: + version "6.2.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e" + integrity "sha1-3Vzb1XqZeZFgl2UtePHMX66gwy4= sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==" + dependencies: + async-limiter "~1.0.0" + +ws@^7.0.0: + version "7.5.5" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.5.tgz#8b4bc4af518cfabd0473ae4f99144287b33eb881" + integrity "sha1-i0vEr1GM+r0Ec65PmRRCh7M+uIE= sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==" + +xml-but-prettier@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/xml-but-prettier/-/xml-but-prettier-1.0.1.tgz#f5a33267ed42ccd4e355c62557a5e39b01fb40f3" + integrity "sha1-9aMyZ+1CzNTjVcYlV6XjmwH7QPM= sha512-C2CJaadHrZTqESlH03WOyw0oZTtoy2uEg6dSDF6YRg+9GnYNub53RRemLpnvtbHDFelxMx4LajiFsYeR6XJHgQ==" + dependencies: + repeat-string "^1.5.2" + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity "sha1-auc+Bt5NjG5H+fsYH3jWSK1FfGo= sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + +xmlchars@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity "sha1-Bg/hvLf5x2/ioX24apvDq4lCEMs= sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + +xtend@^4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity "sha1-u3J3n1+kZRhrH0OPZ0+jR/2121Q= sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + +y18n@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity "sha1-tfJZyCzW4zaSHv17/Yv1YN6e7t8= sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity "sha1-f0k00PfKjFb5UxSTndzS3ZHOHVU= sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity "sha1-27fa+b/YusmrRev2ArjLrQ1dCP0= sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity "sha1-m7knkNnA7/7GO+c1GeEaNQGaOnI= sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + +yaml@^1.10.2, yaml@^1.7.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity "sha1-IwHF/78StGfejaIzOkWeKeeSDks= sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + +yargs-parser@10.x: + version "10.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" + integrity "sha1-cgImW4n36eny5XZeD+c1qQXtuqg= sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==" + dependencies: + camelcase "^4.1.0" + +yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity "sha1-Ew8JcC667vJlDVTObj5XBvek+zg= sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==" + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity "sha1-LrfcOwKJcY/ClfNidThFxBoMlO4= sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" + +yargs@^13.3.0, yargs@^13.3.2: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + integrity "sha1-rX/+/sGqWVZayRX4Lcyzipwxot0= sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==" + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.2" + +yargs@^16.0.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity "sha1-HIK/D2tqZur85+8w43b0mhJHf2Y= sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==" + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yorkie@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yorkie/-/yorkie-2.0.0.tgz#92411912d435214e12c51c2ae1093e54b6bb83d9" + integrity "sha1-kkEZEtQ1IU4SxRwq4Qk+VLa7g9k= sha512-jcKpkthap6x63MB4TxwCyuIGkV0oYP/YRyuQU5UO0Yz/E/ZAu+653/uov+phdmO54n6BcvFRyyt0RRrWdN2mpw==" + dependencies: + execa "^0.8.0" + is-ci "^1.0.10" + normalize-path "^1.0.0" + strip-indent "^2.0.0" + +zenscroll@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/zenscroll/-/zenscroll-4.0.2.tgz#e8d5774d1c0738a47bcfa8729f3712e2deddeb25" + integrity "sha1-6NV3TRwHOKR7z6hynzcS4t7d6yU= sha512-jEA1znR7b4C/NnaycInCU6h/d15ZzCd1jmsruqOKnZP6WXQSMH3W2GL+OXbkruslU4h+Tzuos0HdswzRUk/Vgg==" diff --git a/version.go b/version.go new file mode 100644 index 0000000..3c7fec3 --- /dev/null +++ b/version.go @@ -0,0 +1,13 @@ +package catalyst + +import ( + _ "embed" + "strings" +) + +//go:embed VERSION +var VERSION string + +func GetVersion() string { + return strings.TrimSpace(VERSION) +} diff --git a/websocket.go b/websocket.go new file mode 100644 index 0000000..afd421a --- /dev/null +++ b/websocket.go @@ -0,0 +1,84 @@ +package catalyst + +import ( + "encoding/json" + "log" + "net/http" + "sync" + + "github.com/arangodb/go-driver" + "github.com/gin-gonic/gin" + "github.com/gobwas/ws" + "github.com/gobwas/ws/wsutil" + "github.com/google/uuid" + + "github.com/SecurityBrewery/catalyst/bus" +) + +type websocketBroker struct { + clients map[string]chan []byte + mu sync.Mutex +} + +func (wb *websocketBroker) Publish(b []byte) { + for _, channel := range wb.clients { + channel <- b + } +} + +func (wb *websocketBroker) CloseSocket(id string) { + wb.mu.Lock() + if channel, ok := wb.clients[id]; ok { + close(channel) + delete(wb.clients, id) + } + wb.mu.Unlock() +} + +func (wb *websocketBroker) NewWebsocket() (string, chan []byte) { + id := uuid.New().String() + channel := make(chan []byte, 10) + wb.mu.Lock() + wb.clients[id] = channel + wb.mu.Unlock() + return id, channel +} + +func handleWebSocket(catalystBus *bus.Bus) func(ctx *gin.Context) { + broker := websocketBroker{clients: map[string]chan []byte{}} + + // send all messages from bus to websocket + err := catalystBus.SubscribeUpdate(func(ids []driver.DocumentID) { + b, err := json.Marshal(map[string]interface{}{ + "action": "update", + "ids": ids, + }) + if err != nil { + return + } + + broker.Publish(b) + }) + if err != nil { + log.Println(err) + } + + return func(ctx *gin.Context) { + conn, _, _, err := ws.UpgradeHTTP(ctx.Request, ctx.Writer) + if err != nil { + ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "upgrade failed"}) + return + } + + go func() { + defer conn.Close() + + id, messages := broker.NewWebsocket() + for msg := range messages { + if err := wsutil.WriteServerMessage(conn, ws.OpText, msg); err != nil { + broker.CloseSocket(id) + } + } + }() + } +}